I'm trying to better understand the topic of intents.
An explicit intent is configured with a component's name. In every example I've seen, it's used to start or stop the component. Is this the only purpose of an explicit intent?
An implicit intent doesn't have a target component. Implicit intents can also start/stop a component, but they can also be received by BroadcastReceivers. Is there another way to receive an implicit intent?
When the OS sends the intent with the action set to Action.MAIN, that's an explicit intent, right?
Thanks.
From the android documentation:
Explicit intents specify the component to start by name (the
fully-qualified class name). You'll typically use an explicit intent
to start a component in your own app, because you know the class name
of the activity or service you want to start. For example, start a new
activity in response to a user action or start a service to download a
file in the background.
Implicit intents do not name a specific component, but instead declare
a general action to perform, which allows a component from another app
to handle it. For example, if you want to show the user a location on
a map, you can use an implicit intent to request that another capable
app show a specified location on a map.
Explicit intents, as you've said, are used to start an activity in your application -- or to transition from one "screen" to another. An explicit intent would be something like Intent intent = new Intent(currentContext, ActivityB.class); These types of intents are used when you are within your application and explicitly know which component you want to start depending on how the user interacts with your activity.
Implicit Intents don't directly specify the Android components which should be called, but rather just specify a general action to be performed. These are generally used when you would like some external application to do something for you. An example of an implicit intent used to send an email using an external application would be:
Intent i = new Intent(Intent.ACTION_SEND);
i.setType("message/rfc822");
i.putExtra(Intent.EXTRA_EMAIL , new String[]{"someemail#gmail.com"});
i.putExtra(Intent.EXTRA_SUBJECT, "subject");
i.putExtra(Intent.EXTRA_TEXT , "body");
This intent would query for applications installed on the device that can handle sending an email, but there could be quite a few applications that can do this -- for example, if we have a gmail application, hotmail application, etc. So, basically you're just specifying a general action and asking the system "who can handle this", and the system will handle the rest. These types of intents are used by application developers so they don't have to "reinvent the wheel" if there is already something on the device that can do what the developer wants.
Here's a couple of references that might help explain it better:
http://developer.android.com/guide/components/intents-filters.html
http://www.vogella.com/articles/AndroidIntent/article.html
Is this the only purpose of an explicit intent?
An Intent generally is used to:
start an activity
start or stop a service
send a broadcast
An explicit Intent can be used for any of these.
Implicit intents can also start/stop a component, but they can also be received by BroadcastReceivers.
Whether an Intent is implicit or explicit is independent of what sort of role the Intent is used for.
Is there another way to receive an implicit intent?
An implicit Intent serves the roles listed above. You do not normally see it used for starting and stopping a service, though.
When the OS sends the intent with the action set to Action.MAIN, that's an explicit intent, right?
Not necessarily. If by "the OS" you mean "the home screen", and by "sends the intent with the action set to Action.MAIN", you mean "starts an activity based upon the user tapping on an icon in the launcher", then that is an explicit Intent, to identify the particular activity to start. An explicit Intent can have an action string, so it is not ACTION_MAIN that makes the Intent explicit.
Intent is an object which is used for communication between anyone of the android component(Activity, Services, BroadcastReceiver, ContentProvider) and Operating System.
Intent Class provides various constructors depending on what we intend to do.
In a case, Intent sends request to ActivityManager which activity to start. ActivityManager is a part of OS.
Now question will come that why do we require ActivityManager which is outside our application to communicate between two activities inside application. Here comes concept of Implicit and Explicit Intent.
Explicit Intent : To communication between components(Activity) within one application we use explicit intent.
Eg. Send current date from one activity to another.
Implicit Intent : To communicate between activities of different applications.
Eg. One application requesting photos from gallery application.
In case of Implicit Intent ActivityManager makes things easier.
As its name suggest Intent --> It's an "intention" to do an action.
It is a way of sending a message to perform an action which can be listen by other app or O.S.
In Explicit intent you know which work to perform by which person or class.
In Implicit intent you just ask a work to do ... all the apps capable of doing the activity like sharing a message will be shown in a list and you can do your work from any one of them.
I read the Android Documentation but I still need some more clarification. What exactly is a PendingIntent?
A PendingIntent is a token that you give to a foreign application (e.g. NotificationManager, AlarmManager, Home Screen AppWidgetManager, or other 3rd party applications), which allows the foreign application to use your application's permissions to execute a predefined piece of code.
If you give the foreign application an Intent, it will execute your Intent with its own permissions. But if you give the foreign application a PendingIntent, that application will execute your Intent using your application's permission.
Why PendingIntent is required ? I was thinking like
Why the receiving application itself cannot create the Intent or
Why we cannot use a simple Intent for the same purpose.
E.g.Intent bluetoothIntent= new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
If I send bluetoothIntent to another application, which doesn't have permission android.permission.BLUETOOTH_ADMIN, that receiving application cannot enable Bluetooth with startActivity(bluetoothIntent).
The limitation is overcome using PendingIntent. With PendingIntent the receiving application, doesn't need to have android.permission.BLUETOOTH_ADMIN for enabling Bluetooth. Source.
A Pending Intent is a token you give to some app to perform an action on your apps' behalf irrespective of whether your application process is alive or not.
I think the documentation is sufficiently detailed:
Pending Intent docs.
Just think of use-cases for Pending Intents like (Broadcasting Intents, scheduling alarms) and the documentation will become clearer and meaningful.
In my case, none of above answers nor google's official documentation helped me to grab the concept of PendingIntent class.
And then I found this video, Google I/O 2013, Beyond the Blue Dot session. In this video, ex-googler Jaikumar Ganesh explains what PendingIntent is, and that was the thing gave me the big picture of this.
Below is just transcription of above video (from 15:24).
So what's a pending intent?
It's a token that your app process will give to the location process, and the location process will use it to wake up your app when an event of interest happens. So this basically means that your app in the background doesn't have to be always running. When something of interest happens, we will wake you up. This saves a lot of battery.
This explanation becomes more clear with this snippet of code(which is included in the session's slide).
PendingIntent mIntent = PendingIntent.getService(...);
mLocationClient.requestLocationUpdates(locationRequest, mIntent);
public void onHandleIntent(Intent intent) {
String action = intent.getAction();
if (ACTION_LOCATION.equals(action)) {
Location location = intent.getParcelableExtra(...)
}
}
Pending intent is an intent which will start at some point in the future. Normal intent starts immediately when it is passed to startActivity(Intent) or StartService(Intent).
TAXI ANALOGY
Intent
Intents are typically used for starting Services. For example:
Intent intent = new Intent(CurrentClass.this, ServiceClass.class);
startService(intent);
This is like when you call for a taxi:
Myself = CurrentClass
Taxi Driver = ServiceClass
Pending Intent
You will need to use something like this:
Intent intent = new Intent(CurrentClass.this, ServiceClass.class);
PendingIntent pi = PendingIntent.getService(parameter, parameter, intent, parameter);
getDataFromThirdParty(parameter, parameter, pi, parameter);
Now this Third party will start the service acting on your behalf.
A real life analogy is Uber or Lyft who are both taxi companies.
You send a request for a ride to Uber/Lyft. They will then go ahead and call one of their drivers on your behalf.
Therefore:
Uber/Lyft ------ ThirdParty which receives PendingIntent
Myself --------- Class calling PendingIntent
Taxi Driver ---- ServiceClass
What is an Intent?
An Intent is a specific command in Android that allows you to send a command to the Android OS to do something specific. Think of it as an action that needs to take place. There are many actions that can be done such as sending an email, or attaching a photo to an email, or even launching an application.
The logical workflow of creating an intent is usually as follows:
a. Create the Intent
b. Add Intent options -> Ex. what type of intent we are sending to the OS or any attributes associated with that intent, such as a text string or something being passed along with the intent
c. RUN the Intent
Real-Life Example: Let's say I wake up in the morning and I "INTEND" to go to the washroom. I will first have to THINK about going to the washroom, but that DOESN'T really gets me to the washroom. I will then have to tell my brain to get out of bed first, then walk to the washroom, and then release, then go and wash my hands, then go and wipe my hands. Once I know where I'm going I SEND the command to begin and my body takes action.
What is Pending Intents?
Continuing from the real-life example, let's say I want to take a shower but I want to shower AFTER I brush my teeth and eat breakfast. So I know I won't be showering until at least 30-40 minutes. I still have in my head that I need to prepare my clothes, and then walk up the stairs back to the bathroom, then undress and then shower. However, this will not happen until 30-40 minutes have passed. I now have a PENDING intent to shower. It is PENDING for 30-40 minutes.
That is pretty much the difference between a Pending Intent and a Regular Intent. Regular Intents can be created without a Pending Intent, however, in order to create a Pending Intent you need to have a Regular Intent setup first.
A future intent that other apps can use.
And here's an example for creating one:
Intent intent = new Intent(context, MainActivity.class);
PendingIntent pendIntent = PendingIntent.getActivity(context, 0, intent, 0);
A PendingIntent is a token that you give to another application (e.g. Notification Manager, Alarm Manager or other 3rd party applications), which allows this other application to use the permissions of your application to execute a predefined piece of code.
To perform a broadcast via a pending intent so get a PendingIntent via PendingIntent.getBroadcast(). To perform an activity via an pending intent you receive the activity via PendingIntent.getActivity().
PendingIntent is basically an object that wraps another Intent object. Then it can be passed to a foreign application where you’re granting that app the right to perform the operation, i.e., execute the intent as if it were executed from your own app’s process (same permission and identity). For security reasons you should always pass explicit intents to a PendingIntent rather than being implicit.
PendingIntent aPendingIntent = PendingIntent.getService(Context, 0, aIntent,
PendingIntent.FLAG_CANCEL_CURRENT);
A PendingIntent wraps the general Intent with a token that you give to foreign app to execute with your permission.
For eg:
The notification of your music app can't play/pause the music if you
didn't give the PendingIntent to send broadcast because your music app
has READ_EXTERNAL_STORAGE permission which the notification app
doesn't. Notification is a system service (so it's a foreign app).
A Pending Intent specifies an action to take in the future. It lets you pass a future Intent to another application and allow that application to execute that Intent as if it had the same permissions as your application, whether or not your application is still around when the Intent is eventually invoked.
It is a token that you give to a foreign application which allows the foreign application to use your application’s permissions to execute a predefined piece of code.
If you give the foreign application an Intent, and that application sends/broadcasts the Intent you gave, they will execute the Intent with their own permissions. But if you instead give the foreign application a Pending Intent you created using your own permission, that application will execute the contained Intent using your application’s permission.
To perform a broadcast via a pending intent so get a PendingIntent via PendingIntent.getBroadcast(). To perform an activity via an pending intent you receive the activity via PendingIntent.getActivity().
It is an Intent action that you want to perform, but at a later time. Think of it a putting an Intent on ice. The reason it’s needed is because an Intent must be created and launched from a valid Context in your application, but there are certain cases where one is not available at the time you want to run the action because you are technically outside the application’s context (the two common examples are launching an Activity from a Notification or a BroadcastReceiver.
By creating a PendingIntent you want to use to launch, say, an Activity while you have the Context to do so (from inside another Activity or Service) you can pass that object around to something external in order for it to launch part of your application on your behalf.
A PendingIntent provides a means for applications to work, even after their process exits. Its important to note that even after the application that created the PendingIntent has been killed, that Intent can still run. A description of an Intent and target action to perform with it. Instances of this class are created with getActivity(Context, int, Intent, int), getBroadcast(Context, int, Intent, int), getService (Context, int, Intent, int); the returned object can be handed to other applications so that they can perform the action you described on your behalf at a later time.
By giving a PendingIntent to another application, you are granting it the right to perform the operation you have specified as if the other application was yourself (with the same permissions and identity). As such, you should be careful about how you build the PendingIntent: often, for example, the base Intent you supply will have the component name explicitly set to one of your own components, to ensure it is ultimately sent there and nowhere else.
A PendingIntent itself is simply a reference to a token maintained by the system describing the original data used to retrieve it. This means that, even if its owning application’s process is killed, the PendingIntent itself will remain usable from other processes that have been given it. If the creating application later re-retrieves the same kind of PendingIntent (same operation, same Intent action, data, categories, and components, and same flags), it will receive a PendingIntent representing the same token if that is still valid, and can thus call cancel() to remove it.
In an easy language,
1. A description of an Intent and Target action to perform. First you have to create an intent and then you have to pass an specific java class which you want to execute, to the Intent.
2. You can call those java class which is your class action class by PendingIntent.getActivity, PendingIntent.getActivities(Context, int, Intent[], int), PendingIntent.getBroadcast(Context, int, Intent, int), and PendingIntent.getService(Context, int, Intent, int);
Here you see that Intent which is comes from the step 1
3. You should keep in mind that...By giving a PendingIntent to another application, you are granting it the right to perform the operation you have specified.
That is what I learned after a long reading.
In simple terms
A pending intent is basically an intent that you can pass to other apps or services like notification manager, alarm manager etc. and let them handle when is the right timing/behaviour for it to be executed.
As its name suggest .. PendingIntent
you can pend(do it after some time) it . It work as the other intent ..it is a way of giving your task to some other app to perform on your behalf.
Pending Intent
A pending intent is a wrapper around regular intent that is designed
to be used by another application.
It gives that other application the ability to perform the included
action as it was your application with all the permissions your
application has been granted
When you want to open some application components like Activity/Service/BroadcastReceiver at later time or after some specified time interval you have to send PendingIntent in this case. It acts like a permission slip you gave to another apps to run your application’s code on your behalf after some time. So PendingIntent works beyond process boundaries like you want AlarmManager which is an another app in another process then AlarmManager perfom action on your app specified by PendingIntent
Pending Intent is an intent who provides all permission to other application to do a particular works. When the main activity is destroyed, Android OS takes back the permission from it.
I have came across PendingIntents in Notifications. So here is a simple explanation:
We want to provide an Intent to Notification, in this case we want to open a Activity which performs Camera capture functionality. Here, if we pass simply Intent, the NotificationManager doesnt have this permission although my app has this permission stated in Manifest; due to this the action wont work as NotificationManager doesnt have the permission to do so.
But, if you use PendingIntent, here the permission that my app have will be used instead of NotificationManager. Therefore, even if NotificationManager doesnt have Camera permission and my app has it will still open up the activity and perform the app.
NOTE: Pending intent requires regular Intent to be setup first.