0

After modifying build.gradle with : compileSdkVersion 28 to 32 targetSdkVersion 28 to 32 I can't write a local file from retrofit response. I get error :

java.io.FileNotFoundException: /storage/emulated/0/DontEat/rangt_00001.jpg: open failed: EPERM (Operation not permitted)

AndroidManifest.xml contains :

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

and my code is :

public static void downloadFile(SyncCalls.CallbacksDownload callbacks, final String type, final File file, final Boolean last) {
    final WeakReference<SyncCalls.CallbacksDownload> callbacksWeakReference = new WeakReference<>(callbacks);
    SyncService service = SyncService.retrofit.create(SyncService.class);
    String filename = file.toString().split("/")[5];
    Call<ResponseBody> call = service.downloadFile(filename);
    call.enqueue(new Callback<ResponseBody>() {
        @Override
        public void onResponse(@NonNull Call<ResponseBody> call, @NonNull Response<ResponseBody> response) {
            try {
                OutputStream out = null;
                InputStream in = null;
                ResponseBody body = response.body();
                try {
                    if (body != null) {
                        in = body.byteStream();
                        out = new FileOutputStream(file);
                        byte[] fileReader = new byte[4096];
                        StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
                        StrictMode.setThreadPolicy(policy);
                        while (true) {
                            int read = in.read(fileReader);
                            if (read == -1) {
                                break;
                            }
                            out.write(fileReader, 0, read);
                        }
                        out.flush();
                    }
                } catch (IOException e) {
                    if (BuildConfig.DEBUG) Log.v(Consts.TAG, e.toString());
                } finally {
                    if (in != null) {
                        in.close();
                    }
                    if (out != null) {
                        out.close();
                    }
                }

            } catch (IOException e) {
                if (BuildConfig.DEBUG) Log.v(Consts.TAG, e.toString());
            }
            if (BuildConfig.DEBUG) Log.v(Consts.TAG, "download " + file.toString());
            if (callbacksWeakReference.get() != null)
                callbacksWeakReference.get().onResponseSync(type, "down", last);

        }

Permissions are verified with :

// Storage Permissions variables
private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static final String[] PERMISSIONS_STORAGE = {
        Manifest.permission.READ_EXTERNAL_STORAGE,
        Manifest.permission.WRITE_EXTERNAL_STORAGE
};
//permission method.
public static void verifyStoragePermissions(Activity activity) {
    // Check if we have read or write permission
    int writePermission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
    int readPermission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.READ_EXTERNAL_STORAGE);

    if (writePermission != PackageManager.PERMISSION_GRANTED || readPermission != PackageManager.PERMISSION_GRANTED) {
        // We don't have permission so prompt the user
        ActivityCompat.requestPermissions(
                activity,
                PERMISSIONS_STORAGE,
                REQUEST_EXTERNAL_STORAGE
        );
    }
}

Is my mistake in the code or the permissions please?

I don't develop more because of my very limited English. (It's an app I made many years ago, for personal use only, family, but I can't scale it because of this bug that appeared with new android versions while it was working perfectly so far)

Edit: Actually, I think I'm taking the problem upside down and I'd better use the application's internal data directory with getFilesDir() and I won't have permission problems anymore, if I understood correctly.

Chris972
  • 71
  • 1
  • 8

1 Answers1

0

Add the line in AndroidManifest.xml, inside application tag.. Hope it'll help you.

android:requestLegacyExternalStorage=”true” 
Adi
  • 11
  • 5