Android: manual screen orientation without restarting the activity?
Asked Answered
M

6

10

I need to make an app playing video with a button for full-screen on the video. The button is used to manually switch between landscape and portrait of the video display. We don't want the auto rotation detect. So the Manifest file is set as below.

<activity
    android:name=".VideoActivity"
    android:screenOrientation="portrait"
    android:configChanges="keyboardHidden"/>

I used

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE); or setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);

to manually set the orientation. It works but it restarts the activity - the onCreate() was found called. So the video playback restarts from the beginning unexpectedly. I cannot make it smooth as like as using onConfigurationChanged() - the auto rotation detect method.

So how to make manual screen orientation change without restarting the activity?

Thank you.

Money answered 26/3, 2013 at 8:22 Comment(2)
You can't. Its how the system works. It has to re-do a lot of work and just destroys the Activity, to re-create it.Dignitary
Please refer this : #8032975Batman
M
7

For manaul orientation change:

<activity
    android:name=".VideoDetails"
    android:configChanges="orientation"/>

public class VideoDetails extends Activity {
    ...
    onStart() {
        setRequestedOrientation(orientation);
    }
    onConfigurationChanged(Configuration newConfig){
        // do stuff for orientation change.
    }
    onClick() {
        setRequestedOrientation(orientation);
    }
}

For auto-orientation detect:

<activity
    android:name=".VideoDetails"
    android:configChanges="orientation"/>

public class VideoDetails extends Activity {
    ...
    onConfigurationChanged(Configuration newConfig){
        // do stuff for orientation change.
    }
}
Money answered 29/5, 2013 at 4:9 Comment(0)
S
2

http://developer.android.com/guide/topics/resources/runtime-changes.html. You can have a looking at the link under the heading Handling the Configuration Change Yourself

<activity android:name=".MyActivity"
      android:configChanges="orientation|keyboardHidden"
      android:label="@string/app_name">

Now, when one of these configurations change, MyActivity does not restart. Instead, the MyActivity receives a call to onConfigurationChanged(). This method is passed a Configuration object that specifies the new device configuration.

 android:configChanges="orientation|screenSize" (andorid 3.2 and above screen size also changes. add this)

Suppose your video is 10 minutes. The video plays till 5 minutes and orientation changes, you know that it has played till 5 minutes.

You can save the actual progress of the video in onSaveInstanceState() and get the saved data in onRestoreInstanceState() from the Bundle, after that you can start the playing with either the progress data, or from the beginning if there was no data saved.

When orientation changes activity is destroyed and recreated. If you want to save data and retain you can do as below for saving large set of data

 @Override
 public Object onRetainNonConfigurationInstance() {
 final MyDataObject data = collectMyLoadedData();
 return data;
 }


@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

final MyDataObject data = (MyDataObject) getLastNonConfigurationInstance();
if (data == null) {
    data = loadMyData();
}

}

For small set of data

 @Override
 public void onSaveInstanceState(Bundle savedInstanceState) {
 super.onSaveInstanceState(savedInstanceState);
 // Save UI state changes to the savedInstanceState.
 // This bundle will be passed to onCreate if the process is
 // killed and restarted.
 savedInstanceState.putString("NICK_NAME", Name);//save nick name
 }

 @Override
 public void onRestoreInstanceState(Bundle savedInstanceState) {
 super.onRestoreInstanceState(savedInstanceState);
 // Restore UI state from the savedInstanceState.
 // This bundle has also been passed to onCreate.
 Name = savedInstanceState.getString("NICK_NAME");//restore nick name
 }

To check orientation

@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);

// Checks the orientation of the screen
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
    Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
} else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
    Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
}
}

VideoView in Android. In this case also video is streamed from the server. Check the answer accepted (commonsware answer). Exactly the same i suggested.

Syzran answered 26/3, 2013 at 8:35 Comment(2)
Thanks. Your method of using onSaveInstanceState() and onRestoreInstanceState() is one of solutions. But my concern is the smooth of video playback, since my app playback video streaming from the server. The re-connection and video seek time would make the video playback discontinuous.Money
@user1835097 check the last link. The user was also streaming videos from server. check the accepted answer.Syzran
S
1

Start by adding the android:configChanges node to your Activity's manifest node

android:configChanges="keyboardHidden|orientation"

For more information check this link

Sollars answered 26/3, 2013 at 8:30 Comment(3)
Thanks. Your method seems auto detect orientation change by the system. It can prevent from restarting the activity. But I don't want the auto detect. I need manual set.Money
@user1835097 then you can do by overriding Activity.onConfigurationChangedSollars
@user1835097 check this link c0deattack.wordpress.com/2010/12/25/…Sollars
E
0

Add the tag

"android:configChanges="keyboard|keyboardHidden|orientation|screenSize|navigation" for your activity in Manifest.xml,

And Override the method

public void onConfigurationChanged(Configuration newConfig) {}

If you need to change your layout on orientationchange chek this one replace layout on orientation change

Epicardium answered 26/3, 2013 at 9:6 Comment(0)
C
0

Having the app restart after orientation change is inevitable.

Keep the variable related to video status on Application so that the Activity does not restart playback at the begin.

This code is from a sample app I made to test this answer.

public class MyApplication extends Application {
int counter;
@Override
public void onCreate() {
    super.onCreate();
    counter = 0;
    }
}   

Add the Application on your manifest

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme"
    android:name="com.example.orientationchange.MyApplication" >
    <activity
 ...

Use withing Activity:

public class MainActivity extends Activity {

TextView output;
MyApplication app ;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    app = (MyApplication) getApplication();
    setContentView(R.layout.activity_main);
    output = (TextView) findViewById(R.id.output);
    //A counter thread used to test the solution.
    new CounterTask().execute( 100 );
}
 ...

Now the rotation does not clean the status variables.

You can alternatively use Preferences for a more code-heavy solution to preserving the state. The preferences will also remember the state from one use of the app to another, where the Application state is cleaned onDestroy() of the app.

Cornute answered 26/3, 2013 at 20:38 Comment(0)
B
0

I was looking for solution very long, and for me worked defining orientation in Manifest as locked:

<activity
    android:name=".VideoActivity"
    android:screenOrientation="locked"
    android:configChanges="keyboardHidden"/>

This prevents Activity to be recreated even if you call setRequestedOrientation()

Bally answered 20/1, 2019 at 13:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.