What is the purpose of using android.intent.category.DEFAULT in the Category field of Intent Filters?
Categories are used for implicit Intents. So, If your Activity can be started by an implicit Intent when no other specific category is assigned to activity, activity's Intent filter should include this category. (even if you have other categories in the Intent filter). If you are sure that your activity must be called with any other Category, don't use the Default.
Setting Category to Default doesn't mean that this Activity will be used by default when your app launches. The Activity just says to system that " Oh I could be started, even if the starter Intent's category is set to Nothing at all ! "
This category is mainly used for implicit intents. If your activity wishes to be started by an implicit intent it should include this catetory in its filter.
I think the term "default" should be understood as "default candidate". If the action on a piece of data resolves to multiple activities, then Android will present all candidates to the user and the user can select his preferred default.
Reference:
http://developer.android.com/guide/components/intents-filters.html
Extract from that page:
Android treats all implicit intents passed tostartActivity() as if they contained at least one category: "android.intent.category.DEFAULT" (the CATEGORY_DEFAULT constant). Therefore, activities that are willing to receive implicit intents must include "android.intent.category.DEFAULT" in their intent filters. (Filters with "android.intent.action.MAIN" and "android.intent.category.LAUNCHER" settings are the exception. They mark activities that begin new tasks and that are represented on the launcher screen. They can include "android.intent.category.DEFAULT" in the list of categories, but don't need to.)
Activities will need to support the CATEGORY_DEFAULT so that they can be found by Context.startActivity().
In order to receive implicit intents, you must include the CATEGORY_DEFAULT category in the intent filter. The methods startActivity() and startActivityForResult() treat all intents as if they declared the CATEGORY_DEFAULT category. If we do not declare it in our intent filter, no implicit intents will resolve to our activity.
It is actually to make sure your other activities can be called out when the app is running. LAUNCHER will make the activity that has it the first activity that starts. To use intents to get to the other activities, they have to be listed as "actual" activities by putting DEFAULT. That is from what I know so don't quote me if it's wrong.
It is used to declare some operation as default action (as its name suggest).
Lets consider we have a notepad app(referring to android notepad sample). The first page of app consists of a list of all notepad files. When one notepad file is selected one of the operations like edit note, delete note etc can be performed. But I want to make edit as my default action which means when i press center button of my keypad,edit window should be open.
category:
android.intent.category.DEFAULT
Matches any implicit Intent. This category must be included for your Activity to receive any implicit Intent.
https://codelabs.developers.google.com/codelabs/android-training-activity-with-implicit-intent/index.html?index=..%2F..%2Fandroid-training#6
https://developer.android.com/guide/components/intents-filters
To receive implicit intents, you must include the CATEGORY_DEFAULT category in the intent filter. The methods startActivity() and startActivityForResult() treat all intents as if they declared the CATEGORY_DEFAULT category. If you do not declare this category in your intent filter, no implicit intents will resolve to your activity.
Before an implicit Intent is accepted by an Activity the Intent must pass a category test: Each category in the Intent must match the exact same category in the Intent-filter of the Activity.
The category DEFAULT is automatically applied to all implicit intents (by default) so because of the reason above every Activity that want to receive any implicit intent at all has to include this category in its Intent-filter.
Source
Related
If the intent filters are to resolve implicit intents, then why does
the MainActivity(which is the very first activity that is run when
app is launched) has an intent filter?
Who send an implicit intent to it?
What if the sent implicit intent doesn't have proper data ?
Well, how does the system know which activity is the main activity? It isn't the name- the system doesn't care about the name. Its the activity with the intent filter that says its the main activity.
It can also have other intent filters to launch it any other way you may want. For example, you may have an intent filter to launch it via a deep link.
As for proper data- if launched from the app list or homescreen, it won't have any data. Its on the programmer of the app to make sure that it can do something that makes sense in that case.
It has CATEGORY_LAUNCHER and ACTION_MAIN .
android.intent.action.MAIN means that this activity is the entry point of the application, i.e. when you launch the application, this activity is created.
CATEGORY_LAUNCHER tells that your activity should be displayed in the top-level launcher.
https://developer.android.com/reference/android/content/Intent.html#ACTION_MAIN
Launcher sends implicit intent to it. This is how launcher knows which activity is to be opened on click.
If you send improper data it will not open your activity. For ex:
If you try to start your main activity using implicit intent only in startActivity then it will not start because there is CATEGORY_DEFAULT associated with it. You need to add one more intent_filter to your activity to resolve the intents.
If Activity manager launches the MainActivity through intent-filter with action=main, and category=launcher, then which type of intent is used?
I'm confused little bit. Is it implicit intent?
An intent is an abstract description of an operation to be performed. Its most significant use is in the launching of activities.
when the user clicks on the application icon, the android system looks in the manifest file for the intent with
action="android.intent.action.MAIN"
and
category="android.intent.category.LAUNCHER".
MAIN action is the main entry point of the application.
LAUNCHER category means it should appear in the Launcher as a top-level application.
Intent is just a piece of information about intention. Intent do not starts anything. It just inform OS that there is a need to do something (i.e start app). System looks for apps able to resolve this intention, starts them and pases to them starting intent (becouse you can pass some portion of data in it).
When user clicks app icon in launcher, launcher application generates and sens intent to OS (with explicit name of desired application to start). Android creates separate DVM, main activity class, starts acrivity's life cycle with calling onCreate() and brings activity to foreground.
When the user selects your app icon from the Home screen, the system calls the onCreate() method for the Activity in your app that you've declared to be the "launcher" (or "main") activity. This is the activity that serves as the main entry point to your app's user interface.
You can define which activity to use as the main activity in the Android manifest file, AndroidManifest.xml, which is at the root of your project directory.
The main activity for your app must be declared in the manifest with an intent-filter that includes the MAIN action and LAUNCHER category(That you know probably).
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.
Therefore, activities that are willing to receive implicit intents must include "android.intent.category.DEFAULT" in their intent filters. Filters with "android.intent.action.MAIN" and "android.intent.category.LAUNCHER" settings are the exception. They mark activities that begin new tasks and that are represented on the launcher screen. They can include "android.intent.category.DEFAULT" in the list of categories, but don't need to.
For more details please refer this link:
http://developer.android.com/guide/components/intents-filters.html
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 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);
It seems to me that if startActivity is called with an implicit categoryless intent, only activities with an intent filter specifying the default category (android.intent.category.DEFAULT) can be launched.
The category is not needed in the intent filter for services if we use startService instead of startActivity.
Does everybody see the same behavior ?
Is it documented somewhere in the Android official documentation ?
I think that is documented.
See http://developer.android.com/reference/android/content/Intent.html:
The categories, if supplied, must all
be listed by the activity as
categories it handles. That is, if you
include the categories
CATEGORY_LAUNCHER and
CATEGORY_ALTERNATIVE, then you will
only resolve to components with an
intent that lists both of those
categories. Activities will very often
need to support the CATEGORY_DEFAULT
so that they can be found by
Context.startActivity().
My experience is that an category-less activity can be used with startActivity() if the class is explicitly set in the intent, though. In that case, no intent matching is done.