WRITE_EXTERNAL_STORAGE 无法在棒棒糖上工作,即使它已在清单中设置
Posted
技术标签:
【中文标题】WRITE_EXTERNAL_STORAGE 无法在棒棒糖上工作,即使它已在清单中设置【英文标题】:WRITE_EXTERNAL_STORAGE not working on lollipop even though it's set in the manifest 【发布时间】:2017-05-23 23:08:08 【问题描述】:我正在尝试将应用程序本地数据文件夹中的图像保存到外部存储。我的清单包含以下内容(在清单的应用程序标记之前):
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="23" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="18"/>
当我尝试以下操作时
try
InputStream in = new FileInputStream(filePath);
File outPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File outFile = new File(outPath, "mypicture.jpg");
//try fails at this line
OutputStream out = new FileOutputStream(outFile);
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0)
out.write(buf, 0, len);
in.close();
in = null;
out.flush();
out.close();
out = null;
catch (IOException e)
e.printStackTrace();
我收到此错误:
java.io.FileNotFoundException: /storage/emulated/0/Pictures/mypicture.jpg: open failed: EACCES (Permission denied)
我也尝试了稍微不同的输出路径:
String sdCardPath = Environment.getExternalStorageDirectory() + "/MyFolder";
new File(sdCardPath).mkdirs();
File outFile = new File(sdCardPath, "mypicture.jpg");
但这也给了我一个错误:
java.io.FileNotFoundException: /storage/emulated/0/MyFolder/mypicture.jpg: open failed: ENOENT (No such file or directory)
设备运行的是 Android 4.4.2,因此不需要在运行时请求权限(据我所知无法请求权限)。
为了允许将文件保存到外部存储,是否还缺少其他内容?
【问题讨论】:
【参考方案1】:问题的原因是通过 gradle 拉入的外部库有自己的清单请求 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="18">
我自己的清单仅在不包括 maxSdkVersion="18" 时才有效,因此添加该参数的清单合并导致了此错误。我的解决方案是将我自己的清单更改为:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="23" tools:replace="android:maxSdkVersion" />
我假设 maxSdkVersion="18" 意味着任何运行 SDK 19-22 的设备都不能拥有此权限(23+ 能够在运行时请求它)。
【讨论】:
【参考方案2】:在 Android 6 中,您需要在运行时请求权限。如果你在 4.4 上运行,仍然有这个错误,我认为你还没有创建文件夹。
String sdCardPath = Environment.getExternalStorageDirectory() + "/MyFolder";
new File(sdCardPath) .mkdirs(); //create folders where write files
File outFile = new File(sdCardPath, "mypicture.jpg");
【讨论】:
我已经有一行来创建如上所示的文件夹:new File(sdCardPath).mkdirs();这似乎不能解决问题。 哦。对不起我的包。您是否尝试删除android:maxSdkVersion="18"
。或者你的目录与你的图片路径MyFolder\mypicture.jpg
是否正确?
我已经尝试过使用和不使用 maxSdkVersion,但都没有任何区别。我相信路径是正确的,我也尝试将 mypicture.jpg 直接放入 Environment.getExternalStorageDirectory() 但有同样的错误。就好像在安装时没有授予 WRITE_EXTERNAL_STORAGE 权限,即使它肯定在清单中(我使用 apktool 检查它没有以某种方式被剥离)。
我刚刚注意到一些有趣的事情。当我侧加载应用程序并列出所需的权限时,我看不到“修改或删除 SD 卡的内容”和“读取 SD 卡的内容”,当我安装另一个应用程序时会看到.这似乎很奇怪,因为权限清楚地在清单中,是否需要其他东西才能使这些权限出现在安装时?【参考方案3】:
试试这个:
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/MyFolder");
myDir.mkdirs();
Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
String fname = "Image-" + n + ".jpg";
File file = new File (myDir, fname);
if (file.exists ()) file.delete ();
file.createNewFile();
try
FileOutputStream out = new FileOutputStream(file);
FileInputStream in = new FileInputStream(filePath);
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0)
out.write(buf, 0, len);
in.close();
out.flush();
out.close();
catch (Exception e)
e.printStackTrace();
还为清单添加读写权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
【讨论】:
【参考方案4】:这不是必须的,但请尝试在您的 Manifest 中添加此权限。
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE/>
有时 Android 会欺骗我们。
【讨论】:
以上是关于WRITE_EXTERNAL_STORAGE 无法在棒棒糖上工作,即使它已在清单中设置的主要内容,如果未能解决你的问题,请参考以下文章
请求 WRITE_EXTERNAL_STORAGE 权限的正确方法[关闭]
为啥在 Android Q 及更高版本上不需要 WRITE_EXTERNAL_STORAGE
在运行时请求和允许 WRITE_EXTERNAL_STORAGE 权限对当前会话没有影响
请问,我的androi studio中动态申请权限,Manifest.permission.WRITE_EXTERNAL_STORAGE