Search code examples
javaandroidoncreateonresume

onResume not behaving as expected on return from other activity


I have a small app that calculates the time until a specified date and time. It works well.

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.concurrent.TimeUnit;

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Menu;
import android.widget.DigitalClock;
import android.widget.TextView;

public class Day2GoActivity extends Activity {
private TextView tvWeeks, tvDays, tvHours, tvMinutes, tvSeconds, timeUntil;


public Date curDateTime = new Date();
public Calendar today = Calendar.getInstance();
public Calendar leaving = Calendar.getInstance();
protected SimpleDateFormat sdf = new SimpleDateFormat("E dd-MMM-yyyy HH:mm");

protected Handler h = new Handler();
protected Runnable r = new Runnable() {
    public void run() {
        afficher();
    }
};

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    tvDays = (TextView) findViewById(R.id.tvDays);
    timeUntil = (TextView) findViewById(R.id.timeUntil);
    tvWeeks = (TextView) findViewById(R.id.tvWeeks);
    tvHours = (TextView) findViewById(R.id.tvHours);
    tvMinutes = (TextView) findViewById(R.id.tvMinutes);
    tvSeconds = (TextView) findViewById(R.id.tvSeconds);
}

@Override
protected void onResume() {
    super.onResume();
    Log.i("TAG", "Resuming");
    SharedPreferences sharedPreferences = getSharedPreferences("preferences", MODE_PRIVATE);
    Log.i("MyActvity", "Year = " + sharedPreferences.getInt("year", Calendar.YEAR));

    leaving.set(sharedPreferences.getInt("year", Calendar.YEAR), sharedPreferences.getInt("month", Calendar.MONTH),
            sharedPreferences.getInt("dayOfMonth", Calendar.DAY_OF_MONTH), sharedPreferences.getInt("hour", Calendar.HOUR_OF_DAY),
            sharedPreferences.getInt("minute", Calendar.MINUTE));
    timeUntil.setText("Time until: " + sdf.format(leaving.getTime()));
    r.run();
    Log.w("TAG", "Resumed");

}

private void afficher() {
    today = Calendar.getInstance();
    long millisToGo = leaving.getTimeInMillis() - today.getTimeInMillis();
    long seconds2go = TimeUnit.MILLISECONDS.toSeconds(millisToGo);
    tvSeconds.setText(String.format("%,d seconds", seconds2go));
    long minutes2go = TimeUnit.MILLISECONDS.toMinutes(millisToGo);
    tvMinutes.setText(String.format("%,d minutes", minutes2go));
    long hours2go = TimeUnit.MILLISECONDS.toHours(millisToGo);
    tvHours.setText(String.format("%d hours", hours2go));
    tvDays.setText(String.format("%d days %d hours", (int) hours2go / 24, hours2go % 24));
    long days2go = TimeUnit.MILLISECONDS.toDays(millisToGo);
    tvWeeks.setText(String.format("%d weeks %d days", (int) days2go / 7, days2go % 7));
    h.postDelayed(r, 1000);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    Intent myIntent = new Intent(getApplicationContext(), editDate.class);
    startActivity(myIntent);
    return true;
}

I have an issue, however, when the user changes the date and time. I have a second Activity which, as you can see is called in the onCreateOptionsMenu. It also works fine.

import java.util.Calendar;
import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.widget.DatePicker;
import android.widget.TimePicker;

public class editDate extends Activity {

protected DatePicker dp1;
protected TimePicker tp1;
protected Calendar c;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.edit);
    dp1 = (DatePicker) findViewById(R.id.datePicker1);
    tp1 = (TimePicker) findViewById(R.id.timePicker1);
    tp1.setIs24HourView(true);
    LoadPreferences();
}

@Override
protected void onDestroy() {
    super.onDestroy();
    SavePreferences();
}

private void SavePreferences() {
    SharedPreferences sharedPreferences = this.getSharedPreferences("preferences", MODE_PRIVATE);
    SharedPreferences.Editor editor = sharedPreferences.edit();

    editor.putInt("year", dp1.getYear());
    editor.putInt("month", dp1.getMonth());
    editor.putInt("dayOfMonth", dp1.getDayOfMonth());
    editor.putInt("hour", tp1.getCurrentHour());
    editor.putInt("minute", tp1.getCurrentMinute());
    editor.commit();
}

private void LoadPreferences() {
    SharedPreferences sharedPreferences = this.getSharedPreferences("preferences", MODE_PRIVATE);
    c = Calendar.getInstance();

    try {
        dp1.init(sharedPreferences.getInt("year", c.YEAR), sharedPreferences.getInt("month", c.MONTH),
                sharedPreferences.getInt("dayOfMonth", c.DAY_OF_MONTH), null);
    } catch (IllegalArgumentException e) {
        // TODO Auto-generated catch block
        dp1.init(2012, 5, 1, null);
    }
    tp1.setCurrentHour(sharedPreferences.getInt("hour", c.HOUR_OF_DAY));
    tp1.setCurrentMinute(sharedPreferences.getInt("minute", c.MINUTE));
}

}

The app runs fine, with all the expected entries in the Log cat file:

