Note that there are some explanatory texts on larger screens.

plurals
  1. POHow do I programmatically "restart" an Android app?
    primarykey
    data
    text
    <p>Firstly, I know that one should not really kill/restart an application on Android. In my use case I want to factory-reset my application in a specific case where a server sends a specific information to the client.</p> <p>The user can only be logged in on the server with ONE instance of the application (i.e. multiple devices are not allowed). If another instance gets that "logged-in"-lock then all other instances of that user have to delete their data (factory-reset), to maintain consistency.</p> <p>It is possible to forcibly get the lock, because the user might delete the app and reinstall it which would result in a different instance-id and the user would not be able to free the lock any more. Therefore it is possible to forcibly get the lock.</p> <p>Because of that force-possibility we need to always check in an concrete instance that it has the lock. That is done on (almost) each request to the server. The server might send a "wrong-lock-id". If that is detected, the client application must delete everything.</p> <hr> <p>That was the use-case. No for the implementation-question:</p> <p>I have an <code>Activity</code> A that starts the Login <code>Activity</code> L or the app's main <code>Activity</code> B depending on a sharedPrefs field. After starting L or B it closes itself so that only L or B is running. So in the case that the user is logged in already B is running now.</p> <p>B starts C. C calls <code>startService</code> for the <code>IntentService</code> D. That results in this stack:</p> <p>(A) > B > C > D</p> <p>From the onHandleIntent method of D an event is send to a <a href="http://developer.android.com/reference/android/os/ResultReceiver.html" rel="noreferrer">ResultReceiver</a> R.</p> <p>R now handles that event by providing the user a dialog where he can choose to factory-reset the application (delete the database, sharedPrefs, etc.)</p> <p>After the factory-reset I want to restart the application (to close all activities) and only start A again which then launches the login <code>Activity</code> L and finishes itself:</p> <p>(A) > L</p> <p>The Dialog's onClick-method looks like this:</p> <pre><code>@Override public void onClick(DialogInterface dialog, int which) { // Will call onCancelListener MyApplication.factoryReset(); // (Deletes the database, clears sharedPrefs, etc.) Intent i = new Intent(MyApp.getContext(), A.class); i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); MyApp.getContext().startActivity(i); } </code></pre> <p>And that's the <code>MyApp</code> class:</p> <pre><code>public class MyApp extends Application { private static Context context; @Override public void onCreate() { super.onCreate(); context = getApplicationContext(); } public static Context getContext() { return context; } public static void factoryReset() { // ... } } </code></pre> <p>The problem now is that if I use the <code>FLAG_ACTIVITY_NEW_TASK</code> the Activities B and C are still running. If I hit the back button on the login <code>Activity</code> I see C, but I want to go back to the home screen.</p> <p>If I do not set the <code>FLAG_ACTIVITY_NEW_TASK</code> I get the error:</p> <pre><code>07-07 12:27:12.272: ERROR/AndroidRuntime(9512): android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want? </code></pre> <p>I cannot use the Activities' <code>Context</code>, because the <code>ServiceIntent</code> D might also be called from an background task which is started by the <code>AlarmManager</code>.</p> <p>So how could I solve this to the activity stack becoming (A) > L?</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload