在Android中检查用户是否已经授予权限

33

我已经将所有危险权限定义在一个字符串数组中,如下所示:

String[] perms = {Manifest.permission.READ_CONTACTS,
                      Manifest.permission.READ_PHONE_STATE,
                      Manifest.permission.CALL_PHONE,
                      Manifest.permission.MODIFY_PHONE_STATE};

然后,为了检查它们是否已被授予,我运行这个命令:

Then to check if they have been granted I run this:

for (int i = 0; i < perms.length; i++) {
        if(ContextCompat.checkSelfPermission(this,perms[i])!=PackageManager.PERMISSION_GRANTED)
        {
            ActivityCompat.requestPermissions(this,perms, permsRequestCode);
            break;
        }
    }

由于某种原因,这不起作用。它会询问一次权限,然后如果我手动从设置中禁用它,它会多次弹出对话框。

我该如何解决这个问题?


没有一个答案引用文档,可能是因为以前文档不存在。如果你想要权威文档,可以在这里找到。 - Ben Butterworth
4个回答

32
据我所知,这应该可以运行。但你可以尝试使用以下函数,它可以正常工作。它的方法与你的不同。

据我所知,这应该可以运行。但你可以尝试使用以下函数,它可以正常工作。它的方法与你的不同。

String requiredPermission = android.Manifest.permission.READ_CONTACTS;
int checkVal = getContext().checkCallingOrSelfPermission(requiredPermission);

现在你可以检查:

if (checkVal==PackageManager.PERMISSION_GRANTED){}

6
建议将requiredPermission设置为Manifest.permission.READ_CONTACTS而不是字符串字面值。 - knjk04
为什么推荐它? - Nauman Ash
@knjk04如果有人想要检查Manifest.permission没有的权限,比如"com.qualcomm.permission...",该怎么办? - Walid

29

使用此功能可检查所需的任何权限,可以是单个或多个权限。

public class PermissionsUtils {

public static final int REQUEST_PERMISSION_MULTIPLE = 0;
public static final int REQUEST_PERMISSION_CAMERA = 1;
public static final int REQUEST_PERMISSION_LOCATION = 2;
public static final int REQUEST_WRITE_EXTERNAL = 3;

public static boolean checkAndRequestPermissions(Activity activity) {
    System.out.println("PermissionsUtils checkAndRequestPermissions()");

    int permissionCamera = ContextCompat.checkSelfPermission(activity, Manifest.permission.CAMERA);
    int permissionLocation = ContextCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_FINE_LOCATION);
    int permissionWriteExternal = ContextCompat.checkSelfPermission(activity,
            Manifest.permission.WRITE_EXTERNAL_STORAGE);

    // Permission List
    List<String> listPermissionsNeeded = new ArrayList<>();

    // Camera Permission
    if (permissionCamera != PackageManager.PERMISSION_GRANTED) {
        // Should we show an explanation?
        if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.CAMERA)) {
            Toast.makeText(activity, "Camera Permission is required for this app to run", Toast.LENGTH_SHORT)
                    .show();
        }
        listPermissionsNeeded.add(Manifest.permission.CAMERA);
    }

    // Read/Write Permission
    if (permissionWriteExternal != PackageManager.PERMISSION_GRANTED) {
        listPermissionsNeeded.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
    }

    // Location Permission
    if (permissionLocation != PackageManager.PERMISSION_GRANTED) {
        listPermissionsNeeded.add(Manifest.permission.ACCESS_FINE_LOCATION);
    }

    if (!listPermissionsNeeded.isEmpty()) {
        ActivityCompat.requestPermissions(activity,
                listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]),
                REQUEST_PERMISSION_MULTIPLE);
        return false;
    }

    return true;
}

/**
 * Requests the Camera permission. If the permission has been denied
 * previously, a SnackBar will prompt the user to grant the permission,
 * otherwise it is requested directly.
 */
public static void requestCameraPermission(Activity activity) {
    // Here, thisActivity is the current activity
    // System.out.println("requestCameraPermission() INITIAL");
    // Toast.makeText(this, "requestCameraPermission() INITIAL",
    // Toast.LENGTH_LONG).show();
    if (ContextCompat.checkSelfPermission(activity,
            Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {

        // Should we show an explanation?
        if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.CAMERA)) {
            // Toast.makeText(activity, "Camera permission is
            // needed for this app to run ",
            // Toast.LENGTH_SHORT).show();
            // System.out.println("requestCameraPermission() SHOW INFO");

            // Show an explanation to the user *asynchronously* -- don't
            // block
            // this thread waiting for the user's response! After the user
            // sees the explanation, try again to request the permission.
            ActivityCompat.requestPermissions(activity, new String[] { Manifest.permission.CAMERA },
                    REQUEST_PERMISSION_CAMERA);

        } else {
            // No explanation needed, we can request the permission.
            // System.out.println("requestCameraPermission() ASK
            // PERMISSION");

            ActivityCompat.requestPermissions(activity, new String[] { Manifest.permission.CAMERA },
                    REQUEST_PERMISSION_CAMERA);
        }
        // Permission is granted
    } else {
        System.out.println("requestCameraPermission() PERMISSION ALREADY GRANTED");

    }

}

