android/NDK开发assets资源中文名打包问题
16lz
2021-01-24
项目是C开发的能在android跑了,最近想把项目打包上传googleplay碰到一个问题资源图片没办法打包,原先我的图片资源都是直接拷贝到SDcard一个文件夹下的,C代码层直接访问SDcard的资源图片就OK了 ,安装过程好麻烦图片资源要手动拷贝到sdcard上。
这问题纠结了好久
本想把资源放到res目录下的,但是资源有图片 ini配置档之类的文件C代码层访问这个目录也是问题。
放到这个assets文件呢? 测试过这个目录不支持中文名字,由于项目的资源都是中文命名的,改成英文工作量大也影响其他人的修改。
后来发现把资源压缩成zip能放到assets目录下,太高兴了问题能解决了。
解决方案:
把资源打包成zip 放入assets目录下,当程序启动的时候把zip解压到sdcard目录下,这样C层代码能直接访问sdcard下的资源包了。
解压的代码:
这有个很严重问题apk会很大,而且apk卸载了sdcard中的文件不会自动删除希望各位同仁提供方法。
上面代码有部分参考其他人的,本人一直玩C刚学java不久,相信也有人遇到同样的问题拿出来分享一下,如果有更好的方法希望可以交流交流。
这问题纠结了好久
本想把资源放到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 //解压zippackage 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;@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.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 blocke.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<?xml version="1.0" encoding="utf-8"?>
这有个很严重问题apk会很大,而且apk卸载了sdcard中的文件不会自动删除希望各位同仁提供方法。
上面代码有部分参考其他人的,本人一直玩C刚学java不久,相信也有人遇到同样的问题拿出来分享一下,如果有更好的方法希望可以交流交流。
更多相关文章
- android 支付宝SDK集成
- Android(安卓)热补丁技术——资源的热修复
- 在android的java代码中自定义log
- Android(安卓)拼接两个图片
- [androd] android的在线源码网站,各个版本都有(目前已到俺android
- Android之分享篇(配图适合新人):腾讯分享(QQ空间,好友,群)
- Android中View.setPressed是怎么出现按压效果的
- Android(安卓)studio 快捷键,解决返回上次浏览位置ctrl+alt+left/
- Android(安卓)进阶之了解源码——Activity启动