Sending LinkedHashMap to intent - android

I want send LinkedHashMap to another Intent. But I don't known what method for extras is allowable.
Bundle extras = getIntent().getExtras();
LinkedHashMap<Integer, String[]> listItems = extras.get(LIST_TXT);

You cannot reliably send a LinkedHashMap as an Intent extra. When you call putExtra() with a LinkedHashMap, Android sees that the object implements the Map interface, so it serializes the name/value pairs into the extras Bundle in the Intent. When you want to extract it on the other side, what you get is a HashMap, not a LinkedHashMap. Unfortunately, this HashMap that you get has lost the ordering that was the reason you wanted to use a LinkedHashMap in the first place.
The only reliable way to do this is to convert the LinkedHashMap to an ordered array, put the array into the Intent, extract the array from the Intent on the receiving end, and then recreate the LinkedHashMap.
See my answer to this question for more gory details.

The best way is to convert it to ArrayList of the same type examble :
LinkedHashSet<Long> uniqueIds = new LinkedHashSet();
ArrayList<Long> ids = new ArrayList(uniqueIds);
Intent intent = new Intent(getContext(), UserStoryActivity.class);
intent.putParcelableArrayListExtra(FLAG_USERS_STORY_LIST_IDS, (ArrayList) ids);
startActivity(intent);

Thanks #David Wasser for pointing out this issue.
I have another approach is to use Gson to parse your whatever map to json string, then put into the intent. Less drama!
Code send:
gson.toJson(data)
Code get back:
Kotlin:
gson.fromJson<LinkedHashMap<Int, Int>>(
it.getStringExtra(ARG_DATA),
object : TypeToken<LinkedHashMap<Int, Int>>() {}.type
)
Java:
gson.fromJson(
it.getStringExtra(ARG_DATA),
new TypeToken<ArrayList<Mountain>>(){}.getType()
);

Related

How to pass a 2D array of double between activities?

I need to pass a 2D array of double between activities,this is what i wrote so far :
In the first activity (the sender ) :
Intent intent =new Intent(MapsActivity.this, RoutePath.class);
Bundle b = new Bundle();
b.putSerializable("other_locations", other_locations);
intent.putExtras(b);
startActivity(intent);
In the second one (the receiver ):
Intent intent = getIntent();
Bundle b = intent.getExtras();
double[][] other_locations=(double[][]) b.getSerializable("other_locations");
But I got the ClassCastException, am I doing something wrong?
Convert double 2D array to String 2D array and send it just like you did :
To send :
b.putSerializable("array", other_locations_string);
To get :
String[][] value = (String[][]) b.getSerializable("array");
And then again convert it into double 2d array.
The reason for this behaviour is because Java (and consequently Android) does not let you cast Objects to primitive types, or arrays of primitive types. Why? Because Java considers a valid cast one which converts a super-class object to a sub-class object or vice versa. String[][] extends Object, while double and double[][] do not.
Try this
Convert 2D Array into Hashmap and then use it
Map<Double, Double> map = new HashMap<Double, Double>(other_locations.length);
for (Double[] mapping : other_locations)
{
map.put(mapping[0], mapping[1]);
}
And set map as intent extra and get the extra in second activity

Anyway to have more than one extra added to intent?

