Can you request permissions synchronously in Android Marshmallow (API 23)'s runtime permissions model?

前端 未结 5 1469
既然无缘
既然无缘 2021-02-01 13:09

Say you have a method like this:

public boolean saveFile (Url url, String content) {

   // save the file, this can be done a lot of different ways, but
   // ba         


        
5条回答
  •  心在旅途
    2021-02-01 13:53

    Here's how I solved the "synchronicity" issue without having to explicitly block (and busy-wait), or without requiring a separate "boot-loader" Activity. I refactored splash screen Activity as follows:

    update: A more complete example can be found here.


    note: Because the requestPermissions() API calls startActivityForResult()

    public final void requestPermissions(@NonNull String[] permissions, int requestCode) {
        Intent intent = getPackageManager().buildRequestPermissionsIntent(permissions);
        startActivityForResult(REQUEST_PERMISSIONS_WHO_PREFIX, intent, requestCode, null);
    }
    

    the main view-creation logic was moved from OnCreate() to OnCreate2(), and OnCreate() now handles the permissions check. If RequestPermissions() needs to be called, then the associated OnRequestPermissionsResult() restarts this activity (forwarding a copy of the original bundle).


    [Activity(Label = "MarshmellowActivated",
        MainLauncher = true,      
        Theme = "@style/Theme.Transparent",
        Icon = "@drawable/icon"        
        ////////////////////////////////////////////////////////////////
        // THIS PREVENTS OnRequestPermissionsResult() from being called
        //NoHistory = true
    )]
    public class MarshmellowActivated : Activity
    {
        private const int ANDROID_PERMISSION_REQUEST_CODE__SDCARD = 112;
        private Bundle _savedInstanceState;
    
        public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Permission[] grantResults)
        {
            base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
    
            switch (requestCode)
            {
                case ANDROID_PERMISSION_REQUEST_CODE__SDCARD:
                    if (grantResults.Length > 0 && grantResults[0] == Permission.Granted)
                    {       
                        Intent restartThisActivityIntent = new Intent(this, this.GetType());
                        if (_savedInstanceState != null)
                        {
                            // *ref1: Forward bundle from one intent to another
                            restartThisActivityIntent.PutExtras(_savedInstanceState);
                        }
                        StartActivity(restartThisActivityIntent);
                    }
                    else
                    {                   
                        throw new Exception("SD Card Write Access: Denied.");
                    }
                    break;
            }
        }
    
        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);
    
            ///////////////////////////////////////////////////////////////////////////////////////////////////////////
            // Android v6 requires explicit permission granting from user at runtime for extra sweet security goodness
            Permission extStoragePerm = ApplicationContext.CheckSelfPermission(Android.Manifest.Permission.WriteExternalStorage);
    
            //if(extStoragePerm == Permission.Denied)
            if (extStoragePerm != Permission.Granted)
            {
                _savedInstanceState = savedInstanceState;
                // **calls startActivityForResult()**
                RequestPermissions(new[] { Android.Manifest.Permission.WriteExternalStorage }, ANDROID_PERMISSION_REQUEST_CODE__SDCARD);
            }
            else
            {
                OnCreate2(savedInstanceState);
            }
        }
    
        private void OnCreate2(Bundle savedInstanceState)
        {
            //...
        }
    }
    

    ref1: Forward bundle from one intent to another

    note: This can be refactored to handle more permissions generally. It currently handles the sdcard write permission only, which should convey the pertinent logic with sufficient clarity.

提交回复
热议问题