What are Intent Filters exactly? - android

I've read lots of articles about intent filters and I really can't understand exactly what they do?
so please if anybody can explain to me with a clear example what is the role of intent filters exactly ?
thanks

I think it's well documented here. Summarizing, when (e.g.) you pass an intent to Context.startActivity, or Context.startService, or broadcast it with Context.sendBroadcast, etc, what activity or service (or, what set of broadcast receivers) is the intent delivered to?
Answer: if the intent is "explicit", i.e., it has the component name field set, then it's delivered to the target component it designates -- this typically happens in communication within an application.
Otherwise ("implicit" intent, as is typical for communication between applications), Android must determine the best activity or service (or set of receivers) on its own. How does Android do that? That's where filters come in, and I quote:
It does so by comparing the contents
of the Intent object to intent
filters, structures associated with
components that can potentially
receive intents. Filters advertise the
capabilities of a component and
delimit the intents it can handle.
They open the component to the
possibility of receiving implicit
intents of the advertised type. If a
component does not have any intent
filters, it can receive only explicit
intents. A component with filters can
receive both explicit and implicit
intents.
The web page in question continues with many details and, at the end, a complete, simple example, and I think it would be redundant to copy and paste them here.

Simply put, Intent filters are a way of telling the OS how to launch/communicate with the different activities/services/broadcast receivers in your app. So for example, if you want links that start with http://www.mycompany.com to lead people into your app, an intent filter is the way to accomplish that. Once its setup, anytime someone clicks on a link that starts with that (in any app) the user will be presented with the option to use your app to view that page. You've probably seen this with youtube urls. Likewise, if you want the 'share' link commonly seen in many apps to list your app, would use an intent filter to do that.
hope this helps...

An intent filter lets the system know what data or service requests a component can handle. A component might be an activity, service or broadcast receiver.
If you are writing an image viewer, you would add an intent filter (or several) to the manifest describing the images you can handle. If you are writing a file browser, you might package up the details of an image file in an intent, and the system would sift through intent filters until it found a best match to handle that image. The same goes for any type of data or service that might be passed from one component to the next.

Intent Filters is a way of telling OS that let me handle/provide these kind of Activities/Services
By adding given filter to Manifest tells OS that i can also handle Sms service and whenever you send sms it will show in a list or you can also explicitly use this as your sms service.
<intent-filter>
<action android:name="android.intent.action.SENDTO" />
<action android:name="com.example.code.SMS_INTENT" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="smsto" />
</intent-filter>
And to explicitly using this service call it like ...
Intent intent = new Intent("com.example.code.SMS_INTENT", Uri.parse(uri));
intent.putExtra("from", "code");
startActivity(intent);

IntentFilters are used to declare a pattern of Intent attributes that the declaring component will respond to. You can specify with an IntentFilter that a given Activity, Service or BroadcastReceiver will respond to a combination of action, data mime type, scheme, path, etc. For example if you register an Activity with IntentFilter for ACTION_SEND with data type "text/plain", your Activity will be called each time the users wants to send some text.

intentFilters advertise the capabilities of a component and delimit
the intents that can handle. an IntentFilter that a given Activity,
Service or BroadcastReceiver will respond to a combination of action,
data mime type, scheme, path, etc.
The intent by comparing the intent to intent filters based on three
aspects:
1:- The intent action 2:- The intent data (both URI and data type) 3:- The intent
category
action : Declares the intent action accepted, in the name
attribute. The value must be the literal string value of an action,
not the class constant.
data : Declares the type of data accepted, using one or more
attributes that specify various aspects of the data URI (scheme, host,
port, path, etc.) and MIME type.
category : Declares the intent category accepted, in the name
attribute. The value must be the literal string value of an action,
not the class constant.
For example, This activity handles "SEND" actions with text data.
<intent-filter>
<action android:name="android.intent.action.SEND"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="text/plain"/>
</intent-filter>

Intent filter tells the android system for which intent or event the android components(activity,service ,broadcast receiver) should listen.

Related

Intent without action cannot pass intent filter test. Why?

