【问题标题】:Crash - SecurityException: Permission Denial: isUidActive from pid=XXXX, uid=XXXX requires android.permission.PACKAGE_USAGE_STATS崩溃 - SecurityException: Permission Denial: isUidActive from pid=XXXX, uid=XXXX requires android.permission.PACKAGE_USAGE_STATS
【发布时间】:2021-10-11 07:39:36
【问题描述】:

我收到来自 Crashlytics 的未知崩溃,该崩溃是在 NfcAdapter 中调用 enableReaderMode() 时触发的

Caused by java.lang.SecurityException: Permission Denial: isUidActive from pid=5xx1, uid=1xx7 requires android.permission.PACKAGE_USAGE_STATS
       at android.os.Parcel.createExceptionOrNull(Parcel.java:2387)
       at android.os.Parcel.createException(Parcel.java:2371)
       at android.os.Parcel.readException(Parcel.java:2354)
       at android.os.Parcel.readException(Parcel.java:2296)
       at android.nfc.INfcAdapter$Stub$Proxy.setReaderMode(INfcAdapter.java:1027)
       at android.nfc.NfcActivityManager.setReaderMode(NfcActivityManager.java:242)
       at android.nfc.NfcActivityManager.enableReaderMode(NfcActivityManager.java:218)
       at android.nfc.NfcAdapter.enableReaderMode(NfcAdapter.java:1580)

我在 Activity onResume() 中调用了 NfcAdapter.enableReaderMode(),如下所示

我也添加了<uses-permission android:name="android.permission.NFC" /> 权限

是否需要任何其他权限来防止这些崩溃的发生? 或者在致电NfcAdapter.enableReaderMode() 之前有什么需要检查的吗?

我也看到有人在here 发过关于这些问题的帖子,但似乎还没有答案

【问题讨论】:

    标签: android kotlin


    【解决方案1】:

    我不知道它为什么要求这样做,但有这样的许可:

    <uses-permission
        android:name="android.permission.PACKAGE_USAGE_STATS"
        tools:ignore="ProtectedPermissions" />
    

    你可以通过调用来检查你的应用是否有它:

     public static boolean checkForUsagePermission(Context context) {
            @SuppressLint("WrongConstant")
            UsageStatsManager usm = (UsageStatsManager) context.getSystemService("usagestats");
            long time = System.currentTimeMillis();
            return usm.queryUsageStats(UsageStatsManager.INTERVAL_DAILY, time - 1000 * 1000, time).size() > 0;
        }
    

    当然,您可以通过以下方式请求:

                Intent settingsIntent = new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS);
                startActivityForResult(settingsIntent, REQUEST_STATS_USAGE);
    

    【讨论】:

    • 您好,感谢您的回答,似乎通过在清单中添加PACKAGE_USAGE_STATS,它需要用户的额外权限才能允许系统设置中的使用统计信息,对吧?因此,默认情况下,我总是从checkForUsagePermission() 得到false
    • 这很奇怪,我在 Android 11 上并使用此功能并且它工作正常
    • 嗯,不过,我在 Android 10 上进行测试。无论如何,我使用these approach 来检查PACKAGE_USAGE_STATS 权限。无论如何都会投票给你的答案,希望它可以对其他人有所帮助
    【解决方案2】:

    发现,用户在系统设置中授予的特殊权限(使用统计访问、通知访问……)由 Android 4.4 中添加的AppOpsManager 处理。因此,我添加了一个额外的检查如下

    val mode = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            (getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager).unsafeCheckOpNoThrow(
                AppOpsManager.OPSTR_GET_USAGE_STATS,
                Process.myUid(),
                packageName
            )
        } else null
    
    val granted = if (mode != null && mode != AppOpsManager.MODE_DEFAULT) {
           mode == AppOpsManager.MODE_ALLOWED
        } else {
           checkCallingOrSelfPermission(Manifest.permission.PACKAGE_USAGE_STATS) == PackageManager.PERMISSION_GRANTED
        }
    

    【讨论】:

      猜你喜欢
      • 2011-04-16
      • 2014-02-22
      • 1970-01-01
      • 1970-01-01
      • 2013-09-21
      • 1970-01-01
      • 1970-01-01
      • 2012-12-24
      • 2011-07-17
      相关资源
      最近更新 更多