I have this <intent-filter>
that every time certain link is pressed it opens my app but the problem is it opens a new instance of my app. Is there anyway to trigger onResume() and just resume my app without losing its state or the activities stack?
This is the intent filter:
<intent-filter>
<data android:scheme="http" />
<data android:scheme="https" />
<data android:host="example.com" />
<data android:pathPattern="/.*" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
Thanks to user David Wasser answer below I found answer:
So I created EntryActivity which is launched on top of gmail/inbox app:
public class EntryActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.entry_activity);
Uri uriParams = getIntent().getData();
Log.e("EntryActivity", uriParams.getHost() );
Log.e("EntryActivity", uriParams.getQueryParameter("uid") + " " + uriParams.getQueryParameter("type") + " " + uriParams.getQueryParameter("token") );
Intent startCategory = new Intent(this, GotEmailActivity.class);
startCategory.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(startCategory);
this.finish();
}
}
Then when my app is opened at GotEmailActivity I send email to user with link to open app and GotEmailActivity has attribute android:launchMode="singleTop"
in AndroidManifest so only 1 instance of it is opened:
<!--
Important: notice android:launchMode="singleTop"
which seeks if an instance of this activity is already opened and
resumes already opened instance, if not it opens new instance.
-->
<activity
android:name=".presenters.register.email.GotEmailActivity"
android:label="@string/title_activity_got_email"
android:launchMode="singleTop"
android:theme="@android:style/Theme.Translucent.NoTitleBar" >
Now what is happening is that EntryActivity is opened ontop of Gmail app but it closes inmediatle but first launches GotEmailActivity which is already opened so attribute launchMode Singletop prevents a new instance of such activity.
This behavior also occurs if an app already in multi-window mode gets resized. Your activity can handle the configuration change itself, or it can allow the system to destroy the activity and recreate it with the new dimensions.
In some cases, it might be helpful to maintain multiple back stacks at the same time, with the user moving back and forth between them. For example, if your app includes bottom navigation or a navigation drawer, multiple back stack support allows your users to switch freely between flows in your app without losing their place in any of them.
Otherwise the system Back behavior may be jarring to the user. If an app is in the background and the system needs to free up additional memory for a foreground app, the background app can be killed by the system to free up more memory.
You should create another Activity
that you use as an entry point to your application when responding to that <intent-filter>
. Something like this:
What you need is just a simple Activity that does nothing. Here is an example:
public class EntryActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Check to see if this Activity is the root activity
if (isTaskRoot()) {
// This Activity is the only Activity, so
// the app wasn't running. So start the app from the
// beginning (redirect to MainActivity)
Intent mainIntent = getIntent(); // Copy the Intent used to launch me
// Launch the real root Activity (launch Intent)
mainIntent.setClass(this, MainActivity.class);
// I'm done now, so finish()
startActivity(mainIntent);
finish();
} else {
// App was already running, so just finish, which will drop the user
// in to the activity that was at the top of the task stack
finish();
}
}
}
Put your <intent-filter>
on this activity, instead of your "launcher" Activity. Make sure that in the manifest the task affinity of this activity is the same as the task affinity of the other activities in your application (by default it is, if you haven't explicitly set android:taskAffinity).
When the <intent-filter>
gets triggered, if your application is running, then the EntryActivity
will be started on top of the topmost activity in your application's task and that task will be brought to the foreground. When the EntryActivity
finishes, it will simply return the user to the topmost activity in your application (ie: wherever the user left it when it went into the background).
If your app was not running, the EntryActivity
recognizes this and starts your app from the beginning, passing it the Intent
containing the ACTION and DATA that triggered the <intent-filter>
.
Should work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With