I've got an Android app that I want other apps to be able to launch via an intent. This allows other apps to interact with mine and provide initial inputs etc.
The calling App (call it App-A) does the following:
Intent intent = new Intent("com.myapp.dosomething");
intent.putExtra("com.myapp.value1", "1.25");
intent.putExtra("com.myapp.value2", "bob");
startActivity(intent);
My activity is started with the intent filter:
<intent-filter>
<action android:name="com.myapp.dosomething" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
Everything works fine if the user goes through the normal flow of my app. The user does stuff and then when I know the user is done I call finish() on my activity. Everything is dandy.
However, if part way through doing stuff in my app the user hits the home button instead of finishing the task we end up with a major problem. If they try and restart App-A from the launcher my app pops up instead. The user can never get back to App-A without force killing my app. Even worse, my app is specifically designed to not retain any data between launches and when re-launched in this way it also doesn't get any of the extra data originally passed in so my app has no way to know that this other app is still waiting on mine.
How do I set things up so that App-A doesn't sit there waiting on my app? It should be able to continue running regardless of what my app does. If my app crashes, or doesn't return a value I don't want the calling app to be hung forever.
Any ideas?
Thanks.
On your end: If your app starts up and the requisite data wasn't sent, the scenario you described probably just occured, so immediately finish and indicate an error (assuming your app was called with startActivityForResult, you can send a result code indicating error). You have no context for what was asked of you anymore, the app waiting on yours isn't getting its data anyway, and the user might as well be brought back to the app they were expecting.
On their end: The calling app should add the flag:
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
This flag clears the called app from the activity stack, so users arrive in the expected place next time the calling app is restarted.
Basically, you can do your best to handle this situation, but it's the calling app's responsibility to add this flag and handle this scenario appropriately.
After lots of messing about with this it really seems that the launch flags and the like are of no help what so ever. The only real solution was to track when my app was launched externally and make sure to always close finish when the app is suspended in this case.
By always finishing in onPause I make sure that the calling app always gets a response of some sort. In the case of an interrupted operation I simply pass back a result of 'canceled'.