Passing Hashmap through android intents [duplicate] - android

This question already has answers here:
Android - How to pass HashMap<String,String> between activities?
(5 answers)
Closed 6 years ago.
I have a HashMap(String,HashMap(String,Object)) in one of my activity. How do I send this HashMap to another activity via intents
How to add this HashMap to intent extras?

Sending HashMap
HashMap<String, Object> hashmapobject =new HashMap<>();
HashMap<String, Object> newhashMap=new HashMap<>();
hashmapobject.put("key",newhashMap);
Intent intent = new Intent(SenderActivity.this, NextActivity.class);
intent.putExtra("hashMapKey", hashmapobject);
startActivity(intent);
Receiving HashMap
Intent intent = getIntent();
HashMap<String, Object> hashMapObject = (HashMap<String, Object>) intent.getSerializableExtra("hashMapKey");
HashMap<String, Object> newhashMap=(HashMap<String, Object>)hashMapObject.get("key");

There could be multiple approaches to your problem and each one depends on what datatype you are storing in map. Easiest approach is to use JSONObject from json.org pass it as String and while receiving convert it back to JSON. JSONObject uses a LinkedHashMap inside thus you will be able to use the features of HashMap.
JSONObject obj=new JSONObject();
obj.put("key1", "value1");
obj.put("key2", "value2");
obj.put("key3", "value3");
.
.
.
obj.put("keyN", "valueN");
intent.putExtra("map", obj.toString());
While receiving
JSONObject obj=new JSONObject(getIntent().getStringExtra("map"));
For complex datatypes try considering either JSON Libraries like GSON or use Parcelable interface.

Hi you can use Parcelable :
Write class like this :
public class Person implements Parcelable {
String name;
int age;
Date brithDate;
public Person(String name, int age, Date brithDate) {
this.name = name;
this.age = age;
this.brithDate = brithDate;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.name);
dest.writeInt(this.age);
dest.writeLong(brithDate != null ? brithDate.getTime() : -1);
}
protected Person(Parcel in) {
this.name = in.readString();
this.age = in.readInt();
long tmpbrithDate = in.readLong();
this.brithDate = tmpbrithDate == -1 ? null : new Date(tmpbrithDate);
}
public static final Parcelable.Creator<Person> CREATOR = new Parcelable.Creator<Person>() {
public Persona createFromParcel(Parcel source) {
return new Person(source);
}
public Person[] newArray(int size) {
return new Person[size];
}
};
Put extra :
intent.putExtra("person", new Person("Ahmad",34,date));
Get :
Bundle data = getIntent().getExtras();
Person person= (Person) data.getParcelable("person");
OR you can copy class this site and convert to Parcelable class :
http://www.parcelabler.com/
OR you can use this library hrisey
https://github.com/mg6maciej/hrisey/wiki/Parcelable#details
Or you can use Android Studio have plugins for this:
Android Parcelable code generator (Apache License 2.0)
Auto Parcel (The MIT License)
SerializableParcelable Generator (The MIT License)
Parcelable Code Generator (for Kotlin) (Apache License 2.0)

Related

Has there anyone integrated ODOO with Android?