I want to have more than one extra added to Intent. One to hold a double and one to hold long. Is this possible?
If so, how would I do it and how would I get the information from each extra?
You can add as many extras to an Intent as your heart desires, they are all just key value data:
Intent intent = new Intent();
intent.putExtra("name", "MyName");
intent.putExtra("age", 35);
intent.putExtra("weight", 155.6);
And they can be retrieved using the same key names:
String name = intent.getStringExtra("name");
int age = intent.getIntExtra("age", 0);
double weight = intent.getDoubleExtra("weight", 0.0);
intent.putExtra(#ExtraDoubleKey, #ExtraDoubleValue);
intent.putExtra(#ExtraLongKey, #ExtraLongValue);
Where #ExtraDoubleKey is a string that you will use to access the extra (i.e. "price" or something), and #ExtraDoubleValue is the value of the extra (the double variable you wish to pass). Similarly for #ExtraLongKey and #ExtraLongValue.
Then to access the extras in your next activity you can use:
double doubleValue = getIntent().getExtras().getDouble(#ExtraDoubleKey);
long longValue = getIntent().getExtras().getLong(#ExtraLongKey);
to get the value of the double extra with the key #ExtraDoubleKey.
https://stackoverflow.com/a/11461530/776075
Devunwired is correct.
But the way i see is
you can keep only one value per Type.
Like one string, one int, one double etc..
You are not capable of containing 2 string values. or two integers.
I have experienced this on a program and i have overcome it by using
one string and one Boolean.
You can use Bundle and pass it as a parameter to the Intent.
Intent nextActivity = new Intent(this, Activity2.class);
Bundle passData = new Bundle(); //to hold your data
passDataBndl.putString("fname", fname); //put in some String. the first parameter to it is the id, and the second parameter is the value
nextActivity.putExtras(passDataBndl); //Add bundle to the Intent
startActivityForResult(nextActivity, 0); //Start Intent

Java Android passing data Array double

I have a question about intent in android application
i have an array in class1
double [][] tableCityPair = new double[100][100];
---here code to fill array---
in the end of class i want to send tableCityPair to another class, class2.
how i should declare for array in class2 ?
is this right?
Intent it = getIntent();
double tabelJarakAntarKota= it.getDoubleExtra("tableCityPair",3);
The Bundle class has methods for passing and retrieving an array of doubles:
void putDoubleArray(String, double[])
double [] getDoubleArray(String)
However, these work for one-dimensional arrays. You are attempting to pass a 2D array. I do not know of a direct way to do this. One way to achieve this would be to put N arrays of doubles in a loop.
for(int i=0;i<tableCityPair.length;i++){
bundle.put("tableCity"+i, tableCityPair[i]);
}
And at the receiving end, you do:
double [] aPair = it.getExtras().getDoubleArray("tableCity"+i);
I'm not sure about the performance implications of this though; since you would be adding 100 extras as part of the bundle.
There could be a better way (perhaps make your pair a List<List<Double>> and then implement Parcelable) but I haven't tried any of it so I wouldn't suggest it.
double [][] tableCityPair = new double[100][100];
and then...
make intent it=....
then
put: `it.putExtra("size",tableCityPair.length)`
then:
for(i=0;i<tableCitypair.length;i++)
{
it.putExtra("table"+i,tableVityPair[i][]);
}
THEN in CLASS B
double [][] tableCityPairinB = new double[100][100];
for(i=0;i<getIntent().getExtras("size");i++)
{
double[i][]=getIntent().getExtras("table"+i);
}

Order of items in the keySet of Bundle

Is the order of items in the .keySet() of a Bundle in the same order as items were inserted? I am trying to send a LinkedHashMap through a parcelable from a service to the activity.
Here is the code to insert a linkedHashMap's items into a Bundle using .putSerializable:
Bundle b = new Bundle();
Iterator<Entry<Integer, String>> _cyclesIterator = cycles.entrySet().iterator();
while (_cyclesIterator.hasNext()) {
Entry<Integer, String> _entry = _cyclesIterator.next();
Log.i(TAG,"Writing to JSON CycleID" + _entry.getKey());
b.putSerializable(_entry.getKey().toString(), _entry.getValue());
}
_dest.writeBundle(b);
I am trying to read this back when the bundle is retrieved using this:
Bundle _b = in.readBundle();
if (_b != null) {
for (String _key : _b.keySet()) {
Log.i(TAG,"Reading JSON for cycle " + _key);
_lhm.put(Integer.valueOf(_key), (String)_b.getString(_key));
}
setCycles(_lhm);
}
When items go in, the log says [1,2,3,4] but when they're read back, it is [3,2,1,4]. Is there a way to ensure the same order in both?
Maps have different approach according to their use.
HashMap - The elements will be in an unpredictable, "chaotic", order.
LinkedHashMap - The elements will be ordered by entry order or last reference order, depending on the type of LinkedHashMap.
TreeMap - The elements are ordered by key.
For getting better idea you can also check this Answer.
Maps and sets (and Bundles) carry no inherent order. You could serialize a single TreeMap<Integer, String> instead of iterating and serializing each entry, or you could iterate like you're doing but then also store one more value -- an ArrayList (also serializable) of the keys.

NullPointerException from getIntent().getExtras().getString("to")

InboxDetailActivity.java:
Intent i = new Intent(InboxDetailActivity.this,Compose.class);
Bundle b = new Bundle();
b.putString("To", ConstantData.inbox_from);
Log.d("From Value", ConstantData.inbox_from);
b.putString("Subject", "RE:" + ConstantData.inbox_subject);
Log.d("Subject Value", ConstantData.inbox_subject);
b.putString("FromId", ConstantData.inbox_fromid);
Log.d("From Id Value",ConstantData.inbox_fromid);
i.putExtras(b);
startActivity(i);
Compose.java:
Intent i = getIntent();
Bundle b = i.getExtras();
to = b.getString("To");
subject = b.getString("Subject");
toId = b.getString("FromId");
I am getting NullPointerException at to = b.getString("To");
Bundle b = i.getExtras();
getExtras() returns null.
Agree with John's answer adding possible solution.
What you are doing is create a bundle , insert values in this and then pass this bundle.
And than you just fetch all the values one by one using its keys.
I am working with bundles but I simply add desired values directly using putExtra method. And I haven't got any problem till date. I recommend you to use put extra and check whether it works or not.
I would like to know what makes you to apply this way for bundles? Have you just read it somewhere and started applying this method ? or you have got some options and after some consideration you found it better to apply this method OR your requirement states that. Because normally me and my peers doesn't use bundles and directly pass the extras. And that works for me every time.
using this instead of bundle
i.putString("To", ConstantData.inbox_from);
Log.d("From Value", ConstantData.inbox_from);
i.putString("Subject", "RE:" + ConstantData.inbox_subject);
Log.d("Subject Value", ConstantData.inbox_subject);
i.putString("FromId", ConstantData.inbox_fromid);
Log.d("From Id Value",ConstantData.inbox_fromid);
and in another class..
to = getIntent().getString("To");

Categories

Resources