Android TimePicker hour field disappears after orientation change

I am using a TimePicker under API 1.5 and when the orientation is changed on my device (a stock G1 running 1.6 - though NOT on the 1.5/1.6 emulator), the hour field goes blank. It still remembers the hour, it just doesn't show it. Is there any workaround for this?

The same problem was described by someone else here:

http://groups.google.com/group/android-beginners/browse_thread/thread/b4288004021b876/de5899a2bb291ab5

Nothing helpful was forthcoming - can StackOverflow do better?


Asked by: Leonardo161 | Posted: 24-01-2022






Answer 1

Simply move invoking of methods TimePicker.setCurrentHour and TimePicker.setCurrentMinute to onResume method of your Activity.

Answered by: Anna407 | Posted: 25-02-2022



Answer 2

As mentioned, overriding the onResume() method will sort this issue.

   @Override
    public void onResume() {
        super.onResume();

        TimePicker tmp = (TimePicker) this.findViewById(R.id.yourTimePicker);
        tmp.setCurrentHour(7); // This will also set on rotate

    }

Answered by: Brooke797 | Posted: 25-02-2022



Answer 3

Take a look at this: http://code.google.com/p/android/issues/detail?id=22824 No matter what you do you won't be able to fix the issue without destroying the Activity and recreating it when the rotate occurs. In order to not enter an endless loop simple check to see if the savedInstanceState != null in the onCreate. Something like this will work:

if (savedInstanceState!=null){
    Intent myIntent = 
        new Intent(getApplicationContext(), CurrentClassName.class);
    startActivityForResult(myIntent, 0);  
    finish();
} 

Answered by: Arthur459 | Posted: 25-02-2022



Answer 4

In onSaveInstanceState() for your activity, get the hour value out of the TimePicker and place it in the Bundle. In onRestoreInstanceState() for your activity, get the hour out of the Bundle and put it in the TimePicker.

TimePicker should handle that on its own, but this may work around the problem for you.

Answered by: Alissa825 | Posted: 25-02-2022



Answer 5

I've lost a ton of sleep over this and just figured it out. When you're using a DialogPreference you need to override the showDialog method and reset your currentHour and currentMinute there. Like this:

@Override
protected void showDialog(Bundle state) {
    super.showDialog(state);

    mBeginShiftTp.setCurrentHour(mBeginShiftTp.getCurrentHour());
    mBeginShiftTp.setCurrentMinute(mBeginShiftTp.getCurrentMinute());
    mEndShiftTp.setCurrentHour(mEndShiftTp.getCurrentHour());
    mEndShiftTp.setCurrentMinute(mEndShiftTp.getCurrentMinute());

}

Answered by: Maria207 | Posted: 25-02-2022



Answer 6

Based on the link that DanRoss provided, the issue is related to the picker not updating the hour if the hour has not changed. Regarding orientation changes, this behavior is faulty because the hour before the rotation will always equal the hour after the rotation.

For those using the TimePickerDialog, a way around this is to extend the default implementation and force it to update the hour by updating the time (setting hour and minute to equal 0 in my example) and then update the hour to be the actual hour.

It may be possible to build something similar using only the TimePicker control.

Here is a working example for the TimePickerDialog:

import android.content.Context;
import android.os.Bundle;
import android.widget.TimePicker;

public class TimePickerDialog extends android.app.TimePickerDialog
{
    private final String HOUR_KEY = "Hour";
    private final String MINUTE_KEY = "Minute";
    private int hourOfDay;
    private int minute;

    public TimePickerDialog(Context context, OnTimeSetListener callBack, int hourOfDay, int minute, boolean is24HourView)
    {
        super(context, callBack, hourOfDay, minute, is24HourView);

        this.hourOfDay = hourOfDay;
        this.minute = minute;
    }

    @Override
    public void onTimeChanged (TimePicker view, int hourOfDay, int minute)
    {
        super.onTimeChanged(view, hourOfDay, minute);

        this.hourOfDay = hourOfDay;
        this.minute = minute;
    }

