Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發實例 >> Android4.4下MediaProvider無法向外置SD卡中文件寫數據的解決方法

Android4.4下MediaProvider無法向外置SD卡中文件寫數據的解決方法

編輯: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程序設計有所幫助。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved