{"id":1913,"date":"2014-11-24T13:57:55","date_gmt":"2014-11-24T08:27:55","guid":{"rendered":"http:\/\/codetheory.in\/?p=1913"},"modified":"2014-12-05T15:02:38","modified_gmt":"2014-12-05T09:32:38","slug":"android-intent-filters","status":"publish","type":"post","link":"https:\/\/codetheory.in\/android-intent-filters\/","title":{"rendered":"Understanding Android Intent Filters (Receiving Implicit Intents)"},"content":{"rendered":"
Intents<\/a> sends signals to the Android system telling it that some action needs to be performed by another component (activity, services, broadcast receivers) in the same app or a different app. The system starts resolving which component in which app is responsible to handle this event that just got triggered. Let’s see a simple example of an implicit intent that opens a webpage URL in the browser.<\/p>\n <\/p>\n Pretty simple piece of code where we create an intent with the Note:<\/strong> I highly recommend you to read my article on Android intents<\/a> to completely understand the concept of Intents.<\/p>\n Now imagine if we wanted to advertise<\/em> that our<\/strong> app can also handle such an implicit intent where we take an HTTP URL and do some useful jazz with it. In such a case Android will give two<\/strong> choices to the user – single browser installed (chrome) and our app – from which he can make a selection. To register a component of our app that can receive an implicit intent for a specific action and data, we can declare an Note:<\/strong> An explicit intent has its target specified (while creation) hence there’s no scene of making choices from a list or some such thing. Hence intent filters for them doesn’t make sense inherently.<\/p>\n Let’s see an example now where we’ll register an Activity component in our app as a browser (based on the aforementioned description) in our Make sure that both the sending and receiving activities have requested permission for the type of action ( Now when the intent code that you see above is fired, the user will be given multiple choices among which one of them will be our own app that’ll trigger Similar to this, from my previous article<\/a> on Android intents, we could have an intent filter for the “share” example too ( Given that now we understand the basics of intent filters<\/a> and have seen a few examples, let’s start understanding a bit more about the subelements.<\/p>\n Each activity in the manifest can contain multiple intent filters blocks. Each intent filter specifies the type of intents it’ll accept based on the Let’s understand what each subelement is for:<\/p>\n Action which is the most reasonable action to perform and Data that contains the basic information that drives our action were pretty easy to comprehend but Category is something that might need a bit of an explanation. Using the category attribute, we give\/mention additional information about the action to execute (that’ll be matched for intent resolution). Examples:<\/p>\n You can go through the entire list here<\/a>.<\/p>\n Moving on, an intent filter could have multiple instances of the action, category and data subelements. For example look at this:<\/p>\n Multiple action tags that says the intent action can be It is very important to remember that the implicit intent is tested against a filter by comparing it’s data with each element (action, data, category). When all those three tests are passed the intent is delivered to that particular component. If a match with any of them fails then the delivery won’t happen. Also if you fail to mention any of them in the manifest then also the match won’t happen.<\/p>\n Although remember you can have multiple intent filters like this:<\/p>\n So in this case if the implicit intent fails to conform to the first intent-filter, then the check will be done on the second one and if that matches then woohoo! delivery to that app component (activity in this case) will happen.<\/p>\n Although users could get into There are certain additional rules of the entire Intent Resolution process that are listed in the documentation here<\/a> which I highly recommend you to go through (should be fairly quick).<\/p>\n So in the previous article<\/a>, we’d learnt how to use Android Intents to trigger actions in your own apps (explicit) or some other third party app (implicit where Android resolves matching intents behind the scenes). In this tutorial we went through the concept of intent filters that’ll help us make our application components ready to be triggered by other apps, when they need to.<\/p>\n","protected":false},"excerpt":{"rendered":" Intents sends signals to the Android system telling it that some action needs to be performed by another component (activity, services, broadcast receivers) in the same app or a different app. The system starts resolving which component in which app is responsible to handle this event that just got triggered. Let’s see a simple example … Continue reading “Understanding Android Intent Filters (Receiving Implicit Intents)”<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[121],"tags":[105,89],"_links":{"self":[{"href":"https:\/\/codetheory.in\/wp-json\/wp\/v2\/posts\/1913"}],"collection":[{"href":"https:\/\/codetheory.in\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/codetheory.in\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/codetheory.in\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/codetheory.in\/wp-json\/wp\/v2\/comments?post=1913"}],"version-history":[{"count":7,"href":"https:\/\/codetheory.in\/wp-json\/wp\/v2\/posts\/1913\/revisions"}],"predecessor-version":[{"id":1933,"href":"https:\/\/codetheory.in\/wp-json\/wp\/v2\/posts\/1913\/revisions\/1933"}],"wp:attachment":[{"href":"https:\/\/codetheory.in\/wp-json\/wp\/v2\/media?parent=1913"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/codetheory.in\/wp-json\/wp\/v2\/categories?post=1913"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/codetheory.in\/wp-json\/wp\/v2\/tags?post=1913"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}\r\nString url = "http:\/\/google.com";\r\nIntent intent = new Intent(Intent.ACTION_VIEW);\r\nintent.setData(Uri.parse(url));\r\nstartActivity(intent);\r\n<\/pre>\n
ACTION_VIEW<\/code> intent action and set the data to
google.com<\/code>. Once
startActivity()<\/code> is triggered Android will start looking for all the apps that can handle this and most probably find just one which is the browser (chrome) that can receive it. It’ll launch chrome and open google.com<\/a> in it.<\/p>\n
<intent-filter><\/code><\/a> for that particular component (activity, service or a broadcast receiver) in our manifest file.<\/p>\n
AndroidManifest.xml<\/code>:<\/p>\n
\r\n<activity\r\n android:name="com.pycitup.pyc.WebViewActivity"\r\n android:label="@string\/title_activity_web_view" >\r\n\r\n <intent-filter>\r\n <action android:name="android.intent.action.VIEW" \/>\r\n <category android:name="android.intent.category.DEFAULT" \/>\r\n <data android:scheme="http" \/>\r\n <\/intent-filter>\r\n\r\n<\/activity>\r\n<\/pre>\n
ACTION_VIEW<\/code>) to be performed. In this case all that means is we need the
INTERNET<\/code> permission in our manifest:<\/p>\n
\r\n<uses-permission android:name="android.permission.INTERNET" \/>\r\n<\/pre>\n
WebViewActivity<\/code>. Inside the Activity you could then do things like show up the webpage in a WebView or some other sort of funky stuff.<\/p>\n
ACTION_SEND<\/code>) where once the user wants to share a piece of message, our app shows up along with facebook, whatsapp, gmail, etc.:<\/p>\n
\r\n<activity\r\n android:name="com.pycitup.pyc.ShareActivity"\r\n android:label="@string\/title_activity_share" >\r\n\r\n <intent-filter>\r\n <action android:name="android.intent.action.SEND" \/>\r\n <category android:name="android.intent.category.DEFAULT" \/>\r\n <data android:mimeType="text\/plain" \/>\r\n <\/intent-filter>\r\n\r\n<\/activity>\r\n<\/pre>\n
<action><\/code>,
<category><\/code> and
<data><\/code> subelements. So as soon as an implicit intent passes through (or conforms to) one of the intent filters it is delivered to that activity component or at least considered in the list of initial dialog with choices.<\/p>\n
\n
<action><\/code> – Declares the intent action that you want to be accepted by the intent filter, specified by the
android:name<\/code> attribute. Every
<intent-filter><\/code> element must contain one or more
<action><\/code> elements, else no Intent objects will get through the filter. Also note that the value must be the string value of the intent action, not the class constant (for example
\"android.intent.action.VIEW\"<\/code> and not
Intent.ACTION_VIEW<\/code>).\n<\/li>\n
<category><\/code> – Specifies the accepted intent category in the
android:name<\/code> attribute. Should contain the string value rather than the class constant (
\"android.intent.category.DEFAULT\"<\/code> instead of
Intent.CATEGORY_DEFAULT<\/code>).\n<\/li>\n
<data><\/code> – Declares the type of data accepted using various attributes that you can find here<\/a>. Examples are there in the code samples above which makes this element simple to understand.\n<\/li>\n<\/ul>\n
\n
CATEGORY_LAUNCHER<\/code><\/a> – Show up in the Launcher (Google Experience Launcher or Google Now Launcher or Nova or some other that you installed and use) as a top-level application. In other words the activity is the initial activity of a task (will launch when app starts) and is listed in the system’s application launcher (app drawer).\n<\/li>\n
CATEGORY_BROWSABLE<\/code><\/a> – Activities that can be safely invoked from a browser when a user clicks on a hyperlink.\n<\/li>\n
CATEGORY_ALTERNATIVE<\/code><\/a> – Activity should be included in a list of alternative actions the user can perform on a piece of data. So for instance if your code doesn’t specifies the intent action but sets this category and there’s an intent filter with this category too (but some other intent action name) then without even knowing the action name that intent filter will match with the implicit intent and deliver it to the component. Here’s an example (not sure if a good one):<\/p>\n
\r\nString url = "http:\/\/google.com";\r\nIntent intent = new Intent();\r\nintent.addCategory(Intent.CATEGORY_ALTERNATIVE);\r\nintent.setData(Uri.parse(url));\r\nstartActivity(intent);\r\n<\/pre>\n
\r\n<intent-filter>\r\n <!-- can also try android.intent.action.SEND instead of VIEW -->\r\n <action android:name="android.intent.action.VIEW" \/>\r\n <category android:name="android.intent.category.DEFAULT" \/>\r\n <category android:name="android.intent.category.ALTERNATIVE" \/>\r\n <data android:scheme="http" \/>\r\n<\/intent-filter>\r\n<\/pre>\n<\/li>\n
CATEGORY_DEFAULT<\/code><\/a> – The docs is a little hard to understand compared to this much simpler explanation<\/a>. The
CATEGORY_DEFAULT<\/code> category is applied to all implicit intents (automatically) passed to startActivity() and startActivityForResult(). So if you want your activity to receive implicit intents, it must include a category for
\"android.intent.category.DEFAULT\"<\/code> in its intent filters.\n<\/li>\n<\/ul>\n
\r\n<intent-filter>\r\n <action android:name="android.intent.action.SEND"\/>\r\n <action android:name="android.intent.action.SEND_MULTIPLE"\/>\r\n <category android:name="android.intent.category.DEFAULT"\/>\r\n <data android:mimeType="image\/*"\/>\r\n <data android:mimeType="video\/*"\/>\r\n<\/intent-filter>\r\n<\/pre>\n
ACTION_SEND<\/code> or
ACTION_SEND_MULTIPLE<\/code> (same as
ACTION_SEND<\/code> but for multiple data). Let’s take an example of selecting multiple photos in the gallery app and sharing them. So if you had only
android.intent.action.SEND<\/code> action tag then in the list of choices dialog, Android would show your app only when you tried to share one<\/em> photo, but not multiple<\/em>. But now since we have
android.intent.action.SEND_MULTIPLE<\/code> too we’ll get to select it also when we’re trying to share multiple photos. So this is more like an
OR<\/code> operation (launch the app component or show up in the multi-list either when it’s an
ACTION_SEND<\/code> or<\/strong>
ACTION_SEND_MULTIPLE<\/code>), so your app component must be able to handle both of them – performing action on single image or multiple. You can apply the same logic with the data tag.<\/p>\n
\r\n<activity\r\n android:name="com.pycitup.pyc.ShareActivity"\r\n android:label="@string\/title_activity_share" >\r\n <!-- This activity handles "SEND" actions with text data -->\r\n <intent-filter>\r\n <action android:name="android.intent.action.SEND"\/>\r\n <category android:name="android.intent.category.DEFAULT"\/>\r\n <data android:mimeType="text\/plain"\/>\r\n <\/intent-filter>\r\n <!-- This activity also handles "SEND" and "SEND_MULTIPLE" with media data -->\r\n <intent-filter>\r\n <action android:name="android.intent.action.SEND"\/>\r\n <action android:name="android.intent.action.SEND_MULTIPLE"\/>\r\n <category android:name="android.intent.category.DEFAULT"\/>\r\n <data android:mimeType="image\/*"\/>\r\n <data android:mimeType="video\/*"\/>\r\n <\/intent-filter>\r\n<\/activity>\r\n<\/pre>\n
ShareActivity<\/code> from some other activity like
MainActivity<\/code> but when some other app is trying to trigger a share action your app will show up in the list of choices which could be selected. Once selected based on the incoming data that you get from various Intent methods like
getData()<\/code><\/a>,
getExtras()<\/code><\/a>,
getType()<\/code><\/a>, etc. you can execute appropriate actions.<\/p>\n
Summary<\/h2>\n