編輯:關於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程序設計有所幫助。
OpenCV使用Harris算法實現角點檢測
效果圖源碼KqwOpenCVFeaturesDemo角點是兩條邊緣的交點或者在局部鄰域中有多個顯著邊緣方向的點。Harris角點檢測是一種在角點檢測中最常見的技術。Har
Android開發最佳實踐
本文是Futurice公司的Android開發人員總結的最佳實踐,遵循這些准則可以避免重復制造輪子。如果你對iOS或者WindowsPhone開發感興趣,那麼也請看看iO
內存是手游的硬傷——Unity游戲Mono內存管理與洩漏
WeTest導讀內存是游戲的硬傷,如果沒有做好內存的管理問題,游戲極有可能會出現卡頓,閃退等影響用戶體驗的現象。本文介紹了在騰訊游戲在Unity游戲開發過程中常見的Mon
Android Studio使用AndroidJUnitRunner進行單元測試
目前google是推薦使用AndroidJUnitRunner來進行單元測試的。 使用AndroidJUnitRunner進行測試的時候,需要做在b