简体   繁体   English

如何在Android 6中请求用户权限

[英]How to ask for user permissions in Android 6

I am totally confused regarding the new permission system in Android 6 (Marshmallow). 我对Android 6(棉花糖)中的新权限系统感到困惑。

I am using two so called 'dangeorus permissions' - 我正在使用两个所谓的“ dangeorus权限”-

<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />

And I use these permissions in many places. 而且我在许多地方都使用了这些权限。

I need to access the user accounts for Registering the app, Sending Feedback etc.And I also access Device Id for registering the app. 我需要访问用于注册应用程序,发送反馈等的用户帐户,还需要访问设备ID以注册应用程序。

I wrote two functions to get the list of Mail Accounts and the device id in a Java Class named util, and uses these function in AsyncTask as well as fragments. 我编写了两个函数来获取名为util的Java类中的邮件帐户列表和设备ID,并在AsyncTask和片段中使用这些函数。

Now, I am totally at loss, how to request for those permissions! 现在,我完全不知所措,如何请求这些权限! Should I ask in the functions or every time I call these functions? 我应该询问功能还是每次调用这些功能? And in the AsyncTask, how can I get a response? 在AsyncTask中,如何获得响应?

Please help. 请帮忙。

You shouldn't ask for permissions in AsyncTask. 您不应该在AsyncTask中请求权限。 In fact you shouldn't even retrieve deviceId or some information in it - pass it as a parameter. 实际上,您甚至都不应该检索deviceId或其中的某些信息-将其作为参数传递。

Settings of each application has list of 'dangerous' permissions with their status. 每个应用程序的设置都有“危险”权限及其状态的列表。 If you app targeting sdk 23, they're all disabled by default. 如果您以sdk 23为目标的应用程序,则默认情况下将其全部禁用。 So, when you use code which requires such permission, you need to check if it's granted and if not - ask for it. 因此,当您使用需要此类许可的代码时,需要检查是否已授予该代码,如果没有,请检查该代码。

The simplies way is to create utility class for permissions like this: 简单的方法是为这样的权限创建实用程序类:

public final class PermissionUtils {

    private PermissionUtils() {
    }

    public static boolean checkPermissions(Context context, String... permissions) {
        for (String permission : permissions) {
            if (!checkPermission(context, permission)) {
                return false;
            }
        }
        return true;
    }

    public static boolean checkPermission(Context context, String permission) {
        return ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED;
    }

    public static boolean isDeviceInfoGranted(Context context) {
        return checkPermission(context, Manifest.permission.READ_PHONE_STATE);
    }

    public static void requestPermissions(Object o, int permissionId, String... permissions) {
        if (o instanceof Fragment) {
            FragmentCompat.requestPermissions((Fragment) o, permissions, permissionId);
        } else if (o instanceof Activity) {
            ActivityCompat.requestPermissions((AppCompatActivity) o, permissions, permissionId);
        }
    }
}

And then use it like this: (in your Fragment / Activity) 然后像这样使用它:(在您的片段/活动中)

if (PermissionUtils.isDeviceInfoGranted(this)) {
    //get deviceId and proccess your code
} else {
    String[] permissions = new String[]{READ_PHONE_STATE};
    PermissionUtils.requestPermissions(this, PHONE_STATE_PERMISSION_ID, permissions);
}

Override handler for permission result in your AppCompatActivity or implement OnRequestPermissionsResultCallback interface: 在AppCompatActivity中覆盖权限结果的处理程序,或实现OnRequestPermissionsResultCallback接口:

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    switch (requestCode) {
        case PHONE_STATE_PERMISSION_ID:
            boolean granted = grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED;
            if (granted) {
                //get deviceId and proccess your code
            } else {
                //nobody knows what to do
            }
            break;
        default:
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }
}

As you see, we still have a problem - what to do, if user denied permission? 如您所见,我们仍然有一个问题-如果用户拒绝许可该怎么办? As a variant, we can show explaining dialog. 作为变体,我们可以显示说明对话框。 Or (may be better) ask for permissions only after onboarding screens. 或者(可能更好)仅在入职屏幕之后请求权限。

First of all you must implement the following method in your activity/fragment: 首先,您必须在活动/片段中实现以下方法:

@Override
public void onRequestPermissionsResult(int requestCode,@NonNull String permissions[], @NonNull int[] grantResults) {
    switch (requestCode) {
        case Permissions.READ_CONTACTS: { //Permissions.READ_CONTACTS is an int constant
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                getContactsFromPhone();
            }
        }
    }
}

Then in ur onclick to get this contacts you should ask if you have this permission: 然后在您的onclick中获取此联系人,您应该询问您是否具有此权限:

    if (ContextCompat.checkSelfPermission(activity, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(activity,
                new String[]{Manifest.permission.READ_CONTACTS}, Permissions.READ_CONTACTS); //Permissions.READ_CONTACTS is an int constant
        return false;
    } else {
       getContactsFromPhone();
    }

1) Yes, you should check that permission is granted every time you called these functions. 1)是的,您应该在每次调用这些函数时检查是否已授予许可。
2) You can check and request permissions from main thread. 2)您可以从主线程检查并请求权限。 I think that check and request permissions from AsyncTask isn't good way, because permission request is a dialog, and you will have to wait asynctask thread until you get user response. 我认为从AsyncTask检查和请求权限不是一种好方法,因为权限请求是一个对话框,您将必须等待asynctask线程,直到获得用户响应。 Try to check permission from main thread, get user response, and then, if permission granted, start your asynctask. 尝试从主线程检查权限,获取用户响应,然后(如果授予了权限)启动asynctask。

Dexter是一个Android库,可简化运行时请求权限的过程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM