What is Problem?
if app started as portrait then make activity as portrait , otherwise landscape , but don't detect sensor based or used based rotation otherwise.
My Solution:
Make variable isPortrait in application class and detect orientation in onCreate of Application class then use this variable in all activites to detect what orientation to use.
Problem in My Solution:
No Idea how can I change different configuration layouts and map them accordingly in this scenario , what if user change it orientation to landscape after app started in portrait ? is there any ActivityInfo flag to achieve this behaviour.
use this in your activity tag in manifest
android:configChanges="orientation"
android:screenOrientation="portrait"
In Mainfest within the atvitity tag add below code
android:configChanges="orientation|screenSize"
and in ur activity override onConfiguration method like below
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
log.e("onConfigurationChanged", "screen orientation change");
}
How can I retain same state in landscape.
when I rotted the screen in landscape mode then activity is restarted and
my layout view is showing wrong. so please help me.
you may save your state in a Bundle in onSaveInstanceState() method and restore it back in onCreate() or in onRestoreInstanceState().
or if you want to disable orientation changes, you may add android:screenOrientation="landscape" to your Activity in the manifest file.
If your speaking that your layout doesnt look/fit properly in landscape mode then you will need a new xml with the same name & place it inside a new folder called "layout-land". That should help
For retain same state in landscape mode you must add android:configChanges="orientation|keyboard" in your Current Activity to Handle Configuration Change in your on way as:
<activity
android:configChanges="orientation|keyboard"
...
/>
or for Changing Layout or any View on configChanges you must override onConfigurationChanged of Activity as:
#Override
public void onConfigurationChanged(Configuration newConfig)
{
//Handle config changes here, paying attention to
//the newConfig.orientation value
super.onConfigurationChanged(newConfig);
}
and if you want to save state on any view on Configuration Chnages then you must override onSaveInstanceState() for saving state of view like TextView, EditText,View Layout's .. and onRestoreInstanceState() for Retrieving state back after Device mode rotation.
for more info about how we handle runtime changes you can also see this android topic :
Handling Runtime Changes
I have a simple activity that loads a bitmap in onCreate. I find that if I rotate the device I can see from the logs that onCreate called again. In fact, because all instance variables are set to default values again I know that the entire Activity has been re-instantiated.
After rotating 2 times I get an FC because not enough memory can be allocated for the bitmap. (Are all instances of the activty still alive somewhere? Or does the GC not clean up fast enough?)
#Override
public void onCreate(Bundle savedInstanceState) {
File externalStorageDir = Environment.getExternalStorageDirectory();
File picturesDir = new File(externalStorageDir, "DCIM/Camera");
File[] files = picturesDir.listFiles(new FilenameFilter(){
public boolean accept(File dir, String name) {
return name.toLowerCase().endsWith(".jpg");
}});
if (files.length > 0) {
Bitmap bm = BitmapFactory.decodeStream(new FileInputStream(files[0]));
ImageView view = (ImageView) findViewById(R.id.photo);
view.setImageBitmap(bm);
}
}
From all that I read, onCreate should be called once during the lifetime of an application. Am I wrong about this? How can re-orienting the device cause the activity to be recreated?
android:configChanges="keyboardHidden|orientation|screenSize"
Caution: Beginning with Android 3.2 (API level 13), the "screen size"
also changes when the device switches between portrait and landscape
orientation. Thus, if you want to prevent runtime restarts due to
orientation change when developing for API level 13 or higher (as
declared by the minSdkVersion and targetSdkVersion attributes), you
must include the "screenSize" value in addition to the "orientation"
value. That is, you must decalare
android:configChanges="orientation|screenSize". However, if your
application targets API level 12 or lower, then your activity always
handles this configuration change itself (this configuration change
does not restart your activity, even when running on an Android 3.2 or
higher device).
From docs: http://developer.android.com/guide/topics/resources/runtime-changes.html
What happen when orientation changed
Life Cycle of orientation
onPause();
onSaveInstanceState();
onStop();
onDestroy();
onCreate();
onStart();
onResume();
---- app recreated and now is running ---
If you do long operation in onCreate() and want prevent re-create your activity add configChanges attribute in your mainfest
<activity android:name=".MyActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="#string/app_name">
screenSize if you targeting api >= 13
Activity is recreated after each rotation by default. You can override this behaviour with configChanges attribute of the activity tag in AndroidManifest. For further details and different options, see http://developer.android.com/guide/topics/resources/runtime-changes.html
Actvity Lifecycle when you rotate screen
onPause
onSaveInstanceState
onStop
onDestroy
onCreate
onStart
onRestoreInstanceState
onResume
If you want to prevent FC from not enough memory, you need to deallocate resources in onStop() or onPause(). this allows you to use fresh memory in onCreate().
This is an alternate solution to preventing the recreation of the activity by using
android:configChanges="keyboardHidden|orientation"
As sometimes your activity's layout is different in portrait and landscape (layout, layout-land).
preventing recreate on orientation change will prevent your activity from using the other orientation's layout.
Yes, activity's onCreate() is called everytime when the orientation changes but you can avoid the re-creation of Activity by adding configChanges attribute of Activity in your AndroidManifest file in the activity tag.
android:configChanges="keyboardHidden|orientation"
On Create method will call everytime when you do orientation, to avoid this you have to use
//Define Below in you Manifest file.
<activity
android:name="com.ecordia.activities.evidence.MediaAttachmentView"
android:configChanges="keyboardHidden|orientation|screenSize"
</activity>
//Define Below in your activity.
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
//your code
} else if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
//your code
}
}
It will works like a charm!!
Manifest XML activity Tag:
android:configChanges="keyboardHidden|orientation"
#Override
public void onConfigurationChanged(Configuration newConfig) {
// TODO Auto-generated method stub
super.onConfigurationChanged(newConfig);
}
Use the above code to perform changes related to orientation in your Activity Java Code
Cheers!!!
One of the most common and suggested “solutions” to dealing with orientation changes is to not deal with them. You can do this by setting the android:configChanges flag on your Activity in AndroidManifest.xml as shown below:
<activity
android:name=".MyActivity"
android:label="#string/title_my_activity"
android:configChanges="orientation|screenSize|keyboardHidden" />
This is NOT the correct way to deal with orientation changes.
CORRECT way is to implement the onSaveInstanceState method (this could be in your Activity, Fragment or both) and place the values you need to save in the Bundle argument that gets passed to the method.
It is nicely described here: http://code.hootsuite.com/orientation-changes-on-android/
While it may seem a bit tedious to implement, handling orientation changes properly provides you with several benefits: you will be able to easily use alternate layouts in portrait and landscape orientations, and you will be able to handle many exceptional states such as low memory situations and interruptions from incoming phone calls without any extra code.
While the Manifest way may work, there is a better and proper solution for these types of problems. The ViewModel class. You should have a look here: https://developer.android.com/topic/libraries/architecture/viewmodel
Basically, you extend the ViewModel class and define all the data members in it which we want to be unchanged over re creation of the activity (in this case orientation change). And provide relevant methods to access those from the Activity class. So when the Activity is re created, the ViewModel object is still there, and so are our data!
Kindly see my way of doing it:-
http://animeshrivastava.blogspot.in/2017/08/activity-lifecycle-oncreate-beating_3.html
snippet is:-
#Override
protected void onSaveInstanceState(Bundle b) {
super.onSaveInstanceState(b);
String str="Screen Change="+String.valueOf(screenChange)+"....";
Toast.makeText(ctx,str+"You are changing orientation...",Toast.LENGTH_SHORT).show();
screenChange=true;
}
#Override
public void onCreate(Bundle b) {
super.onCreate(b);
ctx=getApplicationContext();
if(!screenChange) {
String str="Screen Change="+String.valueOf(screenChange);
// ...
}
}
I had the same problem, in which my onCreate is called multiple times when the screen orientation is changed. My problem got solved when i add android:configChanges="orientation|keyboardHidden|screenSize" in the activity tag in manifest
I had the same problem and I did some workaround
Define didLoad boolean variable with false value
private boolean didLoad = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity);
if (!this.didLoad){
// Your code...
this.didLoad = true;
}
I want to make possible to use an activity in landscape / portrait. The activity starts with the layout for the current orientation (that means before starting the activity). After that it has to stick to it, and not react to orientation change.
I tried putting
android:configChanges="orientation"
in the manifest of the activity, and overriding
#Override
public void onConfigurationChanged(Configuration newConfig) {
// TODO Auto-generated method stub
super.onConfigurationChanged(newConfig);
}
to do nothing (tried commenting the super call too, but this lead to exception)
but this has not the effect disabling the rotation change - the change is processed and the layout reconstructed, it just doesn't use the correct one.
And I can't use
android:screenOrientation
Because it seems I have to specify only one mode for always, and that's not what I need either.
And anyways, if I specify something there, the activity gets reconstructed when rotating.
Tried with
android:screenOrientation="nosensor"
that doesn't do anything
Here there's a lock of current orientation with code
http://www.samcoles.co.uk/mobile/android-lock-and-unlock-screen-orientation/
But it achieves the same effect as specifying orientation in XML (keeps layout but reconstructs the activity). It's a bit nearer to what I want (keeps orientation from start), but reconstructs the activity and I don't want it to react at all.
android:configChanges="orientation" doesn't work on the emulator at all, but it works fine on devices.
Try
#Override
public void onConfigurationChanged(Configuration newConfig) {
newConfig.orientation = getResources().getConfiguration().orientation;
super.onConfigurationChanged(newConfig);
}
Add this to onCreate
if (this.getResources().getConfiguration().orientation == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT){
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);}
else {setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);}
Can you please tell me how can I keep the MediaRecorder keeps recording after an orientation change? I try looking into source code of packages/apps/SoundRecorder/src/com/android/soundrecorder/Recorder.java, I don't see it handles that cases.
Thank you.
This might be because by default the system destroys and recreates the Activity when the orientation changes. You can tell the system that your app handles changes like these by modifying the activity's tag in the manifast like this:
<activity android:name=".UIActivity"
android:configChanges="orientation|keyboardHidden"
android:label="#string/app_name"> ...
</activity>
This way you can react to these changes overriding this method:
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
//---code to redraw your activity here---
//...
}
Here, you can redraw your views to support landscape mode, or do simply nothing.