Почему происходит сбой AudioManager при изменении режима RingerMode? - PullRequest
0 голосов
/ 24 апреля 2018

В моем приложении я уже предоставил разрешение на 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: Недостаточно данных для HAL, ожидаемая позиция 1097356, только запись 1097280 04-26 04: 55: 04.434 5065-5065 /?D / AndroidRuntime: завершение работы VM 04-26 04: 55: 04.446 5065-5065 /?E / AndroidRuntime: ИСКЛЮЧИТЕЛЬНОЕ ИСКЛЮЧЕНИЕ: основной процесс: com.example.hasan.ringer, PID: 5065 java.lang.SecurityException: не разрешено изменять состояние «Не беспокоить» в android.os.Parcel.createException (Parcel.java:1942)на android.os.Parcel.readException (Parcel.java:1865) на android.media.IAudioService $ Stub $ Proxy.setRingerModeExternal (IAudioService.java:1161) на android.media.AudioManager.setRingerMode (AudioManager.java:1099) наcom.example.hasan.ringer.MainActivity $ onCreate $ 1.onClick (MainActivity.kt: 20) на android.view.View.performClick (View.java:6579) на android.view.View.performClickInternal (View.java:6556)) на android.view.View.access $ 3100 (View.java:777) на android.view.View $ PerformClick.run (View.java:25660) на android.os.Handler.handleCallback (Handler.java:819) наandroid.os.Handler.dispatchMessage (Handler.java:99) в android.os.Looper.loop (Looper.java:164) в android.app.ActivityThread.main (ActivityThread.java:6656) в java.lang.reflect.Method.invoke (родной метод) на com.android.internal.os.RuntimeInit $ MethodAndArgsCaller.run (RuntimeInit.java:438) в com.android.internal.os.ZygoteInit.main (ZygoteInit.java:823) Вызывается: android.os.RemoteException: трассировка удаленного стека: в com.android.server.audio.AudioService.setRingerModeExternal (AudioService.java:2333) в android.media.IAudioService $ Stub.onTransact (IAudioService.java:199) в android.os.Binder.execTransact (Binder.java:726) 04-26 04: 55: 04.453 1680-4664 / system_process W / ActivityManager: принудительно завершить действие com.example.hasan.ringer / .MainActivity

Ответы [ 2 ]

0 голосов
/ 26 февраля 2019

Это Java-версия ответа от Хасана (см. Код ниже), даже если Kotlin сделает это лучше! :)

Я нашел ответ, требуется разрешение ACCESS_NOTIFICATION_POLICY, в манифесте ниже требуемой строки:

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

И разрешение предоставляется от ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS, как показано ниже:

    NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !notificationManager.isNotificationPolicyAccessGranted()) {
        Intent intent = new Intent(android.provider.Settings.ACTION_NOTIFICATION_POLICY_ACCESS_SETTINGS);
        startActivity(intent);
    }
0 голосов
/ 26 апреля 2018

Я нашел ответ, требуется разрешение ACCESS_NOTIFICATION_POLICY, в манифесте ниже строки обязательно:

<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)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...