How to save List Of HashMap in android? - java

I have a hashmap of string
HashMap<String, String> hashMap = new HashMap<>();
hashMap.put("name", name);
hashMap.put("number", number);
hashMap.put("profileImage", image);
and a List of Hashmap
List<HashMap<String, String>> recents = new ArrayList<>();
recents.add(hashMap);
Now I have to save this list
I have tried using https://github.com/pilgr/Paper to save this List
Paper.book().write("recents", recents);
but i can't get the list back
List<HashMap<String, String>> list = Paper.book().read("recents");
HashMap<String,String> hashMap = list.get(0);
String name = hashMap.get("name");
String number = hashMap.get("number");
String image = hashMap.get("profileImage");
Uses of the code
actually I'm passing this list to recycelerViewAdapeter and from there in OnBindViewHolder() I'm getting all the Hashmap values and displaying it to user
Saving Data Code
Paper.init(this);
List<HashMap<String, String>> recents = new ArrayList<>();
HashMap<String, String> hashMap = new HashMap<>();
hashMap.put("name", name);
hashMap.put("number", number);
hashMap.put("profileImage", image);
recents.add(hashMap);
Paper.book().write("recents", contacts);
Receiving Data Code
Paper.init(requireActivity());
recyclerView = view.findViewById(R.id.recyclerView);
List<HashMap<String, String>> list = Paper.book().read("recents");
Adapter = new Adapter(requireActivity(), list);
recyclerView.setAdapter(Adapter);

You can use Gson and SharedPreferences to do the same.
implementation 'com.google.code.gson:gson:2.8.9'
Example:
private SharedPreferences sp;
private HashMap<String, Boolean> favs;
....
....
public void addFavourite(String wall_name) {
favs = getFavourites();
favs.put(wall_name, true);
setFavourties();
}
public void removeFav(String wall_name) {
favs = getFavourites();
favs.put(wall_name, false);
setFavourties();
}
private void setFavourties() {
SharedPreferences.Editor pe = sp.edit();
Gson gson = new Gson();
String j = gson.toJson(favs);
pe.putString("Favourites", j);
pe.apply();
}
public HashMap<String, Boolean> getFavourites() {
Gson gson = new Gson();
String j = sp.getString("Favourites", null);
if (j != null) {
Type stringBooleanMap = new TypeToken<HashMap<String, Boolean>>() {
}.getType();
return gson.fromJson(j, stringBooleanMap);
} else {
return new HashMap<>();
}
}

Related

How do pass multiple data types to HashMap