Refer to the documentation on IntentFilters:
To pass this test, the action specified in the Intent object must match one of the actions listed in the filter. If the object or the filter does not specify an action, the results are as follows:
If the filter fails to list any actions, there is nothing for an intent to match, so all intents fail the test. No intents can get through the filter.
On the other hand, an Intent object that doesn't specify an action automatically passes the test — as long as the filter contains at least one action.
In my code,
Intent intent = new Intent();
startActivity(intent);
<activity
android:name=".MainActivity2"
android:label="#string/title_activity_main_activity2" >
<intent-filter>
<action android:name="fdsfds.hihi" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
Why my intent cannot launch .MainActivity2 ?
This is probably too late for you to get your answer. I landed here because I had exactly the same doubt as you. I think you have made the same mistak as I did. I confused the intent object with intent filter. But on a careful reading of the documentation my doubt was resolved.
So, if the intent-object (the intent objected that you created) doesn't specify any action but your intent-filter (in the manifest file) has at least one action listed, your intent will pass the action test. There is no gurantee though that it'll pass the rest of the tests for intent matching.
You haven't listed any action in the filter and hence all the action tests would fail (and by extention the intent matching will fail).
Intent intent = new Intent();
intent.setAction("fdsfds.hihi");
startActivity(intent);
Even though one year is passed I'll answer.
First, I agree with you, sometimes the Android doc is inconsistent, it leaves some doubts.
However in this case the documentation is right:
if an Intent does not specify an action, it will pass the test (as long as the filter contains at least one action).
What the documentation doesn't say is that if the action isn't defined then at least the data field (or mime field) must be defined.
In conclusion there can not be an intent without neither an action or a data.
As #Amrut Bidri said, you can't ride a bike without fuel.

How to "release" intent in Android?

I have two Activities in my Android app that deal with NFC. One has a declared IntentFilter in the AndroidManifest.xml, while the other just accepts NFC actions while it is active using a PendingIntent and onNewIntent();. However, sometimes when in the latter activity I actually want to pass the NFC action on the the former. How do I "release" the Intent to a different activity without losing any of the NFC information within?
Use startActivity(Intent intent) but instead of the Intent being created using the specific MyActivity.class form (an explicit Intent), add the action/category that the first Activity is set to react to in its manifest <intent-filter> section (an implicit Intent).

What is the different between Explicit and implicit activity call in android?

What is the difference between explicit and implicit activity call in android? If you explain the answer with a simple example will be good.
For example:
implicit activity call
In intent filter you create action for you activity, so other app can call your activity via this action as following:
<activity android:name=".BrowserActivitiy" 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"/>
</intent-filter>
</activity>
And the other way to call implicit Intent is below:
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.example.com"));
startActivity(intent);
Explicit activity call
You make a call that indicate exactly which activity class:
Intent intent = new Intent(this, ActivityABC.class);
intent.putExtra("Value", "This value for ActivityABC");
startActivity(intent);
Hope this help you understand more about Explicit and implicit activity call in android.
You can get more detail about Android Intent here
Explicit Intents are used to call a specific component. When you know which component you want to launch and you do not want to give the user free control over which component to use.For example, you have an application that has 2 activities. Activity A and activity B. You want to launch activity B from activity A. In this case you define an explicit intent targeting activityB and then use it to directly call it.
Implicit Intents are used when you have an idea of what you want to do, but you do not know which component should be launched. Or if you want to give the user an option to choose between a list of components to use. If these Intents are send to the Android system it searches for all components which are registered for the specific action and the data type. If only one component is found, Android starts the component directly. For example, you have an application that uses the camera to take photos. One of the features of your application is that you give the user the possibility to send the photos he has taken. You do not know what kind of application the user has that can send photos, and you also want to give the user an option to choose which external application to use if he has more than one. In this case you would not use an explicit intent. Instead you should use an implicit intent that has its action set to ACTION_SEND and its data extra set to the URI of the photo.
An explicit intent is always delivered to its target, no matter what it contains; the filter is not consulted. But an implicit intent is delivered to a component only if it can pass through one of the component's filters
Every time I get confused among these in either interview. So, I have summarised it like this, may it help someone to keep this difference in mind.
Summary:
In Implicit Intents, the user implicitly tells the system WHAT should be done, without specifying who should do.
In Explicit Intents, the user explicitly tells the system WHOM to be triggered for whatever the work is.
See Intent Resolution here
http://developer.android.com/guide/topics/intents/intents-filters.html
Explicit intents (activities) refer to a specific class, and in general, are only available to your packages. Implicit intents refer to intent filters where apps publicly announce that they can handle certain types of data or can provide specific services, e.g. send an email. With implicit intents, the users chooses which activity (typically a package) to use to handle the intent or if a default handler is set, it is launched.
When to use which?
Explicit intent: When you know which component can handle your request. So you explicitly mention that component name in the intent.
Intent i = new Intent(context,DetailActivity.class); // DetailActivity.class is the component name
startActivity(i);
Implicit intent: When you don't know which application can handle your request then you mention the action in intent and let the OS decide which application/s is/are suitable for your task.
Example: Play music
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setData(file);
startActivity(intent);
How OS decides?
When there is implicit call with an intent then OS takes out the action and then it matches with all the intent-filters of all the registered activities of all application using PackageManager and then populates the result as a list. It is called intent resolution
So there is a possibility that no application is available in your device which can handle your request. In that case, you will get NullPointer Exception.
So a safer way to call implicit intent would be this
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(file);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}
There are two types of intents:
Explicit Intent:
While creating an Intent object when we explicitly specify and pass on the target component name directly in the intent, it’s an explicit intent.
Implicit Intent:
In this case we delegate the task of evaluating the registered components (registration is usually done using intent filters that we’ll cover later) to Android based on the intent data and the intended action (like send an email, capture a photo, pin location on a map, etc.) that we pass. So Android will automatically fire up the component from the same app or some other app that can handle the intent message/job. The idea in this case is that, let’s say we have to pin a location on a map, for that we don’t have to code our own activity to handle that. Instead just pass on the location data to an app like Google maps that can do the job on our app’s behalf.
source : http://codetheory.in/android-intents/
Implicit intent doesn't specify the component. Intent provides the information of a component
Intent intent=new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.google.com"));
startActivity(intent);
whereas,
Explicit intent specify the component. The intent provides information about the class.
Intent i = new Intent(this, ClassB.class);
startActivity(i);

