Android M请求权限非活动

Dav*_*nly 37 android android-6.0-marshmallow

我的小部件调用Activity范围之外的安全权限.可以在Android之外请求Android M的权限Activity吗?

gre*_*f82 6

不,这是不可能的.您可以做的是发送通知,用户可以点击然后使用活动来请求/管理权限(可能具有对话框主题).


Ben*_*ger 5

我找到了一个似乎工作正常的解决方法。诀窍是创建一个透明的活动,该活动仅用于请求权限并在之后立即完成。当然,您仍然需要一个上下文,但它不必是一个活动。活动可以通过广播返回结果(授予或拒绝)(因为startActivtyForResult在活动之外是不可能的)。

您可以使用此活动:

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)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

而这种风格的活动

<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>
Run Code Online (Sandbox Code Playgroud)

在清单中:

<activity android:name="GetPermissionsActivity" android:theme="@style/Theme.Transparent" />
Run Code Online (Sandbox Code Playgroud)

然后像这样使用它(需要上下文)

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() {
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)