I am trying to pass string and int data (possibly other data types like time) to a HashMap to use in a doinbackground task in Android to amend a URL. The URL uses key value pairs to update a mysql database.
I've read about using an object to pass multiple variable types, but can't get it to work.
private void addChore(){
final String title2 = editTextTaskTitle.getText().toString().trim();
final String description2 = editTextDescription.getText().toString().trim();
final String person2 = itemPerson.toString().trim();
final int monday2 = cbMon;
class NewChore1 {
String title1;
String description1;
String person1;
int monday1;
NewChore1(String title1, String description1, String person1, int monday1){
this.title1 = title1;
this.description1 = description1;
this.person1 = person1;
this.monday1 = monday1;
}
}
class AddChoreM extends AsyncTask<Void,Void,String> {
ProgressDialog loading;
#Override
protected void onPreExecute() {
super.onPreExecute();
loading = ProgressDialog.show(AddChore.this,"Adding...","Wait...",false,false);
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
loading.dismiss();
Toast.makeText(AddChore.this,s,Toast.LENGTH_LONG).show();
}
#Override
protected String doInBackground(Void... v) {
HashMap<String, NewChore1> params1 = new HashMap<>();
params1.put(Config.KEY_CHORE_TASK_TITLE,?);
params1.put(Config.KEY_CHORE_DESCRIPTION,?);
params1.put(Config.KEY_CHORE_PERSON,?);
params1.put(Config.KEY_CHORE_MONDAY,?);
RequestHandler rh = new RequestHandler();
String res = rh.sendPostRequest(Config.URL_ADD, params1);
return res;
}
}
NewChore1 params = new NewChore1(title2, description2, person2, monday2);
AddChoreM addChoreM = new AddChoreM();
addChoreM.execute(params);
}
In RequestHandler, I have used the following.
private String getPostDataString(HashMap<String, Object> params) throws UnsupportedEncodingException {
StringBuilder result = new StringBuilder();
boolean first = true;
for (Map.Entry<String, Object> entry : params.entrySet()) {
if (first)
first = false;
else
result.append("&");
result.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
result.append("=");
result.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
}
return result.toString();
}
Edit: I was not quick enough so there are other answers already but the changes below should work. You can pass your NewChore1 object to your task and extract the parameters in doInBackground:
class AddChoreM extends AsyncTask<NewChore1,Void,String> {
And:
#Override
protected String doInBackground(NewChore1...chore) {
HashMap<String, String> params1 = new HashMap<>();
params1.put(Config.KEY_CHORE_TASK_TITLE, chore[0].title1);
params1.put(Config.KEY_CHORE_DESCRIPTION, chore[0].description1);
params1.put(Config.KEY_CHORE_PERSON,chore[0].person1);
params1.put(Config.KEY_CHORE_MONDAY,chore[0].monday1);
RequestHandler rh = new RequestHandler();
String res = rh.sendPostRequest(Config.URL_ADD, params1);
return res;
}
Finally:
NewChore1 params = new NewChore1(title2, description2, person2, monday2);
new addChoreM.execute(params);
Update:
Since sendPostRequest only accepts HashMap<String, String> you need to change to: HashMap<String, String> params1 = new HashMap<>();
And change your NewChore1 class to take only Strings.
If you use
Map<String, Object> params1 = new HashMap<>();
then you can store any type as value within the map.
Create a constructor for AddChoreM class and set your NewChore1 object through it. You can now easily extract the properties of NewChore1 in doInBackground.
class AddChoreM extends AsyncTask<Void,Void,String> {
ProgressDialog loading;
NewChore1 newChore1Obj;
public AddChoreM(NewChore1 newChore1Obj){
this.newChore1Obj = newChore1Obj;
}
#Override
protected String doInBackground(Void...v) {
HashMap<String, NewChore1> params1 = new HashMap<>();
String res = "";
if(newChore1Obj != null) {
params1.put(Config.KEY_CHORE_TASK_TITLE, newChore1Obj.title1);
params1.put(Config.KEY_CHORE_DESCRIPTION, newChore1Obj.description1);
params1.put(Config.KEY_CHORE_PERSON,newChore1Obj.person1);
params1.put(Config.KEY_CHORE_MONDAY,newChore1Obj.monday1);
RequestHandler rh = new RequestHandler();
res = rh.sendPostRequest(Config.URL_ADD, params1);
}
return res;
}
// Other methods of AsyncTask
//
}
Finally, create and execute AddChoreM like this.
NewChore1 params = new NewChore1(title2, description2, person2, monday2);
AddChoreM addChoreM = new AddChoreM(params);
addChoreM.execute();

Can't retrieve Double from HashMap<Integer, Double>

Somehow I can't retrieve a Double from a HashMap I've made using Gson.
Map<Integer, Double> ratingMap = (Map<Integer, Double>) new GsonBuilder()
.create().fromJson(json, Map.class);
Integer ifilmId = filmId;
Double rating = ratingMap.get(ifilmId);
In this code I've veried that the ratingMap contains {2=5.0}, but when I do ratingMap.get(ifilmId) (where I've verified that ifilmId is in fact 2), the variable rating is null. Am I missing something here?
I create the HashMap in the following way:
if (json.equals("")) {
// noting ever saved
ratingMap = new HashMap<Integer, Integer>();
ratingMap.put(filmId, rating);
} else {
ratingMap = (Map<Integer, Integer>) new GsonBuilder().create()
.fromJson(json, Map.class);
ratingMap.put(Integer.valueOf(filmId), rating);
}
I let Gson format the Integer to a Double, and that seems to work fine but I can't retrieve it.
The total code, including saving to Androids SharedPreferences
public void saveRating(int rating, int filmId) {
SharedPreferences sharedPref = context.getSharedPreferences(
LOCAL_MEM_KEY, 0);
String json = sharedPref.getString(LOCAL_MAP_RATING_KEY, "");
Map<Integer, Integer> ratingMap;
if (json.equals("")) {
// noting ever saved
ratingMap = new HashMap<Integer, Integer>();
ratingMap.put(filmId, rating);
} else {
ratingMap = (Map<Integer, Integer>) new GsonBuilder().create()
.fromJson(json, Map.class);
ratingMap.put(Integer.valueOf(filmId), rating);
}
json = new GsonBuilder().create().toJson(ratingMap, Map.class);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putString(LOCAL_MAP_RATING_KEY, json);
editor.commit();
}
/*
* returns null if no rating found
*/
public Map<Integer, Integer> getRatingFor(int filmId) {
SharedPreferences sharedPref = context.getSharedPreferences(
LOCAL_MEM_KEY, 0);
String json = sharedPref.getString(LOCAL_MAP_RATING_KEY, "");
if (json.equals("")) {
return null;
}
Map<Integer, Integer> ratingMap = (Map<Integer, Integer>) new GsonBuilder()
.create().fromJson(json, Map.class);
Log.d("map", ratingMap.toString());
Integer ifilmId = filmId;
Integer rating = ratingMap.get(ifilmId);
if(rating == null) { //because of this we have to prevent a 0 rating
return null;
} else {
Map<Integer, Integer> returnMap = new HashMap<Integer, Integer>();
returnMap.put(filmId, rating.intValue());
return returnMap;
}
}
Make sure your not passing a null variable when saving
saveRating(int rating, int filmId){
Log.d(TAG, String.valueOf(rating));
}
if (json.equals("")) {
// noting ever saved
ratingMap = new HashMap<Integer, Double>(); <--- Double not Integer
ratingMap.put(filmId, 5.0);
} else {
ratingMap = (Map<Integer, Double>) new GsonBuilder().create()
.fromJson(json, Map.class); <--- double not Integer
ratingMap.put(Integer.valueOf(filmId), 5.0);
}
Make sure when using Doubles to
use 5.0
not 5
public void saveRating(Double rating, int filmId) {
SharedPreferences sharedPref = context.getSharedPreferences(LOCAL_MEM_KEY, 0);
String json = sharedPref.getString(LOCAL_MAP_RATING_KEY, "");
Map<Integer, Double> ratingMap;
if (json.equals("")) {
// noting ever saved
ratingMap = new HashMap<Integer, Double>();
} else {
ratingMap = (Map<Integer, Double>) new GsonBuilder().create().fromJson(json, Map.class);
}
ratingMap.put(filmId, rating);
ratingMap.put(3, 5.0d); // JUST FOR TEST
json = new GsonBuilder().create().toJson(ratingMap, Map.class);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putString(LOCAL_MAP_RATING_KEY, json);
editor.commit();
}
/*
* returns null if no rating found
*/
public Map<Integer, Double> getRatingFor(int filmId) {
SharedPreferences sharedPref = context.getSharedPreferences(LOCAL_MEM_KEY, 0);
String json = sharedPref.getString(LOCAL_MAP_RATING_KEY, "");
if (json.equals("")) {
return null;
}
Map<Integer, Double> ratingMap = (Map<Integer, Double>) new GsonBuilder().create().fromJson(json, Map.class);
Log.d("map", ratingMap.toString());
Log.d("map", ratingMap.get(3) + ""); // JUST FOR TEST
Integer ifilmId = filmId;
Double rating = ratingMap.get(ifilmId);
if (rating == null) { //because of this we have to prevent a 0 rating
return null;
} else {
Map<Integer, Double> returnMap = new HashMap<Integer, Double>();
returnMap.put(filmId, rating);
return returnMap;
}
}

