Android MediasessionCompat callback function for physical media player button keeps crashing - java

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 inside onCreate().
I would like to call out that we recommend handling the onPlay(), onPause(), onFastForward(), etc. callbacks from MediaSession.Callback, as opposed to implementing onMediaButtonEvent(). 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.

Related

Pause other media apps

When I start my MediaPlayer, other apps that are playing audio don't stop. Same when using MediaRecorder.
I managed to use AudioManager to have some functionality, but much of that class is either deprecated, or for high APIs.
For example, I can register a callback, but I can't unregister it cause the abandonAudioFocus() is deprecated.
Looking at sources, it tells me to use a MediaSession, but that's too complicated for my simple goal of playing a simple recorded audio, I don't want to use all the functionality of every single Android platform.
You can do that with AudioManager
AudioManager am = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
// Request audio focus for playback
int result = am.requestAudioFocus(focusChangeListener,
// Use the music stream.
AudioManager.STREAM_MUSIC,
// Request permanent focus.
AudioManager.AUDIOFOCUS_GAIN);
if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
// other app had stopped playing song now , so u can do u stuff now .
}
Audio focus is assigned in turn to each application that requests it.
This means that if another application requests audio focus, your
application will lose it. You will be notifi ed of the loss of audio
focus through the onAudioFocusChange handler of the Audio Focus Change
Listener you registered when requesting the audio focus
private OnAudioFocusChangeListener focusChangeListener =
new OnAudioFocusChangeListener() {
public void onAudioFocusChange(int focusChange) {
AudioManager am =(AudioManager)getSystemService(Context.AUDIO_SERVICE);
switch (focusChange) {
case (AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK) :
// Lower the volume while ducking.
mediaPlayer.setVolume(0.2f, 0.2f);
break;
case (AudioManager.AUDIOFOCUS_LOSS_TRANSIENT) :
pause();
break;
case (AudioManager.AUDIOFOCUS_LOSS) :
stop();
ComponentName component =new ComponentName(AudioPlayerActivity.this,MediaControlReceiver.class);
am.unregisterMediaButtonEventReceiver(component);
break;
case (AudioManager.AUDIOFOCUS_GAIN) :
// Return the volume to normal and resume if paused.
mediaPlayer.setVolume(1f, 1f);
mediaPlayer.start();
break;
default: break;
}
}
};

MediaPlayer delay 0.4 seconds for Bluetooth headset

I'm developing an application with playing audio. In several cases I change the AudioStreamType to AudioManager.STREAM_RING(is mode when music is playing both: speakers and headset). When I use Bluetooth headset, I have a small annoying delay.
So i was reading that Bluetooth has a buffer and and this is logical
, but how I can solve this? Also i tried to change buffer size or delay for mediaPlayer.
So, i create a mediaPlayer like as:
#Override
public void onInit() {
mediaPlayer = new MediaPlayer();
mediaPlayer.setOnCompletionListener(this);
mediaPlayer.setLooping(true);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_RING);
songManager = new SongsManager(context);
}
#Override
public void onPrepare() {
// prepare media player
if (mediaPlayer != null) {
mediaPlayer.reset();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_RING);
absolutePathToPlayingSong = /*some place*/;
mediaPlayer.setDataSource(/*some place*/);
mediaPlayer.prepare();
mediaPlayer.setVolume(volumeLvl, volumeLvl);
}
AudioManager audio = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
audio.setStreamVolume(AudioManager.STREAM_MUSIC, 20, 0);
}
then i just start player:
mediaPlayer.start();
So, i already tried:
to change a prepare() to prepareAsync() - probably it was tiny help, to may be i had a sound hallucinations. Unfortunately it broke a seekTo() in one place
added onPrepared() and start playing from listener - I not sure that it help
Give me please any advance^ how to fix delay for Bluetooth headset? I checked this device in YouTube application and it work great. So problem in my application. sorry my bad English!)
I have 2 target devices android 7.0(SDK 24) and android 4.2 (SDK 16)

Multiple MediaPlayers keep failing - Android studio

