ToneGenerator вылетает в android 6.0

В моем приложении я использую ToneGenerator для воспроизведения простого звука. При тестировании моего приложения путем компиляции приложения с 6.0, мое приложение вылетало случайным образом из-за метода инициализации ToneGenerator. Ниже приведено исключение.

 java.lang.RuntimeException: Init failed 
04-21 12:34:05.497  7166  7166 E MyApplication:     at android.media.ToneGenerator.native_setup(Native Method) 
04-21 12:34:05.497  7166  7166 E MyApplication:     at android.media.ToneGenerator.<init>(ToneGenerator.java:746)

Я использую тон-генератор следующим образом.

    public ToneGenerator toneGenerator;
    public void playSound() { 
       if (toneGenerator == null) {
          toneGenerator = new ToneGenerator(AudioManager.STREAM_NOTIFICATION, 100);
        }
       toneGenerator.startTone(ToneGenerator.TONE_CDMA_ANSWER, 200);
   }


   public void releaseToneGenerator() {
      if (toneGenerator != null) {
        toneGenerator.release();
      }
    }

Кто-нибудь сталкивался с такой же проблемой? .. Раньше мое приложение работало на 4.4, и при этом мы не наблюдали сбоев. В 6.0 вылетает приложение


person Ashok    schedule 20.04.2017    source источник
comment
Нареш, а можно попробовать вызвать функцию выпуска объекта toneGenerator сразу после вызова startTone?   -  person Nakul Sudhakar    schedule 13.07.2017


Ответы (2)


Решил проблему с помощью обработчика.

private static void playTone(Context context, int mediaFileRawId) {
            Log.d(TAG, "playTone");
            try {
                if (toneGenerator == null) {
                    toneGenerator = new ToneGenerator(AudioManager.STREAM_NOTIFICATION, 100);
                }
                toneGenerator.startTone(mediaFileRawId, 200);
                Handler handler = new Handler(Looper.getMainLooper());
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        if (toneGenerator != null) {
                            Log.d(TAG, "ToneGenerator released");
                            toneGenerator.release();
                            toneGenerator = null;
                        }
                    }

                }, 200);
            } catch (Exception e) {
                Log.d(TAG, "Exception while playing sound:" + e);
            }
        }
person Ashok    schedule 13.07.2017

Ниже приведено решение на основе тонального генератора, которое выглядит стабильным с использованием прослушивателя при касании в DialogFragment. Установите onTouchListeners для каждой кнопки в методе OnViewCreated, затем используйте следующий метод прослушивания ontouch, который непрерывно воспроизводит выбранный тон DTMF по вызову SIP при нажатии кнопки, а затем прекращает воспроизведение, когда кнопка больше не нажимается. AnswerDialogListener - это обратный вызов MainActivity.

Изменить: я нарушил корректный вывод ранее работающего тона DTMF RFC2833, пытаясь исправить предупреждение компилятора с помощью toneType = ToneGenerator.TONE_DTMF_0; вместо toneType = toneGenerator.TONE_DTMF_0;