ArrayExceptionOut Of Bound

Updated Question from previous: I filled an array through HashMap, Iam using Asynctask for http request & after filling array put that array in dialog box. When I first run my app it gives me an empty dialog box & didn't give any error but when I re run my app it shows all array elements in dialog box perfectly. Whats the reason ?
//JsonResponse Inner Class in main class
private class JsonResponse extends AsyncTask<String, Void, String>
{
String response = "";
private ArrayList<HashMap<String, String>> prServices_resultList =
new ArrayList<HashMap<String, String>>();
protected void onPostExecute(String result)
{
if(response.equalsIgnoreCase("Success"))
{
ResultList_List = prServices_resultList;
int s=0;
for (HashMap<String, String> hashServices : prServices_resultList)
{
Db_Services[s] = hashServices.get(android_S_CName);
Db_ServicesID[s] = hashServices.get(android_S_ID);
s++;
}
}
}
protected String doInBackground(final String... args)
{
JSONParser jParser = new JSONParser();
JSONArray jArrayServices = jParser.getJSONFromUrl(url_Services);
try
{
for (int i = 0; i < jArrayServices.length(); i++)
{
JSONObject jsonElements = jArrayServices.getJSONObject(i);
String S_id = jsonElements.getString(android_S_ID);
String S_name = jsonElements.getString(android_S_NAME);
HashMap<String, String> hashServices = new HashMap<String, String>();
// adding each child node to HashMap key
hashServices.put(android_S_ID, S_id);
hashServices.put(android_S_NAME, S_name);
// adding HashList to ArrayList
prServices_resultList.add(hashServices);
}
response = "Success";
}
catch(JSONException e)
{
e.printStackTrace();
}
return response;
}
}
In my main class have have a button & when i press i execute AsyncTask:
new JsonResponse().execute;
In main class above onCreate i declare like:
static ArrayList<HashMap<String, String>> ResultList_Services =
new ArrayList<HashMap<String, String>>();
String[] Db_Services = new String[ResultList_Services.size()];
String[] Db_ServicesID = new String[ResultList_Services.size()];
You are creating an empty map here:
ResultList_Services = new ArrayList<HashMap<String, String>>();
Then trying to initialize two arrays with the size of an empty map - being zero.
// ResultList_Services.size() will be zero
String[] Db_Services = new String[ResultList_Services.size()];
String[] Db_ServicesID = new String[ResultList_Services.size()];
So when you try adding to these arrays it will throw an OutOfBoundsException
You could make these Arrays into lists, then you can dynamically add elements as needed without needing to specify a size to start with. If you then need an Array (for other Methods) you can get an array from a list using List#toArray()
As per your comment
You could just create temporary arrays to which you add all the elements and then assign this to your other arrays, something like
protected void onPostExecute(String result)
{
if(response.equalsIgnoreCase("Success"))
{
ResultList_List = prServices_resultList;
String[] tmp_dbServ = new String[prServices_resultList.size()];
String[] tmp_dbServID = new String[prServices_resultList.size()];
int s=0;
for (HashMap<String, String> hashServices : prServices_resultList)
{
tmp_dbServ[s] = hashServices.get(android_S_CName);
tmp_dbServID[s] = hashServices.get(android_S_ID);
s++;
}
Db_Services = tmp_dbServ;
Db_ServicesID = tmp_dbServID;
}
}

