編輯:Android開發實例
本文實例講述了Android4.4下MediaProvider無法向外置SD卡中文件寫數據的解決方法。分享給大家供大家參考,具體如下:
Android4.4平台限制應用對外置SD卡的讀寫權限。MediaProvider通過 checkAccess方法 限制對外置SD卡的讀寫。
private void checkAccess(Uri uri, File file, int modeBits) throws FileNotFoundException { final boolean isWrite = (modeBits & MODE_WRITE_ONLY) != 0; final String path; try { path = file.getCanonicalPath(); } catch (IOException e) { throw new IllegalArgumentException("Unable to resolve canonical path for " + file, e); } Context c = getContext(); boolean readGranted = (c.checkCallingOrSelfUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION) == PackageManager.PERMISSION_GRANTED); if (path.startsWith(sExternalPath) || path.startsWith(sLegacyPath)) { if (!readGranted) { c.enforceCallingOrSelfPermission( READ_EXTERNAL_STORAGE, "External path: " + path); } if (isWrite) { if (c.checkCallingOrSelfUriPermission(uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != PackageManager.PERMISSION_GRANTED) { c.enforceCallingOrSelfPermission( WRITE_EXTERNAL_STORAGE, "External path: " + path); } } } else if (path.startsWith(sCachePath)) { if (!readGranted) { c.enforceCallingOrSelfPermission( ACCESS_CACHE_FILESYSTEM, "Cache path: " + path); } //外置SD卡,isWrite = true } else if (isWrite) { // don't write to non-cache, non-sdcard files. throw new FileNotFoundException("Can't access " + file); } else if (isSecondaryExternalPath(path)) { // read access is OK with the appropriate permission if (!readGranted) { c.enforceCallingOrSelfPermission( READ_EXTERNAL_STORAGE, "External path: " + path); } } else { checkWorldReadAccess(path); } }
從以上代碼我們看出,如果sExternalPath 沒有指向外置SD卡並且path 是外置SD卡的文件路徑,那麼該方法 就會拋出FileNotFoundException,sExternalPath 一般都是指向內部存儲
在應用中 我們通常 通過contentresolver.openOutputStream(uri) 來打開存儲卡上媒體文件的文件流,如果媒體文件在外置SD卡上,那麼我們就無法打開對應的文件流,自然肯定無法向其中寫數據。
為了解決該問題,我們只能改變Android4.4平台下Mediaprovider 對向SD卡寫數據的限制,具體修改方式如下
private void checkAccess(Uri uri, File file, int modeBits) throws FileNotFoundException { final boolean isWrite = (modeBits & MODE_WRITE_ONLY) != 0; final String path; try { path = file.getCanonicalPath(); } catch (IOException e) { throw new IllegalArgumentException("Unable to resolve canonical path for " + file, e); } Context c = getContext(); boolean readGranted = (c.checkCallingOrSelfUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION) == PackageManager.PERMISSION_GRANTED); if (path.startsWith(sExternalPath) || path.startsWith(sLegacyPath) || isSecondaryExternalPath(path)) { if (!readGranted) { c.enforceCallingOrSelfPermission( READ_EXTERNAL_STORAGE, "External path: " + path); } if (isWrite) { if (c.checkCallingOrSelfUriPermission(uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != PackageManager.PERMISSION_GRANTED) { c.enforceCallingOrSelfPermission( WRITE_EXTERNAL_STORAGE, "External path: " + path); } } } else if (path.startsWith(sCachePath)) { if (!readGranted) { c.enforceCallingOrSelfPermission( ACCESS_CACHE_FILESYSTEM, "Cache path: " + path); } //外置SD卡,isWrite = true } else if (isWrite) { // don't write to non-cache, non-sdcard files. throw new FileNotFoundException("Can't access " + file); } else { checkWorldReadAccess(path); } },
對於滿足isSecondaryExternalPath(path) 的文件路徑,我們都可以進行讀寫,對於外置SD卡的文件而言 isSecondaryExternalPath(path) 肯定為true
希望本文所述對大家Android程序設計有所幫助。
可以顯示在的Android任務,通過加載進度條的進展。進度條有兩種形狀。加載欄和加載微調(spinner)。在本章中,我們將討論微調(spinner)。Spinner 用
第一步:代碼混淆(注意引入的第三方jar) 在新版本的ADT創建項目時,混碼的文件不再是proguard.cfg,而是project.properties和pro
JSON代表JavaScript對象符號。它是一個獨立的數據交換格式,是XML的最佳替代品。本章介紹了如何解析JSON文件,並從中提取所需的信息。Android提供了四個
Android的允許通過添加不同種類的處理圖像效果。可以輕松地應用圖像處理技術來增加某些種類的圖像效果。這些影響可能是亮度,黑暗中,灰度轉換等Android提供了Bitm