Deep-linking intent does not work
Asked Answered
P

13

78

I followed the insttructions on https://developer.android.com/training/app-indexing/deep-linking.html, but when I want to trigger the intent through adb with:

adb shell am start
           -W -a android.intent.action.BROWSEABLE
           -d "http://example.com/gizmos" com.myapp.android

I just get

Error: Activity not started, unable to resolve Intent { act=android.intent.action.VIEW dat=example://gizmos flg=0x10000000 pkg=com.myapp.android }

<activity
        android:name=".activities.DeepLinkActivity"
        android:label="@string/title_activity_deep_link">
        <meta-data
            android:name="android.app.searchable"
            android:resource="@xml/searchable" />

        <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="http"
                android:host="example.com"
                android:pathPrefix="/gizmos" />
        </intent-filter>
    </activity>

Have I made any obvious mistakes?

Pyrophyllite answered 17/7, 2014 at 16:22 Comment(8)
@MikeM. No, it is there.Pyrophyllite
@RichardLeMesurier Thanks for pointing out the question, but how is the answer even slightly related to my problem? ;-)Pyrophyllite
@Pyrophyllite ... What?!? No way is it related at all, I totally agree! I linked to the wrong question... I was scanning down the "Related" list on the right and must have had too many tabs open. Some of those posts have some good info in them to help you (but definitely NOT the one I linked to, which is probably the least useful of all of them). Sorry about that, very glad I didn't flag it.Lubow
android.intent.action.BROWSABLE not BROWSEABLEMennonite
Remove my apps package name from the command worked for me.Doersten
@Doersten it also worked when I removed the package name from the start command - could that become an issue? Why specify the package name?Lawson
@Lawson It has not been an issue for us. I did not look into why the command works differently with and without the package name.Doersten
Tutorial's adb command uses android.intent.action.VIEW action instead of BROWSABLEGassing
B
138

EDIT:

Ok first make sure that your package is reachable by adb:

adb shell am start -n com.example.simon.test/.activities.MainActivity

Then to accept multiple data tags you need different intent filters (that's the way it worked for me unlike all the other examples I've seen on the net). E.g.:

<intent-filter>
    ...
    <data android:scheme="http"
          android:host="example.com"/>
</intent-filter>
<intent-filter>
    ...
    <data android:scheme="http"
          android:host="example.com"
          android:pathPrefix="/gizmos"/>
</intent-filter>

NOTE that in the above example the pathPrefix starts with a forward slash !

I am not sure why Google's Docs are so misleading or maybe that was for some different version of adb, but the above changes worked perfectly for me. This helped: Source


This is how I made the Chrome browser route specific links to my app:

<activity
    android:name=".activities.DeepLinkActivity"
    android:label="@string/app_name">
    <!-- Accept chrome links -->
    <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="http"
              android:host="example.com"
            android:pathPrefix="/"/>
    </intent-filter>
    <!-- Accept adb data flag -->
    <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="http"
              android:host="example.com"/>
    </intent-filter>
</activity>

NOTE The 1st filter works on Google Chrome while the 2nd one works on the ADB.

NOTE2 The app choice menu won't be shown if the link is entered into the browser's address bar. It has to be a <a href="http://example.com"></a> link in side some page.

In my opinion everything here is rather blurry and really not how I expected it all to work. But that's how it works on my device.

