在我的应用程序中,我已经授予了 PHONE_STATE
的权限,它正在顺利检测接收/摘机/空闲状态。
如果来电来自重新指定的号码,即使手机静音,我也需要手机响铃,所以我正在更改 AudioManager
状态如下,但应用程序一旦崩溃试图改变铃声模式!!
class PhoneStateReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val state = intent.getStringExtra(TelephonyManager.EXTRA_STATE)
val incomingNumber = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER)
val audio = context.getSystemService(Context.AUDIO_SERVICE) as AudioManager
if (incomingNumber == "(650) 555-1212" && state == TelephonyManager.EXTRA_STATE_RINGING) {
Toast.makeText(context, "Ringing ${audio.ringerMode}", Toast.LENGTH_SHORT).show()
if(audio.ringerMode == AudioManager.RINGER_MODE_SILENT)
audio.apply { // The app crash here!!
ringerMode = AudioManager.RINGER_MODE_NORMAL
setStreamVolume(AudioManager.STREAM_RING,
audio.getStreamMaxVolume(AudioManager.STREAM_RING),
AudioManager.FLAG_ALLOW_RINGER_MODES or AudioManager.FLAG_PLAY_SOUND)
}
val ring = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE)
val r = RingtoneManager.getRingtone(context, ring)
r.play()
}
if (state == TelephonyManager.EXTRA_STATE_OFFHOOK) {
audio.ringerMode = AudioManager.RINGER_MODE_SILENT
Toast.makeText(context, "On Call ", Toast.LENGTH_SHORT).show()
}
if (state == TelephonyManager.EXTRA_STATE_IDLE) {
Toast.makeText(context, "IDLE", Toast.LENGTH_SHORT).show()
}
}
}
在 AndroidManifest.xml
中:
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<receiver
android:name=".broadcasts.PhoneStateReceiver">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
更新
这是 Logcat 错误:
04-26 04:55:04.422 1406-2091/? W/audio_hw_generic: Not supplying enough data to HAL, expected position 1097356 , only wrote 1097280 04-26 04:55:04.434 5065-5065/? D/AndroidRuntime: Shutting down VM 04-26 04:55:04.446 5065-5065/? E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.hasan.ringer, PID: 5065 java.lang.SecurityException: Not allowed to change Do Not Disturb state at android.os.Parcel.createException(Parcel.java:1942) at android.os.Parcel.readException(Parcel.java:1865) at android.media.IAudioService$Stub$Proxy.setRingerModeExternal(IAudioService.java:1161) at android.media.AudioManager.setRingerMode(AudioManager.java:1099) at com.example.hasan.ringer.MainActivity$onCreate$1.onClick(MainActivity.kt:20) at android.view.View.performClick(View.java:6579) at android.view.View.performClickInternal(View.java:6556) at android.view.View.access$3100(View.java:777) at android.view.View$PerformClick.run(View.java:25660) at android.os.Handler.handleCallback(Handler.java:819) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6656) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:823) Caused by: android.os.RemoteException: Remote stack trace: at com.android.server.audio.AudioService.setRingerModeExternal(AudioService.java:2333) at android.media.IAudioService$Stub.onTransact(IAudioService.java:199) at android.os.Binder.execTransact(Binder.java:726) 04-26 04:55:04.453 1680-4664/system_process W/ActivityManager: Force finishing activity com.example.hasan.ringer/.MainActivity
最佳答案
我找到了答案,需要 ACCESS_NOTIFICATION_POLICY
的许可, list 中需要以下行:
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
并且权限是从 ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS
授予的,如下所示:
val notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !notificationManager.isNotificationPolicyAccessGranted) {
val intent = Intent(
android.provider.Settings
.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS)
startActivity(intent)
}
关于java - 为什么 AudioManager 在 RingerMode 改变时崩溃?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50010586/