Android deep links not following path prefix

烈酒焚心 提交于 2019-12-18 15:01:09

问题


The closest I could find was this question here. but it doesnt quite cover the problem im having.

I have deep links in my app setup to use /app as the path prefix. The problem I'm having is that links like http://example.com/upgrade are also trying to open in my app even though it doesn't have /app anywhere in the url. I understand you cant exclude urls specified by the prefix, but isn't the whole point of path prefix to include only those urls?

basically I want links like these to deep link:

http://example.com/app/home
http://example.com/app/specials

but not links like these:

http://exaple.com/
http://example.com/login

and here is what I have in my manifest:

<data android:scheme="http"
    android:host="example.com"
    android:pathPrefix="/app"/>

Edit 1

also found this link but i dont have any empty prefixes, only ones with just a slash "/"

Edit 2

The url that was triggering it was http://example.com/upgrade.php?app=1&method=1&uid=1, I wasn't sure if app after the ? would also trigger it so I changed the prefix to /application but that also didn't work, its still triggering them.

Edit 3

here are the other deep link data tags in the manifest:

profile activity

<data android:scheme="myapp"
    android:host="profile"
    android:pathPrefix="/"/>

login/signup activity

<data android:scheme="myapp"
     android:host="login"
     android:pathPrefix="/signup"/>

main activity

<data android:scheme="myapp"
     android:host="main"
     android:pathPrefix="/"/>

<data android:scheme="http"
     android:host="test.example.com"
     android:pathPrefix="/app"/>

<data android:scheme="http"
     android:host="live.example.com"
     android:pathPrefix="/app"/>

Edit 4

This is getting more and more confusing, if I remove the data tag with myapp as the scheme from the activity (or if i remove the pathPrefix from everything with a prefix of "/") it no longer triggers the deep links from the web urls, even if they have /app in them.


回答1:


I figured it out, It seems like the data tags sort of bleed into one another, so the prefix of "/" on the data with scheme "example" was also applying to all of the schemes in the other data tags. I just had to use separate Intent filters for my custom scheme deep links and the url deep links like so:

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

        <!-- must start with http://test.example.com/app -->
        <!-- http://test.example.com/ won't work since prefix / is in a different intent-filter -->
        <data android:scheme="http"
            android:host="test.example.com"
            android:pathPrefix="/app"/>

        <!-- must start with http://test.example.com/app -->
        <data android:scheme="http"
            android:host="live.example.com"
            android:pathPrefix="/app"/>

    </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" />

        <!-- must start with example://main/ -->
        <!-- http://test.example.com/ won't work since http is in a different intent-filter -->
        <data android:scheme="example"
            android:host="main"
            android:pathPrefix="/"/>

    </intent-filter>
</activity>



回答2:


As explained here, your attributes get merged:

Although it's possible to include multiple <data> elements in the same filter, it's important that you create separate filters when your intention is to declare unique URLs (such as a specific combination of scheme and host), because multiple <data> elements in the same intent filter are actually merged together to account for all variations of their combined attributes.

Putting them into separate instances of <intent-filter> therefore fixes your problem.




回答3:


Running a few tests on my own I think you have created this problem yourself, before continuing to test any more deep links from your app go to

Settings -> Your App Name -> Launch by Default and select Clear defaults

Then navigate back to your app manifest and add the intent filter to your Activity for each url:

In your example you ask for

http://example.com/app/home
http://example.com/app/specials

I am going to assume you have an Activity that would launch each one of these for the URI given above.

for HomeActivity in manifest do:

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

        <!-- http://example.com/app/home -->
        <data android:scheme="http"
            android:host="example.com"
            android:pathPrefix="/app/home"/>

        <!-- https://example.com/app/home -->
        <data android:scheme="https"
            android:host="example.com"
            android:pathPrefix="/app/home"/>

        <!-- custom url scheme example://app/home -->
        <data android:scheme="example"
            android:host="app"
            android:pathPrefix="/home"/>
    </intent-filter>
</activity>

Test with adb shell am start -W -a android.intent.action.VIEW -d http://example.com/app/home and adb shell am start -W -a android.intent.action.VIEW -d example.com/app/home From your terminal

then for your SpecialsActivity

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

        <!-- http://example.com/app/specials -->
        <data android:scheme="http"
            android:host="example.com"
            android:pathPrefix="/app/specials"/>

        <!-- https://example.com/app/specials -->
        <data android:scheme="https"
            android:host="example.com"
            android:pathPrefix="/app/specials"/>

        <!-- custom url scheme example://app/specials -->
        <data android:scheme="example"
            android:host="app"
            android:pathPrefix="/specials"/>
    </intent-filter>
</activity>

Test with adb shell am start -W -a android.intent.action.VIEW -d http://example.com/app/specials and adb shell am start -W -a android.intent.action.VIEW -d example.com/app/specials From your terminal

this is pretty much how it works, if you set your app to handle a http://example.com/ url and select choose by default then, well its going to try to open http://example.com/{anything} using your app

So in short, when you specify your pathPrefix, make sure you include what you really want to intercept and don't choose your app by default if you test a link that shouldn't open your app, just adjust your pathPrefix so it won't be triggered by your app.

For example the URLS above won't open

http://example.com/app

because we haven't defined a <data /> tag to handle this.

UPDATE And to add straight from the docs when using \ or *:

Because '\' is used as an escape character when the string is read from XML (before it is parsed as a pattern), you will need to double-escape: For example, a literal '*' would be written as '\\*' and a literal '\' would be written as '\\\\'. This is basically the same as what you would need to write if constructing the string in Java code.

Good luck and happy coding!



来源:https://stackoverflow.com/questions/34276617/android-deep-links-not-following-path-prefix

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!