I'm new to Android and Java development and am looking for some guidance in setting up a simple soundboard app. What I am trying to do and am having issues in getting it working effectively is handling events for multiple mediaplayers.
For example I am creating a soundboard whereby when I click a button I want all other sounds to be stopped and released from memory and the button I have just pressed to play its assigned sound. I realise that repeating code blocks is not a good programming approach, but I have tried this with arrays and switch statements too with little effect. Any guidance on how to effectively release sounds from memory when using multiple MediaPlayers would be very useful to me. I have included my code below for 4 buttons (I have over 30 on this app)
public class MainActivity extends AppCompatActivity {
private MediaPlayer Meow1,Meow2,Meow3,Meow4;
private Button meowButton1,meowButton2,meowButton3,meowButton4;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Meow1 = new MediaPlayer();
Meow1 = MediaPlayer.create(getApplicationContext(), R.raw.meow1);
// final Boolean Meow1Pause = !Meow1.isPlaying() && Meow1.getCurrentPosition() >1;
meowButton1 = (Button) findViewById(R.id.Meow1);
meowButton1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (Meow1.isPlaying())
{ pauseMusic1();
} else {
Meow1.start();
}}
});
Meow1.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer Meow1) {
Meow1.stop();
Meow1.reset();
Meow1.release();
}
});
Meow2 = new MediaPlayer();
Meow2 = MediaPlayer.create(getApplicationContext(), R.raw.meow2);
meowButton2 = (Button) findViewById(R.id.Meow2);
meowButton2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (Meow2.isPlaying() ){
pauseMusic();
} else {
Meow2.start();
}}
});
Meow2.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer Meow1) {
Meow2.stop();
Meow2.reset();
Meow2.release();
}
});
Meow3 = new MediaPlayer();
Meow3 = MediaPlayer.create(getApplicationContext(), R.raw.meow3);
meowButton3 = (Button) findViewById(R.id.Meow3);
meowButton3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (Meow3.isPlaying())
{ pauseMusic();
} else {
Meow3.start();
}}
});
Meow3.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer Meow1) {
Meow3.stop();
Meow3.reset();
Meow3.release();
}
});
Meow4 = new MediaPlayer();
Meow4 = MediaPlayer.create(getApplicationContext(), R.raw.meow4);
meowButton4 = (Button) findViewById(R.id.Meow4);
meowButton4.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (Meow4.isPlaying())
{ pauseMusic();
} else {
Meow4.start();
}}
});
}
public void pauseMusic() {
if(Meow1 != null && Meow1.isPlaying()) Meow1.pause();
if(Meow2 != null && Meow2.isPlaying()) Meow2.pause();
if(Meow3 != null && Meow3.isPlaying()) Meow3.pause();
if(Meow4 != null && Meow4.isPlaying()) Meow4.pause();
}
}
Run Compiler:
A: Logging event (FE): screen_view(_vs), Bundle[{firebase_event_origin(_o)=auto, firebase_previous_class(_pc)=SplashScreen, firebase_previous_id(_pi)=-6549553702477848745, firebase_screen_class(_sc)=MainActivity, firebase_screen_id(_si)=-6549553702477848744}]
I/zygote: Do partial code cache collection, code=124KB, data=67KB
I/zygote: After code cache collection, code=124KB, data=67KB
I/zygote: Increasing code cache capacity to 512KB
V/FA: Activity resumed, time: 6376787
D/EGL_emulation: eglMakeCurrent: 0x980fde60: ver 3 0 (tinfo 0xa3c3c290)
D/EGL_emulation: eglMakeCurrent: 0x980fde60: ver 3 0 (tinfo 0xa3c3c290)
D/EGL_emulation: eglMakeCurrent: 0x980fde60: ver 3 0 (tinfo 0xa3c3c290)
I/chatty: uid=10085(u0_a85) RenderThread identical 2 lines
D/EGL_emulation: eglMakeCurrent: 0x980fde60: ver 3 0 (tinfo 0xa3c3c290)
V/FA: Inactivity, disconnecting from the service
V/MediaPlayer: resetDrmState: mDrmInfo=null mDrmProvisioningThread=null mPrepareDrmInProgress=false mActiveDrmScheme=false
cleanDrmObj: mDrmObj=null mDrmSessionId=null
V/MediaPlayer: resetDrmState: mDrmInfo=null mDrmProvisioningThread=null mPrepareDrmInProgress=false mActiveDrmScheme=false
cleanDrmObj: mDrmObj=null mDrmSessionId=null
D/TAG1: Button 2 pressed
D/AndroidRuntime: Shutting down VM
E/AndroidRuntime: FATAL EXCEPTION: main
Process: g.convery.cat_sounds, PID: 12276
java.lang.IllegalStateException
at android.media.MediaPlayer.isPlaying(Native Method)
at g.convery.cat_sounds.MainActivity$1.onClick(MainActivity.java:97)
at android.view.View.performClick(View.java:6256)
at android.view.View$PerformClick.run(View.java:24701)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
W/MediaPlayer-JNI: MediaPlayer finalized without being released
W/MediaPlayer-JNI: MediaPlayer finalized without being released
Application terminated.
LOGCAT:
05-31 09:21:30.099 12276-12288/g.convery.cat_sounds W/MediaPlayer-JNI: MediaPlayer finalized without being released
05-31 09:21:30.211 12276-12288/g.convery.cat_sounds I/chatty: uid=10085(u0_a85) FinalizerDaemon identical 33 lines
05-31 09:21:30.212 12276-12288/g.convery.cat_sounds W/MediaPlayer-JNI: MediaPlayer finalized without being released
05-31 09:21:30.283 12276-12284/g.convery.cat_sounds I/zygote: Do partial code cache collection, code=124KB, data=67KB
05-31 09:21:30.286 12276-12284/g.convery.cat_sounds I/zygote: After code cache collection, code=124KB, data=67KB
05-31 09:21:30.287 12276-12284/g.convery.cat_sounds I/zygote: Increasing code cache capacity to 512KB
05-31 09:21:31.159 12276-12307/g.convery.cat_sounds I/chatty: uid=10085(u0_a85) RenderThread identical 2 lines
05-31 09:24:41.746 12276-12276/g.convery.cat_sounds E/AndroidRuntime: FATAL EXCEPTION: main
Process: g.convery.cat_sounds, PID: 12276
java.lang.IllegalStateException
at android.media.MediaPlayer.isPlaying(Native Method)
at g.convery.cat_sounds.MainActivity$1.onClick(MainActivity.java:97)
at android.view.View.performClick(View.java:6256)
at android.view.View$PerformClick.run(View.java:24701)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
05-31 09:24:47.955 12276-12288/g.convery.cat_sounds W/MediaPlayer-JNI: MediaPlayer finalized without being released
05-31 09:24:47.956 12276-12288/g.convery.cat_sounds W/MediaPlayer-JNI: MediaPlayer finalized without being released
You are using the media player after releasing it. Remove these lines from your onCompletionListener and add them to onDestroy of your activity instead
Meow1.release();
Meow2.release();
Meow3.release();
Meow4.release();
Also calling create automatically creates a new instance, you can remove these lines as well
Meow1 = new MediaPlayer();
Meow2 = new MediaPlayer();
Meow3 = new MediaPlayer();
Meow4 = new MediaPlayer();
A better approach would be to use a single media player and just change the datesource when ever user wants to play different source, but this method will take some time before it plays the audio as it will prepare the audio everytime, this would be negligible unless your audio size is quite huge
Look how you're controlling your media now:
if (Meow4.isPlaying()) {
pauseMusic();
} else {
Meow4.start();
}
The first time you call Meow4.isPlaying() you will receive IllegalStateException because your player is not initialized.
Look how your MediaPlayer state is defined and call appropriate function
The second point, when you encounter a duplicate block, you should think of a function.
Meow3 = new MediaPlayer();
Meow3 = MediaPlayer.create(getApplicationContext(), R.raw.meow3);
meowButton3 = (Button) findViewById(R.id.Meow3);
meowButton3.setOnClickListener(new View.OnClickListener() {
});
meowButton3.setOnCompletionListener...
in a function: registerPlayer(Context context, int resourceId, Button controlButton)
Or with higher level of abstraction, create a subclass of `MediaPlayer` and wrap these logic inside it
Definitely you don't want to Meow1.pause() over and over. Instead, store your MeoX in a list then loop over it:
List<MediaPlayer> players = new ArrayList<>();
players.add(Meow1);
....
public void pauseMusic() {
players.stream().filter(p -> p != null && p.isPlaying()).forEach(p -p.pause());
}