Fill Array with HashMap<String, String>

Updated: I filled an array through HashMap, Iam using Asynctask for http request & after filling array put that array in dialog box. When I first run my app it gives me an empty dialog box & didn't give any error but when I re run my app it shows all array elements in dialog box perfectly. Whats the reason ?
//JsonResponse Inner Class in main class
private class JsonResponse extends AsyncTask<String, Void, String> {
String response = "";
private ArrayList<HashMap<String, String>> prServices_resultList = new ArrayList<HashMap<String, String>>();
protected void onPreExecute()
{
}
protected void onPostExecute(String result)
{
if(response.equalsIgnoreCase("Success"))
{
ResultList_List = prServices_resultList;
int z=0;
for (HashMap<String, String> hashList : prServices_resultList)
{
Av_List[z] = hashList.get(android_Av_ID);
Av_Lat[z] = Double.parseDouble(hashList.get(android_Av_LAT));
Av_Lng[z] = Double.parseDouble(hashList.get(android_Av_LONG));
z++;
}
}
}
protected String doInBackground(final String... args)
{
JSONParser jParser = new JSONParser();
JSONArray jArrayServices = jParser.getJSONFromUrl(url_Services);
try{
for (int i = 0; i < jArrayServices.length(); i++)
{
JSONObject jsonElements = jArrayServices.getJSONObject(i);
String S_id = jsonElements.getString(android_S_ID);
String S_name = jsonElements.getString(android_S_NAME);
HashMap<String, String> hashServices = new HashMap<String, String>();
// adding each child node to HashMap key
hashServices.put(android_S_ID, S_id);
hashServices.put(android_S_NAME, S_name);
// adding HashList to ArrayList
prServices_resultList.add(hashServices);
}
response = "Success";
}
catch(JSONException e)
{
e.printStackTrace();
}
return response;
}
}
In my main class when i press a button:
new JsonResponse().execute;
In main class above onCreate i declare like:
static ArrayList<HashMap<String, String>> ResultList_Services = new ArrayList<HashMap<String, String>>();
String[] Db_Services = new String[ResultList_Services.size()];
String[] Db_ServicesID = new String[ResultList_Services.size()];
Now I get an error: java.lang.ArrayIndexOutOfBoundsException: length=0; index=0
First of all, adding values to static field ResultList_Services accessible for UI-thread from the background thread is very bad practice. You should rewrite your code to be thread-safe. The are several options, here is the one:
private class JsonResponse extends AsyncTask<String, Void, String> {
private ArrayList<HashMap<String, String>> resultList = new ArrayList<HashMap<String, String>>();
...
protected String doInBackground(final String... args)
{
...
// adding HashList to private JsonResponse's field
resultList.add(hashServices);
...
}
protected void onPostExecute(String result)
{
if (response.equalsIgnoreCase("Success"))
{
ResultList_Services = resultList;
//TODO: notify your Activity/Dialog on completion
}
}
}
Concerning your question - the reason for not seeing new records, is that you show the dialog when there are no values in the ResultList. You should request to show it from onPostExecute, for example.
You need to do this -
for (HashMap<String, String> hashServices : ResultList_Services)
{
Db_Services[s] = hashServices.get(android_S_CName);
Db_ServicesID[s] = hashServices.get(android_S_ID);
s++;
}
in onPostExcecute() block of your asynctask.

