Reputation: 577
In my application i am using ToneGenerator to play simple sound. When test my application by compiling the application with 6.0, my application randomy crashing due to ToneGenerator init method. Below is the exception.
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)
I am using the tone generator in below way.
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();
}
}
Any one faced same issue?..Previously my application was running on 4.4 and in that we did not observe any crash. In in 6.0 application is crashing
Upvotes: 4
Views: 6052
Reputation: 31
Following is a Tone Generator based solution that appears stable, using an ontouch listener in a DialogFragment. Set your onTouchListeners for each button in the OnViewCreated method, then use the following ontouch listener method, that continuously plays the selected DTMF tone over the SIP call while touching a button, then stops playing when the button is no longer touched. The AnswerDialogListener is the callback to the MainActivity.
Edit: I broke the previously working DTMF tone RFC2833 proper output by trying to fix a compiler warning by using toneType = ToneGenerator.TONE_DTMF_0; instead of 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_2_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_2_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;
}
};
Following is a snippet of the if statement in the MainActivity callback handler to output the DTMF on the active SIP call:
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();
}
}
Upvotes: 0
Reputation: 577
Solved the issue by using handler.
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);
}
}
Upvotes: 13