Bagley answered 20/7, 2014 at 12:29 Comment(17)
Perfect, it's still missing the fact that you need to set android:export="true" (probably for non-launch activities?) and that for instance if your activity is not living in the root directory then the test command would be adb shell am start -n com.example.simon/.test.MainActivityPyrophyllite
Anyway, I am not sure if this is a conceptional problem, but why doesn't the MainActivity get now started when I enter this HTTP address into the Browser App?Pyrophyllite
@Pyrophyllite Nice catch. Exported tag allows components of other apps to be able to call it. Can you update your question with your current command and manifest please?Bagley
Yes, so basically I have only the http scheme as data for the intent filter left and when I enter http://example.com/gizmos into the Browser App or click on a link that directs there that I would be asked whether I want to open this site in my app, but maybe I am misunderstanding the deep-linking concept here.Pyrophyllite
@Pyrophyllite first of all your action is a category. Use -a android.intent.action.VIEW. For me calling activities in separate folders worked too. I'm looking into the browser's now. Afaik different browsers have different schemes set so that might be in the way.Bagley
Oh okay, I was thinking that BROWSABLE was for intent action start from the Browser or otherwise links that would start the browser, but okay. I would expect now that when I want to open a link in a mail program which points to http://example.com/gizmos would ask me, should it be started with Browser or my app.Pyrophyllite
Well, I'd like to say it works now, but it does not. I have not installed Chrome yet. I am mainly testing from within a mail with links inside Gmail. It just does not react to it and jumps to the Browser (Internet app) immediately. When I hold on the link it asks me what to do with the link (copy url, open in browser, share link).. so still no clue what is stopping this :-/Pyrophyllite
Mahoni, it works fine for me but requires DEFAULT category to be set on the filter. If the links are set to be always started with your browser it won't show you the app choice menu. Try going to settings->apps->all->browser(or what ever) and Clear defaults.Bagley
Perfect, at least I get the dialog now. Still not showing up the app, also working with multiple intent-filter and data to try to catch at least one case. Not sure what else might block it.Pyrophyllite
@Pyrophyllite I believe both DEFAULT and BROWSING categories are required, make sure you use them. Also please tell me your API and browser versions. Also are you using gmail app or just the browser?Bagley
Yes, so I am using three categories with VIEW, BROWSABLE and DEFAULT. API wise I am working with Android 4.2 and Android 4.4 (Browser version is 4.1.2). I am using Gmail for testing the opening links currently.Pyrophyllite
Waaaah, got it! Due to copy pasting I changed the tag element for VIEW from <action> to <category> got it now! Of course an intent-filter does not work without defining an <action> tag.Pyrophyllite
@Pyrophyllite just wanted to ask if you didn't set view to be a category :PBagley
Great example for showing that we need different intent filters! Also, the slash in the pathPrefix is important. Well done!Renick
+1 for "/" between package name and path to activity. The docs can be really misleading and non-complete.Fra
Perfect solution for the Manifest. but for the adb, this command works for me: adb shell am start -a android.intent.action.VIEW -d "example.com" com.exampleappPickering
How run this in chrome browser ?Furan
H
21

After some tests this is what worked for me:

    <activity android:name=".activities.MainActivity">
        <intent-filter android:label="@string/app_name">
            <action android:name="android.intent.action.VIEW" />
            <category android:name="android.intent.category.DEFAULT" />
            <category android:name="android.intent.category.BROWSABLE" />
            <data android:scheme="http"
                  android:host="www.example.com"
                  android:pathPrefix=""
                />
            <data android:scheme="myschema"
                  android:host="example"
                  android:pathPrefix=""
                />
        </intent-filter>
    </activity>

This works when clicking any link in the browser such as "http://www.example.com", "http://www.example.com/" or "http://www.example.com/whatever". The same with "myschema://example/whatever".

Also works with adb using this command (with any of those URLs):

adb shell am start -W -a android.intent.action.VIEW -d "http://www.example.com" com.example

Hope it helps to get you started.

When everything is working you will probably want to configure a different pathPrefix for different activities.