android media player on background not stop playing while open other activity

My application has 3 options(Buttons) in my main activity and a media player that plays a song when the application is launched. The media player starts correctly when the application is launched, but If i press a button to start a new activity while the audio is still playing, the application crushes (unfortunately app has stopped).
If i press "OK" in the message it opens the new activity and media player stops.
My aim is to start the new activity and stop the media player (song).
Could anyone help me with these issues.?
TextView logoname;
Button autismlogo,visionlogo,hearinglogo;
private SensorManager mSensorManager;
private ShakeEventListener mSensorListener;
MediaPlayer player;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
logoname = (TextView)findViewById(R.id.logotext);
autismlogo = (Button)findViewById(R.id.autismbutton);
visionlogo = (Button)findViewById(R.id.visionbutton);
hearinglogo = (Button)findViewById(R.id.hearingbutton);
final MediaPlayer player = MediaPlayer.create(MainActivity.this, R.raw.welcome);
player.start();
// ---SENSORS--------
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensorListener = new ShakeEventListener();
mSensorListener.setOnShakeListener(new ShakeEventListener.OnShakeListener() {
public void onShake() {
Intent vision = new Intent(getApplicationContext(),Vision_main.class);
startActivity(vision);
}
});
// ----ON CLICK EVENTS -----------
autismlogo.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent autism = new Intent(getApplicationContext(),Autism_main.class);
startActivity(autism);
}
});
visionlogo.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent vision = new Intent(getApplicationContext(),Vision_main.class);
startActivity(vision);
}
});
hearinglogo.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent hearing = new Intent(getApplicationContext(),Hearing_main.class);
startActivity(hearing);
}
});
}
public void onResume() {
super.onResume();
mSensorManager.registerListener(mSensorListener,
mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_UI);
}
public void onPause() {
super.onPause();
player.stop();
mSensorManager.unregisterListener(mSensorListener);
}
Log Cat error
E/AndroidRuntime(27610): FATAL EXCEPTION: main
E/AndroidRuntime(27610): Process: com.giorgospapadopoulos.move4all, PID: 27610
E/AndroidRuntime(27610): java.lang.RuntimeException: Unable to pause activity {com.giorgospapadopoulos.move4all/com.giorgospapadopoulos.move4all.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.media.MediaPlayer.stop()' on a null object reference
E/AndroidRuntime(27610): at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3260)
E/AndroidRuntime(27610): at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3219)
E/AndroidRuntime(27610): at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:3194)
E/AndroidRuntime(27610): at android.app.ActivityThread.access$1000(ActivityThread.java:151)
E/AndroidRuntime(27610): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1314)
E/AndroidRuntime(27610): at android.os.Handler.dispatchMessage(Handler.java:102)
E/AndroidRuntime(27610): at android.os.Looper.loop(Looper.java:135)
E/AndroidRuntime(27610): at android.app.ActivityThread.main(ActivityThread.java:5254)
E/AndroidRuntime(27610): at java.lang.reflect.Method.invoke(Native Method)
E/AndroidRuntime(27610): at java.lang.reflect.Method.invoke(Method.java:372)
E/AndroidRuntime(27610): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
E/AndroidRuntime(27610): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
E/AndroidRuntime(27610): Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.media.MediaPlayer.stop()' on a null object reference
E/AndroidRuntime(27610): at com.giorgospapadopoulos.move4all.MainActivity.onPause(MainActivity.java:220)
E/AndroidRuntime(27610): at android.app.Activity.performPause(Activity.java:6101)
E/AndroidRuntime(27610): at android.app.Instrumentation.callActivityOnPause(Instrumentation.java:1310)
E/AndroidRuntime(27610): at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3246)
E/AndroidRuntime(27610): ... 11 more
Your error is quite clear. You get a NullPointerException at line 120 in your onPause() method. That's because you haven't created the player object and you try to invoke one of it's methods.
You have declared it as a global variable but you haven't created it. You create a different player object inside your onCreate() method but that's just a local variable.
Firstly in line
final MediaPlayer player = MediaPlayer.create(MainActivity.this, R.raw.welcome);
not declare MediaPlayer player as local, it should be global.
Use this in onPause()
if(player!=null){
player.stop();
}
in onResume()
if(
player!=null){
player.start();
}
by above code player will play music when app in foreground, when app in background player stop playing music and when app again comes in foreground state player will play music.

