我将 targetSdkVersion 升级到 31 telephonyManager.listen 不起作用。考虑以下代码行:
\ntelephonyManager.listen(phoneStateListener,PhoneStateListener.LISTEN_CALL_STATE);
\nlogcat错误信息如下:
\n2022-02-27 13:51:36.313 6426-6426/com.example.app E/AndroidRuntime: FATAL EXCEPTION: main\nProcess: com.example.app, PID: 6426\njava.lang.RuntimeException: Unable to start service com.example.app.myPlayService@7ace64e with Intent { cmp=com.example.app/.myPlayService (has extras) }: java.lang.SecurityException: listen\n at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:4657)\n at android.app.ActivityThread.access$2000(ActivityThread.java:247)\n at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2091)\n at android.os.Handler.dispatchMessage(Handler.java:106)\n at android.os.Looper.loopOnce(Looper.java:201)\n at android.os.Looper.loop(Looper.java:288)\n at android.app.ActivityThread.main(ActivityThread.java:7839)\n at java.lang.reflect.Method.invoke(Native Method)\n at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)\n at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)\n Caused by: java.lang.SecurityException: listen\n at android.os.Parcel.createExceptionOrNull(Parcel.java:2425)\n at android.os.Parcel.createException(Parcel.java:2409)\n at android.os.Parcel.readException(Parcel.java:2392)\n at android.os.Parcel.readException(Parcel.java:2334)\n at com.android.internal.telephony.ITelephonyRegistry$Stub$Proxy.listenWithEventList(ITelephonyRegistry.java:1036)\n at android.telephony.TelephonyRegistryManager.listenFromListener(TelephonyRegistryManager.java:250)\n at android.telephony.TelephonyManager.listen(TelephonyManager.java:5999)\n at com.example.app.myPlayService.onStartCommand(myPlayService.java:186)\n at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:4639)\n at android.app.ActivityThread.access$2000(ActivityThread.java:247)\xc2\xa0\n at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2091)\xc2\xa0\n at android.os.Handler.dispatchMessage(Handler.java:106)\xc2\xa0\n at android.os.Looper.loopOnce(Looper.java:201)\xc2\xa0\n at android.os.Looper.loop(Looper.java:288)\xc2\xa0\n at android.app.ActivityThread.main(ActivityThread.java:7839)\xc2\xa0\n at java.lang.reflect.Method.invoke(Native Method)\xc2\xa0\n at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)\xc2\xa0\n at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)\xc2\xa0\n Caused by: android.os.RemoteException: Remote stack trace:\n at com.android.internal.telephony.TelephonyPermissions.enforceCarrierPrivilege(TelephonyPermissions.java:634)\n at com.android.internal.telephony.TelephonyPermissions.checkReadPhoneState(TelephonyPermissions.java:149)\n at com.android.internal.telephony.TelephonyPermissions.checkCallingOrSelfReadPhoneState(TelephonyPermissions.java:94)\n at com.android.server.TelephonyRegistry.checkListenerPermission(TelephonyRegistry.java:3093)\n at com.android.server.TelephonyRegistry.listen(TelephonyRegistry.java:1024)\nRun Code Online (Sandbox Code Playgroud)\n我已在 Android Manifyst 文件上添加了以下权限,但仍然无法正常工作。
\n<uses-permission android:name="android.permission.READ_PHONE_STATE" />\nRun Code Online (Sandbox Code Playgroud)\n在定位低于 31 或 Android 12 之前,它运行得很好。在Android SDK 31上如何解决这个问题?提前致谢。
\nuse*_*374 16
当目标 API 31 TelephonyManager.listen给出时:java.lang.SecurityException: listen
TelephonyManager.registerTelephonyCallback也是如此,除非禁用ENABLE_GET_CALL_STATE_PERMISSION_PROTECTION 。
开发者选项/应用程序兼容性更改/选择应用程序/启用 targetSdkVersion >= 31
由于TelephonyManager.listen在 API 级别 31 中已弃用,而TelephonyManager.registerTelephonyCallback在 API 级别 31 中添加,因此您应该编写如下代码:
更新callStateListener添加了和的示例phoneStateListener
private void registerCallStateListener() {
if (!callStateListenerRegistered) {
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
telephonyManager.registerTelephonyCallback(getMainExecutor(), callStateListener);
callStateListenerRegistered = true;
}
} else {
telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
callStateListenerRegistered = true;
}
}
}
@RequiresApi(api = Build.VERSION_CODES.S)
private static abstract class CallStateListener extends TelephonyCallback implements TelephonyCallback.CallStateListener {
@Override
abstract public void onCallStateChanged(int state);
}
private boolean callStateListenerRegistered = false;
private CallStateListener callStateListener = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) ?
new CallStateListener() {
@Override
public void onCallStateChanged(int state) {
// Handle call state change
}
}
: null;
private PhoneStateListener phoneStateListener = (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) ?
new PhoneStateListener() {
@Override
public void onCallStateChanged(int state, String phoneNumber) {
// Handle call state change
}
}
: null;
Run Code Online (Sandbox Code Playgroud)
文档链接:
由于TelephonyCallback.CallStateListener需要Manifest.permission.READ_PHONE_STATE并且此权限的保护级别为危险,因此您应该按照本指南请求运行时权限:请求应用程序权限
您在提供 LISTEN_CALL_STATE 时调用监听将触发 onCallStateChanged() 回调。
telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
Run Code Online (Sandbox Code Playgroud)
正如您在文档中看到的,如果您的目标是 Android 31 或更高版本,则 onCallStateChanged() 需要 READ_PHONE_STATE。
需要权限:针对 API 级别 31+ 的应用程序的 READ_PHONE_STATE。
因此,要解决此问题,只需在调用监听调用之前请求权限(但仅当代码在 Android 31+ 上执行时),如下所示:
// for API 31+: you need to first check for READ_PHONE_STATE permission to be able to listen to LISTEN_CALL_STATE
if (Build.VERSION.SDK_INT >= 31)
{
if(ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED)
telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
}
else // no permission needed
telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
Run Code Online (Sandbox Code Playgroud)
这就是我这样做的方式:
private suspend fun updateServiceState() {
withContext(Dispatchers.Main) {
telephonyManager.listen(object : PhoneStateListener() {
override fun onServiceStateChanged(state: ServiceState) {
telephonyManager.listen(this, LISTEN_NONE)
...
}
}, PhoneStateListener.LISTEN_SERVICE_STATE)
}
}
Run Code Online (Sandbox Code Playgroud)
我的目标是 Android 12、API 31,但没有 READ_PHONE_STATE 权限
| 归档时间: |
|
| 查看次数: |
12863 次 |
| 最近记录: |