I see any intent has extra field and a data field.
is there any difference between them or it's just a conceptual difference?
Data
The URI (a Uri object) that references the data to be acted on and/or the MIME type of that data. The type of data supplied is generally dictated by the intent's action. For example, if the action is ACTION_EDIT, the data should contain the URI of the document to edit.
Data return URI
Extras
Key-value pairs that carry additional information required to accomplish the requested action. Just as some actions use particular kinds of data URIs, some actions also use particular extras.
Extras contains a Bundle which is an implementation of HashMap to store key values of specific data .
Extra Return Bundle
For more information About Intent extra And Data refer this Url
According to the documentation, getData() returns a Uri whereas getExtras() returns a Bundle. So yes there is a difference and the difference is not just conceptual.
Data in an intent contains a URI to operate on, such as an URI to email client. And Extras contains the bundle regarding that URI which can carry extra info for data, such as for email client, you can put in subject body etc.
as mentiond in the documentation of the intent :
the data : is not a content , its a URI , that describe what should be done regarding the specified action .
and the Extras contains a Bundle which is an implementation of HashMap to store key values of specific data .
I don't thing that the difference is conceptual. The getExtras() returns a bundle and getData() returns a Uri see documentation.
Usually I approach the Uri from getData() to indicate where to operate on. And the extra field as an Map/Bundle to put parameters or arguments in for whatever I'm using the intent for.
Conceptual or label. It's somehow strange. Here data DO NOT really means data. In fact it simply DON'T MEAN CONTENT.
You should use te extra field to pass non URI data (URI, URL, tel number and such things). You may generally use Extra fields, for simple data
Look at developer.android.com description
data -- The data to operate on, such as a person record in the contacts database, expressed as a Uri (Uniform Resource Identifier).
extras -- This is a Bundle of any additional information. This can be used to provide extended information to the component. For example, if we have a action to send an e-mail message, we could also include extra pieces of data here to supply a subject, body, etc.
Related
In the Intent used to trigger an android.intent.action.CREATE_DOCUMENT action, I add a custom extra with myIntent.putExtra("myPackage.MY_EXTRA","toto").
In the onActivityResult function, when I try to retrieve this extra with intent.getStringExtra("myPackage.MY_EXTRA"), I get a null String (intent is the Intent received as a parameter in the onActivityResult function).
Any idea on how I could solve my problem?
What you want is not likely to be available for any startActivityForResult() call. Putting an extra on an Intent sends that extra to the other activity. There is no requirement for that extra to be returned to you, and few (if any) activities will do that.
So, hold onto the data yourself, such as in a field of your activity.
What is the easiest way to send an ArrayList<float[]> between activities?
Is it possible to send using SharedPreferences or putExtra?
I've only seen examples of sending ArrayList<String> or ArrayList<Int>, and those options are built in through .putStringArrayList etc.
The best way would be to add it as an extra to the Intent's Bundle. This is because Intent extras were created specifically to pass arguments between Activities.
Put Extra
ArrayList<float[]> list = new ArrayList<>();
Intent i = new Intent(FirstActivity.this, SecondActivity.class);
i.putExtra("arg_key", list);
Get Extra
ArrayList<float[]> list = ( ArrayList<float[]>) getIntent().getSerializableExtra("arg_key");
That said, if the data is to be persisted in a Database anyways, you would simply retrieve it from the database. I would not use SharedPreferences for this as it is intended for storing flags, tokens, app settings, etc.
UPDATE
If you want to pass an argument that is not supported by an Intent's extras and is not natively Serializable, have a look at Parcelable. You can implement Parcelable in any of your POJOs to allow them to be added to a Bundle. Parcelable is also faster than Serializable.
This question already has answers here:
Intent.setData vs Intent.putExtra
(4 answers)
Closed 7 years ago.
I don't quite understand the real purpose of Data field for intents.
I have seen some examples like the following:
Intent intent = new Intent(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:"+number));
startActivity(intent);
So from the documentation it seems like Data just gives you the URI, basically where the data is located.
Can't everything just be done using putExtra and just have the Activity get the extra.
For the example above, you could just put the telephone number in the extra and have the activity get the extra and then dial. When would you use setData vs putExtra?
Can't everything just be done using putExtra and just have the Activity get the extra.
Extras do not control routing of Intents. The action string, data (Uri), MIME type, and categories do. Extras are merely payload.
In this case, ACTION_CALL of a tel: Uri might be handled differently than ACTION_CALL of a sip: Uri. Only SIP-compatible VOIP clients could handle the latter. Hence, the activities for telephony-related apps can include details in their <intent-filter> elements to watch for only those Uri schemes that they can handle (among other possible constraints).
putExtra actually adds the data in the intent. It gets serialized when it is sent to another activity where it gets deserialized. These are expensive operations that could affect the performance. There is also a limit on how much data can be sent like this. If you have a big piece of data (several MBs) then it is better to use setData rather than putExtra.
I need to share data between two android apps that are on the same phone without using the internet. The data I want to share includes a several key value pairs of different data types. The options I am aware of are:
Using intents - Send and Receive. But the typical examples
for intents do not involve these use cases. Intents seems more
suited for sharing data of a particular mime type or launch apps (or
let users choose from) to handle the data being shared.
Sharing the SharedPreferences. However the MODE_WORLD_READABLE
or MODE_WORLD_WRITEABLE flags required for this have been deprecated
post API 17.
Broadcast Receivers - But I'm not exactly listening to events.
I want to use a request/response cycle.
Content Providers. This is great except for the fact that I
need to store the data in a database in the app sharing the data. If I have key, value pairs
where the value can be of different data types, this makes the data
table a bit cumbersome. Is there a better way to do this with
content providers?
Which is the best technique to adopt?
I created a small library that makes it simple to share SharedPreferences from one app to another in a READ ONLY fashion using ContentProvider.
Described it here - https://github.com/ratpik/android-sharedpreferences-api/blob/master/README.md
You can set up Broadcast Reciever on one end to listen for particular intent type. And broadcast intents from first application with data held in extras. You can send whole objects via intent using parcerable approach.
More about parcerable approach can be found here
There's a case that the user change the parameters send to servlet through URL,
is there's any way to restrict user not to change paramters,
if not, how can I manage all parameters send to servlets? in a case they are many, is it reasonable to check each one in turn??
You can't restrict the user from sending you anything.
It is the server-side where you can add restrictions.
Usually you get only the parameters you need, so additional parameters should not bother you.
You definitely should check parameters send to your servlet. Thats basically what you do anyways since thats the way clients (such as webpages) communicate with your application.
The simplest way is to hash the parameters with some hidden secret, and pass that back with the URL, then compare the hash to the URL parameters to make sure they match.
Another way is to not use individual parameters, but encrypt them in to a encoded bunch of characters and the whole thing is decrypted on return.
The hash is easier to implement if you don't care that the user sees the actual parameters.
You cannot avoid someone from typing in the URL, but what you do in your servlet is filter the input recieved from the URL, with some java code.
Example:
Just found an interesting link where a Servlet Filter is used to filter out XSS attacks(As you see, there is no such code that avoids someone to type certain characters in the URL, or similar): Link
Simply put, you cannot stop the users from changing the parameters.
You must do input validation on all parameter values. If you have a variable that contains sensitive information, you do not put that on the URL. A really bad example: http://mydomain.com/myservlet?isAdmin=1. Information such as that needs to go into a session since that is stored on the server and out of the user's reach.