Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FileNotFoundException open failed: EPERM (Operation not permitted) during saving image file to internal storage on android

I faced this problem when I tried to save the image to internal storage on android.

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;
}

All goes nice and well, and I can see my Bitmap image in debug mode, but all the same, i get the next error:

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.<init>(FileOutputStream.java:235)
    W/System.err:     at java.io.FileOutputStream.<init>(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

It seems, that reason could be in my Manifest.xml file, but i've already set these permissions:

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />

Thanks for your support, guys.

like image 840
Gongelini Avatar asked Apr 24 '20 11:04

Gongelini


Video Answer


6 Answers

As a temporary fix you could do: In your android/app/src/main/AndroidManifest.xml file, at

<application android:label="APPNAME" android:icon="ICONNAME" ...>

add android:requestLegacyExternalStorage="true", like so:

<application android:label="APPNAME" android:icon="ICONNAME" android:requestLegacyExternalStorage="true">

It will then use the pre-Android 10 way of requesting access to storage, so you can still save your file as you could earlier.

But caution: After you update your app to target Android 11 (API level 30), the system ignores the requestLegacyExternalStorage attribute when your app is running on Android 11 devices, so your app must be ready to support scoped storage and to migrate app data for users on those devices. See https://developer.android.com/training/data-storage/use-cases#opt-out-scoped-storage for more info

like image 168
Rogier Avatar answered Oct 10 '22 17:10

Rogier


I got the issue In android 11 ":" is not allowed in file name. And when you append date at the end of file name its add ":" at the end. so just replace all ":" with "." and its working fine.

        String fileName = 
              System.currentTimeMillis().toString().replaceAll(":", ".") + ".jpg";

like image 45
Makwana Mehul Avatar answered Oct 10 '22 18:10

Makwana Mehul


The permission system in android is very strict, you must take this into account when writing to internal memory Try something like this:

    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();
               }
            }
         }
      });
   }
}
like image 33
adriangc24 Avatar answered Oct 10 '22 17:10

adriangc24


Add the following attribute in your app's Manifest.xml file inside the application tag:

android:requestLegacyExternalStorage="true"

Finally, it will look like this:

<application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        android:requestLegacyExternalStorage="true">
...
</application>
like image 20
Razz Avatar answered Oct 10 '22 17:10

Razz


In android 11 you can use this pattern

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD_MR1) {
    mPath= getActivity().getExternalFilesDir(Environment.DIRECTORY_DCIM) + "/" + now + ".jpeg";
}
else
{
    mPath= Environment.getExternalStorageDirectory().toString() + "/" + now + ".jpeg";
}
like image 37
Muhammad Basit Jamil Abbasi Avatar answered Oct 10 '22 17:10

Muhammad Basit Jamil Abbasi


I would suggest to change it to

        ContextWrapper cw = new ContextWrapper(mContext);
    String fullPath =cw.getExternalFilesDir(Environment.DIRECTORY_MUSIC).toString();
    File directory = cw.getExternalFilesDir(Environment.DIRECTORY_MUSIC);

check it here https://www.programmersought.com/article/50766505696/

like image 36
Mehran Sahandi Far Avatar answered Oct 10 '22 16:10

Mehran Sahandi Far