private View.OnTouchListener myTouchListener = new View.OnTouchListener(){
    public boolean onTouch(View v, MotionEvent event) {
        String callidText = callid;
        AnswerDialogListener listener = (AnswerDialogListener) getActivity();
        int streamType = AudioManager.STREAM_MUSIC;
        int volume = 50;
        if(event.getAction() == MotionEvent.ACTION_DOWN) {
            switch (v.getId()) {
                case R.id.answer_dialog_0_button:
                    toneGenerator = new ToneGenerator(streamType, volume);
                    toneGenerator.getAudioSessionId();
                    listener.onAnswerResponse(callidText, "Keypad0");
                    toneType = toneGenerator.TONE_DTMF_0;
                    toneGenerator.startTone(toneType);
                    return true;
                case R.id.answer_dialog_1_button:
                    toneGenerator = new ToneGenerator(streamType, volume);
                    toneGenerator.getAudioSessionId();
                    listener.onAnswerResponse(callidText, "Keypad1");
                    toneType = toneGenerator.TONE_DTMF_1;
                    toneGenerator.startTone(toneType);
                    return true;
                case R.id.answer_dialog
if (response.equals("Keypad0")) {
            try {
                if (call != null) {
                    call.sendDtmf(0);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else if (response.equals("Keypad1")) {
            try {
                if (call != null) {
                    call.sendDtmf(1);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
button: toneGenerator = new ToneGenerator(streamType, volume); toneGenerator.getAudioSessionId(); listener.onAnswerResponse(callidText, "Keypad2"); toneType = toneGenerator.TONE_DTMF_2; toneGenerator.startTone(toneType); return true; case R.id.answer_dialog_3_button: toneGenerator = new ToneGenerator(streamType, volume); toneGenerator.getAudioSessionId(); listener.onAnswerResponse(callidText, "Keypad3"); toneType = toneGenerator.TONE_DTMF_3; toneGenerator.startTone(toneType); return true; case R.id.answer_dialog_4_button: toneGenerator = new ToneGenerator(streamType, volume); toneGenerator.getAudioSessionId(); listener.onAnswerResponse(callidText, "Keypad4"); toneType = toneGenerator.TONE_DTMF_4; toneGenerator.startTone(toneType); return true; case R.id.answer_dialog_5_button: toneGenerator = new ToneGenerator(streamType, volume); toneGenerator.getAudioSessionId(); listener.onAnswerResponse(callidText, "Keypad5"); toneType = toneGenerator.TONE_DTMF_5; toneGenerator.startTone(toneType); return true; case R.id.answer_dialog_6_button: toneGenerator = new ToneGenerator(streamType, volume); toneGenerator.getAudioSessionId(); listener.onAnswerResponse(callidText, "Keypad6"); toneType = toneGenerator.TONE_DTMF_6; toneGenerator.startTone(toneType); return true; case R.id.answer_dialog_7_button: toneGenerator = new ToneGenerator(streamType, volume); toneGenerator.getAudioSessionId(); listener.onAnswerResponse(callidText, "Keypad7"); toneType = toneGenerator.TONE_DTMF_7; toneGenerator.startTone(toneType); return true; case R.id.answer_dialog_8_button: toneGenerator = new ToneGenerator(streamType, volume); toneGenerator.getAudioSessionId(); listener.onAnswerResponse(callidText, "Keypad8"); toneType = toneGenerator.TONE_DTMF_8; toneGenerator.startTone(toneType); return true; case R.id.answer_dialog_9_button: toneGenerator = new ToneGenerator(streamType, volume); toneGenerator.getAudioSessionId(); listener.onAnswerResponse(callidText, "Keypad9"); toneType = toneGenerator.TONE_DTMF_9; toneGenerator.startTone(toneType); return true; case R.id.answer_dialog_asterisk_button: toneGenerator = new ToneGenerator(streamType, volume); toneGenerator.getAudioSessionId(); listener.onAnswerResponse(callidText, "KeypadAsterisk"); toneType = toneGenerator.TONE_DTMF_S; toneGenerator.startTone(toneType); return true; case R.id.answer_dialog_hash_button: toneGenerator = new ToneGenerator(streamType, volume); toneGenerator.getAudioSessionId(); listener.onAnswerResponse(callidText, "KeypadHash"); toneType = toneGenerator.TONE_DTMF_P; toneGenerator.startTone(toneType); return true; } } if(event.getAction() == MotionEvent.ACTION_UP) { switch (v.getId()) { case R.id.answer_dialog_0_button: toneGenerator.stopTone(); toneGenerator.release(); return true; case R.id.answer_dialog_1_button: toneGenerator.stopTone(); toneGenerator.release(); return true; case R.id.answer_dialog
if (response.equals("Keypad0")) {
            try {
                if (call != null) {
                    call.sendDtmf(0);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else if (response.equals("Keypad1")) {
            try {
                if (call != null) {
                    call.sendDtmf(1);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
button: toneGenerator.stopTone(); toneGenerator.release(); return true; case R.id.answer_dialog_3_button: toneGenerator.stopTone(); toneGenerator.release(); return true; case R.id.answer_dialog_4_button: toneGenerator.stopTone(); toneGenerator.release(); return true; case R.id.answer_dialog_5_button: toneGenerator.stopTone(); toneGenerator.release(); return true; case R.id.answer_dialog_6_button: toneGenerator.stopTone(); toneGenerator.release(); return true; case R.id.answer_dialog_7_button: toneGenerator.stopTone(); toneGenerator.release(); return true; case R.id.answer_dialog_8_button: toneGenerator.stopTone(); toneGenerator.release(); return true; case R.id.answer_dialog_9_button: toneGenerator.stopTone(); toneGenerator.release(); return true; case R.id.answer_dialog_asterisk_button: toneGenerator.stopTone(); toneGenerator.release(); return true; case R.id.answer_dialog_hash_button: toneGenerator.stopTone(); toneGenerator.release(); return true; } } return false; } };

Ниже приведен фрагмент оператора if в обработчике обратного вызова MainActivity для вывода DTMF при активном вызове SIP:

if (response.equals("Keypad0")) {
            try {
                if (call != null) {
                    call.sendDtmf(0);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else if (response.equals("Keypad1")) {
            try {
                if (call != null) {
                    call.sendDtmf(1);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
person crockwave    schedule 19.07.2017