I'm newbee on android, and already read Android app start and end event and Android onClose event but haven't found the answer.
I'm developing a simple application - flashlight.
And I want to release camera LED when application (not activity) is ended. Android has Application onCreate event, but doesn't have an appropriate onEnd/onExit event.
Activity OnDestroy event is not the case, because it is raised each time the device changes its orientation.
Does Application have onEnd event?
Does Application have onEnd event?
No. Mostly, that is because applications do not "end". They are either in the foreground, in the background, or their processes are terminated.
I found a way to do it:
You have a listener onPause() that is triggered when your app goes in background.
And usually when you kill your app in the task manager...your app goes in background for a few sec.
And that is the only way I found to do this.
For my example I have an app that plays a music automatically at launch. (Even if mobile is in silent mode).
I use onPause() to stop music and set original volume back to silent.
protected void onPause(){
super.onPause();
mp.pause(); //that is mediaplayer pause
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC,originalVol, 0);
} //set volume to its original state
Related
I'm trying to be able to start music playback from my app when the headset buttons are clicked while my app is stopped.
I can use MediaSession.Callback onMediaButtonEvent() or the now deprecated registerMediaButtonEventReceiver() to listen for media button click WHILE my app is playing music, but if I pause the music for a minute, with my Activity and playback Service still running, and then I press the headset button, I see that I have lost the ability to receive the media button broadcast. Instead, Google Now opens.
What I'm trying to do is something like Google Play Music. It is able to start music playback even if the app is completely stopped...no services in the background.
I feel that setMediaButtonReceiver() is the one to use for this, but I've not been able to get it to work.
setMediaButtonReceiver(PendingIntent mbr)
Set a pending intent for your media button receiver to allow restarting playback after the session has been stopped. If your app is started in this way an ACTION_MEDIA_BUTTON intent will be sent via the pending intent.
I have the following snippet in my Service.
PendingIntent pi = PendingIntent.getBroadcast(HeadsetService.this, 0, new Intent(HeadsetService.this, RemoteControlReceiver.class), 0);
mMediaSession.setMediaButtonReceiver(pi);
My RemoteControlReceiver BroadcastReceiver is registered in the Manifest but I receive no broadcast when I press the button.
I've also seen that other music player apps lose the ability to receive media button broadcasts once they've stopped playback for about minute.
Any ideas how I can have a more robust media button controls?
Thanks in advance!
First, it is important to distinct MediaSessionCompat from any service such as MediaBrowserServiceCompat.
MediaSessionCompat is communicating with the external MediaSessionStack that dictates which app will get media key commands from external MediaSessionService. On API 26+ the key will be sent to the last playing app. Devices with API < 26 will first look for active playing/buffering session, then for active session and then for last playing session. The latter allows apps to 'steal' the focus by keeping the mMediaSesssion.isActive tag on when they shouldn't. More details about priority can be found in the official guide.
So as long as your app set mMediaSesssion.isActive = true at some point and was last playing, it will get media keys unless mMediaSession.release() was called. The latter removes your session from MediaSessionStack and thus will your session no longer receives media keys. That's why it is important to call release() once you no longer expect user to continue playing video or music. There is one more caveat: If system thinks your app was killed as opposed to ended gracefully, then the app is removed from MediaSessionStack as well, which makes sense, because in service onDestroy() is not necessarily called in such scenario and thus the system releases your session for you. This might happen when you swipe away the app. A workaround I use is to keep the service in foreground while the main app is in use and then end the service after a short delay upon receiving a call to onTaskRemoved() in service.
The call to mMediaSession.release() will happen at some point if you put it in onDestroy() of your service. The service is expected to end when it is not being used, as otherwise it is taking system resources. Thus, it is recommended to end it in onStop() command or when swiping away app or notification. In your case it may happen that power manager killed your service after being inactive for some time. Depending on implementation the some parts of the player might still be working even if the service is destroyed. Also the notification might still be there, as the service is no longer in foreground. That might've fool you into thinking that the service was running. Though without more details, I cannot really say what exactly went wrong in your case.
One additional cause that might prevent your app from getting media keys is if your manifest is not properly configured. Make sure that your BroadcaseReceiver entry includes android.intent.action.MEDIA_BUTTON intent filter.
Another possible mistake is initializing your media key callback MediaSessionCompat.Callback() in the service or any other lifecycle component. Thus, if that component gets destroyed, it can quickly lead to unexpected behavior.
TLDR:
Filter your Logcat for MediaSessionStack|MediaSessionService to ensure that your app gets the media keys. If it doesn't, then:
ensure that mMusicService.isActive = true is set (in e.g. in onPlay())
ensure that mMusicService.release() is not called
ensure that your manifest is properly set
ensure that the system doesn't think your service was killed (e.g. by swiping away the app) as opposed to being ended gracefully
Then make sure your app is handling media keys properly.
In case of custom receiver, they should be there.
In case of androidx.media.session.MediaButtonReceiver they should be in MediaControllerCompat.Callback() whose state should not depend on any service or lifecycle component
I wrote the answer a little bit more general, since it is an old question and others might benefit from it more than the OP.
I have developed an android watch app. It has a play button which when you click starts the sensor manager to analyse the sensor data. Using the data, I recognize the gestures performed by the user. So when I press the play button, sensor data analysis starts and the user can see a stop button to stop the sensor whenever he wants. So once the sensor is started, if I swipe and go back to the home screen and the again open the app, I can see the play button instead of stop button. I want to see the stop button when the user returns. Ideally I want to run a foreground service to detect the sensor readings.
So I want to start a foreground service when the user hits the play button and when the user open the notification, he must see the stop button to stop the sensor data as well as the service. How can I do this? Please advise.
UI:
Save your required UI data to the Bundle of the current states (stop button appearing) using onSaveInstanceState for that instance to your onPause() so that it can be retrieved by the onResume() using onRestoreInstanceState and viewed.
Service:
The Service should be bound to the activity so the two communicate directly. The service can be stopped from the activity using
stopService(new Intent(this, MyService.class));
You can also call stopSelf() from within the Service.
i made a sample android app,which starts a started service by calling startService(serviceintent).
it works fine,but if i forceQuit my application from settings>app>downloaded>force_Quit.my service stops and even destroyed is not called.
i studied for 3-4 days and know about start_sticky in StartOnCommand method.i am able to achieve all aspects of service.
I want to know whatever i am achieving that service stops and doesnot restart automatically even if started as Start_Sticky is normal behaviour according to android.Can i make it restared if user force quit my application.
my manifest is correct i uses process tag also.
if i forceQuit my application from settings>app>downloaded>force_Quit.my service stops and even destroyed is not called.
Correct.
Can i make it restared if user force quit my application.
No. Nothing of your app will run again until something uses an explicit Intent to start one of your components. Usually, that means that the user taps on your icon in the home screen launcher, though there are other explicit-Intent scenarios (e.g., GCM message).
I created an app and I want it to be on all the time. I use it on a tablet in a room. So, I was wondering if there is any chance that the app sends me a notification if it crashed or is turned off?
Thanks!
onPause() is called when you exit the application but don't close it, and onDestroy() is called when you close the application. If you want to do something when either of these two methods is called, override them in your activity and add the notification call in there.
I have been playing with the states all day trying to figure out why, when I press the power button to bring up the lock screen, my app loses focus and calls it's onStop() (as it should) but then it calls the onStart() again before hte screen goes off. This is causing me a problem because some sounds in my app (and presumably other stuff) start playing again while the lockscreen is active.
how can I make sure it is properly backgrounded and stopped when the lockscreen is active?
I faced this exact problem not long ago. In AndroidManifest.xml, make sure you have this:
android:configChanges="keyboardHidden|orientation"
This will prevent your activity from being restarted on runtime 'configuration changes'. See handling the configuration change yourself. That way your app will listen for events that would cause a restart - like orientation and keyboard visibility changes -- and handle them within your Activity.
There is also a very similar question on SO here:
Activity restart on rotation Android