public static void requestLocationPermission(Activity activity) {
    if (ContextCompat.checkSelfPermission(activity,
            Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

        // Should we show an explanation?
        if (ActivityCompat.shouldShowRequestPermissionRationale(activity,
                Manifest.permission.ACCESS_FINE_LOCATION)) {
            Toast.makeText(activity, "LOCATION permission is needed to display location info ", Toast.LENGTH_SHORT)
                    .show();
            // Show an explanation to the user *asynchronously* -- don't
            // block this thread waiting for the user's response! After the
            // user sees the explanation, try again to request the
            // permission.
            ActivityCompat.requestPermissions(activity, new String[] { Manifest.permission.ACCESS_FINE_LOCATION },
                    REQUEST_PERMISSION_LOCATION);

            Toast.makeText(activity, "REQUEST LOCATION PERMISSION", Toast.LENGTH_LONG).show();

        } else {
            // No explanation needed, we can request the permission.

            ActivityCompat.requestPermissions(activity, new String[] { Manifest.permission.ACCESS_FINE_LOCATION },
                    REQUEST_PERMISSION_LOCATION);
            Toast.makeText(activity, "REQUEST LOCATION PERMISSION", Toast.LENGTH_LONG).show();
            // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
            // app-defined int constant. The callback method gets the
            // result of the request.
        }
        // Permission is granted
    } else {

    }
}

public static void requestWriteExternalPermission(Activity activity) {
    if (ContextCompat.checkSelfPermission(activity,
            Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {

        // Should we show an explanation?
        if (ActivityCompat.shouldShowRequestPermissionRationale(activity,
                Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
            Toast.makeText(activity, "Write permission is needed to create Excel file ", Toast.LENGTH_SHORT).show();
            // Show an explanation to the user *asynchronously* -- don't
            // block this thread waiting for the user's response! After the
            // user sees the explanation, try again to request the
            // permission.
            ActivityCompat.requestPermissions(activity, new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE },
                    REQUEST_WRITE_EXTERNAL);

            Toast.makeText(activity, "REQUEST LOCATION PERMISSION", Toast.LENGTH_LONG).show();

        } else {
            // No explanation needed, we can request the permission.
            ActivityCompat.requestPermissions(activity, new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE },
                    REQUEST_WRITE_EXTERNAL);

        }
    }
}

public static boolean hasPermissions(Context context, String... permissions) {
    if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context != null && permissions != null) {
        for (String permission : permissions) {
            if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
                return false;
            }
        }
    }
    return true;
}

}


1
@mahdiazarm。这怎么会是离题的呢?checkSelfPermission(activity, Manifest.permission.X)检查是否已经授予任何权限,如果您查看其他答案,它们也是这样做的,代码的其余部分要求未授予的权限。 - Thracian

1
尝试在String[]{}中添加perms,这对我有效。
for (int i = 0; i < perms.length; i++) {
        if(ContextCompat.checkSelfPermission(this,perms[i])!=PackageManager.PERMISSION_GRANTED)
        {
            ActivityCompat.requestPermissions(this,String[]{perms}, permsRequestCode);
            break;
        }
    }

0
我想到了下面这个辅助函数,它会检查一组必要的权限,并且如果全部都不允许,则返回false。

fun Activity.hasAllPermissionGranted(): Boolean{
    var allPermissionProvided = true
    
    val requiredPermissions = listOf(Manifest.permission.CAMERA,Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.RECORD_AUDIO)
    for (perm in requiredPermissions){

        val checkVal = checkCallingOrSelfPermission(perm)

        if (checkVal!= PackageManager.PERMISSION_GRANTED){
            allPermissionProvided = false
            break;
        }
    }
    return allPermissionProvided
}

在活动中的任何地方像下面这样使用它

class SplashActivity : Activty() {


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        

        //force user for all permission if not given
       if(!hasAllPermissionGranted(){       
    }

  }

}

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