Android M request permission non activity

前端 未结 6 1902
渐次进展
渐次进展 2020-12-11 14:38

My widget makes calls to secure permissions outside of an Activity scope. Is it possible to request permissions for Android M outside of an

相关标签:
6条回答
  • 2020-12-11 14:54

    I found a workaround which seems to work fine. The trick is to create a transparent activity which is only there to request the permissions and is finished immediately afterwards. You'll still need a context of course but it doesn't have to be an activity. The activity can return the result (granted or denied) via a broadcast (since startActivtyForResult is not possible outside of an activity).

    You can use this activity:

    import android.content.Intent
    import android.content.pm.PackageManager
    import android.os.Bundle
    import android.support.v4.app.ActivityCompat
    import android.support.v7.app.AppCompatActivity
    
    internal const val PERMISSIONS_KEY = "permissions"
    internal const val ACTION_PERMISSIONS_GRANTED = "GetPermissionsActivity.permissions_granted"
    internal const val ACTION_PERMISSIONS_DENIED = "GetPermissionsActivity.permissions_denied"
    
    class GetPermissionsActivity: AppCompatActivity() {
    
        private val permissionRequestCode = 0
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            ActivityCompat.requestPermissions(
                this,
                intent.getStringArrayExtra(PERMISSIONS_KEY),
                permissionRequestCode
            )
        }
    
        override fun onRequestPermissionsResult(
            requestCode: Int,
            permissions: Array<out String>,
            grantResults: IntArray
        ) {
            if (requestCode == permissionRequestCode) {
                if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
                    sendBroadcast(Intent(ACTION_PERMISSIONS_GRANTED))
                } else {
                    sendBroadcast(Intent(ACTION_PERMISSIONS_DENIED))
                }
                finish()
            } else {
                super.onRequestPermissionsResult(requestCode, permissions, grantResults)
            }
        }
    }
    

    And this style for the activity

    <style name="Theme.Transparent" parent="Theme.AppCompat">
        <item name="android:windowIsTranslucent">true</item>
        <item name="android:windowBackground">@android:color/transparent</item>
        <item name="android:windowContentOverlay">@null</item>
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowIsFloating">true</item>
        <item name="android:backgroundDimEnabled">false</item>
        <item name="android:windowAnimationStyle">@null</item>
    </style>
    

    In the manifest:

    <activity android:name="GetPermissionsActivity" android:theme="@style/Theme.Transparent" />
    

    And then use it like this (context required)

    class SomeClass : BroadcastReceiver() {
    
        private fun someFunction(context: Context) {
            val intentFilter = IntentFilter()
            intentFilter.addAction(ACTION_PERMISSIONS_GRANTED)
            intentFilter.addAction(ACTION_PERMISSIONS_DENIED)
            context.registerReceiver(this, intentFilter)
            val intent = Intent(context, GetPermissionsActivity::class.java)
            intent.putExtra(PERMISSIONS_KEY, arrayOf(<your permissions>))
            context.startActivity(intent)
        }
    
        override fun onReceive(context: Context, intent: Intent) {
            when {
                intent.action == ACTION_PERMISSIONS_GRANTED -> {
                    context.unregisterReceiver(this)
                    onPermissionsGranted()
                }
                intent.action == ACTION_PERMISSIONS_DENIED -> {
                    context.unregisterReceiver(this)
                    onPermissionsDenied()
                }
                else -> super.onReceive(context, intent)
            }
        }
    
        private fun onPermissionsGranted() {
            // ...
        }
    
        private fun onPermissionsDenied() {
            // ...
        }
    }
    
    0 讨论(0)
  • 2020-12-11 14:55

    No, it's not possible. What you can do is to send a notification where the user can tap and then use an activity to request/manage the permission (maybe with dialog theme).

    0 讨论(0)
  • 2020-12-11 15:02

    You could use the Easy Permissions library.

    Android requires that these request come from an Activity. With Easy Permissions this is no longer an issue, you may request permission from anywhere as long as you provide Context. In addition, if you request a permission that is already granted the user will not be prompted.

    Full disclosure, our company manages and develops this free to use library. That being said, we are confident that it is a useful tool and we would not share it otherwise.

    0 讨论(0)
  • 2020-12-11 15:02

    I was creating an app that required to check for permissions in many activities, so I created a static class that I could use globally in the app. And it worked. This worked for me.

    I created a method to check request for permissions in a different class like this.

    public class CheckForPermissions implements ActivityCompat.OnRequestPermissionsResultCallback {
    private static final int MY_PERMISSIONS_REQUEST_READ_LOCATION = 1;
    
    
        public static void checkForLocationPermissions(Activity context){
            if(ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION)  != PackageManager.PERMISSION_GRANTED
            || ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION)  != PackageManager.PERMISSION_GRANTED){
                ActivityCompat.requestPermissions(context,
                        new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                        MY_PERMISSIONS_REQUEST_READ_LOCATION);
    
        }
    }}
    

    In my Activity, I called the method like this

            CheckForPermissions.checkForLocationPermissions(this);
    
    0 讨论(0)
  • 2020-12-11 15:11

    I think it's possible to request a permission outside of an Activity, as long as you use the method

    ActivityCompat.requestPermissions (Activity activity, String[] permissions, int requestCode)

    from the support library and pass the Activity as a parameter of the method.

    For example:

    ActivityCompat.requestPermissions(targetActivity, new String[] {Manifest.permission.CAMERA}, PERMISSION_REQUEST_CODE);
    

    where targetActivity is the Activity that should implement the method:

    onRequestPermissionsResult (int requestCode, String[] permissions, int[] grantResults)

    That's the method that will handle de permission request result.

    0 讨论(0)
  • 2020-12-11 15:19

    You can only request permission either from Activity or from fragment.

    Figure out a point in your Activity or Fragment where you feel App will require a permission, then call requestPermission method. sending notification will not work because you wanna your code processing un-till you get that requested permissions, and then resume your functionality from onRequestPermissionResult() method.

    0 讨论(0)
提交回复
热议问题