问题
I try to check permissions in my Manifest I set
<uses-permission android:name="android.permission.READ_CONTACTS" />
Then in fragment I try to check
int permissionCheck = ContextCompat.checkSelfPermission(getActivity(),
Manifest.permission.READ_CONTACTS);
But I get only 0 despite of any state of permission in application properties in OS. I checked in Android 4.4.4 MIUI 6.5.1 May be the reason in MIUI
I have got -1 if I try check permission which there isn't in Manifest, but I wanna know the switch state of the permission.
Thanx
回答1:
Add this function to your code and call checkUsagePermission() for READ_COntacts only in MIUI
private boolean checkUsagePermission() {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
AppOpsManager appOps = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE);
int mode = 0;
mode = appOps.checkOpNoThrow("android:read_contacts", android.os.Process.myUid(), getPackageName());
boolean granted = mode == AppOpsManager.MODE_ALLOWED;
if (!granted) {
//write your code here for accept that permission
return false;
}
}
return true;
}
回答2:
0 means PackageManager.PERMISSION_GRANTED
You get zero in Android version below Android 6 because permissions are already provided before the app is installed. If you install this app in a phone running on Android Version 6 or greater then it will return -1 which means PackageManager.PERMISSION_DENIED as Android 6 does not ask for permissions before the app is installed rather it asks for permissions at runtime.
Hence write code like this -
if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_CONTACTS)
== PackageManager.PERMISSION_DENIED)
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.READ_CONTACTS},
PERMISSION_REQUEST_CODE);
This way your app will ask for permission only if you don't have the permission and it will only happen on Android 6 and above. Below Android 6 you will already have the permission.
Edit : It seems MIUI provided run time permissions well before Google introduced them in Android 6. So the problem you are facing is specific to MIUI. If you use any other device other than MIUI below Android 6 then you won't get the option to deny selective permissions. You either provide all permissions or cancel the installation. So you app will work fine on all other devices.
回答3:
I just tested with MI 4W with MIUI 7 6.3.31 Beta.
I am facing the same checkSelfPermission returned true error as you did when I request for Manifest.permission.READ_CONTACTS only.
Even if I have denied a request for Manifest.permission.WRITE_CONTACTS, it will set "Deny" to Manifest.permission.READ_CONTACTS. Checking for both permissions will return true.
Although I have denied, checkSelfPermission(Manifest.permission.READ_CONTACTS) returns true, and occasionally MIUI will pop up a message to inform users that the access to CONTACTS is denied.
Here are my actual permissions: checkSelfPermission(Manifest.permission.READ_CONTACTS)
PermissionUtil:
public static boolean hasSelfPermission(Context context, String permission) {
// Below Android M all permissions are granted at install time and are already available.
if (!isMNC()) {
return true;
}
return context.checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED;
}
public static boolean isMNC() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
}
Test Code:
Log.d(TAG, "READ_CONTACTS: " + PermissionUtil.hasSelfPermission(TestActivity.this, Manifest.permission.READ_CONTACTS));
Log.d(TAG, "WRITE_CONTACTS: " + PermissionUtil.hasSelfPermission(TestActivity.this, Manifest.permission.WRITE_CONTACTS));
Log.d(TAG, "ACCESS_FINE_LOCATION: " + PermissionUtil.hasSelfPermission(TestActivity.this, Manifest.permission.ACCESS_FINE_LOCATION));
Log.d(TAG, "ACCESS_COARSE_LOCATION: " + PermissionUtil.hasSelfPermission(TestActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION));
Log.d(TAG, "CAMERA: " + PermissionUtil.hasSelfPermission(TestActivity.this, Manifest.permission.CAMERA));
Log.d(TAG, "RECORD_AUDIO: " + PermissionUtil.hasSelfPermission(TestActivity.this, Manifest.permission.RECORD_AUDIO));
Log.d(TAG, "READ_EXTERNAL_STORAGE: " + PermissionUtil.hasSelfPermission(TestActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE));
Log.d(TAG, "WRITE_EXTERNAL_STORAGE: " + PermissionUtil.hasSelfPermission(TestActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE));
All permissions were denied in the App Settings.
Results:
04-01 13:16:54.967 25481-25481/com.test.test D/TestActivity: READ_CONTACTS: true
04-01 13:16:54.967 25481-25481/com.test.test D/TestActivity: WRITE_CONTACTS: true
04-01 13:16:54.967 25481-25481/com.test.test D/TestActivity: ACCESS_FINE_LOCATION: false
04-01 13:16:54.968 25481-25481/com.test.test D/TestActivity: ACCESS_COARSE_LOCATION: false
04-01 13:16:54.968 25481-25481/com.test.test D/TestActivity: CAMERA: false
04-01 13:16:54.969 25481-25481/com.test.test D/TestActivity: RECORD_AUDIO: false
04-01 13:16:54.969 25481-25481/com.test.test D/TestActivity: READ_EXTERNAL_STORAGE: false
04-01 13:16:54.970 25481-25481/com.test.test D/TestActivity: WRITE_EXTERNAL_STORAGE: false
I have conducted test on Nexus 5 and denied all permissions.
Results:
04-01 13:16:54.967 25481-25481/com.test.test D/TestActivity: READ_CONTACTS: false
04-01 13:16:54.967 25481-25481/com.test.test D/TestActivity: WRITE_CONTACTS: false
04-01 13:16:54.967 25481-25481/com.test.test D/TestActivity: ACCESS_FINE_LOCATION: false
04-01 13:16:54.968 25481-25481/com.test.test D/TestActivity: ACCESS_COARSE_LOCATION: false
04-01 13:16:54.968 25481-25481/com.test.test D/TestActivity: CAMERA: false
04-01 13:16:54.969 25481-25481/com.test.test D/TestActivity: RECORD_AUDIO: false
04-01 13:16:54.969 25481-25481/com.test.test D/TestActivity: READ_EXTERNAL_STORAGE: false
04-01 13:16:54.970 25481-25481/com.test.test D/TestActivity: WRITE_EXTERNAL_STORAGE: false
Concluded this to be a bug with MIUI 7 6.3.31 Beta.
回答4:
Check this:
https://developer.android.com/reference/android/content/pm/PackageManager.html#PERMISSION_GRANTED
0 stands for PERMISSION_GRANTED
I have created a sample app on Github to demonstrate permission model.
Check Version
/**
* Check build version
*/
if(Build.VERSION.SDK_INT < 23){
displayContacts();
}else {
requestContactPermission();
}
Check for Permission
private void requestContactPermission() {
int hasContactPermission = ActivityCompat.checkSelfPermission(MainActivity.this,Manifest.permission.READ_CONTACTS);
if(hasContactPermission != PackageManager.PERMISSION_GRANTED ) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_CONTACTS}, READ_CONTACT_REQUEST_CODE);
}else {
Toast.makeText(MainActivity.this, "Contact Permission is already granted", Toast.LENGTH_LONG).show();
displayContacts();
}
}
Here, READ_CONTACT_REQUEST_CODE is any integer value
Handle Permission
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode){
case READ_CONTACT_REQUEST_CODE:
// Check if the only required permission has been granted
if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Camera permission has been granted, preview can be displayed
Log.i("Permission", "Contact permission has now been granted. Showing result.");
Toast.makeText(MainActivity.this,"Contact Permission is Granted",Toast.LENGTH_SHORT).show();
displayContacts();
} else {
Log.i("Permission", "Contact permission was NOT granted.");
Toast.makeText(MainActivity.this,"Permission is not Granted",Toast.LENGTH_SHORT).show();
}
break;
}
}
来源:https://stackoverflow.com/questions/35148085/check-permissions-read-contacts-in-miui