Harpy answered 3/9, 2014 at 17:9 Comment(7)
you need to separate myschema://example to another intent filter. according to developer.android.com/training/app-indexing/deep-linking.html - "Note: Intent filters may only contain a single data element for a URI pattern. Create separate intent filters to capture additional URI patterns."Psychometry
@Ferran Maylinch , thank you for your answer ,can we use any site in android:host="www.example.com" ?Uranian
@pic Sure, that URL was just an exampleHarpy
android:pathPrefix="" pathprefix cannot be emptySurvance
Testing with adb doesn't give the real production picture. E.g. I wanted to use myschema://example/whatever for opening an application from email, but GMAIL application doesn't recognize it as a link. Tried to send it as link (wrapped as link's href, using html for email), but Google transforms it as ordinary text. So, the only way I could launch an application and make it see as a link - using only android:scheme="https".Italianize
@Italianize I've got the same issue, did you solve that?Marti
I also have the same problem when attempting to use a custom scheme. Was there a solution?Sachsse
M
8

In my case, I was putting deep linking intent filter in MainActivity which is also main launcher. That caused the problem.

After I created another separate activity and put intent filter there, it solved the problem. Hope this can help others who are facing the same issue.

Mcclelland answered 16/9, 2016 at 15:47 Comment(2)
Yes, this is a good approach, and I keep searching for a solution.Vollmer
This answer, worked for me on Android 12, without this it was working below Android 12. Any idea how to make it work with Laucher activity.Arthropod
I
8

In my case, I am using an emulator and not an actual usb connected device, and hence I had to change -d to -e, like so :

adb shell am start -W -a android.intent.action.VIEW -e "http://www.example.com" com.example

Note the -e before the deep link.

Inulin answered 25/8, 2020 at 10:7 Comment(0)
G
3

First, read @user3249477's answer on this page.

I just wanted to add that instead of what he wrote, you can condense it by using pathPattern:

<activity
    android:name=".activities.DeepLinkActivity"
    android:label="@string/app_name">
    <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="http"
              android:host="example.com"
            android:pathPattern=".*"/>
    </intent-filter>
</activity>

The ".*" matches both the empty string and "/", so both cases are covered. If you end up trying to handle multiple scheme's and host's this becomes especially important, so you don't have to spam a powerset of {http, https} X {"", "/"} X {"foo", "bar", etc.}

Grahamgrahame answered 22/1, 2015 at 3:1 Comment(1)
Can you use ".*" data for host as well?Ehudd
S
3

Make sure your URL is in this format (with the cap letters replaced by your own):

android-app://COM.YOUR.APP.IDENTIFIER/SCHEME/HOST?somegetparams

The adb tool does not require this format. With the above you can now put it in an src, or an href, like so:

<iframe src="android-app://COM.YOUR.APP.IDENTIFIER/SCHEME/HOST?somegetparams"> </iframe> 
<a href="android-app://COM.YOUR.APP.IDENTIFIER/SCHEME/HOST?somegetparams">LINK</a>
Shakeup answered 27/10, 2015 at 2:30 Comment(3)
this is worked for me, thanks mate.. you saved my day ;)Semple
by the way, its only on android.. how about ios..?Semple
@IamByeBlogs iOS you got anything similar to this?Amaliaamalie
F
2

In my case I have a port 8075 in the URL I removed it and it worked

Fry answered 8/8, 2017 at 14:44 Comment(0)
N
2

./adb shell am start -n packagename/.splash.SplashActivity -d "schemeName://content"

Nyhagen answered 16/4, 2018 at 9:44 Comment(0)
M
1

Thanks Simas for your response i would like to add some clarification:

  • after testing your activity with this command:

    adb shell am start -n com.example.simon.test/.activities.MainActivity

  • You will need to test your deeplinks ,after adding the intent filter to your AndroidManifest.xml file (lines are below):

    ... ...

so this is the adb command with which you can test :

adb shell am start -W -a android.intent.action.VIEW -d "http://example.com/gizmos" com.example.packageid

and

adb shell am start -W -a android.intent.action.VIEW -d "http://example.com" com.example.pakageid
Meanly answered 27/10, 2016 at 15:46 Comment(0)
T
1

Use adb shell am start -W -a android.intent.action.VIEW -d "http://example.com/gizmos" com.myapp.android

it will work.

Towns answered 3/8, 2017 at 6:23 Comment(0)
H
0

All of these answers and my own solutions are missing: android:autoVerify="true"! Once I added this into the intent-filter, deeplinks finally started working. So the intent filter should start from:

            <intent-filter android:autoVerify="true">
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

and then your specific scheme, host and pathPrefix (if needed).

Here is the detailed guide for this!

Hemolysis answered 23/4, 2024 at 17:19 Comment(0)
B
-1

if you have not permission issue , it is probably related to API level

Bowie answered 2/5, 2018 at 19:17 Comment(0)
A
-2

Use this intent filter instead,

<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />

<!-- Accepts URIs that begin with "example://gizmos” -->
<data
   android:host="gizmos"
   android:scheme="example" />
</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" />

<!-- Accepts URIs that begin with "http://www.example.com/gizmos” -->
<data 
    android:host="www.example.com"
    android:pathPrefix="gizmos"
    android:scheme="http" />
</intent-filter>
Auer answered 15/3, 2016 at 17:32 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.