Wrong convert Object from JSON

First, sorry for my poor English.
Second, my problem.
I trying convert to JSON and back this structure:
class Revision{
private String auth;
private HashMap<String, List<HashMap<String, Object>>> rev;
public String getAuth(){
return auth;
}
public HashMap<String, List<HashMap<String, Object>>> getRev(){
return rev;
}
public void setAuth(String auth){
this.auth = auth;
}
public void setRev(HashMap<String, List<HashMap<String, Object>>> rev){
this.rev = (HashMap<String, List<HashMap<String, Object>>>) rev.clone();
}
public String toString(){
return "Auth: " + auth + ", rev: " + rev;
}
}
I do it with this code:
public static void main (String[] argc){
Gson gson = new Gson();
Revision revision = new Revision();
HashMap<String, List<HashMap<String, Object>>> HM = new HashMap<String, List<HashMap<String, Object>>>();
List<HashMap<String, Object>> list = new ArrayList<HashMap<String, Object>>();
HashMap<String, Object> HMin = new HashMap<String, Object>();
HMin.put("id", 12);
HMin.put("type", "toster");
list.add(HMin);
HM.put("mark", list);
revision.setRev(HM);
revision.setAuth("ololo");
String json = gson.toJson(revision);
Revision test = new Gson().fromJson(json, Revision.class);
System.out.println(json);
System.out.println(revision);
System.out.println(test);
}
In finally I get this result:
{"auth":"ololo","rev":{"mark":[{"id":12,"type":"toster"}]}}
Auth: ololo, rev: {mark=[{id=12, type=toster}]}
Auth: ololo, rev: {mark=[{id=java.lang.Object#1c672d0, type=java.lang.Object#19bd03e}]}
As you can see, after convertation, Object-type parameters incorrect.
Please, can you tell me, how I can fix this trouble?
Thank you in advance!
Try this out and see if it is working? Yeah, I know you want to support Object type, but this is just for try sake.
Gson gson = new Gson();
Revision revision = new Revision();
HashMap<String, List<HashMap<String, String>>> HM = new HashMap<String, List<HashMap<String, String>>>();
List<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>();
HashMap<String, String> HMin = new HashMap<String, String>();
HMin.put("id", "12");
HMin.put("type", "toster");
list.add(HMin);
HM.put("mark", list);
revision.setRev(HM);
revision.setAuth("ololo");
String json = gson.toJson(revision);
Revision test = new Gson().fromJson(json, Revision.class);
System.out.println(json);
System.out.println(revision);
System.out.println(test);
[Edited]
Now try this snippet directly, with a respective change in Revision class.
Revision test = new Gson().fromJson("{\"auth\":\"ololo\",\"rev\":{\"mark\":[{\"id\":12,\"type\":13}]}}", Revision.class);
System.out.println(test);
Change this in Revision class to this,
HashMap<String, List<HashMap<String, Integer>>> HM = new HashMap<String, List<HashMap<String, Integer>>>();
This is to make sure that its working good with specific type. If it does, we will be sure that it can't work with Obejct type somehow. Then you can file a bug there, for their good. And for the time being you can switch to some other API, if you like to. You can find few options here.

Categories

Resources