interrupting link to my app

I have a problem. I'm using the below code to interrupt links to my app as
<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="twitter.com"/>
<data android:scheme="http" android:host="facebook.com"/>
</intent-filter>
But the problem is that I need to set data scheme and host at runtime i.e. I can add or delete the host at runtime. How to set the value of data scheme and host at runtime? I am using below code but it is not working
IntentFilter filter = new IntentFilter();
filter.addAction("android.intent.action.VIEW");
filter.addCategory("android.intent.category.DEFAULT");
filter.addCategory("android.intent.category.BROWSABLE");
filter.addDataScheme("http");
filter.addDataAuthority("www.facebook.com", null);
RecieveBroadcaster receiver = new RecieveBroadcaster();
registerReceiver(receiver, filter);
Strictly speaking, the string corresponding to ACTION_VIEW is an activity action by convention; the fact that you place it into the intent-filter element of an activity in your manifest, makes it an activity action! The system listens for these on your application's behalf, which is basically why you don't (can't) listen for them yourself. The Context.startActivity() method generates these Intents.
The rules of intent resolution actually determine whether a particular Intent matches any IntentFilters. For activity intents, there may be multiple matches, and that usually displays the "Chooser" interface, so the user can select a target.
There are three Intent "streams" that never cross: startActivity(), sendBroadcast() and startService(). These are all initiated via methods in Context and each has a specific target Activity, BroadcastReceiver and Service respectively.
It is a simple matter to set up a BroadcastReceiver (not ReceiveBroadcaster did you even try that code?) to get the events you are interested in, and then use Context.startActivity() with the Intent you want. You can even use a custom action, so you know it was triggered by the receiver, and not the user.
The only question is: is there a broadcast event you can arrange to receive? There may be a system event you can register for, or you may be able to generate a custom event yourself, via Context.sendBroadcast().
Remember you can inspect the incoming Intent your activity was started with, and "forward" the same or a modified Intent if it doesn't exactly match what you are looking for. As you correctly determined, you cannot dynamically alter an activity's set of IntentFilters, so you will have to inspect the host of every request.
Remember you can also register receivers in your manifest as well, and have that implementation called automatically by the system.

Android: Understanding Intent-Filters

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.
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.
I had to examine the code of android.content.IntentFilter.matchCategories(Set<String> categories) to understand the matching of categories:
Successful match, if your IntentFilter has categories and the Intent doesn't provide Categories
Successful match, if your IntentFilter has all categories of the Intent. The filter also can have additional categories.
No match, if your IntentFilter has no categories and the Intent has categories
No match, if your IntentFilter has not the categories the Intent has
Especially #1 and #3 aren't obvious.

Categories

Resources