问题描述
我无法在android oreo(8.0)api 26中保存图像文件。
代码在api level 25(7.0)中完美运行,我没有在文档中找到任何更改
I can't save an image file in android oreo(8.0) api 26.
The code is working perfectly in api level 25 (7.0) and I didn't find any changes in the documentation "Android 8.0 Behavior Changes"
这是我的代码
String root = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toString();
File myrootDir = new File(root);
if (!myrootDir.exists()) {
myrootDir.mkdir();
}
File myDir = new File(root + "/Myimages");
if (!myDir.exists()) {
myDir.mkdir();
}
final String fname = System.currentTimeMillis()+"myimage.png";
File file = new File(myDir, fname);
if (file.exists())
file.delete();
try {
FileOutputStream out = new FileOutputStream(file);
b.compress(Bitmap.CompressFormat.PNG, 100, out);
out.flush();
out.close();
}catch (Exception e){
Log.e("MYAPP", "exception", e);
}
异常是FileNotFoundException,没有这样的文件或目录。 (但为什么不在android n?)
Exception is FileNotFoundException, No such file or directory. (But Why not in android n ?)
java.io.FileNotFoundException: /storage/emulated/0/Pictures/Myimages/1513151272243myimage.png (No such file or directory)
12-13 13:17:52.243 5839-5839/com.package.package W/System.err: at java.io.FileOutputStream.open0(Native Method)
12-13 13:17:52.243 5839-5839/com.package.package W/System.err: at java.io.FileOutputStream.open(FileOutputStream.java:287)
12-13 13:17:52.243 5839-5839/com.package.package W/System.err: at java.io.FileOutputStream.<init>(FileOutputStream.java:223)
12-13 13:17:52.243 5839-5839/com.package.package W/System.err: at java.io.FileOutputStream.<init>(FileOutputStream.java:171)
12-13 13:17:52.243 5839-5839/com.package.package W/System.err: at com.package.package.DetailPage$12.run(DetailPage.java:737)
12-13 13:17:52.244 5839-5839/com.package.package W/System.err: at android.os.Handler.handleCallback(Handler.java:789)
12-13 13:17:52.244 5839-5839/com.package.package W/System.err: at android.os.Handler.dispatchMessage(Handler.java:98)
12-13 13:17:52.244 5839-5839/com.package.package W/System.err: at android.os.Looper.loop(Looper.java:164)
12-13 13:17:52.244 5839-5839/com.package.package W/System.err: at android.app.ActivityThread.main(ActivityThread.java:6541)
12-13 13:17:52.244 5839-5839/com.package.package W/System.err: at java.lang.reflect.Method.invoke(Native Method)
12-13 13:17:52.244 5839-5839/com.package.package W/System.err: at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
12-13 13:17:52.244 5839-5839/com.package.package W/System.err: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
推荐答案
事实上,有一个轻微的微妙变化运行和定位API 26的应用的权限。
There is, in fact, a slight, subtle change in Permissions for apps running on and targeting API 26.
以前,应用会自动获得所有权限我如果用户已授予该组中至少一个权限,则为给定组。这意味着已经被授予 READ_EXTERNAL_STORAGE
的应用程序也会立即获得 WRITE_EXTERNAL_STORAGE
,无论如何是否明确要求 WRITE_EXTERNAL_STORAGE
。
Previously, apps were automatically granted all permissions in a given group if at least one permission in that group had been granted by the user. This means that an app that had been granted the READ_EXTERNAL_STORAGE
would've had WRITE_EXTERNAL_STORAGE
immediately granted to it as well, regardless of whether WRITE_EXTERNAL_STORAGE
had been explicitly requested.
从Oreo开始,对于针对API 26+的应用,这已经是已更正,并且仅授予明确请求的权限。如果用户已经在同一组中授予了权限,则不会提示新权限,但仍然必须请求。
As of Oreo, for apps targeting API 26+, this has been corrected, and only those permissions that are explicitly requested will be granted. If the user has already granted a permission in the same group, then there will be no prompt for the new permission, but it still must be requested.
这就是问题所在, 在这种情况下。当您在Nougat或以下的应用程序上授予 READ_EXTERNAL_STORAGE
权限时,您自动获得了 WRITE_EXTERNAL_STORAGE
,而没有特别要求那个。当您在Oreo中尝试相同的文件保存过程时,您没有自动获得 WRITE_EXTERNAL_STORAGE
,因此写入最终会失败。
That was the problem, in this case. When the READ_EXTERNAL_STORAGE
permission was granted to your app on Nougat or below, you were automatically getting WRITE_EXTERNAL_STORAGE
, too, without having to request that one specifically. When you try the same file save procedure in Oreo, you aren't getting WRITE_EXTERNAL_STORAGE
automatically, so the write ultimately fails.
只需添加 WRITE_EXTERNAL_STORAGE
的特定请求。如果用户已经授予 READ_EXTERNAL_STORAGE
,则他们不会被另一个提示打扰。或者,您可以从一开始就单独请求 WRITE_EXTERNAL_STORAGE
,其中隐含地包含 READ_EXTERNAL_STORAGE
,并且可以节省您需要两个单独请求。
Simply add a specific request for WRITE_EXTERNAL_STORAGE
. If the user has already granted READ_EXTERNAL_STORAGE
, they won't be bothered with another prompt. Alternatively, you could request solely WRITE_EXTERNAL_STORAGE
from the start, which implicitly includes READ_EXTERNAL_STORAGE
, and would save you the need for two separate requests.
这篇关于无法在android oreo update中保存图像文件。怎么做?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!