1.    介绍
需要安装一些资源到系统中,比如多媒体文件,配置文件或者某种数据文件,可以把它打包放在资源raw目录中,然后在程序中读取解包,并安装在指定目录下

2.    android框架对多媒体的支持
apk包中的数据一般都放在res/raw目录下,只有它的拥有者能通过openRawResourceFd的方式访问,如果不在java层访问,或者要将其安装在其它位置,就需要在java程序中对其进行处理

3.    例程

1)        功能
把多媒体及数据文件打在zip包放在res/raw下,并将其打在安装包apk中,在程序中点击按钮时将其安装在指定目录下

2)        可从此处下载可独立运行的代码

3)        核心代码及说明

package com.android.mydata;

import android.app.Activity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.TextView;
import android.content.res.AssetFileDescriptor;
import android.content.res.Resources;
import android.view.View.OnClickListener;
import android.view.View;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class MyDataActivity extends Activity {
String rootDirectory = "/data/data/com.android.mydata/data/"; // 安装的目录 TextView status;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button btn = (Button) findViewById(R.id.button);
status = (TextView) findViewById(R.id.status);
btn.setText("install"); // 点击此按钮开始安装 status.setText("wait...");
btn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
unpack();
status.setText("okey...");
}
});
}

boolean unpack() {
FileOutputStream out;
byte buf[] = new byte[16384];
try {
Resources res = getResources(); // 获得资源句柄 AssetFileDescriptor fd = res.openRawResourceFd(R.raw.test); // 压缩文件为test.zip
InputStream stream = fd.createInputStream();
ZipInputStream zis = new ZipInputStream(stream);
ZipEntry entry = zis.getNextEntry();
while (entry != null) {
if (entry.isDirectory()) { // 对文件夹处理 File newDir = new File(rootDirectory + entry.getName());
newDir.mkdir();
} else { // 对文件处理 String name = entry.getName();
File outputFile = new File(rootDirectory + name);
String outputPath = outputFile.getCanonicalPath();
name = outputPath
.substring(outputPath.lastIndexOf("/") + 1);
outputPath = outputPath.substring(0, outputPath
.lastIndexOf("/"));
File outputDir = new File(outputPath);
outputDir.mkdirs();
outputFile = new File(outputPath, name);
outputFile.createNewFile();
out = new FileOutputStream(outputFile);

int numread = 0;
do {
numread = zis.read(buf);
if (numread <= 0) {
break;
} else {
out.write(buf, 0, numread);
}
} while (true);
out.close();
}
entry = zis.getNextEntry();
}
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
}

4)        注意:打包数据不能太小,否则会出错。数据打包使用如下命令
zip -r ../test.zip *

4.    参考

1)        源代码语音合成external/svox/picolanginstaller对语音数据的安装