2

I have an Android Wear (WearOS) app that after running for a very long period of time ( say 1 hour plus ) sometimes loses its state.

By losing its state I mean after a long time running the app resumes in "State A" from its notification.

  • State A: Stopped - idle.
  • State B: Running - collecting GPS data.

However, if the app runs for let's say 20 mins it resumes rightly in "State B" from its notification.


My Service Class:

public int onStartCommand(Intent intent, int flags, int startId) {
  Notification notification = this.createNotification();
  super.startForeground(PID, notification);
  return START_STICKY;
}

private Notification createNotification(){
  Log.i("MyService", "createNotification");
  Intent mainIntent = new Intent(this, MyActivity.class);
  mainIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
  PendingIntent pendingIntent = PendingIntent.getActivity(this,0, mainIntent,0);
  // shortened for breviety ... creates notification ...
  return notification;
}

My Activity Class:

private void startWatching() {
  if(this.intentService != null){
    this.stopGpsAndCloseDb();
  }
  this.intentService = new Intent(this, MyService.class);
  this.intentService.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
  super.startService(intentService);
}

Could someone shed some light into this problem, what am I missing? Thanks!

Gui Keller
  • 122
  • 10
  • Where is the state stored? And what do you get in logcat in each of these situations? – Sterling Jul 22 '18 at 16:58
  • The app does not store its state anywhere, do I have to? I thought that the app state was automatically managed by Android. Also, hard to say what happens even using logcat, because as I mentioned the problem happens only _sometimes_ and it is indeed hard to reproduce. Thanks! – Gui Keller Jul 23 '18 at 01:43
  • 1
    If your app has state it relies on, it's responsible for storing/loading it - the OS doesn't do this. Rereading your question... are you saying that sometimes when the OS kills your process, it doesn't restart your service? – Sterling Jul 23 '18 at 13:55
  • 1
    Addendum: as a start, I'd put in stub methods with logging for all the `Service` lifecycle events, to get a handle on what **is** going on when this happens. – Sterling Jul 23 '18 at 13:57
  • Hi @String, I think that you have nailed it! I believe that the "Activity" is getting killed but the "Service" keeps on going. Which means that when I tap on the notification to restore the "Activity" it restores it on its initial state. Could you please provide an example of how I would "store" the app state on the "Service" so the "Activity" returns to its right state? Thanks a lot! – Gui Keller Jul 25 '18 at 06:57
  • After further investigation apparently, all I got to do is set all my _Intents_ to be **SingleTop** and add **singleTop** to the _main_ _Activity_ in the _AndroidManifest.xml_. Also, need to set the correct _Intent_ **Action** and **Category** on the _Service_ - is there anything else? I am going to give this a try. Source: https://stackoverflow.com/questions/5502427/resume-application-and-stack-from-notification/5502950 - [ Some research on _launchModes_: https://stackoverflow.com/questions/25773928/setting-launchmode-singletask-vs-setting-activity-launchmode-singletop ] – Gui Keller Jul 25 '18 at 22:37

1 Answers1

0

In my case, the following below did the trick ( tested / already in production ).

Activity - SINGLE_TOP :

this.intentService = new Intent(this, MyService.class);
this.intentService.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);

Service - START_STICKY & SINGLE_TOP & Action & Category:

Intent mainIntent = new Intent(this, MyActivity.class);
mainIntent.setAction(Intent.ACTION_MAIN);
mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);
mainIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, mainIntent, 0);

AndroidManifest.xml - launchMode="singleTop" :

<activity
        android:name=".MyActivity"
        android:label="@string/app_name"
        android:launchMode="singleTop">

I would like to thank @String for pointing me in the right direction.

Gui Keller
  • 122
  • 10