Does setting the package name make an implicit intent explicit? - android

The intent would be implicit without the third line of code. Does setting the package make it explicit? The component isn't specified, so based on Stack Overflow answers: it is implicit...
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.setPackage("com.example.app");
startActivity(intent);
...but the target app's package name is supplied, so it is explicit, based on the docs:
Explicit intents specify which application will satisfy the intent, by
supplying either the target app's package name or a fully-qualified
component class name.

Explicit means that defined app (aka package) should handle the intent.
When you setup the package that should handle the intent, yes, it makes it explicit.
Addition
I take the definition of explicit into consideration, it means that action is defined.
fully and clearly expressed or demonstrated; leaving nothing merely implied; unequivocal:
Then if check the setPackage docs it says
(Usually optional) Set an explicit application package name that limits the components this Intent will resolve to. If left to the default value of null, all components in all applications will considered. If non-null, the Intent can only match the components in the given application package.
So it's all about how to understand the terms Implicit and Explicit.
For me (and according what I understand from android docs), Implicit is
Hey, I want to share this awesome image, lets give it to the world
Which opens chooser of facebook, instagram, whatsapp etc.
And Explicit is
Hey, I want to share this awesome image with Instagram, open it and share the image please
Which opens instagram only (by package).

Related

Explicit intent and action performed

I am wondering how does the following code works (it starts an activity). I don't get how does the system figure out what is the action that should be preformed. No action is specified for the Intent. I would have expected a set_action.
Intent i = new Intent(this, ActivityTwo.class);
startActivity(i);
I am wondering how is it possible to have an Intent which action is not explicitely specified considering what I read in the documentation:
The primary pieces of information in an intent are:
action -- The general action to be performed, such as ACTION_VIEW, ACTION_EDIT, ACTION_MAIN, etc.
data -- The data to operate on, such as a person record in the contacts database, expressed as a Uri.
I hope it make sense. Thank you for your help.
There are two types of intents in Android, implicit intents and explicit intents.
1) Implicit intent
You set an Action, Category and data type and let Android find an activity that fits the specified characteristics (has an intent filter with the specified Action, Category and Data Type).
2) Explicit intent
As the docs says:
An explicit intent is one that you use to launch a specific app
component, such as a particular activity or service in your app. To
create an explicit intent, define the component name for the Intent
object—all other intent properties are optional.
You tell which activity/service to open explicitly. So the system doesn't need to figure out which one to open, you're already telling it to open a specific Activity/Service.
The one you read in the docs is an implicit intent, this is the explicit one:
Intent i = new Intent(this, ActivityTwo.class);
There are multiple constructor functions for Intent class.
If checking the source code for public Intent(Context packageContext, Class cls), the following info is mentioned:
Create an intent for a specific component. All other fields (action, data,
* type, class) are null, though they can be modified later with explicit
* calls. This provides a convenient way to create an intent that is
* intended to execute a hard-coded class name, rather than relying on the
* system to find an appropriate class for you;

Different types of Android Intents

I have recently started a new Android project and I'm working off the previous developer's code. I'm relatively new to Android and I've come across something that I'm unsure of.
What is the difference between this:
Intent intent = new Intent("com.example.project.MENU");
and this:
Intent intent = new Intent(this, DisplayMenu.class);
I understand what the 2nd code snippet does, I just can't get my head around as to what the first one is doing? Is it referencing the file in the package? Thanks
The first one is an implicit intent, while the second is an explicit intent.
The first one fired an Intent for the action com.example.project.MENU. If you look inside you project AndroidManifest.xml you can see some <intent-filter> balise. This baslise register activity, service or broadcast receiver to different actions.
This mecanism can be used to allow third party app to launch some of your activities.
You can see more on this tutorial http://www.vogella.com/tutorials/AndroidIntent/article.html#intenttypes
Basically an Intent carries some information that are used by the system in order to determine which component should be called for executing the action.
These information are:
Component name: the name of the component that should be launched. (If present the Intent is Explicit)
Action: it specifies the generic action that should be executed (es. ACTION_VIEW, ACTION_SEND). It determines how the rest of the intent is strucutred.
Data: represents the URI that refers to the object that should be associated with the action. For example with the action ACTION_EDIT, the Data should contain the URI of the document that you want modify.
Category: Additional infromation (for example if you want that your app is shown in the launcher you can use CATEGORY_LAUNCHER)
Extras: keys-values pairs that carries additional information
Flags: it is like a metadata that specify how the intent should be managed by the system.
The Intent class provides a lot of different constructors.
The first one you asked for is public Intent (String action)
So, this sets the Action, and lets null all other fields.
The second one public Intent (Context packageContext, Class<?> cls) creates an intent for a specific component by its Component name. All other fields are null. This is a Explicit Intent, since you declare exactly which component should receive it.
The first one is used when you need to call Intent from System
such as Open Camera, Gallery, or Share something to other Application
for example
// this one call Camera to Capture Image
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// this one call gallery to let you select image
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
and That MediaStore.something here is just a Path to the system
for example
MediaStore.ACTION_IMAGE_CAPTURE = "android.media.action.IMAGE_CAPTURE"
Intent.ACTION_PICK = "android.intent.action.PICK"
The first type of intent is mostly used if you want to open another application from your application while the second type of intent is used to open another activity in your application.

Is it possible to set Action to Explicit Intents?

For this code, 'localIntent' seems Explicit Intent directed to 'SecondActivity.class'. But it also seems that it's action has been set as 'SAMPLE'. In this case, is this still Explicit Intent? And when this type of Intent usually is used for?
Intent localIntent = new Intent(getApplicationContext(), SecondActivity.class).setAction("SAMPLE");
startActivity(localIntent);
For Intent of Android, there are only two types like this:
Explicit Intents have specified a component (via setComponent(ComponentName) or setClass(Context, Class)), which
provides the exact class to be run. Often these will not include any
other information, simply being a way for an application to launch
various internal activities it has as the user interacts with the
application.
Implicit Intents have not specified a component; instead, they must include enough information for the system to determine which of the
available components is best to run for that intent.
So, whether you set component or set class, that will be explicit intent.(read more here)

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);

What is the purpose of "android.intent.category.DEFAULT"?

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

Categories

Resources