在Marshmallow 中,如何像Hangouts 那样一一提示两个或多个权限对话框?

In Marshmallow, how to prompt two or more permissions dialog one by one like Hangouts does?

我正在处理我的应用程序代码以在 Marshmallow 设备上工作,我正在管理它的权限对话框以在需要的地方显示。

目前遇到需要两个权限(位置和存储)的场景,我想像环聊一样一一询问。找不到它是如何定制的,有什么解决办法吗?

这是我处理单一权限的代码:

case REQUEST_CODE_WRITE_EXTERNAL_STORAGE: {

    if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
        /Permission is granted
        Toast.makeText(this, "SDK >= 23 & permission Granted ", Toast.LENGTH_SHORT).show();
        return true;

    } else {
        //Permission is revoked
        ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE_WRITE_EXTERNAL_STORAGE);
        return false;
    }
}

并且在 onRequestPermissionsResult() 中:

case REQUEST_CODE_WRITE_EXTERNAL_STORAGE: {

    // If request is cancelled, the result arrays are empty.
    if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

        // permission was granted, yay! Do the
        // contacts-related task you need to do.
        Log.e("PMS", "granted");
        Toast.makeText(this, "SDK >= 23 & permission Granted ", Toast.LENGTH_SHORT).show();

    } else {
        Log.e("PMS", "Not Granted");

        // permission denied, boo! Disable the
        // functionality that depends on this permission.
        int checkStatus = getPermissionStatus(Manifest.permission.WRITE_EXTERNAL_STORAGE);
        if (checkStatus == 3) {
            Toast.makeText(this, "SDK  >= 23 & permission Denied ", Toast.LENGTH_SHORT).show();

        } else if (checkStatus == 4) {
            Toast.makeText(this, "SDK  >= 23 & permission Blocked ", Toast.LENGTH_SHORT).show();

        }
    }
    return;
}

检查此 post 以获得详细答案。我已将 WRITE_EXTERNAL_STORAGE 添加到 @nicks 的回答中。

public static final int REQUEST_MULTIPLE_PERMISSIONS_ID = 456;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    if(checkAndRequestPermissions()) {
        // TODO - all permissions granted already
    }
}

private  boolean checkAndRequestPermissions() {
    int permissionSendMessage = ContextCompat.checkSelfPermission(this,
            Manifest.permission.WRITE_EXTERNAL_STORAGE);
    int locationPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);
    List<String> listPermissionsNeeded = new ArrayList<>();
    if (locationPermission != PackageManager.PERMISSION_GRANTED) {
        listPermissionsNeeded.add(Manifest.permission.ACCESS_FINE_LOCATION);
    }
    if (permissionSendMessage != PackageManager.PERMISSION_GRANTED) {
        listPermissionsNeeded.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
    }
    if (!listPermissionsNeeded.isEmpty()) {
        ActivityCompat.requestPermissions(this, listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]),REQUEST_MULTIPLE_PERMISSIONS_ID);
        return false;
    }
    return true;
}

要一一请求多个权限,您需要在第二个参数String[] ActivityCompat.requestPermissions 方法中添加所有权限。像这样:

ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.ACCESS_COARSE_LOCATION}, REQUEST_CODE_WRITE_EXTERNAL_STORAGE);

如果有帮助请告诉我

我为此使用了权限实用程序:

import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.util.Log;



/**
 * Permission Utils
 */
public final class PermissionUtils {

    public static final String PER_READ_PHONE_STATE = Manifest.permission.READ_PHONE_STATE;
    public static final String PER_GET_ACCOUNTS = Manifest.permission.GET_ACCOUNTS;
    public static final String PER_WAKE_LOCK = Manifest.permission.WAKE_LOCK;
    public static final String FEEDBACK_PERMISSION_REQUEST_CODE = 1001;


    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 AllPermissionsGranted(Context context) {
        return IsAccountsInfoGranted(context) && IsDeviceInfoGranted(context);
    }

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

    //define functions for each permission
    public static boolean IsWakeLockGranted(Context context) {
        return checkPermission(context, PER_WAKE_LOCK);
    }

    public static boolean IsAccountsInfoGranted(Context context) {
        return checkPermission(context, PER_GET_ACCOUNTS);
    }

    public static boolean IsDeviceInfoGranted(Context context) {
        return checkPermission(context, PER_READ_PHONE_STATE);
    }

    public static boolean PermissionsGranted(@NonNull int[] permissionResults) {
        if (permissionResults.length > 0) {
            for (int permission : permissionResults) {
                if (permission != PackageManager.PERMISSION_GRANTED)
                    return false;
            }
            return true;
        } else return false;
    }

    public static void RequestPermissions(Activity activity, int permissionId, String... permissions) {
        ActivityCompat.requestPermissions(activity, permissions, permissionId);
    }
}

使用此代码在任何你想要的地方请求权限:

String[] permissions = new String[]{PermissionUtils.PER_GET_ACCOUNTS, PermissionUtils.PER_READ_PHONE_STATE};
PermissionUtils.RequestPermissions(Act_Launch.this, PermissionUtils.FEEDBACK_PERMISSION_REQUEST_CODE, permissions);

和activity中的这个方法来处理应用程序的许可或拒绝

    /***************************************
     * RequestPermissionResult
     ***************************************/
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode) {
            case PermissionUtils.PERMISSION_REQUEST_CODE:
                if (PermissionUtils.PermissionsGranted(grantResults)) {
                    ShowRegistrationView();
                } else {
                   //Do Whatever you want
                }
                break;
            default:
                super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

您需要在一个数组中同时发送多个权限。 我建议您使用 PermissionHelper or PermissionsDispatcher 库。 然后你可以这样请求:

permissionHelper
     .setForceAccepting(false)// true if you had like force reshowing the permission dialog on Deny (not recommended)
     .request(MULTIPLE_PERMISSIONS_ARRAY);

希望对您有所帮助!