06-01 18:21:04.049: I/ApplicationPackageManager(7750): cscCountry is not German : XEU
06-01 18:21:04.079: I/TAG(7750): Resuming
06-01 18:21:04.089: I/MyActvity(7750): Year = 2014
06-01 18:21:04.089: W/TAG(7750): Resumed
06-01 18:21:05.459: W/KeyCharacterMap(7750): No keyboard for id 0
06-01 18:21:05.459: W/KeyCharacterMap(7750): Using default keymap:    /system/usr/keychars/qwerty.kcm.bin
06-01 18:21:05.519: I/ApplicationPackageManager(7750): cscCountry is not German : XEU
06-01 18:21:05.619: W/Picker(7750): beforeTextChanged: 01, 0, 2, 2
06-01 18:21:05.619: W/Picker(7750): onTextChanged: 01
06-01 18:21:05.619: W/Picker(7750): onTextChanged: 01, 0, 2, 2
06-01 18:21:05.619: W/Picker(7750): aftertextchanged: 01
06-01 18:21:05.619: W/Picker(7750): beforeTextChanged: 01, 0, 2, 2
06-01 18:21:05.619: W/Picker(7750): onTextChanged: 01
06-01 18:21:05.619: W/Picker(7750): onTextChanged: 10, 0, 2, 2
06-01 18:21:05.619: W/Picker(7750): aftertextchanged: 10
06-01 18:21:05.619: W/Picker(7750): beforeTextChanged: 2012, 0, 4, 4
06-01 18:21:05.619: W/Picker(7750): onTextChanged: 2012
06-01 18:21:05.619: W/Picker(7750): onTextChanged: 2014, 0, 4, 4
06-01 18:21:05.619: W/Picker(7750): aftertextchanged: 2014
06-01 18:21:08.239: E/DatePicker(7750): adjustMaxDat : 31 10
06-01 18:21:08.239: W/Picker(7750): beforeTextChanged: 10, 0, 2, 2
06-01 18:21:08.249: W/Picker(7750): onTextChanged: 10
06-01 18:21:08.249: W/Picker(7750): onTextChanged: 01, 0, 2, 2
06-01 18:21:08.249: W/Picker(7750): aftertextchanged: 01
06-01 18:21:08.259: W/Picker(7750): beforeTextChanged: 01, 0, 2, 2
06-01 18:21:08.259: W/Picker(7750): onTextChanged: 01
06-01 18:21:08.259: W/Picker(7750): onTextChanged: 10, 0, 2, 2
06-01 18:21:08.259: W/Picker(7750): aftertextchanged: 10
06-01 18:21:08.259: W/Picker(7750): beforeTextChanged: Jun, 0, 3, 3
06-01 18:21:08.259: W/Picker(7750): onTextChanged: Jun
06-01 18:21:08.259: W/Picker(7750): onTextChanged: Jul, 0, 3, 3
06-01 18:21:08.269: W/Picker(7750): aftertextchanged: Jul
06-01 18:21:10.759: I/TAG(7750): Resuming
06-01 18:21:10.759: I/MyActvity(7750): Year = 2014
06-01 18:21:10.759: W/TAG(7750): Resumed

However it does not update the TextView's timeUntil(). I could believe I had done something wrong here but for two issues. Firstly timeUntil() IS updated when onResume() runs on start-up (after onCreate()), and secondly timeUntil(), IS updated if you change the orientation of the screen. I understand that re-orientation of the screen reruns onCreate() which would suggest that onResume() is working after an onCreate() but not when running on its own. I am completely at a loss.

Does anyone have any ideas?

Following input from Proxy32 (see below) I have changed the onResume void to

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

    timer.scheduleAtFixedRate(new TimerTask() {
        public void run() {
            h.post(new Runnable() {
                @Override
                public void run() {
                    Log.i("TAG", "Resuming");
                    SharedPreferences sharedPreferences = getSharedPreferences("preferences", MODE_PRIVATE);
                    Log.i("MyActvity", "Year = " + sharedPreferences.getInt("year", Calendar.YEAR));

                    leaving.set(sharedPreferences.getInt("year", Calendar.YEAR), sharedPreferences.getInt("month", Calendar.MONTH),
                            sharedPreferences.getInt("dayOfMonth", Calendar.DAY_OF_MONTH),
                            sharedPreferences.getInt("hour", Calendar.HOUR_OF_DAY), sharedPreferences.getInt("minute", Calendar.MINUTE));
                    Log.d("TAG", "date " + sdf.format(leaving.getTime()));
                    timeUntil.setText("Time until: " + sdf.format(leaving.getTime()));
                    timeUntil.invalidate();
                    today = Calendar.getInstance();
                    long millisToGo = leaving.getTimeInMillis() - today.getTimeInMillis();
                    long seconds2go = TimeUnit.MILLISECONDS.toSeconds(millisToGo);
                    tvSeconds.setText(String.format("%,d seconds", seconds2go));
                    long minutes2go = TimeUnit.MILLISECONDS.toMinutes(millisToGo);
                    tvMinutes.setText(String.format("%,d minutes", minutes2go));
                    long hours2go = TimeUnit.MILLISECONDS.toHours(millisToGo);
                    tvHours.setText(String.format("%,d hours", hours2go));
                    tvDays.setText(String.format("%,d days %d hours", (int) hours2go / 24, hours2go % 24));
                    long days2go = TimeUnit.MILLISECONDS.toDays(millisToGo);
                    tvWeeks.setText(String.format("%,d weeks %d days", (int) days2go / 7, days2go % 7));
                }
            });
        }
    }, 0, 1000);
    Log.w("TAG", "Resumed");

}

I have removed afficher too. This now does what I want it to do. Problem solved.


Solution

  • try TextView invalidate() method after you set the text