Android4.4下MediaProvider無法向外置SD卡中文件寫數(shù)據(jù)的解決方法
本文實例講述了Android4.4下MediaProvider無法向外置SD卡中文件寫數(shù)據(jù)的解決方法。分享給大家供大家參考,具體如下:
Android4.4平臺限制應用對外置SD卡的讀寫權(quán)限。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 一般都是指向內(nèi)部存儲
在應用中 我們通常 通過contentresolver.openOutputStream(uri) 來打開存儲卡上媒體文件的文件流,如果媒體文件在外置SD卡上,那么我們就無法打開對應的文件流,自然肯定無法向其中寫數(shù)據(jù)。
為了解決該問題,我們只能改變Android4.4平臺下Mediaprovider 對向SD卡寫數(shù)據(jù)的限制,具體修改方式如下
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程序設計有所幫助。
相關(guān)文章
android12?SD如何動態(tài)申請讀寫權(quán)限
這篇文章主要給大家介紹了關(guān)于android12?SD如何動態(tài)申請讀寫權(quán)限的相關(guān)資料,從Android?6.0開始,權(quán)限不再是在manifest?件中粘貼?下即可,這時候權(quán)限也正式?進?家的視野,需要的朋友可以參考下2023-07-07
Android自定義ViewPagerIndicator實現(xiàn)炫酷導航欄指示器(ViewPager+Fragment)
這篇文章主要為大家詳細介紹了Android自定義ViewPagerIndicator實現(xiàn)炫酷導航欄指示器,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-02-02
Java程序員轉(zhuǎn)Android開發(fā)必讀經(jīng)驗一份
小編最近幾日偷偷的發(fā)現(xiàn)部分Java程序員想轉(zhuǎn)安卓開發(fā),故此加緊補充知識,為大家搜集資料,積極整理前人的經(jīng)驗,希望可以給正處于困惑中的你,帶來些許的幫助。2017-11-11
Android編程實現(xiàn)列表側(cè)滑刪除的方法詳解
這篇文章主要介紹了Android編程實現(xiàn)列表側(cè)滑刪除的方法,結(jié)合實例形式詳細分析了Android列表側(cè)滑刪除功能的原理與具體實現(xiàn)技巧,注釋中包含詳盡的說明,需要的朋友可以參考下2018-01-01

