23

I'm trying to achieve some clean up tools. More and more manufacturers have forbidden rooting devices due to some "security reason", it's forbidden NOT to request for unlock.

After API 28, This code will make error:


ActivityCompat.requestPermissions(this, new String[]{
  Manifest.permission.READ_EXTERNAL_STORAGE,
  Manifest.permission.WRITE_EXTERNAL_STORAGE
}, 1); // Request permission or not, Will got same result

File rootFolder = Environment.getExternalStorageDirectory(); // That is working fine
rootFolder.listFiles(); // That will return null

Sure, I can use this:

android:requestLegacyExternalStorage="true"

But I belive that will be killed in future.

So, Any elegant way to manage SDCard?

Stephan Celis
  • 2,492
  • 5
  • 23
  • 38
Alceatraz
  • 432
  • 1
  • 3
  • 13
  • That will work for Android 10. Use it as even if you compile for Android 11 it works for an Android 10 device. And... That code is not for a removable micro sd card. – blackapps Sep 11 '20 at 06:59
  • 1
    There is a permission called MANAGE_EXTERNAL_STORAGE can be used by certain apps like file managers, device migration apps and such. It can give you complete access to the file system. Your clean up tool should fall in the same category https://developer.android.com/training/data-storage/manage-all-files – Pemba Tamang Apr 21 '21 at 12:31
  • Even if your app technically falls within the allowed categories, it's hard to get the permission from Google unless you're some big company – cmak Jan 30 '22 at 15:48

2 Answers2

42

On Android 10 Environment.getExternalStorageDirectory() and Environment.getExternalStoragePublicDirectory() will return storage paths but paths are not readable or writable.

  1. For Android 10 you can continue to use paths provided by Environment.getExternalStorageDirectory() and Environment.getExternalStoragePublicDirectory() if you add android:requestLegacyExternalStorage="true" to application tag in manifest file. At runtime your app can call Environment.isExternalStorageLegacy() to check if the request has been done.

  2. Another (not known) possibility (only for Android 10) is to add <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" /> to manifest file. The user has to go to the advanced settings of the app and enable from Advanced settings Install unknown apps | Allow from this source. The nice thing with this is that the user can switch the access rights. You can make it easier for the user if you implement an intent for Settings.ACTION_APPLICATION_DETAILS_SETTINGS where he can change the settings. A funny thing is that Environment.isExternalStorageLegacy() returns true then too.

  3. Compiling for Android 11 both options do not work on an Android 11 device. (But they continue to work for Android 10 devices). The paths of Environment.getExternalStorageDirectory() and Environment.getExternalStoragePublicDirectory() are usable again in read mode and very often in write mode too. And this is great as one can simply list the contents of directories like Download or Pictures or DCIM/Camera again using the File class. But adding <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" /> to manifest file and implementing an intent for Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION will give your app read/write access for all files even on removable micro sd card. (Finally you can remove the google ban not being able to read/write your own micro sd card on your own Android device using your own app). Environment.isExternalStorageManager() can be used to check if the permission is on/off. As long as you do not try to upload your app to the play store you are fine.

blackapps
  • 8,011
  • 2
  • 11
  • 25
  • Once you added android:requestLegacyExternalStorage="true" updating your app with android:requestLegacyExternalStorage="false" has no effect. And isExternalStorageLegacy() keeps returning true. One has to deinstall the app. With the new solution there is no such trouble. – blackapps Sep 11 '20 at 14:17
  • Sadly the ,,/Android/data directories under Android 11 stay unaccessable. Also for SAF. – blackapps Sep 14 '20 at 19:08
  • 1
    VLC doesn't have permission `"android.permission.MANAGE_EXTERNAL_STORAGE"` https://github.com/videolan/vlc-android/blob/master/application/vlc-android/AndroidManifest.xml and it still can delete files on Android 11. Also Android Studio gives a warning about `MANAGE_EXTERNAL_STORAGE`, so it usually should not be used by apps – user25 Oct 28 '20 at 23:42
  • @user25, also SAF can be used. And you can ignore the warning, well ...unless you wanna go to the play. – blackapps Oct 28 '20 at 23:51
  • 1
    VLC still uses 29 SDK, that's why it works for them.. – user25 Oct 29 '20 at 10:28
  • Interesting if I want my video recorder app to have feature "loop recording" (which requires deleting old video files while recording, like in Dashcam devices) will it be ok to use `MANAGE_EXTERNAL_STORAGE` permission and publishing update on Google Play? – user25 Oct 29 '20 at 10:30
  • I think that every app can delete its own files without that. And further you cam just try. – blackapps Oct 29 '20 at 11:13
  • yes, of course, I know that app can delete its own files without dialog even in shared MOVIES folder, but if a user reinstalls (deletes and installs app again) then new installation of app doesn't have permission for files that were created by previous installation of the same app (on Android 11) – user25 Oct 29 '20 at 12:06
  • " implementing an intent for Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION" how does one do this magic? I've never had such an arse of a time just to write and read a couple of addresses on and off persistent storage – mist42nz Jun 09 '21 at 12:51
-4

use android:requestLegacyExternalStorage="true" in your Manifest below <application

  • this won't always work in the future without an exception from the play store. So, unless you truly need it, you should avoid using this. – jeff Oct 05 '21 at 16:05