What does an Android Intent do with its URIs? - android

Reading through the document and a couple others, none really specified what an Intent does with the URI that it is passed. I'm simply curious as to what happens when it gets a URI. I know it depends on the scheme, so if the scheme was http, does it then attempt to open that web URI?
I ask since I'm trying to consume RESTful API that sends data back in JSON format. Having it open the URI for me when trying to pass the data from one Activity to another rather than making the HTTP call myself via HttpClient would be nice. Not a big deal but I was just curious if that is how works.

An Intent is just an object ... it does nothing with the URI. An Intent is used in function calls like startActivity(), sendBroadcast(), etc.
For example, when you pass an Intent to startActivity(), that Intent object is made available to the Activity. The Activity can interpret the URI as it pleases.
Android also uses Intent Filters to help route intents to various installed activities, these intent filters may inspect the URI.
Review http://developer.android.com/guide/components/intents-filters.html for all the info.

It's not entirely clear what you mean, however the behavior of Intents is basically dictated by the Android package manager. You can think of an Intent as being a procedure call: you specify someone to handle the Intent, along with some additional data (parameters), possibly some category, etc...
The Android package manager looks at your intent and basically asks the question "what app on the system is prepared to consume and handle this intent?" The system then opens up that app (if it is not already resident in memory), and then throws the intent at the app. Note that there are cases where there exist some possibility of ambiguity among intent handlers: multiple apps could be prepared to handle the intent. You can sometimes see this in the form of the user being asked to select what app should handle the intent (and the user can select a default one).
The dynamic semantics of how intents are handled depends, of course, on the set of apps installed on the system, and may change depending on the type of app installed. It sounds like, in your case, you are mostly concerned with intents that have an ACTION_VIEW action associated with them. In the general case, things that look like URLs will be "caught" by the browser (though there is no guarantee that this be the case!), and the package manager will look at the structure of the URI and say "hey, this looks like it should be handled by app X," I'm going to send this URL to it. (And, of course, new apps can change this behavior by registering other intent filters..)

