My widget makes calls to secure permissions outside of an Activity scope. Is it possible to request permissions for Android M outside of an
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,
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
In the manifest:
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())
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() {
// ...
}
}