How to play music on Android while activities are on foreground - java

I want to play music in the background of my application:
public class BackgroundSoundService extends Service {
MediaPlayer mediaPlayer;
#Override
public void onCreate() {
super.onCreate();
mediaPlayer = MediaPlayer.create(this, R.raw.airport_lounge);
mediaPlayer.setLooping(true);
mediaPlayer.setVolume(100,100);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
mediaPlayer.start();
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
mediaPlayer.stop();
mediaPlayer.release();
}
#Override
public void onLowMemory() {
super.onLowMemory();
}
#Override
public boolean onUnbind(Intent intent) {
return super.onUnbind(intent);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
Then in my MainActivity :
public static Intent musicIntent;
//Start music service
musicIntent = new Intent(this, BackgroundSoundService.class);
startService(musicIntent);
#Override
protected void onPause() {
super.onPause();
stopService(musicIntent);
}
#Override
protected void onResume() {
super.onResume();
startService(musicIntent);
}
I stop it in my onPause the service because if the user switches the Application and doesn't close it the music would continue to play. The problem is that when we change Activity the onPaused is also called but I want the music to continue playing through the entire application.
So in my another Activity :
//start music
startService(MainActivity.musicIntent);
But the music restarts and it's not very good to hear. Any solutions?

You can use ActivityLifecycleCallbacks in your application class.
public class MusicApplication extends Application implements ActivityLifecycleCallbacks {
int activitiesOnTop = 0;
#Override
public void onCreate() {
super.onCreate();
registerActivityLifecycleCallbacks(this);
}
#Override
public void onActivityResumed(Activity activity) {
// one of application activities is visible
activitiesOnTop ++;
}
#Override
public void onActivityStopped(Activity activity) {
activitiesOnTop --;
if(activitiesOnTop == 0){
// none of activities are on foreground
}
}
}
There are other solutions mentioned in the How to check if activity is in foreground or in visible background?.

It depends on the application structure, for example, if you build some tab or navigationDrawer based navigation, you will likely build some fragments and your MainActivity will be your only activity, so it's onPause method will only be called if user closes your application. But this scenario won't hold as your application grows (unless it's quite simple).
So another approach is to launch your service in your application instance, in case you use it.

Related

How to use 'Service' in an internet browser App

I am newbie so please forgive me for anything wrong that I am doing or if I am asking the question in the wrong way.
I recently created a simple media player on android studio and used Java Service to play the media when I closed the app and it works fine. Now I have created a simple web browser app using WebView and I want to use the same "Java Service" to keep my web browser app running even when it is minimized but I have no idea how to convert the media player code to use on the web browser app. I have researched a lot and nobody else seems to want to create a browser that keeps running in the background. Please can you assist me in solving this?
Because I am new to Java, it is difficult for me to try and convert the code from media player to web browser
So here is my media player code:
MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button start, stop;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
start = (Button) findViewById(R.id.buttonStartService);
stop = (Button) findViewById(R.id.buttonStopService);
start.setOnClickListener(this);
stop.setOnClickListener(this);
}
#Override
public void onClick(View view) {
if (view == start){
startService(new Intent(this, MyService.class));
}else if(view == stop){
stopService(new Intent(this, MyService.class));
}
}
}
MyService.java
public class MyService extends Service {
private MediaPlayer player;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
player = MediaPlayer.create(this, Settings.System.DEFAULT_RINGTONE_URI);
player.setLooping(true);
player.start();
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
player.stop();
}
}
Here is my MainActivity for the Webbrowser that I have created:
public class MainActivity extends AppCompatActivity {
WebView browser;
EditText link;
Button btn_visit;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
browser = (WebView) findViewById(R.id.webview);
link = (EditText) findViewById(R.id.editTextLink);
btn_visit = (Button) findViewById(R.id.btn_view);
browser.setWebViewClient(new myWebViewClient());
btn_visit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String url = link.getText().toString();
browser.getSettings().setLoadsImagesAutomatically(true);
browser.getSettings().setJavaScriptEnabled(true);
browser.loadUrl(url);
}
});
}
private class myWebViewClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
}
}
```
So now I need to create another MyService that will allow the webbrowser to run in the
background but dont know how to go about it:
```
public class MyService extends Service {
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
}
#Override
public void onDestroy() {
}
}
As I said, there no errors that I am getting on the media player app. I just want to be able to use the same code on the internet browser app but don't know how to convert it.

