首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >FileNotFoundException打开失败:将图像文件保存到安卓内部存储时EPERM (不允许操作)

FileNotFoundException打开失败:将图像文件保存到安卓内部存储时EPERM (不允许操作)
EN

Stack Overflow用户
提问于 2020-04-24 19:00:16
回答 4查看 27.6K关注 0票数 17

当我试图将图片保存到android的内部存储器时,我遇到了这个问题。

代码语言:javascript
运行
复制
public static String setImage(Bitmap image) {
    if (image != null) {
        FileOutputStream outputStream = null;
        File dir = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Caramel");
        dir.mkdir();
        String fileName = System.currentTimeMillis() + ".jpg";
        File file = new File(dir, fileName);
        try {
            outputStream = new FileOutputStream(file);
            image.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
            outputStream.flush();
            outputStream.close();
            return fileName;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (outputStream != null) {
                    outputStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    return null;
}

一切都很顺利,我可以在调试模式下看到我的位图图像,但仍然会收到下一个错误:

代码语言:javascript
运行
复制
W/System.err: java.io.FileNotFoundException: /storage/emulated/0/Caramel/1587724428205.jpg: open failed: EPERM (Operation not permitted)
W/System.err:     at libcore.io.IoBridge.open(IoBridge.java:495)
W/System.err:     at java.io.FileOutputStream.(FileOutputStream.java:235)
W/System.err:     at java.io.FileOutputStream.(FileOutputStream.java:186)
W/System.err:     at com.example.caramel.Position.setImage(Position.java:176)
W/System.err:     at com.example.caramel.PositionActivity.onActivityResult(PositionActivity.java:129)
W/System.err:     at android.app.Activity.dispatchActivityResult(Activity.java:8300)
W/System.err:     at android.app.ActivityThread.deliverResults(ActivityThread.java:4905)
W/System.err:     at android.app.ActivityThread.handleSendResult(ActivityThread.java:4953)
W/System.err:     at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51)
W/System.err:     at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
W/System.err:     at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
W/System.err:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2043)
W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:106)
W/System.err:     at android.os.Looper.loop(Looper.java:216)
W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:7464)
W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
W/System.err:     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:549)
W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:955)
W/System.err: Caused by: android.system.ErrnoException: open failed: EPERM (Operation not permitted)
W/System.err:     at libcore.io.Linux.open(Native Method)
W/System.err:     at libcore.io.ForwardingOs.open(ForwardingOs.java:166)
W/System.err:     at libcore.io.BlockGuardOs.open(BlockGuardOs.java:254)
W/System.err:     at libcore.io.ForwardingOs.open(ForwardingOs.java:166)
W/System.err:     at android.app.ActivityThread$AndroidOs.open(ActivityThread.java:7360)
W/System.err:     at libcore.io.IoBridge.open(IoBridge.java:481)
W/System.err:   ... 17 more

看起来,原因可能在我的Manifest.xml文件中,但我已经设置了这些权限:

谢谢你们的支持,伙计们。

EN

回答 4

Stack Overflow用户

发布于 2020-10-15 17:45:43

作为一个临时修复,您可以这样做:在您的android/app/src/main/AndroidManifest.xml

文件,位于

添加android:requestLegacyExternalStorage="true"

,如下所示:

然后它将使用Android 10之前的方式请求访问存储,所以你仍然可以像之前一样保存你的文件。

但请注意:在您将应用程序更新为目标Android11(API30级)后,当您的应用程序在Android11设备上运行时,系统会忽略requestLegacyExternalStorage属性,因此您的应用程序必须准备好支持作用域存储,并为这些设备上的用户迁移应用程序数据。请参见

https://developer.android.com/training/data-storage/use-cases#opt-out-scoped-storage

了解更多信息

票数 12
EN

Stack Overflow用户

发布于 2020-04-24 19:09:07

android的权限系统是非常严格的,你在写内存的时候一定要考虑到这一点,试试这样:

代码语言:javascript
运行
复制
public class MainActivity extends AppCompatActivity {
   Button save;
   Bitmap bitmap;
   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      Drawable drawable = getResources().getDrawable(R.drawable.mario);
      bitmap = ((BitmapDrawable) drawable).getBitmap();
      save = findViewById(R.id.save);
      save.setOnClickListener(new View.OnClickListener() {
         @Override
         public void onClick(View v) {
            ContextWrapper cw = new ContextWrapper(getApplicationContext());
            File directory = cw.getDir("imageDir", Context.MODE_PRIVATE);
            File file = new File(directory, "UniqueFileName" + ".jpg");
            if (!file.exists()) {
               Log.d("path", file.toString());
               FileOutputStream fos = null;
               try {
                  fos = new FileOutputStream(file);
                  bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
                  fos.flush();
                  fos.close();
               } catch (java.io.IOException e) {
                  e.printStackTrace();
               }
            }
         }
      });
   }
}
票数 6
EN

Stack Overflow用户

发布于 2020-12-16 13:04:08

在应用程序的Manifest.xml文件中的应用程序标记内添加以下属性:

代码语言:javascript
运行
复制
android:requestLegacyExternalStorage="true"

最后,它看起来像这样:

代码语言:javascript
运行
复制
...
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61406818

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档