Android: Understanding Intent-Filters

2019-01-30 08:38发布

问题:

I would like to create an Intent-Filter, so that certain links will trigger the start of my application (see this stackoverflow-thread for example: How to register some URL namespace (myapp://app.start/) for accessing your program by calling a URL in browser in Android OS? )

While trying, I figured out, that I dont quite understand how Intents and Intent-Filters (defined in the Manifest.xml) actually work. What is the difference between the following:

<action android:name="android.intent.action.VIEW" />
<action android:name="android.intent.action.MAIN" />

or the following:

<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.MAIN" />

And what is actually the difference between category and action Intent-Filters. I read this page http://developer.android.com/reference/android/content/Intent.html but I still missing a basic understanding.

回答1:

Instead of looking at it from your app's point of view, flip it around and look at it from the Intent side.

When an Intent is created, the creator has no idea what apps are on the system to handle that Intent. But the creator does know what it wants to do (e.g., an app might want to let the user pick out a contact from somewhere on the device), and needs to reach out to other apps on the system to ask for what's desired.

To do this, Intents have several pieces of information attached to them. Among them are actions and categories.

The actions define in a general way the action the Intent wants to do, like VIEW a contact, PICK an image from the Gallery, etc.

The category is an additional piece of information that gives the Intent another way to differentiate itself. For example, when a link in the browser is clicked, the Intent that is created has the BROWSABLE category attached to it.

So, when the OS resolves the Intent, it will look for registered Activities or BroadcastReceivers that have an intent filter that includes all of pieces of information. If the Intent specifies the PICK action, Activities that do not have an intent-filter with the PICK action will be discarded from the list of candidates to handle the Intent.

In this way, the combined set of action, categories, type, and (possibly) scheme associated with an Intent serve to pinpoint the set of Activities that can handle the Intent. When you set up your intent-filter in your manifest, you are telling the OS which class of Intents you can handle.



回答2:

I had to examine the code of android.content.IntentFilter.matchCategories(Set<String> categories) to understand the matching of categories:

  1. Successful match, if your IntentFilter has categories and the Intent doesn't provide Categories
  2. Successful match, if your IntentFilter has all categories of the Intent. The filter also can have additional categories.
  3. No match, if your IntentFilter has no categories and the Intent has categories
  4. No match, if your IntentFilter has not the categories the Intent has

Especially #1 and #3 aren't obvious.