0

I am making an android app that needs the MANAGE_EXTERNAL_STORAGE permission (and the read/write permission before android 11). The app requests the permission the first time it starts (using the code of the accepted answer from here).

However, when the user provides the permission they have to manually press the back button to return to the app so it can continue its flow. I have a file manager app on my phone that returns to the app automatically once the permission is granted. So I am looking for a way to implement this in my app as well, preferably using the new method google suggest instead of the now deprecated startActivityForResult

The app I mention is available on playstore here

What I tried?

Replaced the startActivityForResult using ActivityResultLauncher, which is the way google recommends, because startActivityForResult is now deprecated, but it didn't really change the app's behavior/solve the problem. In fact, it seems to be receiving a rejected result whether the user accepts it or not.

  • "I have a file manager app and thus would like to return to the app automatically once the permission is granted" -- being a file manager does not change the fact that Android no longer allows apps in the background to affect the foreground UI very much. – CommonsWare Dec 28 '22 at 16:47
  • @CommonsWare that is the product of an edit of another member on my question. What I wanted to write(which I have now wrote and hopefully won't be edited again) is that the app in the playstore (which is not mine) already implements what I want to do. – Georgios Tsakiridis Dec 28 '22 at 18:35

1 Answers1

0

After searching more thoroughly I found this post and I used part 3) of this answer, which seems to be doing the trick. I also tried replacing the startActivityForResult with the ActivityResultLauncher that Google recommends and it works fine. So the final code is:

  1. Paste this code on the start of MainActivity(or in the activity you want), just after the properties' declarations:

    Handler handler = new Handler();
    
     Runnable checkSettingOn = new Runnable() {
    
         @Override
         public void run() {
             if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
                 return;
             } else {
                 if (Environment.isExternalStorageManager()) {
                     //You have the permission, re-launch MainActivity
                     Intent i = new Intent(MainActivity.this, MainActivity.class);
                     i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                     startActivity(i);
                     return;
                 }
                 handler.postDelayed(this, 200);
             }
         }
     };
    
  2. After this, create an ActivityResultLauncher, which will handle the user's denial part:

    ActivityResultLauncher<Intent> storageLauncher =registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), new ActivityResultCallback<ActivityResult>() {
         @Override
         public void onActivityResult(ActivityResult result) {
             if (SDK_INT >= Build.VERSION_CODES.R)
                 if (!Environment.isExternalStorageManager())
                     //DO STH IF USER DENIES
         }
     });
    
  3. When asking for the permission you then start the handler:

     try {
                     Intent storageIntentTry = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
                     storageIntentTry.addCategory("android.intent.category.DEFAULT");
                     storageIntentTry.setData(Uri.parse(String.format("package:%s", getApplicationContext().getPackageName())));
                     storageLauncher.launch(storageIntentTry);
                     handler.postDelayed(checkSettingOn, 1000);
                 } catch (Exception e) {
                     Intent storageIntentCatch = new Intent();
                     storageIntentCatch.setAction(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
                     storageLauncher.launch(storageIntentCatch);
                     handler.postDelayed(checkSettingOn, 1000);
                 }
    

(Ignore names of intents - can be anything that makes sense)