I am currently developing an android application for a client who is insisting to use Odoo for API. I don't have any idea about it. I am not getting it even after referring to this link. They provide an URL, Database name, username, and password. If anyone did Odoo with Android before, can you give any suggestions?
There are a lot of ways to connect Android to Odoo. Here they are:
Json-RPC
XML-RPC (especially aXMLRPC, this is what I am using)
There is also a framework called Odoo Mobile Framework . I have tried it but found a lot of issues and I was not able to get it work properly. You can find the documentation here.
Odoo has a Web Service API which is available for Python, Ruby, PHP and Java. I strongly recommend to take a look.
For my case, I have cloned the aXMLRPC git repository, created a package in my project and adapted the original package name. But recently I have found this on Stack Overflow explaining how to add aXMLRPC to your Android project using Gradle (I didn't give it a try yet).
Odoo had made available three endpoints:
xmlrpc/2/db to get the list of available databases on your server, it does not require to be authenticated;
xmlrpc/2/common to log in to the server, it does not require to be authenticated;
xmlrpc/2/object, is used to call methods of odoo models via the execute_kw RPC function.
public class OdooConnect {
String url;
private XMLRPCClient client;
public OdooConnect(String serverAddress, String path) {
url = serverAddress + "/xmlrpc/2/" + path;
client = new XMLRPCClient(url);
}
public Object login(String db, String username, String password) {
Object object;
try {
object = client.call("login", db, username, password);
return object;
} catch (XMLRPCException e) {
e.printStackTrace();
}
return null;
}
public Object checkServer() {
Object object;
try {
object = client.call("list", new Object[]{});
return object;
} catch (XMLRPCException e) {
e.printStackTrace();
}
return null;
}
}
In this class, the constructor as arguments the server address (it can be http(s)://your_ip_address:the_port_number) and the path ('db', 'common' or 'object').
The checkServer method returns an object which is actually an array containing the list of available databases.
The login mehtod returns an Integer which is the Id of the authenticated user.
For the Odoo CRUD mehtods (search_read, search_count, search, write, create, unlink) you can take a look to the Odoo Web Service API Java code matching the method you want.
Here is an example of the search_read method. I assume that you've an XMLRPCClient named client.
public Object search_read(String db, int user_id, String password, String object, List conditions, Map<String, List> fields) {
Object result = null;
try {
result = client.call("execute_kw", db, user_id, password, object, "search_read", conditions, fields);
} catch (XMLRPCException e) {
e.printStackTrace();
}
return result;
}
Where
object is an Odoo model for example "res.partner"
conditions is the domain (filter) something like this: Collections.singletonList(Collections.singletonList(Arrays.asList("supplier", "=", true)));
fields, the fields you want to get,
fields = new HashMap() {{put("fields", Arrays.asList("id","name","is_company","street")); }};
You must cast the result of the method to Object[] which will give you an array containing a list of objects each representing a record.
Object[] objects = (Object[]) result;
if (objects.length > 0) {
for (Object object : objects) {
String name= OdooUtil.getString((Map<String, Object>) object, "name");
boolean is_company= OdooUtil.getBoolean((Map<String, Object>) object, "is_company");
String street = OdooUtil.getString((Map<String, Object>) object, "street");
int id= OdooUtil.getInteger((Map<String, Object>) object, "id");
}
}
Here the OdooUtil class
public class OdooUtil {
public static String getString(Map<String, Object> map, String fieldName) {
String res = "";
if (map.get(fieldName) instanceof String) {
res = (String) map.get(fieldName);
}
return res;
}
public static Integer getInteger(Map<String, Object> map, String fieldName) {
Integer res = 0;
if (map.get(fieldName) instanceof Integer) {
res = (Integer) map.get(fieldName);
}
return res;
}
public static Double getDouble(Map<String, Object> map, String fieldName) {
Double res = 0.0;
if (map.get(fieldName) instanceof Double) {
res = (Double) map.get(fieldName);
}
return res;
}
public static Boolean getBoolean(Map<String, Object> map, String fieldName) {
Boolean res = false;
if (map.get(fieldName) instanceof Boolean) {
res = (Boolean) map.get(fieldName);
}
return res;
}
public static Float getFloat(Map<String, Object> map, String fieldName) {
Float res = 0f;
if (map.get(fieldName) instanceof Float) {
res = (Float) map.get(fieldName);
}
return res;
}
}
If you have a many2one field you only have access to the id and the name of the related record. You can use the following class to get the id and the name of the many2one record.
public class Many2One {
private int id;
private String name;
public Many2One() {
}
public static Many2One getMany2One(Map<String, Object> stringObjectMap, String fieldName) {
Integer fieldId = 0;
String fieldValue = "";
Many2One res = new Many2One();
if (stringObjectMap.get(fieldName) instanceof Object[]) {
Object[] field = (Object[]) stringObjectMap.get(fieldName);
if (field.length > 0) {
fieldId = (Integer) field[0];
fieldValue = (String) field[1];
}
}
res.id = fieldId;
res.name = fieldValue;
return res;
}
public int getId() {
return id;
}
public String getName() {
return name;
}
}
Example of usage of Many2One class
String partner_name= Many2One.getMany2One((Map<String, Object>) object, "partner_id").getName();
int partner_id= Many2One.getMany2One((Map<String, Object>) object, "partner_id").getId();
For other remaining CRUD methods, you can easily find a way how they work by reading the Odoo Web Service API documentation.
I hope this gives you some insights.
This is Just an Example did to access contacts/partners from odoo:
#!/usr/bin/env python
import csv
from xmlrpclib import ServerProxy
SERVER = 'http://localhost:8069'
DATABASE = 'testcompany'
USERNAME = 'admin'
PASSWORD = 'password'
FILE_PATH = 'ODOO_clientsMain2_test.csv'
server = ServerProxy('http://localhost:8069/xmlrpc/common')
user_id = server.login(DATABASE, USERNAME, PASSWORD)
server = ServerProxy('http://localhost:8069/xmlrpc/object')
def search(list, key):
for item in list:
return item[key]
reader = csv.reader(open(FILE_PATH,'rb'))
for row in reader:
#print row
partner_template = {
'name': row[0],
#'company_id': row[1],
}
if row[2] is not None and row[2]<>'':
partner_template.update({'email': row[2]})
if row[5] is not None and row[5]<>'':
partner_template.update({'tin': row[5]})
if row[6] is not None and row[6]<>'':
partner_template.update({'ref': row[6]})
if row[8] is not None and row[8]<>'':
partner_template.update({'phone': row[8]})
if row[9] is not None and row[9]<>'':
partner_template.update({'mobile': row[9]})
print partner_template
partner_id = server.execute_kw(DATABASE, user_id, PASSWORD, 'res.partner', 'create', [partner_template])
#create External ID
external_ids = {
'model': 'res.partner',
'name': row[11],
'res_id': partner_id,
}
external_id = server.execute_kw(DATABASE, user_id, PASSWORD, 'ir.model.data', 'create', [external_ids])
# update related fields
if row[7] is not None and row[7]<>'':
#look up and update payment term
payment_term_id = server.execute_kw(DATABASE, user_id, PASSWORD, 'account.payment.term', 'search_read', [[['name','=',row[7]],['active', '=', True]]],{'fields': ['id'], 'limit': 1})
if payment_term_id is not None:
id = server.execute_kw(DATABASE, user_id, PASSWORD, 'res.partner', 'write', [[partner_id],{'property_payment_term': search(payment_term_id,'id')}])
if row[10] is not None and row[10]<>'':
#look up and update pricelist
pricelist_id = server.execute_kw(DATABASE, user_id, PASSWORD, 'product.pricelist', 'search_read', [[['name','=',row[10]],['active', '=', True]]],{'fields': ['id'], 'limit': 1})
if pricelist_id is not None:
id = server.execute_kw(DATABASE, user_id, PASSWORD, 'res.partner', 'write', [[partner_id],{'property_product_pricelist': search(pricelist_id,'id')}])
If you are creating your application from stretch and only required Android API for Odoo, here is open-source API https://github.com/oogbox/odoo-mobile-api (Odoo android api)
To use in android, first add the following dependency to your app level build.gradle
compile 'com.oogbox.api:odoo:1.0.0'
Documentation: https://github.com/oogbox/odoo-mobile-api#getting-started
Thanks

Naming convention with Firebase serialization/deserialization?

I wonder to know how Firebase serialize/deserialize POJO object to/from json, does it use Jackson or Gson or any similar library else.
I have trouble about naming convention with Firebase. My model some like this:
class Data {
private String someFieldName;
private String anotherFieldName;
public Data() {}
public void setSomeFieldName(String) {...}
public String getSomeFieldName(String) {...}
public void setAnotherFieldName(String) {...}
public String getAnotherFieldName() {...}
}
And the expected result in Firebase should be:
{
"some_field_name" : "...",
"another_field_name" : "..."
}
with Gson I can use FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES for my purpose, as in Gson doc:
Here's a few examples of the form "Java Field Name" ---> "JSON Field Name":
someFieldName ---> some_field_name
_someFieldName ---> _some_field_name
aStringField ---> a_string_field
aURL ---> a_u_r_l
How can I convert my POJO object to "Firebase value" with specific naming convention and vice versa, or there are any way to customize the serialize/deserialize process?
Thanks!
When reading the data back from the Firebase database you can use the #PropertyName annotation to mark a field to be renamed when being serialized/deserialized, like so:
#IgnoreExtraProperties
class Data {
#PropertyName("some_field_name")
public String someFieldName
#PropertyName("another_field_name")
private String anotherFieldName;
public Data() {}
}
Make sure that your field is public and not private or else the annotation will not work (I also believe that Firebase uses Jackson to handle the object mapping under the hood, but don't think you can actually customize HOW it uses it).
Personally I prefer keeping explicit control over the serialization/deserialization process, and not relying on specific framework and/or annotations.
Your Data class can be simply modified like this :
class Data {
private String someFieldName;
private String anotherFieldName;
public Data() {}
public Data(Map<String, Object> map) {
someFieldName = (String) map.get("some_field_name") ;
anotherFieldName = (String) map.get("another_field_name") ;
}
public Map<String, Object> toMap() {
Map<String, Object> map = new HashMap<>();
map.put("some_field_name", someFieldName);
map.put("another_field_name", anotherFieldName);
return map ;
}
}
For writing value to firebase, simply do :
dbref.setValue(data.toMap());
For reading :
Map<String, Object> map = (Map<String, Object>) dataSnapshot.getValue();
data = new Data(map);
They are some advantages with this solution :
No assumption is made on underlying json framework
No need to use annotations
You can even further decouple you Object model from your Json model by externalizing the methods toMap() and constructor to a DataMapper (snippet hereunder)
public static Data fromMap(Map<String, Object> map) {
String someFieldName = (String) map.get("some_field_name") ;
String anotherFieldName = (String) map.get("another_field_name") ;
return new Data(someFieldName, anotherFieldName);
}
public static Map<String, Object> toMap(Data data) {
Map<String, Object> map = new HashMap<>();
map.put("some_field_name", data.getSomeFieldName());
map.put("another_field_name", data.getAnotherFieldName());
return map ;
}

Android: How can i sort HashMap by values from two sources?

I have created a records based on date, name and url from default browser and google chrome. I combine the history information based on the two browser and display it using Hashmap. So now what i am trying to do is I would like to do a sort by date and also by name. However, due to my knowledge i am facing difficulties implementing it. Any advice and suggestions will be greatly appreciated. Thank you in advance.
//default browser
if (mCur.moveToFirst() && mCur.getCount() > 0) {
int titleIdx = mCur.getColumnIndex(Browser.BookmarkColumns.TITLE);
int urlIdx = mCur.getColumnIndex(Browser.BookmarkColumns.URL);
int dateIdx = mCur.getColumnIndex(Browser.BookmarkColumns.DATE);
while (mCur.isAfterLast() == false) {
HashMap temp = new HashMap();
temp.put(FIRST_COLUMN,getDate(mCur.getLong(dateIdx), "dd/MM/yyyy HH:mm:ss "));
temp.put(SECOND_COLUMN, mCur.getString(titleIdx));
temp.put(THIRD_COLUMN, mCur.getString(urlIdx));
list.add(temp);
mCur.moveToNext();
}
}
//google chrome
if (mCur2.moveToFirst() && mCur2.getCount() > 0) {
int dateIdx2 = mCur2.getColumnIndex(Browser.BookmarkColumns.DATE);
int titleIdx2 = mCur2.getColumnIndex(Browser.BookmarkColumns.TITLE);
int urlIdx2 = mCur2.getColumnIndex(Browser.BookmarkColumns.URL);
while (mCur2.isAfterLast() == false) {
HashMap temp = new HashMap();
temp.put(FIRST_COLUMN, getDate(mCur2.getLong(dateIdx2), "dd/MM/yyyy HH:mm:ss "));
temp.put(SECOND_COLUMN, mCur2.getString(titleIdx2));
temp.put(THIRD_COLUMN, mCur2.getString(urlIdx2));
list.add(temp);
mCur2.moveToNext();
}
}
Create a Model class for your data with sorting comparators like below:
public class MyItem {
String title;
String url;
String date;
public MyItem(String title, String url, String date) {
this.title = title;
this.url = url;
this.date = date;
}
public static Comparator<MyItem> sortByDate = new Comparator<MyItem>() {
#Override
public int compare(MyItem item1, MyItem item2) {
return item1.date.compareTo(item2.date);
}
};
public static Comparator<MyItem> sortByTitle = new Comparator<MyItem>() {
#Override
public int compare(MyItem item1, MyItem item2) {
return item1.title.compareTo(item2.title);
}
};
}
Then use it like this in your code
Create a list/array of Myitems
then call the function to sort => Arrays.sort(yourMyItemsObject, MyItem.sortByTitle);
Change the code of compare() Method as per your need of sort.
Use Inner class concept for sorting the hash map, dont use two hash map,
First sort the hash map of class level and then sort the hash value, by this in the same hash map you will get the both sorted value
Look at Sortable HashMap-like data structure in Java? for using sortable HashMap like data structures.
You'll need to combine all data into one Map object and then sort it just before you want to display the result to the user.
good luck

Write and Read an object array to parcelable

I have a JSON file that is being parsed with Gson. The problem I have is there are nested arrays in the Json e.g.
"assets":[
{
"Address":"Crator1, The Moon",
"Title":"The Moon",
"AudioFile":null,
"Categories":[
{
"CategoryName":"Restaurants",
"Description":"blah blah",
"ExternalLink":"",
"File":"",
"FileName":"0",
"CategoryID":0,
"ParentCategoryID":786,
"Id":334,
"Image":"",
},
I know it's invalid, it's just for an example. So based on previous questions I have asked and research I believe I should have my code as follows in order to parse the JSON correctly:
public class JsonAssets implements Parcelable{
String Address;
String Title;
String AudioFile;
Categories[] categories;
private class Categories{
String CategoryName;
String Description;
String ExternalLink;
String File;
String FileName;
int CategoryID;
int ParentCategoryID;
int Id;
String Image;
}
}
The class is passed as follows:
JsonReader reader = new JsonReader(new InputStreamReader(is, "UTF-8"));
reader.beginObject();
reader.nextName();
reader.beginArray();
JsonObject obj = null;
while (reader.hasNext()) {
try{
switch(type){
case ASSET_UPDATE:
obj = gson.fromJson(reader, JsonAsset.class);
break;
}
So I read and write the address, audio file as so:
public static final Parcelable.Creator<AssetJson> CREATOR = new Parcelable.Creator<AssetJson>() {
public AssetJson createFromParcel(Parcel in) {
return new AssetJson(in);
}
public AssetJson[] newArray(int size) {
return new AssetJson[size];
}
};
public void writeToParcel(Parcel paramParcel, int paramInt) {
paramParcel.writeString(Address);
paramParcel.writeString(Title);
paramParcel.writeString(AudioFile);
}
private JsonAsset(Parcel in) {
Address = in.readString();
Title = in.readString();
AudioFile = in.readString();
}
The problem I have is I don't know how to read and write Categories[] to the parcel. The fact that it is an object array has me stumped.
This is my first experience with parcelables and I'm trying to take over someone elses code. So if anyone could explain how I would parcel an object array, I'd greatly appreciate it.
Thank you!
Simple, first make your Category class implement Parcelable, implement all the logic for reading and writing back there, then use Parcel class writeParcelableArray method to write an array of parcelables.
Hope this help.
I managed to find the correct solution (for me) so if anyone else is coming up against this, follow this link:
http://www.javacreed.com/gson-deserialiser-example/
It shows how to parse nested array and deserialize.

Deserialize JSON with Gson in an object

I have a JSON string such as below. That comes from a Website (the URL outputs below to a page) which I'm using in an android application.
{"posts": [{"id":"0000001","longitude":"50.722","latitude":"-1.87817","position":"Someplace 1","altitude":"36","description":"Some place 1 "},{"id":"0000002","longitude":"50.722","latitude":"-1.87817","position":"Some PLace 2","altitude":"36","description":"Some place 2 description"}]}
I would like to deserialize this into a List where I can iterate through them later on the application. How do I do this? I have created a class with properties and methods and a List class as below and then using fromJson to deserialize it, but it returns NULL. Hope the question is clear and many thanks in advance.
ListClass
package dataaccess;
import java.util.List;
public class LocationList {
public static List<Location> listLocations;
public void setLocationList(List <Location> listLocations) {
LocationList.listLocations = listLocations;
}
public List<Location> getLocationList() {
return listLocations;
}
}
GSON
public LocationList[] getJsonFromGson(String jsonURL) throws IOException{
URL url = new URL(jsonURL);
String content = IOUtils.toString(new InputStreamReader(url.openStream()));
LocationList[] locations = new Gson().fromJson(content, LocationList[].class);
return locations;
}
You try to deserialize into an array of LocationList objects - that surely wasn't your intent, was it? The json snippet doesn't contain a list of lists.
I would drop the class LocationList (except it ought to be extened in future?), and use a pure List. Then, you have to create a type token like this:
java.lang.reflect.Type type = new com.google.gson.reflect.TypeToken<ArrayList<Location>>() {}.getType();
List<Location> locations = new Gson().fromJson(content, type);
What if this JSON response can be parsed using native classes, here is a solution for the same:
String strJsonResponse="Store response here";
JsonObject obj = new JsonObject(strJsonResponse);
JsonArray array = obj.getJsonArray("posts");
for(int i=0; i<array.length; i++)
{
JsonObject subObj = array.getJsonObject(i);
String id = subObj.getString("id");
String longitude = subObj.getString("longitude");
String latitude = subObj.getString("latitude");
String position = subObj.getString("position");
String altitude = subObj.getString("altitude");
String description = subObj.getString("description");
// do whatever procedure you want to do here
}

Categories

Resources