项目是C开发的能在android跑了,最近想把项目打包上传googleplay碰到一个问题资源图片没办法打包,原先我的图片资源都是直接拷贝到SDcard一个文件夹下的,C代码层直接访问SDcard的资源图片就OK了 ,安装过程好麻烦图片资源要手动拷贝到sdcard上。
这问题纠结了好久
本想把资源放到res目录下的,但是资源有图片 ini配置档之类的文件C代码层访问这个目录也是问题。
放到这个assets文件呢? 测试过这个目录不支持中文名字,由于项目的资源都是中文命名的,改成英文工作量大也影响其他人的修改。
后来发现把资源压缩成zip能放到assets目录下,太高兴了问题能解决了。
解决方案:
把资源打包成zip 放入assets目录下,当程序启动的时候把zip解压到sdcard目录下,这样C层代码能直接访问sdcard下的资源包了。
解压的代码:
Test.java: //判断资源是否需要安装,需要跳转到安装页面
public class Test extends Activity {
super.onCreate(savedInstanceState);
JmpPage();
}
private void JmpPage(){
String path = android.os.Environment.getExternalStorageDirectory() + "/Test";
String ZipPath = android.os.Environment.getExternalStorageDirectory() + "/Test.zip";
long length = 28;//Test 文件大小 设置比原文件夹小
//判断是否有SDcard
if(android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)){
File file = new File(path);
long FileSize = 0;
if(file.exists())
{
FileSize = GetFileSize(new File(path))/(1024*1024); //获取SDcard剩余容量
Log.v("Test","FileSize:"+FileSize);
}
file = new File(ZipPath);//删除zip
if(file.exists()){
file.delete();
}
if(FileSize < length){//如果资源包小于37M数据包不完整
if(GetAvailableSdcard() > (length+4))//sdcard内存需要大于39M才可以安装资源
{
Intent intent = new Intent(Test.this, InstallActivity.class); //跳转到解压页面
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
else
{
Toast.makeText(Test.this, "sdcard容量满了,请删除一些!", 1).show();
}
}
Log.v("Test","FileSize > length");
}
else{
Toast.makeText(Test.this, "未找到sdcard无法安装程序!", 1).show();
}
}
private long GetAvailableSdcard()
{
android.os.Environment.getExternalStorageDirectory();
StatFs statFs = new StatFs(android.os.Environment.getExternalStorageDirectory().toString());
// 获取block的SIZE
long BlockSize = statFs.getBlockSize();
// 可使用的Block的数量
long AvailaBlock = statFs.getAvailableBlocks();
long AvailableSize = AvailaBlock * BlockSize;
return AvailableSize;
}
//获取文件夹大小
private long GetFileSize(File file){
long result = 0;
File[] filelist=file.listFiles();
for(int i = 0; i < filelist.length; i++) {
if(filelist[i].isDirectory()) {
result += GetFileSize(filelist[i]);
} else {
result += filelist[i].length();
}
}
return result;
}
InstallActivity.java //解压zip
package com.Test;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import com.Test.R;
import android.app.Activity;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
public class InstallActivity extends Activity {
final private int ZipFileMax = 29965053;//文件夹大小
private int UnZipSize;
private ProgressBar progressbar;
private TextView showtext;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.install);
progressbar = (ProgressBar)findViewById(R.id.progressBar1);
showtext = (TextView)findViewById(R.id.textView1);
final String ZipFileName = android.os.Environment.getExternalStorageDirectory() + "/Test.zip";
final String UnZipLocation = android.os.Environment.getExternalStorageDirectory() + "/";
new Thread(){
public void run(){
CopyAssets();
Log.e("Test",ZipFileName);
Decompression dec = new Decompression(ZipFileName, UnZipLocation);
dec.UnZip();
File file = new File(ZipFileName);//zipFilename
if(file.exists()){
file.delete();
}
UpdateProgress(2);
try {
sleep(2000);
finish();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}.start();
}
private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg){
if(!Thread.currentThread().isInterrupted()){
switch(msg.what){
case 0:
progressbar.setMax(ZipFileMax);
break;
case 1:
progressbar.setProgress(UnZipSize);
// int n = (UnZipSize*100)/ZipFileMax;
//Log.v("Test","百分比:"+n+"%");
//showtext.setText(n);
break;
case 2:
//Toast.makeText(GetNumberActivity.this, "安装完毕", 1).show();
showtext.setText("安装完毕,请重新启动程序进入!");
break;
case 3:
showtext.setText("配置系统中。。。");
case -1:
//String error = msg.getData().getString("error");
// Toast.makeText(InstallActivity.this, error, 1).show();
break;
}
}
super.handleMessage(msg);
}
};
private void UpdateProgress(int type)
{
Message msg = new Message();
msg.what = type;
handler.sendMessage(msg);
}
public String getSDPath(){
File sdDir = null;
boolean sdCardExist = android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED); //判断sd卡是否存在
if (sdCardExist)
{
sdDir =android.os.Environment.getExternalStorageDirectory();//获取跟目录
}
return sdDir.toString();
}
public class Decompression {
private String ZipFile;
private String Location;
public Decompression(String zipFile, String location) {
ZipFile = zipFile;
Location = location;
_dirChecker("");
}
public void UnZip() {
try {
BufferedInputStream fin = new BufferedInputStream(new FileInputStream(ZipFile));
ZipInputStream zin = new ZipInputStream(fin);
ZipEntry ze = null;
byte[] buf = new byte[1024];
int n= 0;
int len = 0;
// ZipFileMax = 52272746;//zin.available();
Log.v("Test","ZipFileMax:"+ZipFileMax);
UpdateProgress(0);
while ((ze = zin.getNextEntry()) != null) {
// Log.v("Test", "pacth:" + ze.getName());
// Log.v("Test","Len:"+ze.getSize());
// Log.v("Test","Time:"+ze.getTime());
if(ze.isDirectory()) {
_dirChecker(ze.getName());
} else {
BufferedOutputStream fout = new BufferedOutputStream(new FileOutputStream(Location + ze.getName()));
while((n = zin.read(buf,0,1024))> 0)
{
fout.write(buf,0,n);
UnZipSize += n;
UpdateProgress(1);
}
zin.closeEntry();
fout.close();
}
}
zin.close();
} catch(Exception e) {
Log.e("Test", "unzip", e);
}
}
private void _dirChecker(String dir) {
File f = new File(Location + dir);
if(!f.isDirectory()) {
f.mkdirs();
}
}
}
private void CopyAssets() {
AssetManager assetManager = getAssets();
String[] files = null;
try {
files = assetManager.list("");
} catch (IOException e) {
Log.e("Test", e.getMessage());
}
UpdateProgress(3);
for(String filename : files) {
InputStream in = null;
OutputStream out = null;
try {
in = assetManager.open(filename);
out = new FileOutputStream(android.os.Environment.getExternalStorageDirectory()+"/" + filename);
CopyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch(Exception e) {
Log.e("Test", e.getMessage());
}
}
}
private void CopyFile(InputStream in, OutputStream out) throws IOException {
byte[] buf = new byte[1024];
int n;
BufferedInputStream fin = new BufferedInputStream(in);
BufferedOutputStream fout = new BufferedOutputStream(out);
while((n = fin.read(buf)) != -1){
fout.write(buf, 0, n);
}
}
}
AndroidManifest.xml
这有个很严重问题apk会很大,而且apk卸载了sdcard中的文件不会自动删除希望各位同仁提供方法。
上面代码有部分参考其他人的,本人一直玩C刚学java不久,相信也有人遇到同样的问题拿出来分享一下,如果有更好的方法希望可以交流交流。