在NfcAdapter
中调用enableReaderMode()
时,Crashlytics触发了一个未知的崩溃
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上看到有人发布了关于这些问题的帖子,但似乎还没有答案
发布于 2021-10-14 02:23:55
发现,用户在系统设置中授予的特殊权限(使用状态访问、通知访问、…)是由AppOpsManager
处理的,它是在Android4.4中添加的。因此,我添加了额外的检查,如下所示
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
}
发布于 2021-10-11 08:07:22
我不知道为什么它会这样要求,但确实有这样的许可:
<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);
https://stackoverflow.com/questions/69522598
复制相似问题