Weird issue with media player and async playing aacp/shoutcast stream on android

I'm trying to build a custom player for a radio station, and they want to move from mpeg to aac to lower the bitrate (mostly for mobile users) however when i started the project i was testing it against the mpeg stream, When i change it to the new aac stream my player seems to lock for a period of time, then the UI thread is killed by android while the player is attempting to load the stream in the background. I do get some initial errors about it being unable to play, but maybe 30 seconds after the app is killed i get an orphaned async player re-spawning in the background with it's sticky notification and the stream starts playing?
the logcat output shows these lines around when it crashes
I/dalvikvm﹕ threadid=3: reacting to signal
I/dalvikvm﹕ Wrote stack traces to '/data/anr/traces.txt'A/libc﹕ Fatal signal 6 (SIGABRT) at 0x000008eb (code=0), thread 32258
I see the sticky for the orphaned async task and it's playing audio when i click it (to regain audio focus) but the main app/ui thread is obviously completely reset
The code that spawns the async task is as follows:
private class PlayAsync extends AsyncTask<String, Void, Boolean> {
private String url_to_play = "";
#Override
protected void onPreExecute() {
super.onPreExecute();
textView_info.setText("Buffering...");
}
#Override
protected Boolean doInBackground(String... params) {
url_to_play = params[0];
Bundle b = new Bundle();
b.putString("url", url_to_play);
Intent i = new Intent(MainActivity.this, MusicService.class);
i.putExtras(b);
try {
stopService(new Intent(MainActivity.this, MusicService.class));
} catch (Exception ex) {
//
}
startService(i);
return true;
}
#Override
protected void onPostExecute(Boolean result) {
isMuted = isMuted();
if (isMuted) {
textView_info.setText("Playing Muted!");
} else
textView_info.setText("Playing");
isBuffering = false;
}
#Override
protected void onProgressUpdate(Void... values) {
}
protected void onError(MusicService mp, int what, int extra) {
// The MediaPlayer has moved to the Error state, must be reset!
button_stop.performClick();
}
}

Categories

Resources