I have trouble to play music across all activity, I had implement service and handle onPause to stop the music when going to background (not visible to user).
The problem is when i navigate to another activity, the onPause method is called that make my music stop. How to fix this issue? I need to play my music across all my activity in foreground only and dont wan to play it when the application in the background. Appeciate anyone know how to solve this.
This is my base activity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
startIntent = new Intent(getApplicationContext(), MusicService.class);
if(binder==null){
bindService(startIntent,this, Context.BIND_AUTO_CREATE);
}
}
#Override
protected void onDestroy() {
super.onDestroy();
if(binder.getMyService()!=null){
stopService(startIntent);
unbindService(this);
}
}
#Override
protected void onStart() {
super.onStart();
}
#Override
protected void onPause() {
super.onPause();
if(binder!=null) {
binder.getMyService().pauseMusic();
}
}
#Override
protected void onResume() {
super.onResume();
if(binder!=null){
binder.getMyService().resumeMusic();
}
}
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
binder = (MusicService.Binder) service;
}
#Override
public void onServiceDisconnected(ComponentName name) {
}
this is my mainactivity extends base activity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startIntent = new Intent(MainActivity.this, MusicService.class);
startService(startIntent);
}
#Override
protected void onDestroy() {
super.onDestroy();
}
public void how(View view) {
Intent intent = new Intent(this, AboutActivity.class);
this.startActivity(intent);
}
You could implement code that will track current activity in your app. (Good example: How to get current activity)
And stop music only when "current activity" is null.
PS: depending on your implementation of tracking current activity you might want to check current activity not onPause() right away but with some delay .
Don't stop the audio play in onPause() as Harin Kaklotar suggested. You can use his method of onDestroy() or you can have it in an asynchronous task and turn off the sound by using surfaceDestroyed(). You can refer the android documentation of AudioManager if you need anything else of the sort.
https://developer.android.com/reference/android/media/AudioManager.html
Hope I Helped :D
UPDATE
You can create a system to check if your app is in the foreground or background. This involves counting how many activities are paused. Add this to all your activities:
#Override
protected void onPause() {
super.onPause();
MainActivity.Pause++;
}
#Override
protected void onResume() {
super.onResume();
MainActivity.Pause--;
}
And in your MainActivty,
if (Pause == NUMBER_OF_ACTIVITIES) {
//PAUSE MUSIC HERE
}
You have to use ActivityLifecycleCallbacks to tell if you app is in the foreground or background.
For example:
public class DummyActivityLifecycleCallbacks implements ActivityLifecycleCallbacks {
#Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) { }
#Override public void onActivityStarted(Activity activity) { }
#Override public void onActivityResumed(Activity activity) { }
#Override public void onActivityPaused(Activity activity) { }
#Override public void onActivityStopped(Activity activity) { }
#Override public void onActivityDestroyed(Activity activity) { }
#Override public void onActivitySaveInstanceState(Activity activity, Bundle savedInstanceState) { }
}
public class OnApplicationForegroundBackgroundEnterCallbacks extends DummyActivityLifecycleCallbacks {
private Listener listener;
private int activityStartStopCounter = 0;
public interface Listener {
public void onEnterForeground();
public void onEnterBackground();
}
public OnApplicationForegroundBackgroundEnterCallbacks(Listener listener) {
this.listener = listener;
}
#Override public void onActivityStarted(Activity activity) {
if(++activityStartStopCounter == 1) listener.onEnterForeground();
}
#Override public void onActivityStopped(Activity activity) {
if(--activityStartStopCounter == 0) listener.onEnterBackground();
}
}
Then in Application.onCreate call:
registerActivityLifecycleCallbacks(new OnApplicationForegroundBackgroundEnterCallbacks(this));
Related
FLAG_SECURE Not Working with Android 12.
Code is given below which is used in my APP. It work till Android 11 but on Android 12 I can Take screen shots(when app is either in foreground or while App is in the(displayed in Task list) background . Please Suggest If there is any other work around available.
No one should be able to take screen shot while App is Background but displayed in open Apps List.
public class MyApplicationContext extends Application {
private Context context;
public void onCreate() {
super.onCreate();
context = getApplicationContext();
setupActivityListener();
}
private void setupActivityListener() {
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
#Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE); }
#Override
public void onActivityStarted(Activity activity) {
}
#Override
public void onActivityResumed(Activity activity) {
}
#Override
public void onActivityPaused(Activity activity) {
}
#Override
public void onActivityStopped(Activity activity) {
}
#Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
#Override
public void onActivityDestroyed(Activity activity) {
}
});
}
}
I have an android studio project. When I am rotating screen, android destroys and recreates main activity. How can I check during the destruction, if android going to recreate activity?
You can determine if the activity is finishing by user choice (user chooses to exit by pressing back for example) using isFinishing() in onDestroy.
#Override
protected void onDestroy() {
super.onDestroy();
if (isFinishing()) {
// wrap stuff up
} else {
//It's an orientation change.
}
}
Another alternative (if you're only targeting API>=11) is isChangingConfigurations.
#Override
protected void onDestroy() {
super.onDestroy();
if (isChangingConfigurations()) {
//It's an orientation change.
}
}
Override the Activity lifecycle methods to see the flow.And then use the appropriate method to check activity current state like isChangingConfigurations()
Example code snippet.
MainActivity.java
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
protected void onStart() {
super.onStart();
Log.i(MainActivity.class.getSimpleName(),"OnStart Called");
}
#Override
protected void onRestart() {
super.onRestart();
Log.i(MainActivity.class.getSimpleName(),"OnRestart Called");
}
#Override
protected void onDestroy() {
super.onDestroy();
Log.i(MainActivity.class.getSimpleName(),"OnDestroy Called");
}
#Override
protected void onPause() {
super.onPause();
Log.i(MainActivity.class.getSimpleName(),"OnPause Called");
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.i(MainActivity.class.getSimpleName(),"OnConfiguration Changed Called");
}
}
For more details see the official page activity-lifecycle
I have really hard time with background music in my app. I just want to play music in all activities - when I press home button I want to stop music. I want "stop or play" music button in all activities, but couldnĀ“t make it work.
So I decided to make embarassing choice - play it only in 1 activitiy by
onCreate
backgroundmusic = MediaPlayer.create(StoryActivity.this, R.raw.creepy_music);
backgroundmusic.start();
onPause
#Override
protected void onPause() {
super.onPause();
backgroundmusic.release();
finish();
}
Can you please help me with easy activity lifecycle? So when a user presses home button - music will stop. When he will come back to app - music will be restored and this activity too (it is not MainActivity)
Thank you, guys
Here are the different LifeCycle states. Now to your answer,
#Override
protected void onStop() {
super.onStop();
backgroundmusic.pause();
length = backgroundmusic.getCurrentPosition();
}
#Override
protected void onResume() {
super.onResume();
backgroundmusic.seekTo(length);
backgroundmusic.start();
}
In public class MainActivity extends AppCompatActivity, It's the AppCompatActivity that is the main source of an Activity's functionality, hence in the above methods like super.onResume(); and super.onStop(); super refers to the AppCompatActivity class
assume that you can get the music service in the Application ,you may be looking for this :
public class MyApp extends Application{
MusicService musicService;
#Override
public void onCreate() {
super.onCreate();
registerActivityLifecycleCallbacks(new ActivityLifecycleCallbacks() {
#Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
}
#Override
public void onActivityStarted(Activity activity) {
}
#Override
public void onActivityResumed(Activity activity) {
if(musicService==null) return;
if(!musicService.isPlaying()){
musicService.play();
}
}
#Override
public void onActivityPaused(Activity activity) {
if(musicService==null) return;
if(musicService.isPlaying()){
musicService.pause();
}
}
#Override
public void onActivityStopped(Activity activity) {
}
#Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
#Override
public void onActivityDestroyed(Activity activity) {
}
});
}
}
Hope this helps
I am working in a Hello Otto basic project in order to learn a bit how it works. This is my BusProvider over Otto 7.0.1. In MainActivity I have two buttons, after tap on the first one I post a string in the bus object. This is my BusProvider
public class BusProvider {
private BusProvider() {}
private static Bus bus;
public static Bus getInstance() {
if (bus == null){
bus = new Bus();
}
return bus;
}
}
MainActivity who will sent a String to Main2Activity using the bus class
public class MainActivity extends AppCompatActivity {
private Bus bus;
#Bind(R.id.myButton)Button mButton;
#Bind(R.id.button2)Button mButton2;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setLibreries();
this.bus = BusProvider.getInstance();
}
#Override
protected void onPause() {
super.onPause();
}
#Override
protected void onResume() {
super.onResume();
}
public void setLibreries(){
ButterKnife.bind(this);
}
#OnClick(R.id.myButton)
protected void buttonPressed1( ){
Toast.makeText(this, "click on the 1 button",Toast.LENGTH_SHORT).show();
BusProvider.getInstance().post("HELLO OTTO");
Intent intent = new Intent(MainActivity.this,Main2Activity.class);
startActivity(intent);
}
#OnClick(R.id.button2)
protected void buttonPressed(){
Toast.makeText(this, "click on the 2 button",Toast.LENGTH_SHORT).show();
}
}
Main2Activity how receives the String
public class Main2Activity extends AppCompatActivity {
private Bus bus;
#Bind(R.id.this_is_a_text_view) TextView myTextButter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
bus = BusProvider.getInstance();
ButterKnife.bind(this);
myTextButter.setText("HELLO");
}
#Override
protected void onResume() {
BusProvider.getInstance().register(this);
super.onResume();
}
#Override
protected void onPause() {
super.onPause();
BusProvider.getInstance().unregister(this);
}
#Subscribe
public void gettingStringPosted(String message){
Log.d("OTTO", "OTTO subscribe has been called "+message);
Toast.makeText(this,message,Toast.LENGTH_SHORT).show();
}
}
The problem is that the Toast with the message I am sending in MainActivity to Main2Activity
HELLO OTTO
is never showed.
What I am doing wrong?
The problem is that your Main2Activity has not been registered yet to Otto when your BusProvider.getInstance().post("HELLO OTTO"); line comes.
Here is how your code does:
Bus.post()
Bus.register()
This is how it should go:
Bus.register()
Bus.post()
You can't solve this by moving the line BusProvider.getInstance().post("HELLO OTTO"); under the startActivity() call because Activity.onResume() might not get called straight away so your register call (in onResume) could still happen after post call. I hope this makes sense to you.
This is just example of otto, to make sense how it is. Let's assume you have a service, and in it getting locations and sending to activities.
public class TrackingService extends Service {
Bus bus;
LocationListener mListener = new LocationListener() {
#Override
public void onLocationChanged(Location location) {
bus.post(new MyLocation(location));
}
};
// Other service related methods..
}
And activity
#Override
protected void onResume() {
BusProvider.getInstance().register(this);
super.onResume();
}
#Override
protected void onPause() {
super.onPause();
BusProvider.getInstance().unregister(this);
}
#Subscribe
public void locationChanged(MyLocation location){
Toast.makeText(this, "you got new location", Toast.LENGTH_SHORT).show();
}
Thats just it.
BTW, and this is the what i mentioned for you in my comment
In MainActivity
Intent intent = new Intent(getBaseContext(), Main2Activity.class);
intent.putExtra("MY_INFO", "INFO");
startActivity(intent)
In Main2Activity
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.view);
Intent intent = getIntent();
String info = intent.getStringExtra("MY_INFO");
}
How do i start a service when an activity is opened, I am using intent but the service isn't starting at all. Music is meant to be played when a certain page is opened, but no service is running at all.
This is the code i am using to start the service on the MainPage class.
public class BackgroundMusic extends Service implements Application.ActivityLifecycleCallbacks, Runnable {
MediaPlayer player;
private static final Handler uiHandler = new Handler(Looper.getMainLooper());
#Override
public void onCreate() {
super.onCreate();
player = MediaPlayer.create(this, R.raw.backgroundmusic);
player.setLooping(true);
player.setVolume(100, 100);
player.start();
Intent BackgrndMusic = new Intent(this, MainPage.class);
startService(BackgrndMusic);
getApplication().registerActivityLifecycleCallbacks(this);
}
#Override
public void onDestroy() {
super.onDestroy();
// stop listening for activities
getApplication().unregisterActivityLifecycleCallbacks(this);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onActivityStarted(Activity activity) {
// do not destroy this service
uiHandler.removeCallbacks(this);
}
#Override
public void onActivityStopped(Activity activity) {
// if an activity don't show up in 1 second, destroy this service
uiHandler.postDelayed(this, 1000);
}
#Override
public void run() {
// no more activity, destroy this service
stopSelf();
}
#Override
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
Intent BackgrndMusic = new Intent(BackgroundMusic.this, MainPage.class);
startService(BackgrndMusic);
}
#Override
public void onActivityResumed(Activity activity) {
Intent BackgrndMusic = new Intent(BackgroundMusic.this, MainPage.class);
startService(BackgrndMusic);
}
#Override
public void onActivityPaused(Activity activity) {
Intent BackgrndMusic = new Intent(BackgroundMusic.this, MainPage.class);
stopService(BackgrndMusic);
}
#Override
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
}
#Override
public void onActivityDestroyed(Activity activity) {
Intent BackgrndMusic = new Intent(BackgroundMusic.this, MainPage.class);
stopService(BackgrndMusic);
}
}
Use
#Override
protected void onResume()
{
super.onResume();
startService(foo);
}
#Override
protected void onDestroy()
{
super.onDestroy();
StopService(foo);
}