I am a newbie in Android Developer
I am building a game app on Android Studio. But, I have had a problem about Background music while playing game. I have used Bound Service to handle through the class: MusicService extends Service implements MediaPlayer.OnErrorListener. But, my App was stopped when I run.
I have tried to fixed and explored solutions, but, I can't run app...
This is source code:
MusicService.java
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnErrorListener;
import android.os.Binder;
import android.os.IBinder;
import android.widget.Toast;
public class MusicService extends Service implements MediaPlayer.OnErrorListener {
private final IBinder mBinder = new ServiceBinder();
MediaPlayer mPlayer;
private int length = 0;
public MediaPlayer Player;
public MusicService() {
}
public class ServiceBinder extends Binder {
public MusicService getService() {
return MusicService.this;
}
}
#Override
public IBinder onBind(Intent arg0) {
return mBinder;
}
#Override
public void onCreate() {
super.onCreate();
Player = MediaPlayer.create(this, R.raw.one);
mPlayer.setOnErrorListener(this);
if (mPlayer != null) {
mPlayer.setLooping(true);
mPlayer.setVolume(100, 100);
}
mPlayer.setOnErrorListener(new OnErrorListener() {
public boolean onError(MediaPlayer mp, int what, int
extra) {
onError(mPlayer, what, extra);
return true;
}
});
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
mPlayer.start();
return START_STICKY;
}
public void pauseMusic() {
if (mPlayer.isPlaying()) {
mPlayer.pause();
length = mPlayer.getCurrentPosition();
}
}
public void resumeMusic() {
if (mPlayer.isPlaying() == false) {
mPlayer.seekTo(length);
mPlayer.start();
}
}
public void stopMusic() {
mPlayer.stop();
mPlayer.release();
mPlayer = null;
}
#Override
public void onDestroy() {
super.onDestroy();
if (mPlayer != null) {
try {
mPlayer.stop();
mPlayer.release();
} finally {
mPlayer = null;
}
}
}
public boolean onError(MediaPlayer mp, int what, int extra) {
Toast.makeText(this, "music player failed", Toast.LENGTH_SHORT).show();
if (mPlayer != null) {
try {
mPlayer.stop();
mPlayer.release();
} finally {
mPlayer = null;
}
}
return false;
}
}
and, MainActivity.java
public class MainActivity extends AppCompatActivity {
private boolean mIsBound = false;
private MusicService mServ;
private ServiceConnection Scon =new ServiceConnection(){
public void onServiceConnected(ComponentName name, IBinder service) {
MusicService.ServiceBinder binder = (MusicService.ServiceBinder)service;
mServ =binder.getService();
}
public void onServiceDisconnected(ComponentName name) {
mServ = null;
}
};
// Activity create UI its
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
// Activity start.
#Override
protected void onStart() {
super.onStart();
// create Intent for MusicService.
Intent intent = new Intent(MainActivity.this,MusicService.class);
// call method bindService(..) to bind activity
this.bindService(intent, Scon, Context.BIND_AUTO_CREATE);
}
//Activity stop
#Override
protected void onStop() {
super.onStop();
if (mIsBound) {
this.unbindService(Scon);
mIsBound = false;
}
}
Then, I didn't also forget add the code following in AndroidManifest
<service
android:name=".MusicService"
android:enabled="true"
android:exported="true"></service>
That's all problems mine. This makes me so confuse
Help you, please
Thank you very much
Can you add more log debug in logcat? Not sure but I guess problem is you call:
mPlayer.start();
in onStartComand(). Your service should implement MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener,MediaPlayer.OnCompletionListener and above function should be call in
void onPrepared(MediaPlayer mp)
Related
I am trying to run my Android radio app in the background. So when I click the back button after a little time it has been forced to stop. Automatically calls the onDestroy() method. How do I fix this problem?
This is the main activity class onBackPressed() button code.
#Override
public void onBackPressed(){
System.out.println("onBackPressed");
serviceIntent.addCategory(Intent.CATEGORY_HOME);
serviceIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(serviceIntent);
moveTaskToBack(true);
//activity.moveTaskToBack(true);
}
This is the console log
> I/System.out: onPrepared I/System.out: onBackPressed I/System.out:
> onDestroy I/System.out: onDestroy1 I/System.out: onDestroy2
> V/MediaPlayer: resetDrmState: mDrmInfo=null
> mDrmProvisioningThread=null mPrepareDrmInProgress=false
> mActiveDrmScheme=false V/MediaPlayer: cleanDrmObj: mDrmObj=null
> mDrmSessionId=null W/MediaPlayer: mediaplayer went away with unhandled
> events
MainActivity
package com.jiat.yesradio;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity implements MusicStoppedListener {
private ImageView imagePlayPause;
String stream = "https://radio.lankayes.lk/8002/stream";
boolean musicPlaying = false;
Intent serviceIntent;
#Override
protected void onCreate(Bundle savedInstanceState) {
System.out.println("onCreate MainA");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imagePlayPause = (ImageView) findViewById(R.id.imagePlayPause);
imagePlayPause.setImageResource(R.drawable.play_icon);
serviceIntent = new Intent(this, MyPlayService.class);
// serviceIntent = new Intent(this, SimpleMyPlayService.class);
ApplicationClass.context = (Context) MainActivity.this;
imagePlayPause.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
System.out.println("onClick");
if (!musicPlaying) {
System.out.println("onClick_inside_music_player");
startService(serviceIntent);
playAudio();
imagePlayPause.setImageResource(R.drawable.pause_icon);
musicPlaying = true;
}
else {
stopPlayService();
stopService(serviceIntent);
imagePlayPause.setImageResource(R.drawable.play_icon);
musicPlaying = false;
}
}
});
}
#Override
public void onBackPressed(){
System.out.println("onBackPressed");
/* serviceIntent.addCategory(Intent.CATEGORY_HOME);
serviceIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(serviceIntent);*/
moveTaskToBack(true); //activity.moveTaskToBack(true);
}
private void stopPlayService() {
System.out.println("stopPlayService");
try {
stopService(serviceIntent);
} catch (SecurityException e) {
Toast.makeText(this, "Error:" + e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
private void playAudio() {
System.out.println("playAudio");
serviceIntent.putExtra("AudioLink", stream);
// serviceIntent.putExtra("SimpleAudioLink", stream);
try {
startService(serviceIntent);
} catch (SecurityException e) {
Toast.makeText(this, "Error:" + e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
#Override
public void onMusicStopped() {
System.out.println("onMusicStopped");
imagePlayPause.setImageResource(R.drawable.play_icon);
musicPlaying = false;
}
}
MyPlayService class.
package com.jiat.yesradio;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;
import android.widget.Toast;
public class MyPlayService extends Service implements MediaPlayer.OnCompletionListener, MediaPlayer.OnPreparedListener,
MediaPlayer.OnErrorListener, MediaPlayer.OnSeekCompleteListener, MediaPlayer.OnInfoListener,
MediaPlayer.OnBufferingUpdateListener {
private MediaPlayer mediaPlayer;
String link;
private MusicStoppedListener musicStoppedListener;
Context context;
public MyPlayService() {
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
System.out.println("onBind");
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public void onCreate() {
super.onCreate();
System.out.println("onCreate");
mediaPlayer = new MediaPlayer();
mediaPlayer.setOnCompletionListener(this);
mediaPlayer.setOnPreparedListener(this);
mediaPlayer.setOnErrorListener(this);
mediaPlayer.setOnSeekCompleteListener(this);
mediaPlayer.setOnInfoListener(this);
mediaPlayer.setOnBufferingUpdateListener(this);
mediaPlayer.setLooping(true);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("onStartCommand");
link = intent.getStringExtra("AudioLink");
mediaPlayer.reset();
musicStoppedListener = (MusicStoppedListener) ApplicationClass.context;
if (!mediaPlayer.isPlaying()) {
try {
mediaPlayer.setDataSource(link);
mediaPlayer.prepareAsync();
} catch (Exception e) {
Toast.makeText(this, "Error:" + e.getMessage(), Toast.LENGTH_SHORT).show();
}
}
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
System.out.println("onDestroy");
if (mediaPlayer != null) {
System.out.println("onDestroy1");
if (mediaPlayer.isPlaying()) {
System.out.println("onDestroy2");
mediaPlayer.stop();
}
mediaPlayer.release();
}
}
#Override
public void onBufferingUpdate(MediaPlayer mediaPlayer, int i) {
System.out.println("onBufferingUpdate");
}
#Override
public void onCompletion(MediaPlayer mediaPlayer) {
/* if (mediaPlayer.isPlaying()) {
mediaPlayer.stop();
}
musicStoppedListener.onMusicStopped();
stopSelf();*/
System.out.println("onCompletion");
}
#Override
public boolean onError(MediaPlayer mediaPlayer, int what, int i1) {
System.out.println("onError");
switch (what) {
case MediaPlayer.MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK:
Toast.makeText(this, "MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK", Toast.LENGTH_SHORT).show();
break;
case MediaPlayer.MEDIA_ERROR_SERVER_DIED:
Toast.makeText(this, "MEDIA_ERROR_SERVER_DIED", Toast.LENGTH_SHORT).show();
break;
case MediaPlayer.MEDIA_ERROR_UNKNOWN:
Toast.makeText(this, "MEDIA_ERROR_UNKNOWN", Toast.LENGTH_SHORT).show();
break;
}
return false;
}
#Override
public boolean onInfo(MediaPlayer mediaPlayer, int i, int i1) {
System.out.println("onInfo");
return false;
}
#Override
public void onPrepared(MediaPlayer mediaPlayer) {
System.out.println("onPrepared");
if (!mediaPlayer.isPlaying()) {
mediaPlayer.start();
}
}
#Override
public void onSeekComplete(MediaPlayer mediaPlayer) {
System.out.println("onSeekComplete");
}
}
Heres my problem:
I am implementing a music player (PlayerActivity.java / xml) which is bound to a service (PlayerService.java) that basically is just an instance of a musicplayer so that it can run in the background. When lefting the app or changing the activity and the restarting the activity i want to bind to the still running service without stopping or restarting it. I have tried using only bindService() but that made me face the problem: somehow without calling startService() before bindService the Service doesn't get initialized or it takes a few milliseconds so that the functions only get null when accessing service functions.
Here is my service class:
public class playerService extends Service {
public boolean running = false;
public MediaPlayer mediaPlayer;
public boolean isPrepared = false;
private String url;
public class serviceBinder extends Binder {
public playerService getService() {
return playerService.this;
}
}
public boolean isRunning(){
return running;
}
private IBinder mBinder = new serviceBinder();
#Nullable
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.w("Service", "started");
mediaPlayer = new MediaPlayer();
running = true;
Log.e("!!!", running + "");
return START_STICKY;
}
public void pause() {
mediaPlayer.pause();
}
public void resume() {
mediaPlayer.start();
}
public void setupPlayer() {
try {
if (mediaPlayer != null) {
mediaPlayer.reset();
}
} catch (Exception e) {
Log.e("MediaPlayer", e.getMessage());
}
try {
mediaPlayer.setDataSource(url);
mediaPlayer.prepareAsync();
} catch (Exception e) {
Log.e("MediaPlayerToo", e.getMessage());
}
}
public void reset(){
mediaPlayer.reset();
}
public void updateUrl(String url){
this.url = url;
}
public void start(){
mediaPlayer.start();
}
public int getCurrentPosition(){
return mediaPlayer.getCurrentPosition();
}
public int getDuration(){
return mediaPlayer.getDuration();
}
#Override
public void onDestroy() {
super.onDestroy();
mediaPlayer.stop();
mediaPlayer.reset();
}
}
I experimented with waiting until the Service has started with a boolean. But when i add any kind of code
after
mService = binder.getService();
startService(intent);
it seems to not get created at all.
Here is also my onServiceConnected class
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
playerService.serviceBinder binder = (playerService.serviceBinder) service;
Intent intent = new Intent(getApplicationContext(), playerService.class);
mService = binder.getService();
startService(intent);
//... <- adding code here will result in the Service not starting?!!
}
I know that my problem is quite confusing, but this was the best i could come up explaining it. I would be really glad if you had any idea because this problem stops me from deployment. Thank you very much!!
Im creating an app in android studio where I want 10 clips to be played at the same time side by side. Im having some problems with some lags already at three clips and I wounder if Im better off using threads? In that case how?
Any hint would be very much apreciated
Here is my code so far. I know it is not very efficient and I am better off using an array of a player object for example but Im just testing so far:
public class MainActivity extends AppCompatActivity implements TextureView.SurfaceTextureListener {
private MediaPlayer mp1, mp2, mp3;
private TextureView tv1, tv2, tv3;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv1 = findViewById(R.id.textureView1);
tv2 = findViewById(R.id.textureView2);
tv3 = findViewById(R.id.textureView3);
tv1.setSurfaceTextureListener(this);
tv2.setSurfaceTextureListener(this);
tv3.setSurfaceTextureListener(this);
}
#Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) {
Surface surface = new Surface(surfaceTexture);
mp1 = MediaPlayer.create(this, R.raw.a7);
mp1.setSurface(surface);
// mp1.prepareAsync(); //
mp1.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp1) {
mp1.start();
}
});
Surface surface2 = new Surface(surfaceTexture);
mp2 = MediaPlayer.create(this, R.raw.a9);
mp2.setSurface(surface2);
// mp1.prepareAsync(); //
mp2.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp2) {
mp2.start();
}
});
Surface surface3 = new Surface(surfaceTexture);
mp3 = MediaPlayer.create(this, R.raw.a10);
mp3.setSurface(surface3);
// mp1.prepareAsync(); //
mp3.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp3) {
mp3.start();
}
});
}
#Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
}
#Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
return false;
}
#Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}
#Override
protected void onPause() {
if (mp1 != null && mp1.isPlaying()) {
mp1.pause();
}
super.onPause();
}
#Override
protected void onResume() {
if (mp1 != null) {
mp1.start();
}
super.onResume();
}
#Override
protected void onDestroy() {
if (mp1 != null) {
mp1.stop();
mp1.release();
mp1 = null;
}
super.onDestroy();
}
}
You should play media in a different non-ui thread. like this:-
public class MediaService extends Service {
private MediaPlayer mp1, mp2, mp3;
private static final String ACTION_START = TAG + ".ACTION_START";
private IBinder mBinder = new MyBinder();
private MediaPlayer.OnPreparedListener mMediaPrepared = new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer mp) {
Log.d(TAG, "MediaPlayer.onPrepared");
onCommandPlay(mp);
}
};
#Override
public IBinder onBind(Intent intent) {
Log.v(TAG, "onBind");
return mBinder;
}
#Override
public void onCreate() {
super.onCreate();
m1 = MediaPlayer.create(this, R.raw.a1);
m2 = MediaPlayer.create(this, R.raw.a2);
m3 = MediaPlayer.create(this, R.raw.a9);
}
#Override
public void onDestroy() {
super.onDestroy();
if (m1 != null) m1 .release();
if (m2 != null) m2 .release();
if (m3 != null) m3 .release();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
final String action = intent.getAction();
Log.d(TAG, "onStartCommand: " + intent.getAction());
if (ACTION_START.equals(action)) {
onCommandStart();
return START_STICKY;
}
stopSelf();
return Service.START_STICKY_COMPATIBILITY;
}
/**
* Performs actions related to media player when Service onStartCommand method is called
*
*/
private void onCommandStart() {
// Create Notifications with remote views
mNotification = new NotificationCompat.Builder(this).setTicker("Media Service started...")
.setSmallIcon(R.mipmap.ic_launcher)
.setContent(collapsed)
.setAutoCancel(false)
.setOngoing(true)
.build();
startForeground(NOTIFICATION_ID, mNotification);
startPlaying();
}
private void onCommandPlay(MediaPlayer mp) {
try {
mp.start();
} catch (IllegalStateException e) {
Log.e(TAG, "onCommandPlay", e);
}
}
/**
* Start playing the provided media item
*
*/
private void startPlaying() {
mCurrent = item;
try {
mp1.reset();
mp1.setOnPreparedListener(mMediaPrepared);
mp2.reset();
mp2.setOnPreparedListener(mMediaPrepared);
mp3.reset();
mp3.setOnPreparedListener(mMediaPrepared);
AssetFileDescriptor afd1 = getResources().openRawResourceFd(getResources().openRawResourceFd(R.raw.a9););
AssetFileDescriptor afd2 = getResources().openRawResourceFd(getResources().openRawResourceFd(R.raw.a10););
AssetFileDescriptor afd3 = getResources().openRawResourceFd(getResources().openRawResourceFd(R.raw.a8););
mp1.setDataSource(afd1 .getFileDescriptor(), afd1 .getStartOffset(), afd1.getLength());
mp2.setDataSource(afd2 .getFileDescriptor(), afd2 .getStartOffset(), afd2 .getLength());
mp3.setDataSource(afd3 .getFileDescriptor(), afd3 .getStartOffset(), afd3 .getLength());
mp1.prepareAsync();
mp2.prepareAsync();
mp3.prepareAsync();
} catch (IOException e) {
Log.e(TAG, "startPlaying", e);
}
}
public class MyBinder extends Binder {
public MediaService getService() {
return MediaService.this;
}
}
}
then start the service from Activity like this:
Intent intent = new Intent(context, MediaService.class);
intent.setAction(ACTION_START);
startServie(intent);
You should also handle different media playing use-cases. You can refer this link for more.
I am making a game app but the music still keeps playing even when I closed the game. how to stop? and how to change background music once I go to another activity after I clicked a button
public class BackgroundSoundService extends Service {
private static final String TAG = null;
MediaPlayer player;
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
player = MediaPlayer.create(this, R.raw.rysk);
player.setLooping(true); // Set looping
player.setVolume(100,100);
}
public int onStartCommand(Intent intent, int flags, int startId) {
player.start();
return 1;
}
public void onStart(Intent intent, int startId) {
// TO DO
}
public IBinder onUnBind(Intent arg0) {
// TO DO Auto-generated method
return null;
}
public void onStop() {
}
public void onPause() {
}
#Override
public void onDestroy() {
player.stop();
player.release();
}
#Override
public void onLowMemory() {
}
}
this is my main activity (PlayActivity.class)
Intent svc=new Intent(this, BackgroundSoundService.class);
startService(svc);
I want to change the music when I clicked a button and went to CatActivity
You should have to work with registerReceiver,unregisterReceiver.
May this helps you.
MainActivity.java
public class MainActivity extends AppCompatActivity {
private Button btn_startservice;
private Button btn_stopservice;
private TextView tv_servicecounter;
ServiceDemo myService;
boolean isBound;
BroadcastReceiver broadcastRec = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
int datapassed = intent.getIntExtra("value", 0);
tv_servicecounter.setText(String.valueOf(datapassed));
}
};
#RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_servicecounter = (TextView) findViewById(R.id.tv_activity_main_count);
btn_startservice = (Button) findViewById(R.id.btn_activity_main_startservices);
btn_stopservice = (Button) findViewById(R.id.btn_activity_main_stopservices);
btn_startservice.setOnClickListener(
new View.OnClickListener() {
#RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR1)
#Override
public void onClick(View v) {
Intent objIntent = new Intent(MainActivity.this, ServiceDemo.class);
if (!isBound) {
bindService(objIntent, myConnection, Context.BIND_AUTO_CREATE);
isBound = true;
startService(objIntent);
} else {
isBound = false;
unbindService(myConnection);
}
}
}
);
btn_stopservice.setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent objIntent = new Intent(MainActivity.this, ServiceDemo.class);
if (isBound) {
isBound = false;
unbindService(myConnection);
stopService(objIntent);
} else {
stopService(objIntent);
}
}
}
);
}
#Override
protected void onResume() {
registerReceiver(broadcastRec, new IntentFilter("USER_ACTION"));
super.onResume();
}
#Override
protected void onStop() {
this.unregisterReceiver(broadcastRec);
super.onStop();
}
private ServiceConnection myConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className,
IBinder service) {
myService = ((ServiceDemo.MyLocalBinder) service).getService();
isBound = true;
}
public void onServiceDisconnected(ComponentName arg0) {
isBound = false;
}
};
#Override
protected void onDestroy() {
super.onDestroy();
if (isBound) {
unbindService(myConnection);
isBound = false;
}
}
}
And ServiceDemo.java
public class ServiceDemo extends Service {
int i;
private MyThread mythread;
public boolean isRunning = false;
Notification notification;
#Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate");
mythread = new MyThread();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "Service Started", Toast.LENGTH_SHORT).show();
if (!isRunning) {
mythread.start();
isRunning = true;
}
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
mythread.interrupt();
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_SHORT).show();
}
public void sendBrodcastMsg(int value) {
Intent intent = new Intent();
intent.setAction("USER_ACTION");
intent.putExtra("value", value);
sendBroadcast(intent);
}
#RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
class MyThread extends Thread {
static final long DELAY = 100;
#Override
public void run() {
while (isRunning) {
try {
i++;
Thread.sleep(DELAY);
sendBrodcastMsg(i);
shownotification();
} catch (InterruptedException e) {
isRunning = false;
e.printStackTrace();
}
}
stopSelf();
}
}
#RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
public void shownotification() {
Intent in = new Intent(this, MainActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(this, (int) System.currentTimeMillis(), in, 0);
notification = new NotificationCompat.Builder(this)
.setContentTitle(String.valueOf(i))
.setContentText(String.valueOf(i))
.setSmallIcon(R.drawable.musicplayer)
.setContentIntent(pIntent)
.setAutoCancel(true).build();
;
startForeground(101, notification);
}
public class MyLocalBinder extends Binder {
ServiceDemo getService() {
return ServiceDemo.this;
}
}
private final IBinder myBinder = new MyLocalBinder();
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return myBinder;
}
}
put this two lines in manifest.
<service android:name=".ServiceDemo"
android:enabled="true"/>
You need to stop the player in onPause(). Following code can be used:
#Override
protected void onPause() {
super.onPause();
if (this.isFinishing()){
player.stop();
}
}
Check Android Stop Background Music for more details
for that you should stop the service in the onCreate method of the Activity. Below is the code for it :
stopService(new Intent(MyService.MY_SERVICE));
Best of Luck!
In Your MainActivity , You Should Call stopService() Inside MainActivity
#Override
public void OnPause() {
stopService(svc);
}
I am new to Android. I'm trying to create a music player which will play specific MP3 based on the count (controlled by Rc variable) and based on the button sequence (controlled by BitCount variable) should change. And I have one stop button by clicking which I should be able to stop the music.
My problem is everything is working fine when UI is on foreground but when screen goes to background then also music start running (it's OK let music be running on background) but when once again I bring my UI from background to foreground than by clicking stop button I am unable to stop the music, it runs continuously. This same problem is happening when I am rotating my mobile.
Code:
package com.example.tallite;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.app.Activity;
import android.content.SharedPreferences;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.Toast;
public class MainActivity extends Activity implements OnSeekBarChangeListener {
MediaPlayer OurSong;
public Handler handler1 = new Handler();
Button Start;
Button Stop;
Button Button21;
Button Button22;
Button StopButton;
public int GProgreess=0;
int Rc=0;
int BitCount=6;
int SeekPos=0;
int Period=500;
int BreakVar=0;
Thread myThread ;
public TextView text1,text2,text3,text4;
private SeekBar bar;
private TextView textProgress,textAction;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toast.makeText(this, "onCreate()", Toast.LENGTH_LONG).show();
text1 = (TextView)findViewById(R.id.textbit1);
text2 = (TextView)findViewById(R.id.textbit2);
text3 = (TextView)findViewById(R.id.textbit3);
text4 = (TextView)findViewById(R.id.textbit4);
Button21=(Button)findViewById(R.id.button21);
Button22=(Button)findViewById(R.id.button22);
StopButton=(Button)findViewById(R.id.buttonstop);
bar = (SeekBar)findViewById(R.id.seekBar1);
textProgress = (TextView)findViewById(R.id.textViewProgress);
OurSong=MediaPlayer.create(MainActivity.this,R.raw.a);
try {
OurSong.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
bar.setOnSeekBarChangeListener(this); // set seekbar listener.
/*handler1.post(runnable1);
stopPlaying();*/
StopButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v)
{
stopPlaying();
BitCount=5;
handler1.removeCallbacks(runnable1);
}/****End of on clk******/
});/*****End of set on clk listener*****/
Button21.setOnClickListener(new View.OnClickListener() {
public void onClick(View v)
{
stopPlaying();
Rc=0;
BitCount=13;
handler1.removeCallbacks(runnable1);
handler1.post(runnable1);
}/****End of on clk******/
});/*****End of set on clk listener*****/
Button22.setOnClickListener(new View.OnClickListener() {
public void onClick(View v)
{
stopPlaying();
Rc=0;
BitCount=15;
handler1.removeCallbacks(runnable1);
handler1.post(runnable1);
}/****End of on clk******/
});/*****End of set on clk listener*****/
}
#Override
protected void onStart() {
//the activity is become visible.
super.onStart();
/*handler1.removeCallbacks(runnable1);*/
}
#Override
protected void onPause() {
super.onPause();
}
#Override
protected void onResume() {
super.onResume();
}
#Override
protected void onStop() {
//the activity is no longer visible.
super.onStop();
Toast.makeText(this, "onStop()", Toast.LENGTH_LONG).show();
}
#Override
protected void onDestroy() {
//The activity about to be destroyed.
super.onDestroy();
Toast.makeText(this, "onDestroy()", Toast.LENGTH_LONG).show();
}
private void stopPlaying()
{
if (OurSong != null)
{
OurSong.stop();
OurSong.release();
OurSong = null;
}
}
/* private void stopPlaying()
{
OurSong.stop();
OurSong.release();
}*/
public Runnable runnable1= new Runnable() {
#Override
public void run() {
if(BitCount==13)
{
text1.setText("1");
text2.setText(""+Rc);
text3.setText(""+BitCount);
if(Rc==0||Rc==6||Rc==10)
{
stopPlaying();
OurSong=MediaPlayer.create(MainActivity.this,R.raw.a);
OurSong.start();
}
if(Rc==2||Rc==4||Rc==8||Rc==12)
{
stopPlaying();
OurSong=MediaPlayer.create(MainActivity.this,R.raw.b);
OurSong.start();
}
if(Rc==13)
{
stopPlaying();
OurSong=MediaPlayer.create(MainActivity.this,R.raw.c);
OurSong.start();
}
Rc++;
if(Rc>BitCount)
{
text4.setText(""+Rc);
Rc=0;
}
}/****End of bitcount=13****/
if(BitCount==15)
{
text1.setText("2");
text2.setText(""+Rc);
text3.setText(""+BitCount);
if(Rc==0||Rc==8||Rc==12)
{
stopPlaying();
OurSong=MediaPlayer.create(MainActivity.this,R.raw.a);
OurSong.start();
}
if(Rc==2||Rc==4||Rc==6||Rc==10||Rc==14)
{
stopPlaying();
OurSong=MediaPlayer.create(MainActivity.this,R.raw.b);
OurSong.start();
/* Toast.makeText(getApplicationContext(), "-",
Toast.LENGTH_LONG).show();*/
}
if(Rc==15)
{
stopPlaying();
OurSong=MediaPlayer.create(MainActivity.this,R.raw.c);
OurSong.start();
/*Toast.makeText(getApplicationContext(), "|",
Toast.LENGTH_LONG).show();*/
}
Rc++;
if(Rc>BitCount)
{
text4.setText(""+Rc);
Rc=0;
}
}/***End of bitcount=15***/
if(BitCount==5)
{
text1.setText("Rc"+Rc);
stopPlaying();
}
if(BitCount==6)
{
text1.setText("x"+Rc);
stopPlaying();
}
handler1.postDelayed(runnable1, Period);
}
};
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
GProgreess=progress+20;
textProgress.setText("Bit/Minute: "+(progress+20));
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
seekBar.setSecondaryProgress(seekBar.getProgress());
SeekPos=GProgreess;
Period=(int)(30000/SeekPos);
/*textProgress.setText("Period: "+Period);*/
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
When you close your app, ur activity is destroyed and hence reference to ur media player variable is lost. When you recreate ur activity you get a new set of reference and hence ur unable to stop it.
You will have to create a Service name it as MediaPlayerService which will deal with all media related actions like play, pause etc..
You can read about service over here:
http://developer.android.com/guide/components/services.html
If you want an example for media player, you can check RandomMusicPlayer, an excellent media player example provided by android in android sample projects.
Here is my implementation of MediaPlayerService
MediaPlayerService Class:
package com.cyberinsane.musicplayerlibrary;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.net.Uri;
import android.os.Binder;
import android.os.IBinder;
import android.os.PowerManager;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
import android.widget.Toast;
public class MediaPlayerService extends Service implements OnCompletionListener, OnPreparedListener, OnErrorListener {
private static final int NOTIFICATION_ID = 1;
public static final String INTENT_URL = "url";
public enum MediaState {
Playing, Paused, Stopped
}
private MediaState mState = MediaState.Stopped;
private MediaPlayer mPlayer;
private NotificationManager mNotificationManager;
public String mCurrentUrl = "";
public static final String ACTION_TOGGLE_PLAYBACK = "com.cyberinsane.musicplayerlibrary.action.TOGGLE_PLAYBACK";
public static final String ACTION_PLAY = "com.cyberinsane.musicplayerlibrary.action.PLAY";
public static final String ACTION_PAUSE = "com.cyberinsane.musicplayerlibrary.action.PAUSE";
public static final String ACTION_STOP = "com.cyberinsane.musicplayerlibrary.action.STOP";
#Override
public void onCreate() {
super.onCreate();
mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent != null) {
String action = intent.getAction();
String url = intent.getExtras().getString(INTENT_URL);
if (url != null) {
if (!url.equals(mCurrentUrl)) {
mCurrentUrl = url;
mState = MediaState.Stopped;
relaxResources(true);
processPlayRequest();
} else {
if (action.equals(ACTION_TOGGLE_PLAYBACK)) {
processTogglePlaybackRequest();
} else if (action.equals(ACTION_PLAY)) {
processPlayRequest();
} else if (action.equals(ACTION_PAUSE)) {
processPauseRequest();
} else if (action.equals(ACTION_STOP)) {
processStopRequest(false);
}
}
}
}
return START_STICKY;
}
private void processTogglePlaybackRequest() {
if (mState == MediaState.Paused || mState == MediaState.Stopped) {
processPlayRequest();
} else {
processPauseRequest();
}
}
private void processPlayRequest() {
try {
if (mState == MediaState.Stopped) {
createMediaPlayerIfNeeded();
mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mPlayer.setDataSource(getApplicationContext(), Uri.parse(mCurrentUrl));
mPlayer.prepare();
} else if (mState == MediaState.Paused) {
mState = MediaState.Playing;
setUpAsForeground("Playing...");
if (!mPlayer.isPlaying()) {
mPlayer.start();
if (mIMediaPlayer != null) {
mIMediaPlayer.onAudioPlay();
}
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
private void processPauseRequest() {
if (mState == MediaState.Playing) {
mState = MediaState.Paused;
mPlayer.pause();
relaxResources(false);
if (mIMediaPlayer != null) {
mIMediaPlayer.onAudioPause();
}
}
}
private void processStopRequest(boolean force) {
if (mState == MediaState.Playing || mState == MediaState.Paused || force) {
mState = MediaState.Stopped;
relaxResources(true);
stopSelf();
}
}
private void createMediaPlayerIfNeeded() {
if (mPlayer == null) {
mPlayer = new MediaPlayer();
mPlayer.setWakeMode(getApplicationContext(), PowerManager.PARTIAL_WAKE_LOCK);
mPlayer.setOnPreparedListener(this);
mPlayer.setOnCompletionListener(this);
mPlayer.setOnErrorListener(this);
} else
mPlayer.reset();
}
private void relaxResources(boolean releaseMediaPlayer) {
stopForeground(true);
if (releaseMediaPlayer && mPlayer != null) {
mPlayer.reset();
mPlayer.release();
mPlayer = null;
}
}
#Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Toast.makeText(getApplicationContext(), "Media player error! Resetting.", Toast.LENGTH_SHORT).show();
Log.e("MusicPlayer", "Error: what=" + String.valueOf(what) + ", extra=" + String.valueOf(extra));
mState = MediaState.Stopped;
relaxResources(true);
if (mIMediaPlayer != null) {
mIMediaPlayer.onError();
}
return true; // true indicates we handled the error
}
#Override
public void onPrepared(MediaPlayer mp) {
mState = MediaState.Playing;
updateNotification("Playing...");
if (!mPlayer.isPlaying()) {
mPlayer.start();
if (mIMediaPlayer != null) {
mIMediaPlayer.onAudioPlay();
}
}
}
#Override
public void onCompletion(MediaPlayer mp) {
mState = MediaState.Stopped;
relaxResources(true);
stopSelf();
if (mIMediaPlayer != null) {
mIMediaPlayer.onAudioStop();
}
}
/**
* Updates the notification.
*/
private void updateNotification(String text) {
mNotificationManager.notify(NOTIFICATION_ID, buildNotification(text).build());
}
private void setUpAsForeground(String text) {
startForeground(NOTIFICATION_ID, buildNotification(text).build());
}
private NotificationCompat.Builder buildNotification(String text) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(this.getApplicationContext());
builder.setSmallIcon(R.drawable.ic_launcher)
.setOngoing(true)
.setContentTitle("Cyberinsane MusicPlayer")
.setContentText(text)
.setContentIntent(
PendingIntent.getActivity(getApplicationContext(), 0, new Intent(getApplicationContext(),
MediaPlayerActivity.class), PendingIntent.FLAG_UPDATE_CURRENT))
.setContentInfo("Awesome");
return builder;
}
#Override
public void onDestroy() {
mState = MediaState.Stopped;
relaxResources(true);
}
public class LocalBinder extends Binder {
MediaPlayerService getService() {
return MediaPlayerService.this;
}
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
private final IBinder mBinder = new LocalBinder();
private IMediaPlayer mIMediaPlayer;
public MediaPlayer getMediaPlayer() {
return mPlayer;
}
public void setIMediaPlayer(IMediaPlayer mediaPlayer) {
mIMediaPlayer = mediaPlayer;
}
public MediaState getMediaState() {
return mState;
}
public boolean isPlaying() {
return (mState == MediaState.Playing);
}
public String getCurrentUrl() {
return mCurrentUrl;
}
public long duration() {
if (mPlayer != null) {
return mPlayer.getDuration();
}
return 0;
}
public long position() {
if (mPlayer != null) {
return mPlayer.getCurrentPosition();
}
return 0;
}
public void seekTo(long position) {
if (mPlayer != null) {
mPlayer.seekTo((int) position);
}
}
}
MediaPlayerActivity Class:
package com.cyberinsane.musicplayerlibrary;
import java.io.File;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
public class MediaPlayerActivity extends Activity implements IMediaPlayer {
private ImageButton mButtonPlay;
private EditText mEditTextUrl;
private SeekBar mSeekBarProgress;
private boolean mIsBound;
private String mExtStorePath;
private MediaPlayerService mMediaService;
private Handler mSeekHandler = new Handler();
private Runnable mSeekRunnable = new Runnable() {
#Override
public void run() {
seekStartUpdation();
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.media_player_activity);
mButtonPlay = (ImageButton) findViewById(R.id.buttonPlay);
mEditTextUrl = (EditText) findViewById(R.id.editTextURL);
mSeekBarProgress = (SeekBar) findViewById(R.id.seekBarMediaProgress);
mExtStorePath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator;
doBindService();
initListeners();
}
private void initListeners() {
mButtonPlay.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
String urlExt = mEditTextUrl.getText().toString();
if (urlExt != null && !urlExt.equals("")) {
String url = mExtStorePath + urlExt;
startService(new Intent(MediaPlayerService.ACTION_TOGGLE_PLAYBACK).putExtra(
MediaPlayerService.INTENT_URL, url));
}
}
});
mSeekBarProgress.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
mMediaService.seekTo(seekBar.getProgress());
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
// empty
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
// empty
}
});
}
#Override
protected void onResume() {
super.onResume();
doBindService();
}
#Override
protected void onDestroy() {
super.onDestroy();
doUnbindService();
}
#Override
protected void onPause() {
super.onPause();
doUnbindService();
}
private ServiceConnection mConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName className, IBinder service) {
mMediaService = ((MediaPlayerService.LocalBinder) service).getService();
mMediaService.setIMediaPlayer(MediaPlayerActivity.this);
setControlState();
}
#Override
public void onServiceDisconnected(ComponentName className) {
mMediaService = null;
}
};
private void doBindService() {
bindService(new Intent(MediaPlayerActivity.this, MediaPlayerService.class), mConnection,
Context.BIND_AUTO_CREATE);
mIsBound = true;
}
private void doUnbindService() {
if (mIsBound) {
unbindService(mConnection);
mIsBound = false;
}
}
#Override
public void onAudioPlay() {
setPlayerState(true);
}
#Override
public void onAudioPause() {
setPlayerState(false);
}
#Override
public void onAudioStop() {
setPlayerState(false);
mSeekBarProgress.setProgress(0);
}
#Override
public void onError() {
// handle errors here
}
private void setControlState() {
if (mMediaService.isPlaying()) {
mEditTextUrl.setText(mMediaService.getCurrentUrl().replace(mExtStorePath, ""));
setPlayerState(true);
} else {
setPlayerState(false);
}
}
public void setPlayerState(boolean isPlaying) {
if (isPlaying) {
mButtonPlay.setImageResource(R.drawable.ic_pause);
mSeekBarProgress.setMax((int) mMediaService.duration());
seekStartUpdation();
} else {
mButtonPlay.setImageResource(R.drawable.ic_play);
seekStopUpdate();
}
}
public void seekStartUpdation() {
mSeekBarProgress.setProgress((int) mMediaService.position());
mSeekHandler.postDelayed(mSeekRunnable, 1000);
}
public void seekStopUpdate() {
mSeekHandler.removeCallbacks(mSeekRunnable);
}
}
Media Player Event Listener
package com.cyberinsane.musicplayerlibrary;
public interface IMediaPlayer {
public void onAudioPlay();
public void onAudioPause();
public void onAudioStop();
public void onError();
}
And finally my Manifest file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.cyberinsane.musicplayerlibrary"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.cyberinsane.musicplayerlibrary.MediaPlayerActivity"
android:label="#string/app_name"
android:launchMode="singleTask" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name="com.cyberinsane.musicplayerlibrary.MediaPlayerService"
android:exported="false" >
<intent-filter>
<action android:name="com.cyberinsane.musicplayerlibrary.action.TOGGLE_PLAYBACK" />
<action android:name="com.cyberinsane.musicplayerlibrary.action.PLAY" />
<action android:name="com.cyberinsane.musicplayerlibrary.action.PAUSE" />
<action android:name="com.cyberinsane.musicplayerlibrary.action.SKIP" />
<action android:name="com.cyberinsane.musicplayerlibrary.action.REWIND" />
<action android:name="com.cyberinsane.musicplayerlibrary.action.STOP" />
</intent-filter>
</service>
</application>
</manifest>