Music stops on moving to another activity, while using background service to play music

I'm developing a game, I have used services to play music on all activities.
I want to stop the music when we hit the home key, it shouldn't stop playing music when moving from one activity to another.
public class backService extends Service {
private MediaPlayer mp;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
mp.stop();
mp.release();
}
#Override
public void onCreate() {
super.onCreate();
mp = MediaPlayer.create(this, R.raw.all);
mp.setLooping(true);
mp.start();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
and my main activity file
public class Home extends AppCompatActivity {
private AdView mAdView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
hide();
setContentView(R.layout.activity_home);
Intent i = new Intent(this, backService.class);
adv();
}
#Override
protected void onResume(){
super.onResume();
Intent i = new Intent(this, backService.class);
startService(i);
}
#Override
protected void onStop() {
super.onStop();
Intent i = new Intent(this, backService.class);
stopService(i);
}
#Override
protected void onDestroy(){
super.onDestroy();
Intent i = new Intent(this, backService.class);
stopService(i);
}
}
How can I stop the music when I hit the home key and keep playing the music when we switch between other activities
TIA
Please remove the stopService(i) inside onStop() method in Activity coz whenever you are going one Activity to Another Activity then onStop() method will be called, that's why your service is killing.
If you want to pause or stop music while press home button then implements ComponentCallbacks2 interface to Activity like this
#Override
public void onTrimMemory(final int level) {
if (level == ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN) {
if(mService != null){
mService.pauseMusic();
}
}
}
Try to stop the service in
#Override
public void onPause()
{
super.onPause();
// Check if app is in foreground
if(!isAppOnForeground(context))
{
stop music here
}
}
below is the method to check if the app is in foreground or not . just replace your package here "your package name here";
public static boolean isAppOnForeground(Context context)
{
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<ActivityManager.RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
if (appProcesses == null) {
return false;
}
final String packageName = "your package name here";
for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
if (appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND && appProcess.processName.equals(packageName)) {
return true;
}
}
return false;
}

How can I play sound on all of my activities

I want to use my sound on all my activities not only main activity. I put this lines
MediaPlayer ring = MediaPlayer.create(MainActivity.this, R.raw.song);
ring.start();
but that works only in main Activity.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MediaPlayer ring = MediaPlayer.create(MainActivity.this, R.raw.song);
ring.start();
you can try something like this
1. add this code in your all activity
MediaPlayer ring = MediaPlayer.create(MainActivity.this,
R.raw.song);
ring.start();
2. create one method like this and call this msg from your activity in which you want to play music
public void Playmusic(Context context){
MediaPlayer ring = MediaPlayer.create(context, R.raw.song);
ring.start();
}
now just call this method like this
Playmusic(MainActivity.this);
play your songs in service and initialize the media player object there only
Intent svc=new Intent(this, BackgroundSoundService.class);
startService(svc);
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.idil);
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() {
}
}
Please call this service in Manifest
<service android:enabled="true" android:name=".BackgroundSoundService " />

Not able to function the media player properly in the background services

