在 MIUI 中检查权限 READ_CONTACTS

Posted

技术标签:

【中文标题】在 MIUI 中检查权限 READ_CONTACTS【英文标题】:Check permissions READ_CONTACTS in MIUI 【发布时间】:2016-02-02 08:10:52 【问题描述】:

我尝试检查权限 在我的清单中我设置了

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

然后在片段中我尝试检查

int permissionCheck = ContextCompat.checkSelfPermission(getActivity(),
            Manifest.permission.READ_CONTACTS);

但是,尽管操作系统中的应用程序属性有任何许可状态,但我只得到 0。 我签入了 Android 4.4.4 MIUI 6.5.1 可能是MIUI中的原因

如果我尝试检查清单中没有的权限,我得到-1,但我想知道权限的切换状态。

感谢

【问题讨论】:

您必须手动允许在 MIUI 中读取联系人,因为操作系统默认阻止读取联系人。 您解决问题了吗?谢谢! 不,我不认为这个问题是 MIU 的错误 【参考方案1】:

将此函数添加到您的代码并仅在 MIUI 中为 READ_CONtacts 调用 checkUsagePermission()

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 表示 PackageManager.PERMISSION_GRANTED

您在 Android 6 以下的 Android 版本中获得零,因为在安装应用之前已经提供了权限。如果您在运行 Android 版本 6 或更高版本的手机上安装此应用程序,那么它将返回 -1,这意味着 PackageManager.PERMISSION_DENIED 因为 Android 6 在安装应用程序之前不请求权限,而是在运行时请求权限。

因此编写这样的代码 -

if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_CONTACTS)
                == PackageManager.PERMISSION_DENIED)
            ActivityCompat.requestPermissions(this,
                    new String[]Manifest.permission.READ_CONTACTS,
                    PERMISSION_REQUEST_CODE);

这样,只有在您没有权限时,您的应用才会请求权限,并且只会在 Android 6 及更高版本上发生。在 Android 6 以下,您将已经拥有该权限。

编辑:似乎 MIUI 在 Google 在 Android 6 中引入它们之前就提供了运行时权限。所以你面临的问题是特定于 MIUI 的。如果您使用 Android 6 以下的 MIUI 以外的任何其他设备,则您将无法获得拒绝选择性权限的选项。您要么提供所有权限,要么取消安装。因此,您的应用可以在所有其他设备上正常运行。

【讨论】:

我知道 0 表示 PackageManager.PERMISSION_GRANTED。但是当应用程序权限中的权限也关闭时,我得到 0。当我安装应用程序 Android 时,要求我允许 READ_CONTACTS。但我想排除用户的错误行为。 在android 6及以下(包括你的MIUI)中,一旦提供了权限,你就不能撤销它。这就是为什么它总是为0。我不知道你是如何在MIUI中关闭权限的。您只能从 Android 6 设备的“设置”中拒绝权限。 安装 Android 应用后问我“您是否允许阅读联系人”。如果我说不,此权限将被关闭。如果我关闭此权限,我可以从 OS GUI 获得相同的结果。作为结果。我无法识别用户是否这样做,也无法对他说“应用程序无法正常工作” 是的,我刚刚用 MIUI 进行了检查。似乎 MIUI 在 Google 在 Android 6 中引入它们之前就提供了运行时权限。所以你面临的问题是 MIUI 特有的。如果您使用 Android 6 以下的 MIUI 以外的任何其他设备,则您将无法获得拒绝选择性权限的选项。您要么提供所有权限,要么取消安装。因此,您的应用程序将在所有其他设备上正常工作。希望这会有所帮助。【参考方案3】:

我刚刚用 MIUI 7 6.3.31 Beta 测试了 MI 4W。

我遇到的 checkSelfPermission 返回了与我仅请求 Manifest.permission.READ_CONTACTS 时相同的错误。

即使我拒绝了 Manifest.permission.WRITE_CONTACTS 请求,它也会将“拒绝”设置为 Manifest.permission.READ_CONTACTS。检查这两个权限将返回 true。

虽然我已经拒绝了,但是checkSelfPermission(Manifest.permission.READ_CONTACTS)返回true,偶尔MIUI会弹出消息通知用户CONTACTS的访问被拒绝。

这是我的实际权限: 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;
    

测试代码:

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));

应用设置中的所有权限均被拒绝。

结果:

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

我在 Nexus 5 上进行了测试并拒绝了所有权限。

结果:

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

断定这是 MIUI 7 6.3.31 Beta 的错误。

【讨论】:

// 在 Android M 以下,所有权限都是在安装时授予的,并且已经可用。// 并非所有设备都如此。例如在 Redmi prime 2 上,它是 android Lollipop 5.1.1 。正如您所说,所有权限都已授予,但在此自定义的 android 用户中可以明确拒绝该权限,然后您的代码仍然返回 true,这是不正确的。您必须单独检查 Marshmallow 下方的 MIUI 设备。请先检查所有情况,这可能会误导开发人员。【参考方案4】:

检查这个:https://developer.android.com/reference/android/content/pm/PackageManager.html#PERMISSION_GRANTED

0 代表 PERMISSION_GRANTED

我在 Github 上创建了一个示例应用来演示权限模型。

检查版本

/**
* Check build version
*/
if(Build.VERSION.SDK_INT < 23)
    displayContacts();
else 
    requestContactPermission();

检查权限

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();
    

这里,READ_CONTACT_REQUEST_CODE 是任意整数值

处理权限

@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;
    

【讨论】:

检查 SDK 版本是多余的。您可以直接检查是否授予权限。这样,您将不必要地进行 2 次检查。 这对我来说永远不会发生,因为每次我有 0 PackageManager.PERMISSION_GRANTED == 0 和 hasContactPermission == 0 所以我会看到“已授予联系权限”,但不是真的,因为我在应用程序属性中手动关闭了此权限,并且此设计无法识别此 @user5546244 你能告诉我你使用的是什么设备以及什么版本吗?因为在授予 1 次权限后,它将持续到下一次。您可以转到设置,然后禁用再次询问用户的权限。 @user5546244 你试过实现我的 Github 演示吗? 小米MI4 MUIUI 6.5.1

以上是关于在 MIUI 中检查权限 READ_CONTACTS的主要内容,如果未能解决你的问题,请参考以下文章

miui12稳定版怎么root

miui稳定版怎么破解root权限

权限 - 如何在运行时运行 MIUI 的手机中请求和/或更改它们?

如何在 MIUI 中打开 Draw Overlay 权限弹出窗口?

小米root权限怎么开启miui12

如何获得删除小米(MIUI)设备中联系人的权限?