讀寫Android中assets目錄下的文件的方法詳解
Android資源文件大致可以分為兩種:
第一種是res目錄下存放的可編譯的資源文件:
這種資源文件系統(tǒng)會(huì)在R.java里面自動(dòng)生成該資源文件的ID,所以訪問這種資源文件比較簡單,通過R.XXX.ID即可;
第二種是assets目錄下存放的原生資源文件:
因?yàn)橄到y(tǒng)在編譯的時(shí)候不會(huì)編譯assets下的資源文件,所以我們不能通過R.XXX.ID的方式訪問它們。那我么能不能通過該資源的絕對路徑去訪問它們呢?因?yàn)閍pk安裝之后會(huì)放在/data/app/**.apk目錄下,以apk形式存在,asset/res和被綁定在apk里,并不會(huì)解壓到/data/data/YourApp目錄下去,所以我們無法直接獲取到assets的絕對路徑,因?yàn)樗鼈兏揪蜎]有。
還好Android系統(tǒng)為我們提供了一個(gè)AssetManager工具類。
查看官方API可知,AssetManager提供對應(yīng)用程序的原始資源文件進(jìn)行訪問;這個(gè)類提供了一個(gè)低級(jí)別的API,它允許你以簡單的字節(jié)流的形式打開和讀取和應(yīng)用程序綁定在一起的原始資源文件。
Android除了提供/res目錄存放資源文件外,在/assets目錄也會(huì)提供存放資源文件,在/assets目錄下面不會(huì)在R.java里面自動(dòng)生成ID,所以讀取assets目錄下面的資源文件需要提供路徑,我們可以通過AssetManager類來訪問這些文件。
作者需要實(shí)現(xiàn)從 A.apk( 資源apk ,把所有的資源如:so、apk、可執(zhí)行文件等放到assets目錄下面,apk沒有實(shí)現(xiàn)邏輯代碼)拷貝資源到指定目錄下,所以作者創(chuàng)建了一個(gè)實(shí)現(xiàn)資源拷貝邏輯的 B.apk( 一個(gè)Service,也可用Activity實(shí)現(xiàn)),由于拷貝路徑一般情況下是不可訪問或者創(chuàng)建的(每個(gè)apk安裝之后只能訪問/data/data/自己包名/下面的私有空間),作者需要這個(gè)apk能夠獲取系統(tǒng)權(quán)限(System權(quán)限),則必須在AndroidManifest.xml聲明shareduserid,具體如何操作下一節(jié)進(jìn)行記錄。
一、AssetManager讀取文件常用的幾個(gè)API
1.文件讀取方式
AssetManager.open(String filename),返回的是一個(gè)InputSteam類型的字節(jié)流,這里的filename必須是文件,而不能是文件夾,AssetManager打開資源文件的open方法是一個(gè)重載方法,可以添加一個(gè)打開方式的int參數(shù),根據(jù)參數(shù)不同可做相應(yīng)操作。具體請看官方文檔http://web.mit.edu/clio/MacData/afs/sipb/project/android/docs/reference/android/content/res/AssetManager.html
2.資源文件是可以存在文件夾以及子目錄
public final String[]list(String path),返回當(dāng)前目錄下面的所有文件以及子目錄的名稱??梢酝ㄟ^遞歸遍歷整個(gè)文件目錄,實(shí)現(xiàn)所有資源文件的訪問。String[] Array of strings, one for each asset. These file names are relative to 'path'. You can open the file by concatenating 'path' and a name in the returned string (via File) and passing that to open().
二、相關(guān)實(shí)現(xiàn)代碼
資源APK(A.apk)
具體實(shí)現(xiàn)代碼片段,由于使用系統(tǒng)權(quán)限,生成的路徑可以自己改一下B.apk
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); try { ctxDealFile = this.createPackageContext("com.zlc.ipanel", Context.CONTEXT_IGNORE_SECURITY); } catch (NameNotFoundException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } btn3.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub try { String uiFileName = "ipanelJoin"; deepFile(ctxDealFile, uiFileName); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); textView.setText("file is wrong"); } } }); // } public void deepFile(Context ctxDealFile, String path) { try { String str[] = ctxDealFile.getAssets().list(path); if (str.length > 0) {//如果是目錄 File file = new File("/data/" + path); file.mkdirs(); for (String string : str) { path = path + "/" + string; System.out.println("zhoulc:\t" + path); // textView.setText(textView.getText()+"\t"+path+"\t"); deepFile(ctxDealFile, path); path = path.substring(0, path.lastIndexOf('/')); } } else {//如果是文件 InputStream is = ctxDealFile.getAssets().open(path); FileOutputStream fos = new FileOutputStream(new File("/data/" + path)); byte[] buffer = new byte[1024]; int count = 0; while (true) { count++; int len = is.read(buffer); if (len == -1) { break; } fos.write(buffer, 0, len); } is.close(); fos.close(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }
相關(guān)文章
Android自定義帶動(dòng)畫效果的圓形ProgressBar
這篇文章主要為大家詳細(xì)介紹了Android自定義帶動(dòng)畫效果的圓形ProgressBar,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-05-05Android開發(fā)之Flutter與webview通信橋梁實(shí)現(xiàn)
這篇文章主要為大家介紹了Android開發(fā)之Flutter與webview通信橋梁實(shí)現(xiàn),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06詳解Android Libgdx中ScrollPane和Actor事件沖突問題的解決辦法
這篇文章主要介紹了詳解Android Libgdx中ScrollPane和Actor事件沖突問題的解決辦法的相關(guān)資料,希望通過本文能幫助到大家,需要的朋友可以參考下2017-09-09android使用 ScrollerView 實(shí)現(xiàn) 可上下滾動(dòng)的分類欄實(shí)例
本篇文章主要介紹了android使用 ScrollerView 實(shí)現(xiàn) 可上下滾動(dòng)的分類欄實(shí)例,具有一定的參考價(jià)值,有興趣的可以了解一下。2017-01-01Android 通知使用權(quán)(NotificationListenerService)的使用
這篇文章主要介紹了Android 通知使用權(quán)(NotificationListenerService)的使用的相關(guān)資料,需要的朋友可以參考下2017-06-06Android 軟鍵盤出現(xiàn)不適應(yīng)的解決辦法總結(jié)
這篇文章主要介紹了Android 軟鍵盤出現(xiàn)不適應(yīng)的解決辦法總結(jié)的相關(guān)資料,需要的朋友可以參考下2017-03-03Android Studio finish()方法的使用與解決app點(diǎn)擊“返回”(直接退出)
這篇文章主要介紹了Android Studio finish()方法的使用與解決app點(diǎn)擊“返回”(直接退出),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04RxJava實(shí)戰(zhàn)之訂閱流基本原理示例解析
這篇文章主要為大家介紹了RxJava實(shí)戰(zhàn)之訂閱流基本原理示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12簡單實(shí)現(xiàn)Android滾動(dòng)公告欄
這篇文章主要為大家詳細(xì)介紹了如何簡單實(shí)現(xiàn)Android滾動(dòng)公告欄,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-01-01