In my app, I want a media file to play, and to keep playing if the user rotates the screen (destroying the Activity), but I want it to stop playing if the user moves to a differ
Prior to Honeycomb, onRetainNonConfigurationInstance()
as mentioned in the accepted answer is the best way to do this.
Starting with Honeycomb, that's deprecated, but there is a much simpler way: call isChangingConfigurations()
instead, during any of your onPause()
/onStop()
/onDestroy()
.
Finally, if using the support library FragmentActivity (
android.support.v4.app.FragmentActivity) on pre-Honeycomb, onRetainNonConfigurationInstance()
is declared final, but you can override onRetainCustomNonConfigurationInstance()
instead for the same effect.
I finally figured out the answer to my own question!
public class MyActivity extends Activity {
Display display;
int originalRotation;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
originalRotation = display.getRotation();
}
public boolean endingDueToConfigurationChanging() {
int newRotation = display.getRotation();
return (newRotation != originalRotation);
}
}
Display.getRotation() is designed to return a constant indicating whether the device is 0, 90, 180 or 270 degrees off its natural rotation. However, when the device is rotated, this value is updated before the activity ends--it's actually updated as early as in onPause()! So if you compare the value in onPause() (the new value) with the one in onCreate() (the original value) then you know the Activity it shutting down due to a screen rotation or not.
You can also try using View#onConfigurationChanged
in case its applicable in your case(i.e - you have a view for your media player and have a reference to it in the view).
Your solution has at least one potential problem.
According to Android documentation:
Some device configurations can change during runtime (such as screen orientation, keyboard availability, and language). When such a change occurs, Android restarts the running Activity (onDestroy() is called, followed by onCreate()).
Testing for a change in rotation only handles one case. Since this is likely to be the most common cause of configuration change, it's an OK solution. But what if you could handle all cases, existing or added in some future version of Android, without the overhead of handling configuration yourself?
Updated to use onRetainNonConfigurationInstance
. Android docs have this to say about it:
Called by the system, as part of destroying an activity due to a configuration change, when it is known that a new instance will immediately be created for the new configuration.
Also changed chain to super.onDestroy() to happen after stopping media, but not entirely sure about that. Guess it depends on what stopping media means, and what effect destroying may have on stopping media.
private Boolean mConfigurationChange = false;
public Object onRetainNonConfigurationInstance() {
mConfigurationChange = true;
return null;
}
public void onDestroy() {
if (!mConfigurationChange) {
// Code to stop media file goes here.
}
super.onDestroy();
}
You can try listening for the ACTION_CONFIGURATION_CHANGED intent and setting an internal flag indicating the pause is from a configuration change.
I'm not sure if you will receive the intent in time or that you will be guaranteed it will arrive in time as it is probably asynchronous. Might be worth a try though.