An intent is an abstract description of an operation to be performed.uri specific data that intent has to do operation on it:
Intent Structure
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.
Some examples of action/data pairs are:
ACTION_VIEW content://contacts/people/1 -- Display information about the person whose identifier is "1".
ACTION_VIEW tel:123 -- Display the phone dialer with the given number filled in. Note how the VIEW action does what what is
considered the most reasonable thing for a particular URI.
ACTION_VIEW content://contacts/people/ -- Display a list of people, which the user can browse through. This example is a typical
top-level entry into the Contacts application, showing you the list of
people. Selecting a particular person to view would result in a new
intent { ACTION_VIEW content://contacts/N } being used to start an
activity to display that person.
So you can see that same Action with different data/uri perform different Action on data operate on.

Related

Share Email intent or Generic message intent

I have 2 types of Intents for sharing. One for simple generic messaging like SMS/Slack etc. and Another one for email. What I can't seem to figure out is how to make where I can find a way to resolve what someone has chosen via the chooser and use the appropriate intent.
(This would be done via pressing the share button and all send options would show in the chooser
Any help with this would be awesome.
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("text/plain");
Intent chooser = Intent.createChooser(shareIntent,"");
My thought was when resolving the chooser I could see if it was an email type but that doesn't seem to work either.
Once you have fired off an Intent, control of what happens is outside your control. The chooser will not provide a callback to your app once the user chooses an action- instead the system will pass the intent you launched on to the selected application.
As discussed in How to filter specific apps for ACTION_SEND intent (and set a different text for each app), if you want to customize the chooser you have a few options. You can:
Use Intent.EXTRA_INITIAL_INTENTS to surface other intents in addition to the default option.
Create your own custom chooser that provides the behavior you want
The first option may not be ideal because the ordering of options might not be want you want.
The second option provides much more control, but is a lot of work to maintain, particularly if you want newer platform features like directly sharing with a contact.
Another option would be to change your UI to offer separate "share" and "email" options, then use the default intents for each.

Why does an "Intent Selector" exists, what is it used for?

Android's Intent class provides an API called setSelector. I am trying to understand it from the example given in the documentation.
I want to ask that why did Android need to add this API ? What was breaking in Intent before this API ?
My understanding from reading the references is that the problem this API is intending to solve is where you want to send a launcher intent for an app that meets some general restrictions. Say you want to match all apps that open .mp3 files, but you don't want to actually open an mp3 file, you just want to launch an app that supports that. In that case, you could create a generic ACTION_MAIN, CATEGORY_LAUNCHER intent, and set the selector to an intent with an mp3 mime type or data URI.
Before this API there would be no way to do that - if you wanted to target an app that supports opening mp3s, you would have to send an intent for an mp3, which could either cause music to start playing, or cause the music player to throw an error. Also, depending on the music player's launch mode, the launcher intent may return to an existing instance of the music player, while the mp3 intent might create a new one.
According to my understanding, it gives choice to user which intent he wants to select. In that documentation they have given that it gives selection of intents whether user wants to open app's main activity or wants to launch any diff app/activity other than user's app. This is what i understood from that documentation. Check this links for your reference : https://code.google.com/p/android/issues/detail?id=67162 & http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.4_r1/android/content/Intent.java#Intent.setSelector%28android.content.Intent%29

Using Intent filter for inter process communication

I want to enable my application to be called from different applications by using urls or sort of rest enablement, such that different actions in my application can be performed by the different clients.
For e.g. there is action "a" which helps the user to navigate to a particular screen in my application.
I am planning to use it using urls it can be custom schemes or http. I have already read the debates between custom schemes and http schemes :).
So for e.g if a client calls mysite.com://a?queryParam=1&queryParam=2 then depending on the action "a" and query params i am navigating to particular screen.
I am using intent filters here for inter process communication. Then i will write a url handler depending on the type of action. Action type can be derived from the last path segment of the query. .Fetching of query parameters can be done through uri.getQueryParameters. Is using the intent filter and URI apis right for this kind of scenarios ?.
I had read about AIDL which can be used for inter process communication, but that is very tightly bound and client has to know lot of information about the provider or my application. i somehow want the rest type enablement of my application.
cheers,
Saurav
I'm not entirely sure I understood the request, but this answer seems a good one for you.
This allow you to intercept all Intents with the android.intent.action.VIEW action, but only those that match your URI. So if the user clicks on a link with matching url scheme he will have to choose the application to open it (browser or your app). Once you have the Intent you can analize it and take your actions.

How to attach an image with sms without showing Action chosser in android?

I have to attach an image file with the sms on button click i use this code
final Intent smsIntent = new Intent(android.content.Intent.ACTION_SEND);
smsIntent.putExtra("sms_body", "Hello World!");
smsIntent.putExtra("address", "0123456789");
smsIntent.putExtra(Intent.ACTION_ATTACH_DATA,screenshotUri);
smsIntent.setType("image/png");
startActivity(smsIntent);
But this shows a chooser to choose an action like Facebook,Email,Messages etc.
But i do not want any the chosser view it will directly show the message intent with attached file.
What you are looking for cannot be done using implicit Intents. Because that is how the Android system is designed to handle implicit intents. If you want your intent to be handled by a specific application then you have to make them explicit, i.e., specify a component that has to handle the intent. But when you use explicit intents to handle any situation such as yours, then there is a great chance of your app to break when the specific component (i.e. Application) doesn't not exist in the target device. Android is being adopted by several OEMs, therefore each of them tend to replace the stock Messaging application with their own. So what seems to work on one device may not work on the other.
If you want to achieve what you want then you may have to get the list of Messaging applications on various devices, (you can find the stock Android app's component name from the emulator itself). And use the PackageManager to find if the component exists. If it does, the start and explicit intent, in which you won't receive an IntentChooser. If the component doesn't exist send an implicit intent.
You can learn more about intents from here.
Determining if an Activity exists on the current device? - This post will help you to find if the target component exists.

How to secure Intent data while sending it across applications

I am working on the security aspects of my android application.
I would like to know about the ways to secure the Intent data and extras while sending it from one application to another so that no other application other than these two can snoop it.
One of the brute-force approaches would be to use android's encryption-decryption to encode intent data, is there a better way to achieve the same ??
Thanks in advance.
As pointed in the other answers, although you can send an intent to a fully qualified activity, nothing prevents someone from creating an application with the same package.
You might want to add an additional security step to this scheme:
First send a 'Challenge' intent to the remote activity (it should, for example, encrypt a random string you provided using a shared passphrase and send it back to you).
If that first security step is ok, you may freely send unencrypted messages to this remote app by using its fully qualified activity.
This is rather lame security, but perhaps it's sufficient for your needs.
Please take a look at CommonsWare's comment below.
A more secure way might be to code your activity as a Bound Service, keeping the Challenge step, but by means of more private communication.
My guess is that if you use an explicit intent, i.e. specifying the class to which the intent is to be sent to, then no other class can intercept that intent and look at its data.
This method however, may fail if the class name in the application that you're trying to send the information to changes.
If an intent specifies the the target, which is part of the sender application's package, then other applications won't have the chance to capture it - it will be delivered to the intended receiver.
On the other hand, if you send an intent to another application, there is no guarantee that the receiver of the intent will have the implementation you expect: if you send your intent to com.mycompany.security.SecureReceiver, but instead of your application, another application is installed with the given class description, than you will send your intent to that application.
Also, Android is an open system. If someone compiles his own application framework, than he can manipulate the Intent delivery system.
Do you want to protect your data from the user, or from malicious applications?

Categories

Resources