打开应用权限设置

34

关于Android M上的粒度权限。

如果用户两次拒绝了权限请求,

或者用户标记为“不再询问”。

我该如何直接打开/链接到应用程序权限设置?


12
在此情况下,似乎Settings中没有Intent操作,即使在MNC文档中也没有。 ACTION_APPLICATION_DETAILS_SETTINGS可能是最接近的一个。 - CommonsWare
2个回答

28

假设在AndroidManifest.xml文件中有以下内容:

<uses-permission android:name="android.permission.WRITE_CALENDAR"/>
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
<!-- ETC. -->

接下来,就像下面的示例活动一样,我们可以检查现有/授予的权限,如果缺少任何权限,则将用户发送到应用程序设置:

然后,就像下面的示例活动一样,我们可以检查现有/已授权的权限,如果缺少任何权限,则将用户发送到应用程序设置页面:
package com.example.permissions.myapplication;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private static final int REQUEST_APP_SETTINGS = 168;

    private static final String[] requiredPermissions = new String[]{
            Manifest.permission.WRITE_CALENDAR,
            Manifest.permission.WRITE_CONTACTS
            /* ETC.. */
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        /* All version with SDK_INT < 22 grant permissions on install time. */
        if (Build.VERSION.SDK_INT > 22 && !hasPermissions(requiredPermissions)) {
            Toast.makeText(this, "Please grant all permissions", Toast.LENGTH_LONG).show();
            goToSettings();
        }
    }

    private void goToSettings() {
        Intent myAppSettings = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, Uri.parse("package:" + getPackageName()));
        myAppSettings.addCategory(Intent.CATEGORY_DEFAULT);
        myAppSettings.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivityForResult(myAppSettings, REQUEST_APP_SETTINGS);
    }

    public boolean hasPermissions(@NonNull String... permissions) {
        for (String permission : permissions)
            if (PackageManager.PERMISSION_GRANTED != checkSelfPermission(permission))
                return false;
        return true;
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_APP_SETTINGS) {
            if (hasPermissions(requiredPermissions)) {
                Toast.makeText(this, "All permissions granted!", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(this, "Permissions not granted.", Toast.LENGTH_LONG).show();
            }
        }
        super.onActivityResult(requestCode, resultCode, data);
    }
}

我刚刚在 Nexus 6 / AndroidOS 6(棉花糖)上尝试了一下。


2
仅作简单补充,此方法不适用于第三方应用程序权限解决方案,例如在OnePlus 2 Oxygen OS中使用的解决方案。在Oxygen OS中,设置是从自定义设置视图中管理的。 - user2229108
@Corne 这是指应用程序崩溃了,还是什么也没有发生? - rpattabi
3
您进入了一个应用屏幕,但是在 Oxygen OS 中,权限不是从该屏幕管理的。一切都还能正常运作,只是您无法从该屏幕更改权限,仅此而已。 - user2229108
感谢您的添加。 - Andrei Mărcuţ
我正在开发一个基于Lolipop的应用,但突然决定升级到M版本。请帮忙解决问题,因为当我在M版本上安装应用时,它会崩溃。我已经在build.gradle中更新了目标SDK版本和所有相关内容。 - Harsha

20

使用此代码启动您的应用程序权限设置页面

Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
            Uri.parse("package:" + getPackageName()));
    intent.addCategory(Intent.CATEGORY_DEFAULT);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(intent);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接