无法在android oreo更新中保存图像文件。怎么做?

时间:2017-12-13 07:23:12

标签: java android android-8.0-oreo

我无法在android oreo(8.0)api 26中保存图像文件 该代码在api level 25(7.0)中完美运行,我在文档中找不到任何更改" 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?)

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)

2 个答案:

答案 0 :(得分:15)

事实上,针对API 26运行和定位的应用的权限略有细微变化。

以前,如果用户授予了该组中至少一个权限,则应用会自动授予给定组中的所有权限。这意味着,无论是否明确请求READ_EXTERNAL_STORAGE,已授予WRITE_EXTERNAL_STORAGE的应用也会立即授予WRITE_EXTERNAL_STORAGE

从Oreo开始,对于针对API 26+的应用,此问题已得到纠正,并且只会授予明确请求的权限。如果用户已经在同一组中授予了权限,则不会提示新权限,但仍然必须请求它。

在这种情况下,这就是问题所在。在Nougat或更低版本上为您的应用授予READ_EXTERNAL_STORAGE权限后,您自动获得WRITE_EXTERNAL_STORAGE,而无需专门申请。{1}}当您在奥利奥尝试相同的文件保存程序时,您不会自动获得WRITE_EXTERNAL_STORAGE,因此写入最终会失败。

只需添加WRITE_EXTERNAL_STORAGE的特定请求即可。如果用户已经授予READ_EXTERNAL_STORAGE,则他们不会被其他提示所困扰。或者,您可以从一开始就单独请求WRITE_EXTERNAL_STORAGE,其中隐含地包含READ_EXTERNAL_STORAGE,并且可以节省您对两个单独请求的需求。

答案 1 :(得分:1)

我也遇到了同样的问题,我在2个月内遇到了这个问题。我已经首先在清单中授予WRITE_EXTERNAL_STORAGE权限,并再次检查它是否具有写入权限。我认为这不是许可问题。因为当我使用oreo测试文件夹正在创建时,我正在创建的文件夹中存在损坏的图像文件。因为它没有进入画廊,然后在保存它返回我图像没有捕获。我只在android 7.1.1和oreo中遇到这个问题。 Upto android 7.0它运行正常。我已经检查了设备samsung galaxy note 8和谷歌像素xl 2.我正在使用带有gps和以下功能的自定义相机

public void onImageAvailable(ImageReader reader) {
                    Image image = null;
                    try {
                        image = reader.acquireLatestImage();
                        ByteBuffer buffer = image.getPlanes()[0].getBuffer();
                        byte[] bytes = new byte[buffer.capacity()];
                        buffer.get(bytes);
                        save(bytes);

用于图像字节保存,保存功能包含以下代码

OutputStream output = null;
                    try {
                        output = new FileOutputStream(finalFile);
                        output.write(bytes);
                    } finally {
                        if (null != output) {
                            output.close();
                        }
                    }