    @Override
    public Bundle onSaveInstanceState()
    {
        Bundle savedInstanceState = super.onSaveInstanceState();

        if (savedInstanceState == null)
        {
            savedInstanceState = new Bundle();
        }

        savedInstanceState.putInt(HOUR_KEY, this.hourOfDay);
        savedInstanceState.putInt(MINUTE_KEY, minute);

        return savedInstanceState;
    }

    @Override
    public void onRestoreInstanceState(Bundle savedInstanceState)
    {
        super.onRestoreInstanceState(savedInstanceState);

        // The code for updating the hour is currently not doing anything
        // if the hour has not changed.
        // Force it to update by setting it to zero first
        this.updateTime(0, 0);

        this.hourOfDay = savedInstanceState.getInt(HOUR_KEY);
        this.minute = savedInstanceState.getInt(MINUTE_KEY);

        // Now it will update
        this.updateTime(this.hourOfDay, this.minute);
    }
}

Answered by: Caroline572 | Posted: 25-02-2022



Answer 7

This bug is related on Android Official Forum Bug 5483. Well, and that discussion, they suggest a simple solution and it works for me. I added the attribute android:onConfigurationChanges=orientation on my activity on AndroidManifest.xml.

Important: Depending of you activity(others widgets ...), it can have side effects

Answered by: Dainton656 | Posted: 25-02-2022



Answer 8

I realize I'm a little late to the party, but seeing as this problem still exists, I feel it deserves an actual answer.

From what I've read elsewhere, the issue has to do with the individual number fields of the TimePicker all having exactly the same ID. The reason this is a problem is because when you rotate the screen, android closes all of your dialogs, reopens all of your dialogs usings the typical onCreateDialog -> onPrepareDialog, and then, most importantly, after you have made your dialogs, it goes back through and restores what used to be there. This means that no matter what you do beforehand, android is going to come in and break your TimePicker.

The answer, although not the prettiest option, is to come in after android and set it again.

Here's how I did it, I simply made my own TimePicker:

public class MyTimePicker extends TimePicker {

