Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android deep link does not work if the app is opened by deep link already

Deep link does not work if the app is opened by deep link already.

However, if I open the app not by triggering a deeplink, like clicking the app icon to open the app. Then triggering deeplink afterward would always work.


Here come the details:

So I have my activity set up like this in AndroidManifest, namely LaunchActivity.

<activity     android:name="some.package.name.LaunchActivity"     android:screenOrientation="portrait"     android:theme="@style/Theme.SomeTheme">     <intent-filter>         <action android:name="android.intent.action.MAIN" />         <category android:name="android.intent.category.LAUNCHER" />     </intent-filter>     <intent-filter>         <action android:name="android.intent.action.VIEW" />         <category android:name="android.intent.category.DEFAULT" />         <category android:name="android.intent.category.BROWSABLE" />         <data android:scheme="dlscheme" android:host="dlhost" />     </intent-filter> </activity> 

And in LaunchActivity, I would print a log in onCreate() to indicate that it have been there.

I used

adb shell am start -W -a android.intent.action.VIEW -d "dlscheme://dlhost/param" some.package.name 

to test the deep link.

With the app killed, I used the above command. It can open the app and route to the correct activity, no problem. And have the following log.

adb shell am start -W -a android.intent.action.VIEW -d "dlscheme://dlhost/param" some.package.name Starting: Intent { act=android.intent.action.VIEW dat=dlscheme://dlhost/param pkg=some.package.name } Status: ok Activity: some.package.name/.activity.LaunchActivity ThisTime: 898 TotalTime: 898 WaitTime: 919 Complete 

However, if I enter the same command again, without killing the app. It would only open the app, but it will not open the correct activity, and produce the following log.

adb shell am start -W -a android.intent.action.VIEW -d "dlscheme://dlhost/param" some.package.name Starting: Intent { act=android.intent.action.VIEW dat=dlscheme://dlhost/param pkg=some.package.name } Warning: Activity not started, its current task has been brought to the front Status: ok Activity: some.package.name/.activity.LaunchActivity ThisTime: 0 TotalTime: 0 WaitTime: 6 Complete 

with this extra line

Warning: Activity not started, its current task has been brought to the front 

I actually also tried this with a website, using this chrome intent:

intent://dlhost/param#Intent;scheme=dlscheme;package=some.package.name;end 

and it would behave the same.

like image 407
Shing Avatar asked Mar 11 '16 02:03

Shing


Video Answer


2 Answers

In the manifest file of your project, you need to add the following to your main activity.

android:launchMode="singleTask" 

So, in the manifest, you would have something similar to the below:

<activity android:name="some.package.name.LaunchActivity"        android:launchMode="singleTask"       android:screenOrientation="portrait"       android:theme="@style/Theme.SomeTheme">           <intent-filter>               <action android:name="android.intent.action.MAIN" />               <category android:name="android.intent.category.LAUNCHER" />           </intent-filter>           <intent-filter>               <action android:name="android.intent.action.VIEW" />               <category android:name="android.intent.category.DEFAULT" />               <category android:name="android.intent.category.BROWSABLE" />               <data android:scheme="dlscheme" android:host="dlhost" />           </intent-filter>  </activity> 

Basically what this does is create a new task and a new instance will be pushed to the task as the root one. However, if any activity instance exists in any tasks, the system routes the intent to that activity instance through the onNewIntent() method call. In this mode, activity instances can be pushed to the same task. And if the user clicks the BACK key from the current activity, the system will return the user to the previous activity.

On the other hand, in singleTop if an instance of activity already exists at the top of the current task and system routes intent to this activity, no new instance will be created because it will fire off an onNewIntent() method instead of creating a new object.

More information can be found here.

Hope this helps :)

like image 185
Michele La Ferla Avatar answered Sep 19 '22 23:09

Michele La Ferla


In the manifest file of your project, you need to add the follow to your main activity.

android:launchMode="singleTask" 

And handle the deeplink inside onNewIntent()

@Override protected void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);     setContentView(R.layout.activity_recipe);     onNewIntent(getIntent()); }  protected void onNewIntent(Intent intent) {     String action = intent.getAction();     String data = intent.getDataString();     if (Intent.ACTION_VIEW.equals(action) && data != null) {         String recipeId = data.substring(data.lastIndexOf("/") + 1);         Uri contentUri = RecipeContentProvider.CONTENT_URI.buildUpon()                 .appendPath(recipeId).build();         showRecipe(contentUri);     } } 
like image 35
resource8218 Avatar answered Sep 16 '22 23:09

resource8218