My app crashec when rotating the device. I know it crashes because whenI rotate the screen it tries to create new View to draw and display but how can it create the view and display it properly on the launch but crashes when trying to create the second new view?
I dont know what part of my code I should post here? Can you give a clue to solve this problem?
I found something usefull. I put try/catch statement and now when I rotate the device, it doesnt crash but displays a blank page, when I re-rotate to the old position it display the page. here is my code
#Override
protected void onCreate(Bundle savedInstanceState) {
try{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
} catch (Exception e) {
Log.i("my_error", e.getMessage());
}
}
but eclipse cannot catch the exception.
How can I solve this problem?
There are two possible ways to do this:
1) You don't care about the orientation change of the screen and you just want to be "resized". Just add the following properties in your Manifest file:
<activity
android:name=".SplashScreen"
android:configChanges="orientation|keyboardHidden|screenSize" ... />
and add this lines of code in your activity:
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// do nothing, just override
}
2) You do care about the orientation change. Then there are a couple of things that you should know about the activity lifecycle in an orientation change.
Firstly the onConfigurationChanged() is called and you should store in a Bundle everything that you need. For example the user has editted an EditText and you should save the value.
Why to do that? Because afterwards the onCreate() method will be called again in order for you to implement a different layout or alter something in the Views. You should then take the previously saved Bundle and restore the variables that you saved in your newly created layout.
Just add the android:configChanges="orientation" to your activity
<activity android:name=".MyActivity"
android:configChanges="orientation"/>
if you given like this, then oncreate will not called if your screen orientation is changed.
If you need more information about this you can check this link
There are a couple of things you can do:
1) Ignore screen orientation changes. If your app is only designed for portrait mode, most likely it won't look good in landscape mode and vice versa. Best is to specify the target orientation in your activities.
2) If you want to allow orientation changes, then you should have written some code re-create the view with different/modified layout. Mind sharing the code with us?
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
//Override this and recreate your view or set adapter here
}
Dont forget to add android:configChanges="orientation" in your manifest.
On a side note you can fix orientation through manifest like this -
android:screenOrientation="portrait"
Add this to your Activity tag in the manifest:
android:configChanges="orientation|screenSize"
This will cause that the activity is not recreated on rotation change.
The flag sreenSize is for newer devices(API level 13 or higher), with including only the orientation flag the activity will stil recreate when rotating on devices running API level 13 or higher.
Related
I am trying to handle change orientation. I enforce orientation in Manifest:
android:screenOrientation="landscape"
android:configChanges="orientation|screenSize"
Then in Activity I set onConfigurationChanged, but it doesn't work. It doesn't handle the change orientation. When I don't set orientation in Manifest, everything works perfect, but I need landscape when the activity starts.
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
startActivity(
new Intent(GraphActivity.this, MainActivity.class)
.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP));
}
}
Thanks guys
onConfigurationChanged won't be called if you have set fixed orientation in manifest
what if user runs app in portrait? it will start with horizontal layout, then if user still want to be in portrait then he must rotate device to landscape and back again to portrait? your described behavior looks to me like bad UX...
but, answering: there is no "landscape-only-on-start" for screenOrientation... if you really want to program such behavior then you have to use some code, especially setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_HORIZONTAL); method, but probably also some manual orientation calculation (sensor callbacks)
I have an activity that has android:windowIsTranslucent set to true and android:windowBackground set to a translucent background. I just changed my target and compile sdk version to 27, and I get an exception when launching this activity now:
java.lang.IllegalStateException: Only fullscreen opaque activities can request orientation
Since this is a new sdk, there isn't anything online about it yet (and it seems to result from this line of code: https://android.googlesource.com/platform/frameworks/base.git/+/master/core/java/android/app/Activity.java#987 )
Is there any way to get around this? The app doesn't crash if I take out android:screenOrientation="portrait" from my manifest for this activity, but I would like to be able to keep it like that.
I also faced the same problem.
As others said, If I deleted android:screenOrientation="portrait" or overrided it with android:screenOrientation="unspecified", then the exception was gone.
And it seems that the front activity's orientation follows the behind activity's orientation.
I thought about it.
If the front activity is transparent and the behind activity's orientation is different,
the display becomes strange.
So, I can understand why this check logic was added
However, I wonder that why this problem was not occurred in Developer Preview 8.0.0.
The workaround is to set targetSdk back to 26.
The reason why is your application crashes is here in this commit.
As you can see here, you are not the only one - this behavior has been reported to Google as issue. It has been fixed, but we don't know how and when it will be released.
I can also confirm what "sofakingforever" says in comments, if there is non-translucent activity with fixed orientation behind your translucent, the translucent will not rotate. So you can just remove android:screenOrientation="portrait" from manifest as well.
The solution worked for me is deleting
android:screenOrientation="portrait"
from all the full screen transparent activities which means their theme contains
<item name="android:windowIsTranslucent">true</item>
Also to make sure that orientation works correct for below Oreo I added this to the onCreate() of the activities.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// This activity is a fullscreen transparent activity, so after Oreo Android doesn't allow fullscreen
// transparent activities to specify android:screenOrientation="portrait" in the manifest. It will pick up
// from the background activity. But for below Oreo we should make sure that requested orientation is portrait.
if (VERSION.SDK_INT < VERSION_CODES.O) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
}
I solved this issues by changing this line in NoActionBar styles
In target version 27 only i got this issue and i solved by using below line
<item name="android:windowIsTranslucent">false</item>
So what I did was remove any screenOrientation property from manifest and add it to my BaseActivity (from which all my activities extend), this code
if(!(this instanceof TranslucentActivity)){
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
The TranslucentActivity will have the orientation from the Activity behind.
it seems like it's a new feature/bug on API 27.
However, you can delete
android:screenOrientation
Or
android:screenOrientation="unspecified"
I recently faced the issue and here's the solution.
No need to change the screen orientation parameter which you set at the android manifest file.
Just add two folders in
res>values
as res>values-v26
and res>values-v27
Then copy your styles.xml and themes.xml file there.
and change the following parameters from TRUE to FALSE.
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowIsTranslucent">false</item>
It will work.
A common bug of Android 8.0
Thanks #JerabekJakub. My test result - keep sdk 27 and remove the following lines can also solve the crash.
android:configChanges="orientation"
android:screenOrientation="portrait"
1) Remove this
android:screenOrientation="portrait"
from minifiest.xml
2) on Activity add these two lines
protected void onCreate(Bundle savedInstanceState) {
setOrientation(this)
super.onCreate(savedInstanceState);
// other other all code here
}
3) Just copy-paste the code in your Activity
public static void setOrientation(Activity context) {
if (android.os.Build.VERSION.SDK_INT == Build.VERSION_CODES.O)
context.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
else
context.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
I had this problem on Android 8 using BottomSheetDialogs. It was crashing every time I open some translucent bottom sheet dialog.
I fixed the problem by adding new theme.xml in values-v26, with same theme as default one, but completely removing windowIsTranslucent item from there.
After that, I still had translucent bottom sheet dialogs in my app and it is working perfectly.
Found it interesting. It may help someone using these dialogs.
I have a ListFragment which opens an Activity when it is clicked. Now, my problem is that my listener is lost when the screen is rotated. The click events does not respond. I have tried android:configChanges , it fixes the listener problem but the layout of the whole activity looks weird. Any possible solutions to set listener again on configuration change?
Best solution: The better way to handle the problem by using onSaveInstanceState().see this link Handling Runtime Changes
No.2: You can detect the change and then handle it through the below method:
public void onConfigurationChanged(Configuration config) {
super.onConfigurationChanged(config);
// Checks the orientation
if (config.orientation == Configuration.ORIENTATION_LANDSCAPE) {
Toast.makeText(this, "landscape mode", Toast.LENGTH_SHORT).show();
} else if (config.orientation == Configuration.ORIENTATION_PORTRAIT){
Toast.makeText(this, "portrait mode", Toast.LENGTH_SHORT).show();
}
}
The forced solution: if you don't want to recycle the activity lifecycle on orientation change then you can add this in your manifest:
<activity android:name=".YourActivity"
android:configChanges="orientation|keyboardHidden"
android:label="#string/app_name">
The last one is the worst solution, but works.
As my suggestion never use the last one because you can't able to do any kind of recycle things in future. but for emergency solution its good.
I saw some related questions on SO, but I'm not able to resolve my issue.
I've created separate layout for PORTRAIT and LANDSCAPE mode.
I've modified the AndroidManifest.xml file for corresponding orientation change but onConfigurationChanged() is not working when I'm implementing it in activity.
Now the issue is at layout.addView(graphView, lp); in onCreate().
I've written absolute hard-coded value in GraphView class.
So it works perfectly foe PORTRAIT mode but graphView is not correctly placed when I switch to LANDSCAPE mode.
To resolve this I've created GraphViewLand class which is coded exclusively for LANDSCAPE mode. But it is not getting called from onConfigurationChanged().
Rest of the layout is coming perfectly as I've created separate main.xml file for each orientation. But since graphView is created programmatically, it is not placed properly.
Am I doing anything wrong here?
I just read this from here:
For any types of configuration changes you say that you handle there, you will receive a call to your current activity's onConfigurationChanged(Configuration) method instead of being restarted. If a configuration change involves any that you do not handle, however, the activity will still be restarted and onConfigurationChanged(Configuration) will not be called.
onCreate() method
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
init();
RelativeLayout layout = (RelativeLayout) findViewById(R.id.MainLayout);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
lp.addRule(RelativeLayout.ALIGN_TOP, btnindex.getId());
GraphView graphView = new GraphView(this, values, "CurrentGraph",
horlabels, verlabels);
layout.addView(graphView, lp);
}
onConfigurationChanged() method
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
Log.v("LAND", "SCPAE");
}
}
Any help appriciated :)
If you create two different types of view (for landscape and portrait) in xml and you have to write logic on different types of view then donot use android:configChanges in manifest.
If you have no android:configChanges in manifest and you have different sets of layout for landscape and portrait then when you change orientation your control will come to onCreate() inside that method you can write your logic.
Did you code onConfigurationChanged as an override in your Activity class?
Basic override:
// Called on rotation.
// Does not call onDestroy anymore due to android:configChanges="keyboardHidden|orientation" in manifest
#Override
public void onConfigurationChanged(Configuration newConfig) {
// TODO Auto-generated method stub
super.onConfigurationChanged(newConfig);
}
My manifest declaration for info:
<activity android:name=".Slime"
android:label="#string/app_name"
android:configChanges="keyboardHidden|orientation"
android:screenOrientation="landscape">
How do you say that the onConfigurationChanged() method is not called? Is the log not being printed? Isn't the toast being shown?
Secondly, you mention that the issue is at layout.addView in onCreate(). Do note that if android:configChanges is present in your manifest, then onCreate() is not called on orientation change. You need to move the piece of code that programmatically modifies the UI layout into the onConfigurationChanged() method.
I'm having a hard time with the screen orientation in Android. I have an activity which captures a signature after the user draws his signature on the device. And for that activity I am passing a parceable object and I get it in oncreate. When the activity changes the orientation sometimes the activity cannot get the parceable object and gives an exception. I tried using a static object for the parceable object but no use. I tried onsaveinstance state method and onRetainNonConfigurationInstance methods as well.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.signature_capture_view);
Bundle bundle = getIntent().getExtras();
info = bundle.getParcelable("info");
logo= (Bitmap) bundle.get("logo");
}
And my save instance state method is like this;
#Override
protected void onSaveInstanceState(Bundle outState) {
outState.putParcelable("info", info);
super.onSaveInstanceState(outState);
}
From the onconfiguration changed method i call the setcontentview method to set a fresh layout.
#Override
public void onConfigurationChanged(Configuration newConfig) {
setContentView(R.layout.signature_capture_view);
super.onConfigurationChanged(newConfig);
}
Sometimes when the orientation changes an out of memory exception occurs from the setcontentview method.
Any help would be greatly appreciated. Thanks in advance.
Try to set the below android:configChanges attributes inside the AndroidManifest.xml file:
<activity android:name=".MyActivity"
android:label="#string/app_name"
android:configChanges="orientation|keyboardHidden">
And if you wants that your application should be fixed to open either in Portrait or in Landscape mode then add android:screenOrientation inside the activity tag:
<activity android:name=".MyActivity"
android:label="#string/app_name"
android:configChanges="orientation|keyboardHidden"
android:screenOrientation="portrait">
if you are changing the View in landscape / portrait then you should follow these steps to resolve the out of memory error.
set this in the manifest on the activity tag
android:configChanges="orientation"
in Anctivity put
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
this.recreate();
}
Try to set this in the manifest on the activity tag for the out of memory error:
android:configChanges="orientation"
I finally found the answer to my out of memory, In my signature drawing view I did not check the bitmap in the view for null and everytime the device changes the orientation it creates the bitmap inside the view. And it generates the OOM. So i inserted a null check for the bitmap and the oom disappeared. Thanks for the quick replys guys.