    public MyTimePicker(Context context) {
        super(context);
    }
    public MyTimePicker(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    public MyTimePicker(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    private final static String B_MIN = "bMin";
    private final static String B_HOUR = "bHour";
    private final static String B_SUPER = "bSuper";

    // here's the first key, we're going to override how the TimePicker saves 
    // its state

    @Override
    public Parcelable onSaveInstanceState() {
        Bundle bundle = new Bundle();
        bundle.putParcelable(B_SUPER, super.onSaveInstanceState());
        bundle.putInt(B_MIN, getCurrentMinute());
        bundle.putInt(B_HOUR, getCurrentHour());
        return bundle;
    }

    // this function gets called when we are restoring, but before android 
    // does its thing

    @Override
    public void onRestoreInstanceState(Parcelable state) {
        if (state instanceof Bundle) {
            final Bundle bundle = (Bundle) state;
            super.onRestoreInstanceState(bundle.getParcelable(B_SUPER));

            // here it is, not the prettiest option, but it gets the job done
            // we simply wait 0.1 sec and then update the TimePicker
            // since all of this happens in the same thread, its guarenteed to
            // be after the android reset

            // also, this handler gets the HandlerLeak warning, I don't 
            // think this can leak though seeing as it's only called once 
            // with a 100 ms delay

            (new Handler() {
                @Override
                public void handleMessage(Message msg) {

                    setCurrentMinute(bundle.getInt(B_MIN));
                    setCurrentHour(bundle.getInt(B_HOUR));
                }
            }).sendEmptyMessageDelayed(0, 100);

            return;
        }
        super.onRestoreInstanceState(state);
    }
}    

And yes, the handler is necessary. If you simply run the setCurrent commands from onRestoreInstanceState android will simply override you.

Answered by: Briony651 | Posted: 25-02-2022



Answer 9

I see this problem was active earlyer but I solved problem and if someone has this problem this is solve: Everything doing in onResume(), first get value for hour, then set hour on timePicker to hour+1 and then set to hour. That's working for me.

Answered by: Lana805 | Posted: 25-02-2022



Answer 10

Crazy solution that works:

  • Run AsynTask in onResume()
  • Sleep for 50msec
  • Switch back to UI thread, using Activity.runOnUiThread()
  • In UI thread set min/hour to 0
  • Then set min/hour to your values

Here is a gist with the code, ready for copy-paste :)
https://gist.github.com/sorrro/9415702

Answered by: Brooke576 | Posted: 25-02-2022



Similar questions

android - Changing orientation clears the TimePicker

I just started learning Android application development and I noticed the following issue while trying different activity elements. I have the following code in my Main activity <TableLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/mainLayout" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TableRow android:id="@+...


android - appWidget Orientation Code

I have code in an appwidget that I want to run when the phone's orientation changes on the home screen, ie like when the keyboard flips out. I have an image that I want to change in an imageview in my appwidget. I can't use different layouts linked to the orientation (ie "layout" and "layout-land") because I don't know the name of the image file until runtime, it is created at runtime. Is there anyway to trigger code to ru...


Android Screen orientation, shake cellphone crashes the application

I am having search application, which loads data retreived from the webservice. While application on create it shows progress dialog once its done with loading data it dismiss the progress dialog. problem is while loading if i change the orientation of the phone it works fine it try to load activity again, but if i start shaking the cellphone while it is loading data application get crashed, any solution ??...


android - From WebView Errors to ImageView Cover-ups to Screen Orientation

It all started with a simple WebView within an Android app. This view loads info from a public URL. Nothing unusual there. However ... if there should be a network interruption, you can easily end up with an error displayed prominently in the WebView. Well, that's no good, right? So I searched the docs and elsewhere for a way to suppress this, or trap it ... and fou...


Android Bluetooth crashes after orientation change

My code is based on the BluetoothChat sample from the API. I connect to another device just fine and I can read and write to the connection no problem. But then if I turn the device the orientation of the UI changes automatically. After this, if I try to write to the Bluetooth connection, my application crashes! It seems weird that the orientation of the screen somehow affects the Bluetooth. I am new to Android, an...


android - How to change orientation of xml "layout" area in Eclipse

The xml files that contains the Activity layouts can be rendered by Eclipse. How do I get that Eclipse screen area to have vertical orientation, not horizontal (inside Eclipse - it correctly shows as vertical in the emulator)? Peter


Android - Forced locale reset on orientation changes

I try to force the locale in my app to one the user specified. As this may be used to demonstrations, I want to change the language/locale in the app and not anytime for the whole device. I looked around SO and tried to use every hint I found here. The result: I can restart my test activity with the new language, but if I change the orientation, the locale will always be reseted to the device one. I


How can the landscape screen orientation be restricted in android?

How can the landscape screen orientation be restricted in android?


Problem saving WebView scroll position during orientation change in Android 2.1

I have a problem preserving the current scroll position of content loaded in Android's WebView control during orientation changes. The issue currently exist only in Android 2.1 and Android 2.1 Update 1 The code that I use is based on the default Browser application and looks like this: @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mWebView = n...


android - How to detect orientation change in home screen widget?

I am writing a home screen widget and want to update the home screen widget when the device orientation changes from portrait to landscape or the other way. How can I make it? Currently, I tried to reigster to CONFIGURATION_CHANGED action like the code below, but the Android didn't allow me to do that by saying "IntentReceiver components are not allowed to register to receive intents". Can someone help me? Thanks.


android - Gracefully handling screen orientation change during activity start

I'm trying to find a way to properly handle setting up an activity where its orientation is determined from data in the intent that launched it. This is for a game where the user can choose levels, some of which are int portrait orientation and some are landscape orientation. The problem I'm facing is that setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) doesn't take effect until the activity...






Still can't find your answer? Check out these communities...



Android Google Support | Android Community | Android Community (Facebook) | Dev.io Android



top