I used the code from this link MediaSession onMediaButtonEvent works for a few seconds then quits - Android to capture the keyevents of the remote button and send it to the audio() function where the selection will be played by another mediaplayer.
I run into the same problems where the code will crash after a few seconds. I so far tried to do a loop and also made the audio track not to do at.stop() or do at.release but eventually it still crashes. This keeps the service alive for a bit but then will still crash. I have the code and logcat
public class PlayerService extends Service {
private MediaSessionCompat mediaSession;
AudioTrack at;
@Override
public void onCreate() {
super.onCreate();
MediaSession ms = new MediaSession(getApplicationContext(), getPackageName());
ms.setActive(true);
ms.setCallback(new MediaSession.Callback() {
@Override
public boolean onMediaButtonEvent(Intent mediaButtonIntent) {
KeyEvent keyEvent = (KeyEvent) mediaButtonIntent.getExtras().get(Intent.EXTRA_KEY_EVENT);
if (keyEvent.getAction() == KeyEvent.ACTION_DOWN) {
switch (keyEvent.getKeyCode()) {
case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
audio("button0");
break;
case KeyEvent.KEYCODE_MEDIA_REWIND:
audio("button1");
break;
case KeyEvent.KEYCODE_MEDIA_NEXT:
audio("button2");
break;
case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
audio("button3");
break;
}
}
return super.onMediaButtonEvent(mediaButtonIntent);
}
});
Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
PendingIntent mediaButtonReceiverPendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, mediaButtonIntent, 0);
ms.setMediaButtonReceiver(mediaButtonReceiverPendingIntent);
at = new AudioTrack(AudioManager.STREAM_MUSIC, 48000, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT,
AudioTrack.getMinBufferSize(48000, AudioFormat.CHANNEL_OUT_STEREO, AudioFormat.ENCODING_PCM_16BIT), AudioTrack.MODE_STREAM);
**//at.setLoopPoints(3, 10,10000000);
at.play();
at.stop();
at.release();**
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onDestroy() {
super.onDestroy();
mediaSession.release();
}
public void audio(String command) {
MediaPlayer player = new MediaPlayer();
try {
switch (command) {
case "button0":
player = MediaPlayer.create(this, R.raw.button0);
break;
case "button1":
player = MediaPlayer.create(this, R.raw.button1);
break;
case "button2":
player = MediaPlayer.create(this, R.raw.button2);
break;
case "button3":
player = MediaPlayer.create(this, R.raw.button3);
break;
}
player.start();
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
}
}
My logcat log
2022-02-13 19:08:01.568 19045-19060/com.example.medialistenercopy W/MediaPlayer-JNI: MediaPlayer finalized without being released
2022-02-13 19:08:01.568 19045-19060/com.example.medialistenercopy I/MediaPlayerNative: setListener
2022-02-13 19:08:01.569 19045-19060/com.example.medialistenercopy I/MediaPlayerNative: disconnect
2022-02-13 19:08:01.580 19045-19060/com.example.medialistenercopy I/MediaPlayerNative: destructor
2022-02-13 19:08:01.581 19045-19060/com.example.medialistenercopy I/MediaPlayerNative: disconnect
2022-02-13 19:08:56.467 19045-19045/com.example.medialistenercopy D/AndroidRuntime: Shutting down VM
--------- beginning of crash
2022-02-13 18:57:56.595 17903-17903/com.example.medialistenercopy E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.medialistenercopy, PID: 17903
java.lang.RuntimeException: Unable to stop service com.example.medialistenercopy.PlayerService@e1c144e: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v4.media.session.MediaSessionCompat.release()' on a null object reference
at android.app.ActivityThread.handleStopService(ActivityThread.java:3880)
at android.app.ActivityThread.access$1700(ActivityThread.java:208)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1733)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:205)
at android.app.ActivityThread.main(ActivityThread.java:6991)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:884)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v4.media.session.MediaSessionCompat.release()' on a null object reference
at com.example.medialistenercopy.PlayerService.onDestroy(PlayerService.java:114)
at android.app.ActivityThread.handleStopService(ActivityThread.java:3860)
at android.app.ActivityThread.access$1700(ActivityThread.java:208)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1733)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:205)
at android.app.ActivityThread.main(ActivityThread.java:6991)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:884)
2022-02-13 18:57:56.668 17903-17903/com.example.medialistenercopy I/Process: Sending signal. PID: 17903 SIG: 9
Is the problem because the fake audio track ended too soon or because I have another mediaplayer playing sounds too. I am tweeking everything I can.
I tried to tweek the audio track and I got
2022-02-13 20:58:55.609 27560-27560/com.example.medialistenercopy V/AudioTrack: getMinFrameCount=3844: afFrameCount=1920, afSampleRate=48000, afLatency=80
2022-02-13 20:58:55.610 27560-27560/com.example.medialistenercopy V/AudioTrack: set(): streamType -1, sampleRate 48000, format 0x1, channelMask 0x3, frameCount 3844, flags #0, notificationFrames 0, sessionId 0, transferType 3, uid -1, pid -1
2022-02-13 20:58:55.610 27560-27560/com.example.medialistenercopy V/AudioTrack: Building AudioTrack with attributes: usage=1 content=2 flags=0x0 tags=[]
2022-02-13 20:58:55.619 27560-27560/com.example.medialistenercopy W/AudioTrack: Use of stream types is deprecated for operations other than volume control
2022-02-13 20:58:55.619 27560-27560/com.example.medialistenercopy W/AudioTrack: See the documentation of AudioTrack() for what to use instead with android.media.AudioAttributes to qualify your playback use case
2022-02-13 20:58:55.625 27560-27560/com.example.medialistenercopy V/AudioTrack: ~AudioTrack, releasing session id 8857 from 27560 on behalf of 27560
2022-02-13 20:58:55.626 27560-27560/com.example.medialistenercopy W/MediaAnalyticsItem: Unable to record: [1:audiotrack:0:-1::0:-1:1:0:5:android.media.audiotrack.underrunframes=1922:android.media.audiotrack.type=AUDIO_CONTENT_TYPE_MUSIC:android.media.audiotrack.usage=AUDIO_USAGE_MEDIA:android.media.audiotrack.samplerate=48000:android.media.audiotrack.channelmask=3:] [forcenew=0]
The specific reason for your crash is likely because you do not assign the field
mediaSession; you've instead assigned an instance of MediaSession to a variable in a function scope insideonCreate().I would like to call out that we recommend handling the
onPlay(),onPause(),onFastForward(), etc. callbacks from MediaSession.Callback, as opposed to implementingonMediaButtonEvent(). The reason for this, is that not all actions are provided as a media button, such as seek commands, ratings or custom actions.For more information about media sessions, see also my contextual video on this topic and the dedicated codelab.