Match “/app” and not “/appinst” with android:pathP

2019-07-21 03:47发布

问题:

I'm trying to make an intent that filters some specific urls. The urls that I'm trying to catch are:

  • http://host.com/app
  • http://host.com/app/
  • http://host.com/app?...
  • http://host.com/app/?...

That can be done by

<intent-filter>
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.BROWSABLE" />
    <category android:name="android.intent.category.DEFAULT" />
    <data android:scheme="http" android:host="host.com"
        android:pathPrefix="/app" android:pathPattern="[app.*]"/>
</intent-filter>

My problem comes because I already have a url that is:

  • http://host.com/appinstall

And I don't want to try to open the app in that url.

I have already tried

  • android:pathPattern="[app]
  • android:pathPattern="[app.*]
  • android:pathPattern="[app?.*]
  • android:pathPattern="[app\?.*]
  • android:pathPattern="[app\\?.*]
  • android:pathPattern="[app|app?.*]
  • android:pathPattern="[app|app\?.*]
  • android:pathPattern="[app|app\\?.*]
  • android:pathPattern="[nativeapp\z|nativeapp\?.*|nativeapp/.*]"
  • android:pathPattern="[nativeapp\\z|nativeapp\\?.*|nativeapp/.*]"

and not one of them worked. Even [app\\?.*] opened /appinstall.

Note: before someone asks. I have the /appinstall controller because the app that I'm working on started being and iPhone app and the appInstall url has a lot of cases to treat the redirection to the app store.

回答1:

You need to use android:path instead of android:pathPrefix or android:pathPattern since this will match a path of /app exactly and /appinstall will be ignored.

<!-- Matches "http://host.com/app" exactly, note that querystring, fragment
    identifiers and the trailing slash are not considered part of the path and 
    are therefore ignored so URLs that will match:
       http://host.com/app
       http://host.com/app/
       http://host.com/app?some=value
       http://host.com/app/?some=value
       http://host.com/app#fragmentIdentifier
       http://host.com/app/#fragmentIdentifier
       http://host.com/app?some=value#fragmentIdentifier
       http://host.com/app/?some=value#fragmentIdentifier
    URLs that will NOT match
       http://host.com/app/index.htm
       http://host.com/appinstall
       http://host.com/appinstall/
       http://host.com/app/subdirectory
       http://host.com/app/subdirectory/
       http://host.com/apple.htm
 -->
<data android:scheme="http" android:host="host.com" android:path="/app" />

If you want to also match the root of the website then you'll need to add an additional <data> element:

<data android:scheme="http" android:host="host.com" android:path="/" />


回答2:

android:pathPattern is very rudimentary and isn't really a reg-ex, it only allows operators "." and "*".

You'll have to be very clever in order to achieve your goal. One way might be...

<!-- Matches "http://host.com/app" exactly, URLs that will match:
       http://host.com/app
       http://host.com/app/
 -->
<data android:scheme="http" android:host="host.com" android:path="/" />

<!-- Matches URLs prefixed with "http://host.com/app/"
       http://host.com/app/
       http://host.com/app/?query=value
       http://host.com/app/somepage.htm
 -->
<data android:scheme="http" android:host="host.com" android:pathPrefix="/app/" />

<!-- Matches URLs prefixed with "http://host.com/app?"
       http://host.com/app?query=value
 -->
<data android:scheme="http" android:host="host.com" android:pathPrefix="/app?" />

EDIT:

Please ignore the above, I have discovered that this is incorrect because the "path" you're able to match against DOES NOT include the querystring or fragment identifier parts or the trailing slash of the URL. I'll provide another answer in a sec.