9

I am struggling with the <data> element in the AndroidManifest.xml file to get my URI matching working. I want to match the following URIs:

but not

I got it mostly working with

<data android:scheme="http"
      android:host="example.com"
      android:pathPattern="/..*" />

<data android:pathPattern="/..*/" />

but it still matches http://example.com/something/else.

How can I exclude these?

Mahoni
  • 7,088
  • 17
  • 58
  • 115
  • The problem is the `*` which is a wildcard to "everything else after". Try removing it, and see if it works ! – Leonardo Jul 21 '14 at 23:51
  • @LeonardoFerrari Yes, but the wildcard is also necessary to match all types of characters between the two or one forward slash. – Mahoni Jul 22 '14 at 00:01
  • I'm sorry if this doesn't help, but here's a [regex that works for your situtation](http://regex101.com/r/rT5rZ5/1). I don't know if that helps because I don't know android. Hope it helps a little and good luck! – skamazin Jul 30 '14 at 14:43

3 Answers3

8

Unfortunately the wildcards that can be used for the pathPattern tag are very limited and what you want is currently impossible through pure xml.

This is because once you accept "/.*" everything gets accepted (that include slashes). And since we can't provide data tags that are NOT to be accepted the only way is to check the data inside of your activity. Here's how to accomplish what you are up to:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    Uri data = getIntent().getData();

    Log.d("URI", "Received data: " + data);
    String path = data.getPath();

    // Match only path "/*" with an optional "/" in the end.
    // * to skip forward, backward slashes and spaces
    Pattern pattern = Pattern.compile("^/[^\\\\/\\s]+/?$");
    Matcher matcher = pattern.matcher(path);
    if (!matcher.find()) {
        Log.e("URI", "Incorrect data received!");
        finish();
        return;
    }

    // After the check we can show the content and do normal stuff
    setContentView(R.layout.activity_main);

    // Do something when received path data is OK
}

Activity inside the manifest would look like this:

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

If you don't want your activity to check if the data is correct you will have to change your requirements.

Simas
  • 43,548
  • 10
  • 88
  • 116
  • 5
    The problem with this solution is that once your activity has received the Intent, if it doesn't do anything with it, other activities will not get a chance to receive it. – Pierre-Luc Paour Jul 30 '14 at 15:24
4

Unless you have very many possible variations of paths you want to catch, just declare all of them explicitly (using path and pathPrefix) to avoid too-broad patterns.

<data android:scheme="http" android:host="example.com" android:path="/something" />
<data android:scheme="http" android:host="example.com" android:pathPrefix="/foo" />
Pierre-Luc Paour
  • 1,725
  • 17
  • 21
-6
 <data android:scheme="http"
  android:host="example.com"
  android:pathPattern="\/[\w]+\/?$" />


 

Here you say there will be one slash \/ (since slash must be escaped) followed by 1 or more word character afterwards there could be one more slash (but this is optional) at the end of the string

Have a look at DEMO

Community
  • 1
  • 1
gaw
  • 1,960
  • 2
  • 14
  • 18
  • I don't think these regexp characters are legal here. Already the plus does not work. – Mahoni Jul 24 '14 at 09:56
  • Oh Manifest only accepts . * and escape \\ according to http://stackoverflow.com/questions/4762251/android-matching-a-url-pattern so it seems your task is not possible then – gaw Jul 24 '14 at 10:10