I've search alot but i couldn't find the full answer , anyway i've added a service to my game but now the problem is when i press the home/app list button the service ( BGM ) is still on , i've alot try to stop the service on (onPause function) in the main activity but my game use more then one activity , so when i start another activity the BGM is lost ( cuz it's calling MainActivity->onPause function )
so what i sohuld do ?
(my Serivce class)
package com.hema.mrlibya.firstgame;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;
/**
* Created by MrLibya on 18/04/17.
*/
public class BGMusic extends Service {
MediaPlayer mMediaPlayer;
#Override
public void onCreate(){
super.onCreate();
mMediaPlayer = MediaPlayer.create(this,R.raw.bg);
}
public int onStartCommand(Intent intent, int flags, int startId) {
mMediaPlayer.setLooping(true); // Set looping
mMediaPlayer.start();
return START_NOT_STICKY;
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onDestroy() {
mMediaPlayer.stop();
mMediaPlayer.release();
}
/*
public void onPause() {
mMediaPlayer.pause();
length=mMediaPlayer.getCurrentPosition();
}
public void onResume(){
mMediaPlayer.seekTo(length);
mMediaPlayer.start();
}
*/
}
(Manifest)
<service android:enabled="true" android:name="BGMusic" />
(In the MainActivity i've only write on ( onCreate function )
startService(new Intent(this, BGMusic.class));
Firstly: I suggest not to use a service at all, since it is not necessary. Just instantiate the music player in the application. But that is up to your preference.
Secondly (your actual problem): When switching activies just set a flag e.g. keepMusicOn = true; and then
public void onPause() {
if(!keepMusicOn){
mMediaPlayer.pause();
}
//reset flag so that the music stops next time onPause is called
keepMusicOn = false;
...
}
I found the solotuion here
it's work 100%
Related
I have two activities a main activity which has Recyclerview and a detailedActivity which is launched every time the user clicks on one of the items of the Recyclerview. The detailedActivity has a mediaplayer component that is being created everytime a detailedActivity is created. Now in the onDestroy method I always free the resources taken by the mediaPlayer by this code:
#Override
protected void onDestroy() {
if (mMediaPlayer != null) {
if (mMediaPlayer.isPlaying()) {
mMediaPlayer.stop();}
mMediaPlayer.release();
mMediaPlayer=null;
}
super.onDestroy();
}
The app freezes for a while every time I click the back button while the mediaplayer is still preparing. The message that I get in the logcat is this:
I/Choreographer: Skipped 112 frames! The application may be doing too much work on its main thread.
So this freezing only happens if I destroyed the activity while it is preparing but if it is already in the prepared state it won't happen. I use prepreAsync to fetch the media from the internet.
Thanks. Any help is highly appreciated. I have been stuck in this problem for days!
OK. I've kind of worked around the problem. I am writing this for anyone who might encounter the same situation as I did. I made two boolean flags in the scope of the class like this:
boolean prepared = false;
boolean cancel = false;
After that in the onpreapred method I set prepared to true.
mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
prepared = true;
}
});
In the onDestroy method I check whether the mediaplayer is already prepared or not if prepared I release it from the method its self.
#Override
protected void onDestroy() {
if (mMediaPlayer != null) {
if (mMediaPlayer.isPlaying()) {
mMediaPlayer.stop();
}
if (prepared) {
mMediaPlayer.release();
mMediaPlayer = null;
}
cancel = true;
}
super.onDestroy();
}
Otherwise, I set cancel to true and implement on OnBufferingUpdateListener interface and override its method and release the mediaplayer from there.
#Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
if (cancel) {
mp.reset();
mp.release();
mMediaPlayer = null;
Log.i("msg", " mp released");
}
}
Try to remove rechecking if mediaplayer is running or not.
#Override
protected void onDestroy() {
if (mMediaPlayer != null) {
mMediaPlayer.stop();
mMediaPlayer.release();
}
super.onDestroy();
}
If it still happens, try to remove checking mediaplayer in your onDestroy().
-- UPDATE --
This could be related with this bug:
https://code.google.com/p/android/issues/detail?id=959
This could be a help:
Android MediaPlayer reset freezes UI
I was trying to add background sound for 5 sec. in the introductory screen of my app. I tried it on avd as well as on real phone but sound isn't working. where am i wrong?
I am copying java code of my main screen...
package com.example.akg;
import android.app.Activity;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Bundle;
public class Opening extends Activity {
MediaPlayer song;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_opening);
Thread tim=new Thread(){
public void run(){
try{
song=MediaPlayer.create(Opening.this, R.raw.music);
sleep(5000);
}catch(InterruptedException e){
e.getStackTrace();
}finally{
Intent inten=new Intent(Opening.this, MainActivity.class);
startActivity(inten);
}
}
};
tim.start();
}
protected void onPause(){
super.onPause();
song.release();
finish();
}
}
To play background sound to your activity, use following code:
try {
song=MediaPlayer.create(Opening.this, R.raw.music);
song.prepare();
song.start();
} catch (Exception e) {
e.printStackTrace();
}
And to stop background sound, use:
#Override
public void onPause() {
super.onPause();
if(song != null && song.isPlaying()) {
song.stop();
}
}
This link might be helpful to you:
Media Player with Play/Pause, Rewind, Forward, Previous and Next functionality with Seekbar
To play the sound, you need to call:
song.start();
From the android documentation for MediaPlayer:
To start the playback, start() must be called. After start() returns successfully, the MediaPlayer object is in the Started state. isPlaying() can be called to test whether the MediaPlayer object is in the Started state.
I have 6 activities in my app. I want to play different sound throughout whole app. But the problem is that when I start second activity from first activity I want same sound continue from point where its playing in first activity. But unable to find any solution on SO. how to do this? Please help me.
I am using MediaPlayer.
use the application class, or any singleton pattern for that matter you can persist data across activities
https://developer.android.com/reference/android/app/Application.html
In your activities onPause() you have to save the current progress of the track to the shared preferences, then in your activities onResume() get the progress and resume the mediaplayer...
public void onPause() {
super.onPause();
mediaplayer.pause();
int progress = mediaplayer.getCurrentPosition();
getSharedPreferences(getPackageName(), Activity.MODE_PRIVATE).edit().putInt("track_progress",progress).commit();
}
public void onResume() {
int progress = getSharedPreferences(getPackageName(), Activity.MODE_PRIVATE).getInt("track_progress",0);
mediaplayer.seekTo(progress);
mediaplayer.start();
}
Well yeah, or as #Brian says, use a singleton ... :)
Update as a singleton e.g.
public class BackgroundPlayer {
private static final String TAG = BackgroundPlayer.class.getName();
private static BackgroundPlayer instance;
public static BackgroundPlayer instance() {
if(instance==null) instance = new BackgroundPlayer();
return instance;
}
private MediaPlayer mediaPlayer;
public void startBackgroundMusic(Context ctx, int res) {
if(mediaPlayer==null) {
mediaPlayer = MediaPlayer.create(ctx, res);
mediaPlayer.setLooping(true);
}
if(mediaPlayer!=null&&!mediaPlayer.isPlaying())
Log.i(TAG,"started");
mediaPlayer.start();
}
public void stopBackgroundMusic() {
if(mediaPlayer!=null)
Log.i(TAG,"stopped");
mediaPlayer.stop();
mediaPlayer.release();
mediaPlayer = null;
}
}
Now you can access the same instance of the BackgroundPlayer anywhere in your code with
BackgroundPlayer.instance()
and you can call
BackgroundPlayer.instance().startBackgroundMusic(Context, resource);
BackgroundPlayer.instance().stopBackgroundMusic();
anywhere. Now you have to make sure you call .startBackgroundMusic in your first activities onCreate() and call .stopBackgroundMusic in the last activity on the stack, so the sound doesn't keep going when the user leaves your app.
I am trying to create my first android application and what I'm trying to accomplish here is to play a sound and then stop it via the same button.
It kind of works as it plays the sound when I click it and stops when I click it again but will not play when I click it the third time to start the sound again.
I'm eventually going to have a few sounds in here and so would like to know if how my project is laid out correctly? Can I save some time anywhere? Have I got something the wrong way round?
package test.soundy.com;
import android.app.Activity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class TestActivity extends Activity {
private MediaPlayer sound;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
sound = MediaPlayer.create(Test.this, R.raw.sound1);
Button test = (Button)this.findViewById(R.id.button1);
test.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (sound.isPlaying()) {
sound.stop();
} else {
sound.start();
}
}
});
}
}
Any help would be much appreciated, thanks.
WHEN START/PAUSE:
if(sound.isPlaying()){
sound.pause();
}else{
sound.start();
}
WHEN START/STOP:
if(sound.isPlaying()) {
sound.stop();
} else {
sound.reset();
sound.setDataSource(yourURL); //or InputStream etc.
sound.prepare();
sound.start();
}
Also you can use sound.seekTo(time) to skip to a position.
Remember when you want to play a new sound(or restart) you should first reset, setDataSource, prepare and then start it.
EDIT: get the FileDescripter
AssetManager assetManager=Context.getAssets();
AssetFileDescriptor fileDescriptor = assetManager.openFd("a2.mp3");
mediaPlayer.setDataSource(fileDescriptor.getFileDescriptor());
EDIT: I haven't found a way to turn raw file into filedescriptor so I use the static method of MediaPlayer
MediaPlayer mediaPlayer = MediaPlayer.create(Activity.this,R.raw.a1);
mediaPlayer.setOnCompletionListener(new musicCompletionListener());
mediaPlayer.start();
private class musicCompletionListener implements OnCompletionListener {
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
mediaPlayer.release();
}
}
alse release the mediaplayer when stop it.
Have you tried resetting the MP?
if (sound.isPlaying()) {
sound.stop();
} else {
sound.reset();
sound.prepare();
sound.start();
}
Edited...
The full state diagram is here: http://developer.android.com/reference/android/media/MediaPlayer.html
I am using a media player.
I have the option for starting ,stopping and pausing the player. The problem I have is that I cannot find the option to resume the song from the point that it previously was paused..
Any help provide would be really helpful.
Thank you for your attention but I've got it myself
for pausing the Mediaplayer I used:
Mediaplayer.pause();
length=Mediaplayer.getCurrentPosition();
and for resuming the player from the position where it stopped lately is done by:
Mediaplayer.seekTo(length);
Mediaplayer.start();
I think you should go through the documentation found here: http://developer.android.com/reference/android/media/MediaPlayer.html
Some quotes from the docs:
Playback can be paused and stopped,
and the current playback position can
be adjusted. Playback can be paused
via pause(). When the call to pause()
returns, the MediaPlayer object enters
the Paused state. Note that the
transition from the Started state to
the Paused state and vice versa
happens asynchronously in the player
engine. It may take some time before
the state is updated in calls to
isPlaying(), and it can be a number of
seconds in the case of streamed
content.
Calling start() to resume
playback for a paused MediaPlayer
object, and the resumed playback
position is the same as where it was
paused. When the call to start()
returns, the paused MediaPlayer object
goes back to the Started state.
Calling pause() has no effect on a
MediaPlayer object that is already in
the Paused state.
States explained:
And quote from the start() method of the MediaPlayer
public void start ()
Starts or resumes
playback. If playback had previously
been paused, playback will continue
from where it was paused. If playback
had been stopped, or never started
before, playback will start at the
beginning.
So to answer your question directly, to resume the paused MediaPlayer instance from the point where it was paused use start() again on that instance.
In the accepted answer, the correct order is:
Mediaplayer.start();
Mediaplayer.seekTo(length);
in case you use two Buttons one for play and one for pause then the below code is working and tried:
playbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mPlayer = MediaPlayer.create(MainActivity.this,
R.raw.adhan);
if (mPlayer.isPlaying()) {
} else {
mPlayer.seekTo(length);
mPlayer.start();
}
}
});
pausebtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mPlayer.pause();
length = mPlayer.getCurrentPosition();
}
});
public class MainActivity extends AppCompatActivity {
MediaPlayer mediaPlayer;
public void play(View view) {
mediaPlayer.start();
}
public void pause(View view){
mediaPlayer.pause();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mediaPlayer= MediaPlayer.create(this,R.raw.someaudio);
}
}
Make two buttons for play and pause. And use this code. It worked for me.
what about this way?
package com.mycompany.audiodemo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.media.MediaPlayer;
import android.view.View;
public class MainActivity extends AppCompatActivity {
MediaPlayer mediaPlayer=null;
int playPosition=0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mediaPlayer = MediaPlayer.create(this,R.raw.sampleaudio);
}
public void playAudio(View view){
//mediaPlayer.seekTo(playPosition);
mediaPlayer.start();
}
public void pauseAudio(View view){
mediaPlayer.pause();
//playPosition = mediaPlayer.getCurrentPosition();
}
}