I read many posts about this problem like [this link][1] and one solution is add orientation configChanges to manifest and handle onConfigurationChanged event in order to prevent onCreate activity to be called again when rotation. I did it and event is triggered properly, however, after this execution, onCreate method is also executed! why? what I am missing? Thank you
manifest,
<activity
android:name="webPush"
android:configChanges="keyboardHidden|orientation"/>
activity,
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
setContentView(R.layout.vistaaib);
}
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.vistaaib);
...
I think this will work.........
<activity android:name=".MyActivity"
android:configChanges="orientation|keyboardHidden"
android:label="#string/app_name">
Beginning with Android 3.2 (API level 13), the will "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 you must use
android:configChanges="orientation|screenSize"
I Did this.
I added This code to manifest and it works perfect.
<activity
android:name="?"
android:label="#string/?"
android:theme="#style/?"
android:configChanges="orientation|screenSize">
You will need to add this under you activity if you want to change something when the device is rotation.
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();
}
}
Write this two lines of code in manifest file in that Activity.
Seem this will solve your problem.<activity
android:name=".YourActivity"
android:configChanges="orientation|keyboardHidden"/>
Your activity will be restarted on any configuration change. Most likely it is being restarted because the keyboard state changes. Try adding this to the activity's attributes:
android:configChanges="orientation|keyboard|keyboardHidden"
If you are working for API level 12 or lower
In menifest file, put following just after declaring your Activity Name.
android:configChanges="orientation"
e.g.-
<activity
android:name=".NameOfYourActivity"
android:configChanges="orientation"/>
And in android 3.2(API level 13) or higher version screen size also changes on rotation changes so declare this too.
for this,
android:configChanges="orientation|screenSize"
Following Could be the reason
Event :screenSize
The current available screen size has changed. This represents a change in the currently available size, relative to the current aspect ratio, so will change when the user switches between landscape and portrait. 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).
Added in API level 13.
so along with "orientation" add "screenSize" as well
Related
So the general consensus is this; most people use their phones in portrait and most people use their tablet in landscape. Depending on which activity it is my app's layout goes crazy when you rotate on the phone to landscape and it just wouldn't be worth the time to fix considering users are unlikely to rotate here and have no reason to do so. I'm aware of the ole orientation="portrait" trick in the Manifest in the activity element, however this locks tablet users into portrait which wouldn't be appropriate. I would like to disable portrait on all my activities for tablet users yet simultaneously disable landscape on most all my activites for phone users. I tried to pull a fast one by making a layout-large-land folder and no layout-large folder, but that doesn't prevent the orientation from changing on tablets.
If you just use setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) from code you will catch interesting effect on Android 26+. If the system autorotation option is enabled and you hold phone in landscape orientation and start new Activity it will appears in landscape orientation and then rotate to portrait in a few seconds. You doesn't catch such effect if set android:screenOrientation="portrait" option in the AndroidManifest. But there are not way to have different rotation option into AndroidManifest for phone and tablet.
There's way to solve that if you wish lock portrait orientation on phone and unlock autorotation on tablet.
Set option android:screenOrientation="locked" in the AndroidManifest for each Activity in you project.
<activity android:name=".SomeActivity"
android:screenOrientation="locked" />
where "locked" – Locks the orientation to its current rotation, whatever that is. Added in API level 18 from Android docs
Then set in parent BaseActivity such code
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState)
int orientation = getResources().getConfiguration().orientation;
if (isTablet()) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
} else if(orientation != Configuration.ORIENTATION_PORTRAIT) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
}
There are a few ways to detect that current device is Tablet. Choose implementation of isTablet() method yourself.
I guess you can use a code like this in onCreate() method:
int screenLayoutSize = getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK;
if (screenLayoutSize == Configuration.SCREENLAYOUT_SIZE_SMALL || screenLayoutSize == Configuration.SCREENLAYOUT_SIZE_NORMAL) {
setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
And don't specify any orientation in xml, so by default it switches in both mode.
My suggestion would be to first find the way to know at run-time whether the activity is being executed in a Tablet by invoking a resource as explained in this answer. Then set the orientation as explained in this answer.
-Do One thing put this on the in the res/values file as bools.xml or whatever (file names don't matter here):
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="portrait_only">true</bool>
</resources>
and Put this one in res/values-sw600dp and res/values-xlarge:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="portrait_only">false</bool>
</resources>
and then into java class file write this below code in onCreate method:
if(getResources().getBoolean(R.bool.portrait_only)){
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
Devices that are more than 600 dp in the smallest width direction.
see the below link for the how to add directories and file into android studio project
I am implementing a way where the user can disable screen rotation from the app settings. If the box is checked then any Activity can be automatically rotated and follow the phone rotation settings. If not checked then the autorotation is disabled.
I know how to do it per Activity like this
if(!GlobalVar.sharedPreferences_static.isAutoRotate()){
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}else{
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_USER);
}
Is there a way I can do this once for all the activities (the whole app) instead of doing it for every Activity? Thank you.
If I understood your problem correctly, here is what you can do: create an empty Activity (without setting its content) like this:
public class EmptyActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Your screen orientation logic here
}
}
and then you make all other Activities extend the EmptyActivity. So, you just need to implement your screen orientation logic once.
The same thing can be done in the manifest with:
android:screenOrientation="landscape"
but that attribute doesn't work if (only) applied to the application tag. You'd still have to put it on every activity, but at least it's syntactically easier.
You just add this line into your activity like this
<activity
android:name="Package name"
android:label="App anem"
android:screenOrientation="landscape" //Orientation
>
</activity>
Or you can set like this programmatically like this in the starting of the activity...
if (Config.sDeviceType.equalsIgnoreCase("MO")) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
I need to check if the device launcher home screen support orientation, is that possible? if so please help me out.
for instance, Samsung Galaxy Note 2 does not support launcher orientation while Galaxy Mega does.
You can handle yourself the screen rotations by modifying the Manifest file, just add android:configChanges="orientation" for the activities you want. It means that the system will not handle by itself the orientation changes anymore.
Then in order to implement the actions to do during the orientation changes, add the following code in your Activity:
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
//TODO
} else if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
//TODO
}
}
For the devices, I think you can try filtering with the models for example: android.os.Build.MODEL.
My code works as expected on smaller and bigger devices (Motorola Xoom, Samsung Galaxy Player 4.0, Kyocera Digno), but for the Samsung Galaxy Tab 7.0, after launching an ACTION_IMAGE_CAPTURE intent and taking a picture, when the app returns onDestroy() is called, followed by onCreate(), then onActivityResult() is called, and finally, onDestroy() and onCreate() are called again, which is of course undesireable - only onActivityResult() should be called.
Possibles clues:
The Galaxy Tab 7.0 has a screen size that is explicity not supported in the manifest file (and this is the only device I have tested with an unsupported screen size), so the user may choose scretch-to-fit or zoom-to-fit. Both UIs have the same (bad) behavior.
The camera activity seems to switch orientation when previewing a picture. My app only supports portrait mode (edit: on smaller screens - on non-xlarge screens, it supports orientation changes). Maybe the orientation change is destroying my activity, somehow.
I have tried launching and returning from a different intent (email intent), and my app is not destroyed and re-created in that case.
Let me know if more information or a code sample is needed.
Edit: the issue has been narrowed down to the orientation change. As per Karthik's answer, setting android:configChanges="orientation" fixes the issue. The only problem is, my app supports orientation changes on xlarge screens. This setting breaks this functionality on those devices. I've tried using android:configChanges="#string/config_changes" and providing a different string depending on the screen size, but now I'm getting an "Installation error: INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION". According to this, Android Activity, how to override manifest's android:configChanges with Java code?, there is no way to set it programmatically. Is my only option left to handle all orientation changes in my app manually?
You are right, it is due to the orientation change. Camera works in Landscape mode in Galaxy Tab.
So you can add android:configChanges="orientation" to your <activity> tag in manifiest file.
This would solve your problem. onDestroy() and onCreate() will not be called upon return from camera.
I discovered that the reason my app restarts is because the device runs out of memory when starting the camera app and the OS recycled my main Activity. That wouldn't be a problem, except I had a Fragment-based layout and some Fragment initialization was being done in onCreate(), regardless of the savedInstanceState. This caused the automatic Fragment restoration to be discarded and made the app look like it was restarting from the beginning when in fact it was just trying to be restored.
Ex:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// add main menu -- WRONG!
MainMenuFragment mainMenu = new MainMenuFragment();
FragmentTransaction ft = this.getSupportFragmentManager().beginTransaction();
ft.add(R.id.contents, mainMenu);
ft.commit();
if (savedInstanceState != null) {
// <restore state>
}
else {
// <initialize stuff>
}
}
To fix it, I skipped the Fragment initialization when savedInstanceState was not null and made sure that the state was being saved correctly in onSaveInstanceState() and restored in onCreate(), and implemented the normal handling for onActivityResult().
Ex:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
// <restore state>
}
else {
// <initialize stuff>
// add main menu -- CORRECT!
MainMenuFragment mainMenu = new MainMenuFragment();
FragmentTransaction ft = this.getSupportFragmentManager().beginTransaction();
ft.add(R.id.contents, mainMenu);
ft.commit();
}
}
I am having trouble with telling Android to not call onCreate() when the orientation changes. I have added android:configChanges="orientation" to my manifest but still when the orientation changes onCreate() is called. Here is my code.
AndroidManifest.xml
<activity android:name="SearchMenuActivity" android:theme="#android:style/Theme.NoTitleBar" android:configChanges="orientation"></activity>
SearchMenuActivity.java
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Set the current layout to the search_menu
setContentView(R.layout.search_menu_activity);
Log.d(TAG, "onCreate() Called");
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
//don't reload the current page when the orientation is changed
Log.d(TAG, "onConfigurationChanged() Called");
super.onConfigurationChanged(newConfig);
}
And my LogCat Output
06-23 12:33:20.327: DEBUG/APP(2905): onCreate() Called
//Orientation Changes
06-23 12:33:23.842: DEBUG/APP(2905): onCreate() Called
Does anyone know what I am doing wrong? Thanks.
This was my gremlin for the ~same problem:
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 http://developer.android.com/guide/topics/resources/runtime-changes.html)
TL;DR: add "|screenSize" to android:configChanges="orientation" for API 14+
A couple of things to try:
android:configChanges="orientation|keyboardHidden|screenSize" rather than android:configChanges="orientation"
Ensure that you are not calling setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); anywhere. This will cause onConfigurationChange() to not fire.
Check that you are not using android:screenOrientation in your manifest.
If none of that works, read through the Android doc on handling runtime changes and make sure you are doing everything correctly. There may be something somewhere else in your code that's causing the problem. http://developer.android.com/guide/topics/resources/runtime-changes.html
EDIT: As derrik pointed out, I assumed that you were changing the configuration with the accelerometer detecting what way the device was facing. If you want the configuration to change as the keyboard is shown/hidden the configChanges in the manifest must include keyboardHidden as well.
Try use this one.....
android:configChanges="orientation|keyboardHidden|screenSize"
You should change the configChanges entry in AndroidManifest.xml to:
android:configChanges="keyboardHidden|orientation"
Otherwise, sliding the keyboard doesn't trigger onConfigurationChange() even though the orientation changes. I just tested this on my HTC Desire Z.
Add this to your manifest to each activity.
android:configChanges="keyboardHidden|orientation|screenSize"
Then, override onConfigurationChanged on your activity as such
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
}
Manifest:
<activity
android:name=".MainActivity"
android:configChanges="orientation|keyboardHidden|screenSize">
</activity>
Activity & Fragment:
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.d(TAG, "onConfigurationChanged " +
(newConfig.orientation
== Configuration.ORIENTATION_LANDSCAPE
? "landscape" : "portrait"));
}
Output:
10-29 21:53:26.951 D/FragmentOne: onConfigurationChanged landscape
10-29 21:53:26.951 D/MainActivity:onConfigurationChanged landscape
It wasn't triggering in my Fragment (Fragments aren't registered in the AndroidManifest.xml) so I had to move it to the Activity managing my Fragment, in my case the TabsPagerActivity.
Few things can be cross check:
In my case I was tracking language change of device using the onConfigurationChanged.
Few things need to know about onConfigurationChanged is there is some difference in behavious between onConfigurationChanged of Activity and Application.
When you change the configuration of device the Application level onConfigurationChanged will be call automatically and immediately but onConfigurationChanged of activity will call when you navigate to that activity.
and another thing is only locale in manifest will not work sometime So you have declare other config change event along with the locale(in my case) that should be like android:configChanges="layoutDirection|locale"