I have implemented the media player in my project and I want to play the music even when I close my application , but when I kill my application then it should stop playing the music.
My problem which I am facing is that my application starts playing the music again with the previous one playing already whenever I open my unkilled application again.What am i doing wrong ??
My requirement is that the music should start playing as soon as i open the app,and it should keep on playing in the background even if i close(not killed) my app.But when i kill my app then the music should stop playing
Here is my code -
Main_activity.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
String msg = "Android : ";
private Button play,pause,restart;
LocalService mService;
boolean mBound = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
play=(Button) findViewById(R.id.play);
pause=(Button) findViewById(R.id.pause);
restart=(Button) findViewById(R.id.restart);
play.setOnClickListener(this);
pause.setOnClickListener(this);
restart.setOnClickListener(this);
Intent intent = new Intent(this, LocalService.class);
startService(intent);
}
/** Called when the activity is about to become visible. */
#Override
protected void onStart() {
super.onStart();
Log.d(msg, "The onStart() event");
Intent intent = new Intent(this, LocalService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
/** Called when the activity has become visible. */
#Override
protected void onResume() {
super.onResume();
Log.d(msg, "The onResume() event");
}
/** Called when another activity is taking focus. */
#Override
protected void onPause() {
super.onPause();
Log.d(msg, "The onPause() event");
}
/** Called when the activity is no longer visible. */
#Override
protected void onStop() {
super.onStop();
Log.d(msg, "The onStop() event");
}
/** Called just before the activity is destroyed. */
#Override
public void onDestroy() {
super.onDestroy();
Log.d(msg, "The onDestroy() event");
Log.d("mbound value",mBound+"");
if (mBound) {
Intent intent=new Intent(this,LocalService.class);
stopService(intent);
unbindService(mConnection);
mBound = false;
}
}
#Override
public void onClick(View v) {
switch (v.getId()){
case(R.id.play):
if(mBound)
mService.start_mp();
break;
case(R.id.pause):
if(mBound)
mService.pause_mp();
break;
case (R.id.restart):
if(mBound)
mService.restart_mp();
break;
default:
break;
}
}
/** Defines callbacks for service binding, passed to bindService() */
public ServiceConnection mConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName className,
IBinder service) {
// We've bound to LocalService, cast the IBinder and get LocalService instance
LocalService.LocalBinder binder = (LocalService.LocalBinder) service;
mService = binder.getService();
mBound = true;
}
#Override
public void onServiceDisconnected(ComponentName arg0) {
mBound = false;
}
};
}
LocalService.java
public class LocalService extends Service {
private MediaPlayer mediaPlayer;
// Binder given to clients
private final IBinder mBinder = new LocalBinder();
#Nullable
#Override
public IBinder onBind(Intent intent) {
Log.i("Onbind called","");
return mBinder;
}
/** Called when the service is being created. */
#Override
public void onCreate() {
super.onCreate();
mediaPlayer=MediaPlayer.create(this,R.raw.jingle);
}
/** The service is starting, due to a call to startService() */
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
mediaPlayer.start();
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
return START_STICKY;
}
/** Called when all clients have unbound with unbindService() */
#Override
public boolean onUnbind(Intent intent) {
return true;
}
/** Called when a client is binding to the service with bindService()*/
#Override
public void onRebind(Intent intent) {
super.onRebind(intent);
}
/** Called when The service is no longer used and is being destroyed */
#Override
public void onDestroy() {
super.onDestroy();
// Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
}
/**
* Class used for the client Binder. Because we know this service always
* runs in the same process as its clients, we don't need to deal with IPC.
*/
public class LocalBinder extends Binder {
LocalService getService() {
// Return this instance of LocalService so clients can call public methods
return LocalService.this;
}
}
public void start_mp(){
if(!mediaPlayer.isPlaying())
mediaPlayer.start();
}
public void pause_mp(){
mediaPlayer.pause();
}
public void restart_mp(){
if(mediaPlayer.isPlaying()) mediaPlayer.release();
mediaPlayer=MediaPlayer.create(this,R.raw.jingle);
mediaPlayer.start();
}
}
P.S.-I have applied the buttons in my application for the player functionality inside my app .
I got the solution.Whenever I press my homebutton ,then my onstop() method is executed and I get whatever I aim at,on pressing back button the default action of android is to destroy the activity.
Pressing the default back button of android device will call the finish() method of the activity and hence OnDestroy() will be called,by pressing the HomeButton the OnStop() method will be called.

How to update text with a Countdowntimer in a service

Let's assume I have a service like that,and I have a TextView to update in every tick,TextView is located in MainActivity. How can I update the TextView in every tick?
public class CountDownTimerService extends Service {
public CountDownTimerService() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
CountDownTimer.start();
return START_STICKY;
}
private CountDownTimer countDownTimer = new CountDownTimerWithPause(300000, 1) {
#Override
public void onTick(long millisUntilFinished) {
/*
In this part i need to update text on MainActivity
*/
}
#Override
public void onFinish() {
Log.i("Timer","Timer finished");
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
You have to use an IntentService to pass messages between your Activity and your Service. You can do it yourself but there is some known libraries which are very efficient and simple to use and do this stuff for you, like EventBus.
This is a very helpful tutorial for EventBus, it is very clean and simple to understand, hope it'll help!
https://guides.codepath.com/android/Communicating-with-an-Event-Bus

Categories