Parsing Json string retrieving all fields - java

I have been trying to parse json with volley , somehow i managed to extract some data but i am unable parse other fields . What i am trying do is checking which user role is doctor and store only that user to a1 arraylist
{"user1":{"password":"******","presence":{"lastSeen":1484695229773,"status":"online"},"role":"Patient"},"user2":{"password":"******","presence":{"lastSeen":1484695229773,"status":"offline"},"role":"Doctor"}}
here is my code :
public class Users extends AppCompatActivity {
ListView usersList;
TextView noUsersText;
ArrayList<String> al = new ArrayList<>();
int totalUsers = 0;
ProgressDialog pd;
private Firebase mRef;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_users);
usersList = (ListView)findViewById(R.id.usersList);
noUsersText = (TextView)findViewById(R.id.noUsersText);
pd = new ProgressDialog(Users.this);
pd.setMessage("Loading...");
pd.show();
String url = "https://**********.firebaseio.com/users.json";
StringRequest request = new StringRequest(Request.Method.GET, url, new Response.Listener<String>(){
#Override
public void onResponse(String s) {
doOnSuccess(s);
}
},new Response.ErrorListener(){
#Override
public void onErrorResponse(VolleyError volleyError) {
System.out.println("" + volleyError);
}
});
RequestQueue rQueue = Volley.newRequestQueue(Users.this);
rQueue.add(request);
usersList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
UserDetails.chatWith = al.get(position);
startActivity(new Intent(Users.this, Chat.class));
}
});
}//oncreate ends here
public void doOnSuccess(String s){
try {
JSONObject obj = new JSONObject(s);
Iterator i = obj.keys();
String key = "";
while(i.hasNext()){
key = i.next().toString();
if(!key.equals(UserDetails.username)) {
al.add(key); /// here want to store only user with doctor role
//currently all users are displaying
}
totalUsers++;
}
} catch (JSONException e) {
e.printStackTrace();
}
if(totalUsers <=1){
noUsersText.setVisibility(View.VISIBLE);
usersList.setVisibility(View.GONE);
}
else{
noUsersText.setVisibility(View.GONE);
usersList.setVisibility(View.VISIBLE);
usersList.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, al));
}
pd.dismiss();
}
}
i am successfully getting the Root Object "user1" and "user2" but i want to extract all other fields as well
kindly tell how i have to change my code for all fields.
EDITED
public void doOnSuccess(String s){
try {
JSONObject obj = new JSONObject(s);
Iterator i = obj.keys();
String key = "";
while(i.hasNext()){
key = i.next().toString();
JSONObject singleUser = (JSONObject) obj.get(key);
String role = singleUser.get("role").toString();
if(!key.equals(UserDetails.username)) {
if (role.equals("Doctor")) {
// doctors.add(keys);
al.add(key);
}
}
totalUsers++;
}
} catch (JSONException e) {
e.printStackTrace();
}
if(totalUsers <=1){
noUsersText.setVisibility(View.VISIBLE);
usersList.setVisibility(View.GONE);
}
else{
noUsersText.setVisibility(View.GONE);
usersList.setVisibility(View.VISIBLE);
usersList.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, al));
}
pd.dismiss();
}
}

You get the values from the User Object as follows
JSONObject user = obj.getJSONObject("user1");
String role = user.getString("role");
JSONObject presence = user.getJSONObject("presence");
String status = presence.getString("status");

This should give all users with doctor role.
JSONParser parser = new JSONParser();
Object obj = parser.parse(new FileReader(
"sample.json"));
JSONObject jsonObject = (JSONObject) obj;
Set<String> keySet = jsonObject.keySet();
List<String> doctors = new ArrayList<>();
for (String keys : keySet) {
JSONObject singleUser = (JSONObject) jsonObject.get(keys);
String role = singleUser.get("role").toString();
if (role.equals("Doctor")) {
doctors.add(keys);
}
}
System.out.println("Doctor users are --" + doctors);
Output -
Doctor users are --[user2]

You have embedded JSON objects that can be easily accessed by the JSON object method: (assuming 'userList' is your root JSONObject);
JSONObject user2 = userList.getJSONObject("user2");
These objects can then have their properties accessed via:
String user2Password = user2.getString("password");
Note the property 'presence' is also an embedded JSONObject, and so will have to be accessed with the JSONObject.getJSONObject() method.
So if you want to store these values in an ArrayList, simply create:
ArrayList<JSONObject> userArrayList = new ArrayList<JSONObject>();
... and then proceed to store values (probably iteratively) with:
userArrayList.add(user2);

Related

Value type org.json.JSONObject cannot be converted to JSONArray

Not sure where I make a mistake.
Code:
public class VaccinationTotalUSA extends Fragment {
RecyclerView rvRecentRecord;
ProgressBar progressBar;
private static final String TAG = VaccinationTotalUSA.class.getSimpleName();
ArrayList<VaccinationTimeline> recentRecords;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_vaccination, container, false);
// call view
rvRecentRecord = view.findViewById(R.id.vaccinationRecord);
progressBar = view.findViewById(R.id.progress_circular_vaccination);
rvRecentRecord.setLayoutManager(new LinearLayoutManager(getActivity()));
// Volley Fetch
getDataFromServer();
return view;
}
private void showRecyclerView() {
VaccinationAdapter vaccinationAdapter = new VaccinationAdapter(recentRecords);
rvRecentRecord.setAdapter(vaccinationAdapter);
}
private void getDataFromServer() {
String url = "https://disease.sh/v3/covid-19/vaccine/coverage/countries/USA";
recentRecords = new ArrayList<>();
StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
progressBar.setVisibility(View.GONE);
if (response != null) {
Log.e(TAG, "onResponse:" + response);
try {
JSONObject jsonObject = new JSONObject(response);
JSONArray jsonArray = jsonObject.getJSONArray("timeline");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject data = jsonArray.getJSONObject(i);
Iterator key = data.keys();
while (key.hasNext()) {
String timedata = key.next().toString();
recentRecords.add(new VaccinationTimeline(key, timedata));
}
}
showRecyclerView();
}catch (JSONException e) {
e.printStackTrace();
}
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
progressBar.setVisibility(View.GONE);
Log.e(TAG, "onResponse" + error);
}
});
Volley.newRequestQueue(getActivity()).add(stringRequest);
}
}
JSON: Note: Can't really use jsonObject.getString() on timeline nested list since everything gets updated each day, i.e, 4/18/2021 data comes in, 3/19/2021 will be removed
{
"country": "USA",
"timeline": {
"3/19/21": 118313818,
"3/20/21": 121441497,
"3/21/21": 124481412,
"3/22/21": 126509736,
"3/23/21": 128217029,
"3/24/21": 130473853,
"3/25/21": 133305295,
"3/26/21": 136684688,
"3/27/21": 140180735,
"3/28/21": 143462691,
"3/29/21": 145812835,
"3/30/21": 147602345,
"3/31/21": 150273292,
"4/1/21": 153631404,
"4/2/21": 157606463,
"4/3/21": 161688422,
"4/4/21": 165053746,
"4/5/21": 167187795,
"4/6/21": 168592075,
"4/7/21": 171476655,
"4/8/21": 174879716,
"4/9/21": 178837781,
"4/10/21": 183467709,
"4/11/21": 187047131,
"4/12/21": 189692045,
"4/13/21": 192282781,
"4/14/21": 194791836,
"4/15/21": 198317040,
"4/16/21": 202282923,
"4/17/21": 202282923
}
}
I have tried many ways to display this json data, with and without iterator. I want to use iterator because I want to be able to retrieve both list name and data inside of list, i.e, 4/17/2021:1111111
Error Output:
E/VaccinationTotalUSA: onResponse:{"country":"USA","timeline":{"3/19/21":118313818,"3/20/21":121441497,"3/21/21":124481412,"3/22/21":126509736,"3/23/21":128217029,"3/24/21":130473853,"3/25/21":133305295,"3/26/21":136684688,"3/27/21":140180735,"3/28/21":143462691,"3/29/21":145812835,"3/30/21":147602345,"3/31/21":150273292,"4/1/21":153631404,"4/2/21":157606463,"4/3/21":161688422,"4/4/21":165053746,"4/5/21":167187795,"4/6/21":168592075,"4/7/21":171476655,"4/8/21":174879716,"4/9/21":178837781,"4/10/21":183467709,"4/11/21":187047131,"4/12/21":189692045,"4/13/21":192282781,"4/14/21":194791836,"4/15/21":198317040,"4/16/21":202282923,"4/17/21":202282923}}
W/System.err: org.json.JSONException: Value {"country":"USA","timeline":{"3\/19\/21":118313818,"3\/20\/21":121441497,"3\/21\/21":124481412,"3\/22\/21":126509736,"3\/23\/21":128217029,"3\/24\/21":130473853,"3\/25\/21":133305295,"3\/26\/21":136684688,"3\/27\/21":140180735,"3\/28\/21":143462691,"3\/29\/21":145812835,"3\/30\/21":147602345,"3\/31\/21":150273292,"4\/1\/21":153631404,"4\/2\/21":157606463,"4\/3\/21":161688422,"4\/4\/21":165053746,"4\/5\/21":167187795,"4\/6\/21":168592075,"4\/7\/21":171476655,"4\/8\/21":174879716,"4\/9\/21":178837781,"4\/10\/21":183467709,"4\/11\/21":187047131,"4\/12\/21":189692045,"4\/13\/21":192282781,"4\/14\/21":194791836,"4\/15\/21":198317040,"4\/16\/21":202282923,"4\/17\/21":202282923}} of type org.json.JSONObject cannot be converted to JSONArray
at org.json.JSON.typeMismatch(JSON.java:112)
at org.json.JSONArray.<init>(JSONArray.java:96)
at org.json.JSONArray.<init>(JSONArray.java:108)
at com.programming_concept.senior_project.VaccinationTotalUSA$1.onResponse(VaccinationTotalUSA.java:83)
W/System.err: at com.programming_concept.senior_project.VaccinationTotalUSA$1.onResponse(VaccinationTotalUSA.java:69)
at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:82)
at com.android.volley.toolbox.StringRequest.deliverResponse(StringRequest.java:29)
at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:102)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6669)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
There is no array in that JSON. In JSON, an array is denoted by square brackets ([ and ]). There are no square brackets in that JSON.
You have an outer JSON object, with two properties: country and timeline. timeline is another JSON object, with keys based on dates and values that are integers.
So, you need to revise your plans to work with the JSON as it is, which means JSONArray jsonArray = jsonObject.getJSONArray("timeline"); needs to turn into JSONObject timelineJson = jsonObject.getJSONObject("timeline");.
And note that there are many better JSON parsers available for Android, such as Moshi.
You're trying to set the "timeline" value to a JSONArray variable while that value would actually be a JSONObject. Here's a way you can retrieve both the key and value:
JSONObject jsonObject = new JSONObject(response);
JSONObject subObject = jsonObject.getJSONObject("timeline");
// Separate the keys into a JSONArray
JSONArray keys = subObject.names();
// Retrieve the keys and values
for(int i=0; i < keys.length(); i++) {
String key = keys.getString(i);
int value = subObject.getInt(key);
Log.d("LOG_TAG", key + " : " + value);
}
You can try the follwing code. I have hardcoded the json response in the Main class itself. Also I have used ObjectMapper which is much better than using JsonObject class
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
public class AssessmentBridgeApplication {
public static void main(String[] args) throws JsonMappingException, JsonProcessingException {
String json = "{\"country\":\"USA\",\"timeline\":{\"3/19/21\":118313818,\"3/20/21\":121441497,\"3/21/21\":124481412,\"3/22/21\":126509736,\"3/23/21\":128217029,\"3/24/21\":130473853,\"3/25/21\":133305295,\"3/26/21\":136684688,\"3/27/21\":140180735,\"3/28/21\":143462691,\"3/29/21\":145812835,\"3/30/21\":147602345,\"3/31/21\":150273292,\"4/1/21\":153631404,\"4/2/21\":157606463,\"4/3/21\":161688422,\"4/4/21\":165053746,\"4/5/21\":167187795,\"4/6/21\":168592075,\"4/7/21\":171476655,\"4/8/21\":174879716,\"4/9/21\":178837781,\"4/10/21\":183467709,\"4/11/21\":187047131,\"4/12/21\":189692045,\"4/13/21\":192282781,\"4/14/21\":194791836,\"4/15/21\":198317040,\"4/16/21\":202282923,\"4/17/21\":202282923}}";
ObjectMapper mapper = new ObjectMapper();
VaccinationRecords vaccinationRecords = new VaccinationRecords();
vaccinationRecords = mapper.readValue(json, VaccinationRecords.class);
System.out.println(vaccinationRecords.getTimeline());
}
}
=========================
import java.util.Map;
public class VaccinationRecords {
private String country;
Map<String, Object> timeline;
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public Map<String, Object> getTimeline() {
return timeline;
}
public void setTimeline(Map<String, Object> timeline) {
this.timeline = timeline;
}
}

How can i hide some specific category by id for some users in android

Below is my code. I want to hide some category for some users on their selection basis.
So anyone can please tell me how can I do this? I want to filter out some categories for users who select veg. I store this data in local storage via sharedprefs, so if user selects veg then I want to hide/filter nonveg items/categories
private void GetCategory() {
Map<String, String> params = new HashMap<String, String>();
categoryArrayList = new ArrayList<>();
ApiConfig.RequestToVolley(new VolleyCallback() {
#Override
public void onSuccess(boolean result, String response) {
//System.out.println("======cate " + response);
if (result) {
try {
JSONObject object = new JSONObject(response);
if (!object.getBoolean(Constant.ERROR)) {
JSONArray jsonArray = object.getJSONArray(Constant.DATA);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
SharedPreferences prfs = getSharedPreferences("PREF", Context.MODE_PRIVATE);
String pref = prfs.getString("pref", "");
categoryArrayList.add(new Category(
jsonObject.getString(Constant.ID),
jsonObject.getString(Constant.NAME),
jsonObject.getString(Constant.SUBTITLE),
jsonObject.getString(Constant.IMAGE)));
}
categoryRecyclerView.setAdapter(new CategoryAdapter(
MainActivity.this, categoryArrayList,
R.layout.lyt_category, "cate"));
} else {
lytCategory.setVisibility(View.GONE);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}, MainActivity.this, Constant.CategoryUrl, params, false);
}
You can use one flag in Category model to know if category data is hide or not and then depending open the selection of veg/non-veg update the list.

Android using JSON Error : "Error parsing data org.json.JSONException: Value "

I have this code that i used it in local host to display a listView when I upload it ,nothing is displayed in my ListView. So this what i did. Normally i get all data saved in my database but the screen is empty.
private ListView listView;
public static final String URL="http://gabes.comlu.com/Base_Controle/getAllEmp.php";
// static String TAG_JSON_ARRAY="";
private String JSON_STRING;
static JSONObject result = null;
public static final String TAG_JSON_ARRAY = "result";
private void showEmployee(){
JSONObject jsonObject = null;
ArrayList<HashMap<String,String>> list = new ArrayList<HashMap<String, String>>();
try {
jsonObject = new JSONObject(JSON_STRING);
JSONArray result = jsonObject.getJSONArray(TAG_JSON_ARRAY);
for(int i = 0; i<result.length(); i++){
JSONObject jo = result.getJSONObject(i);
String nom1 = jo.getString("nom");
String tele1 = jo.getString("tele");
String grade1 = jo.getString("grade");
String image1 = jo.getString("image");
String site1 = jo.getString("site");
String email1 = jo.getString("email");
HashMap<String,String> employees = new HashMap<>();
// employees.put("Type",type);
employees.put("log",nom1);
employees.put("a",tele1);
employees.put("pre",grade1);
employees.put("d",image1);
employees.put("c",site1);
employees.put("b", email1);
list.add(employees);
}
} catch (JSONException e) {
e.printStackTrace();
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
ListAdapter adapter = new SimpleAdapter(
getActivity(), list, R.layout.list_item1,
new String[]{"log","pre","a","b","c","d"},
new int[]{R.id.id, R.id.name,R.id.a});
listView.setAdapter(adapter);
}
Your JSON_ARRAY constant has no value:
static String TAG_JSON_ARRAY="";
You are trying to get a JSONArray with an empty tag and this is why you get an Exception.
You can parse this json data using GSON library.
Gson gson = new Gson();
Type listType = new TypeToken<ArrayList<test>>() {
}.getType();
ArrayList<test> Data = (ArrayList<test>) gson.fromJson(json, listType);
Here Test is class of your json data :
public class test {
String nom;
String add;
String tele;
public String getNom() {
return nom;
}
public void setNom(String nom) {
this.nom = nom;
}
public String getAdd() {
return add;
}
public void setAdd(String add) {
this.add = add;
}
public String getTele() {
return tele;
}
public void setTele(String tele) {
this.tele = tele;
}
}
Thank you all :)
I solved the problem by editing this :
private String JSON_STRING;
static JSONObject result = null;
......
try {
JSONArray result = new JSONArray(json);
for(int i = 0; i<result.length(); i++){
}
protected void onPostExecute(String s) {
super.onPostExecute(s);
loading.dismiss();
JSON_STRING = s;
showEmployee(s);
}

Adding Android 4.x support with AsyncTask to JSON parser

I have such JSONparser class:
public class JSONParser {
static InputStream is = null;
static JSONObject jObj;
static String json = "";
// constructor
public JSONParser() {
}
public JSONObject getJSONFromUrl(String url) {
// Making HTTP request
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet httpPost = new HttpGet(url);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "UTF-8"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
json = sb.toString();
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
// try parse the string to a JSON object
try {
jObj = new JSONObject(json);
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
// return JSON String
return jObj;
}
}
and such activity:
public class BankExchangersListActivity extends ExpandableListActivity {
private static String url;
// JSON Node names
private static final String TAG_Exchangers = "bank_exchangers";
private static final String TAG_ID = "id";
private static final String TAG_NAME = "name";
private static final String TAG_address = "address";
private static final String TAG_location_name = "location_name";
private static final String TAG_latitude = "latitude";
private static final String TAG_longitude = "longitude";
private static final String TAG_exchanger_type_name = "exchanger_type_name";
private static final String TAG_exchanger_curr_value = "value";
private static final String TAG_currency_list_name = "currency_list_name";
private static final String TAG_direction_of_exchange_name = "direction_of_exchange_name";
JSONArray banks = null;
JSONArray exc_currencies = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
String bank;
bank = this.getIntent().getStringExtra("Bank_id");
url = "****/**_**_***_list/"+bank+".json";
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bank_exchangers_list);
// Hashmap for ListView
ArrayList<HashMap<String, String>> contactList = new ArrayList<HashMap<String, String>>();
// Creating JSON Parser instance
JSONParser jParser = new JSONParser();
// getting JSON string from URL
JSONObject json = jParser.getJSONFromUrl(url);
ArrayList result = new ArrayList();
try {
// Getting Array of Contacts
banks = json.getJSONArray(TAG_Exchangers);
// looping through All Contacts
for(int i = 0; i < banks.length(); i++){
JSONObject c = banks.getJSONObject(i);
exc_currencies = c.getJSONArray("currency_values");
HashMap<String, String> map2 = new HashMap<String, String>();
ArrayList secList = new ArrayList();
for(int k = 0; k < exc_currencies.length(); k++){
JSONObject m = exc_currencies.getJSONObject(k);
String currency = m.getString(TAG_exchanger_curr_value);
String currency_list_name = m.getString(TAG_currency_list_name);
String direction_of_exchange_name = m.getString(TAG_direction_of_exchange_name);
Log.e("wazzzup", currency); //here is trouble: how to do new array with linking to parent?
HashMap child = new HashMap();
child.put(TAG_exchanger_curr_value, currency );
child.put(TAG_currency_list_name, currency_list_name );
child.put(TAG_direction_of_exchange_name, direction_of_exchange_name );
secList.add(child);
}
// Storing each json item in variable
String id = c.getString(TAG_ID);
String name = c.getString(TAG_NAME);
Log.e("name", name); //here is trouble: how to do new array with linking to parent?
String address = c.getString(TAG_address);
String location_name = c.getString(TAG_location_name);
String latitude = c.getString(TAG_latitude);
String longitude = c.getString(TAG_longitude);
String exchanger_type_name = c.getString(TAG_exchanger_type_name);
HashMap<String, String> map = new HashMap<String, String>();
map.put(TAG_ID, id);
map.put(TAG_NAME, name);
map.put(TAG_address, address);
map.put(TAG_location_name, location_name);
map.put(TAG_latitude, latitude);
map.put(TAG_longitude, longitude);
map.put(TAG_exchanger_type_name, exchanger_type_name);
// adding HashList to ArrayList
contactList.add(map);
result.add(secList);
}
} catch (JSONException e) {
e.printStackTrace();
}
/*ListAdapter adapter = new SimpleAdapter(this, contactList,
R.layout.bank_exchanger_list_element,
new String[] { TAG_NAME, TAG_location_name, TAG_address, TAG_exchanger_type_name, TAG_latitude, TAG_longitude }, new int[] {
R.id.bank_e_n, R.id.nas_punkt_e_n , R.id.adress_obm_e_n , R.id.tip_obm_e_n , R.id.shirota_e_n , R.id.dolgota_e_n });
setListAdapter(adapter);*/
SimpleExpandableListAdapter expListAdapter =
new SimpleExpandableListAdapter(
this,
contactList,
R.layout.bank_exchanger_list_element,
new String[] { TAG_NAME, TAG_location_name, TAG_address, TAG_exchanger_type_name, TAG_latitude, TAG_longitude },
new int[] {
R.id.bank_e_n, R.id.nas_punkt_e_n , R.id.adress_obm_e_n , R.id.tip_obm_e_n , R.id.shirota_e_n , R.id.dolgota_e_n },
result, //something goes here
R.layout.exchanger_currencies,
new String[] {TAG_exchanger_curr_value, TAG_currency_list_name, TAG_direction_of_exchange_name},
new int[] { R.id.currencyvalue_e_n, R.id.currency_list_name_e_n, R.id.direction_of_exchange_e_n}
);
setListAdapter( expListAdapter );
ExpandableListView elv = (ExpandableListView) getExpandableListView();
for(int i=0; i < expListAdapter.getGroupCount(); i++)
elv.expandGroup(i);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.bank_exchangers_list, menu);
return true;
}
}
On android 2.3.3 it works properly. But on 4.x i see errors, after searching I understood that I need to use AsyncTask. Is it true?
But how do I use it here? If there are any useful examples, please let me know.
Just how to get it working on Android 4.x?
You should already use AsyncTask under Android 2.x. It greatly improves responsiveness. Here is a fragment from my MEGA API library (currently under development):
private class AsyncRequestConnection extends AsyncTask<Void, Void, String> {
private final Request request;
public AsyncRequestConnection(Request request) {
this.request = request;
}
#Override
protected String doInBackground(Void... params) {
try {
HttpPost p = createRequestHttpMessage(request);
String resp = new String(stripResponse(getRequestClient().execute(p)));
Log.v(TAG, resp);
return resp;
} catch (Exception e) {
Log.e(TAG, "Cannot complete API request", e);
cancel(false);
return null;
}
}
#Override
protected void onCancelled() {
request.backoff();
if (request.hasReachedMaxBackoff()) {
request.cancel(R.string.error_internal);
} else {
requestQueue.enqueue(request);
}
requestConnection = null;
nextRequest();
}
#Override
protected void onPostExecute(String result) {
if (result != null) {
request.attachResponse(result);
request.handleResponse();
requestConnection = null;
nextRequest();
} else {
request.cancel(R.string.error_internal);
}
}
}
doInBackgroud() is the only method that is run on a different thread. Here, all your costly operations should happen.
getRequestClient() returns a HttpClient (AndroidHttpClient.newInstance(AGENT_NAME) or reused object for multiple requests in a row).
Since you are running muliple threads here, make sure doInBackground() does not access any global data structure. In my example, get getRequestClient() is sure to be only called from this location and there is only one such AsyncTask at any time. Otherwise you need some kind of mutex. Also, the Request object is sure to used by this class exlusively. Event handling (call-back methods) is implemented in the Request object as well but for simpler tasks you could simply do everything you want to do in onCancel() and onPostExecute().
If you only want to download a JSON object and parse it, you probably won't even need a constructor and private member variables. Simply replace the first Void by String to pass the URL string to doInBackground() and replace String by JSONObject.

Efficient way of downloading data in Android App from MySQL

I was just wondering if my code is ok in terms of downloading. My app needs a lot of data from a database so quick download times are crucial. The download time is ok but I think it can be programmed more efficient. Can you have a look at this? This class downloads many different companies and when downloaded they are put in a HashMap corresponding to their category. When finished downloading this class return a HashMap which contains multiple Hashmaps(categories) and in these Hashmaps the downloaded data. Dont mind the actual workflow but please concentrate on the way this class downloads data. Is there a way to do this faster?
public class CompanyDAO {
private static Controller delegate;
private static String companyUrl = "http:// URL HERE";
private Map<Object, Object> companyMap = new HashMap<Object, Object>();
private Map<String, Integer> pinMap = new HashMap<String, Integer>();
public CompanyDAO (Controller _delegate, Map<String, Integer> map) {
delegate = _delegate; //reference to controller
pinMap = map;
}
public void getCompanyData(ArrayList<Object> categoriesArray) {
for (int i = 0; i < categoriesArray.size(); i++) {
Map<String, Object> categoriesInMap = new HashMap<String, Object>();
//ArrayList<Object> categoriesInMapArray = new ArrayList<Object>();
companyMap.put(categoriesArray.get(i), categoriesInMap);
}
this.downloadCompanyData();
}
private void downloadCompanyData() {
companyUrl = companyUrl + delegate.ID;
try {
new DownloadCompanyData().execute(companyUrl).get(10000, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TimeoutException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private class DownloadCompanyData extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
String response = "";
for (String url : urls) {
DefaultHttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
try {
HttpResponse execute = client.execute(httpGet);
InputStream content = execute.getEntity().getContent();
BufferedReader buffer = new BufferedReader(new InputStreamReader(content));
String s = "";
while ((s = buffer.readLine()) != null) {
response += s;
}
} catch (Exception e) {
e.printStackTrace();
}
}
return response;
}
#SuppressWarnings("unchecked")
#Override
protected void onPostExecute(String result) {
JSONArray companyDataArray;
try {
companyDataArray = new JSONArray(result);
for(int i=0;i<companyDataArray.length();i++){
JSONObject id = companyDataArray.getJSONObject(i);
String catName = id.getString(Controller.CAT_NAME);
if (companyMap.get(catName) != null) {
Markers marker = new Markers(new LatLng(id.getDouble("latitude"), id.getDouble("longitude")), id.getString(Controller.CAT_NAME), id.getString(Controller.ID), id.getString(Controller.SUBSCRIPTION), pinMap.get(catName), id.getString(Controller.TITLE), id.getString(Controller.COMPANY_NAME), id.getString(Controller.WWW), id.getString(Controller.STREET), id.getString(Controller.HOUSE_NUMBER), id.getString(Controller.HOUSE_ADD));
((Map<String,Object>) companyMap.get(catName)).put(id.getString(Controller.TITLE), marker.markerInformationMap);
}
}
delegate.setCompanyHashMap(companyMap);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
I guess you're missing the point of the AsyncTask
it's supposed to do all the work in doInBackground() and then use the onPostExecute to deliver it to the UI.
But what you're doing is doing the network operation on doInBackground and doing data parsing on onPostExecute.
Furthermore, a JSON object is a raw data that needs further parsing. You should do all the parsing on the background. For example, let's say your companyData is address, phone number, size and name. You could have a class like this (p.s. I'm writing all this without testing, there will be a little mistake here in there, but you'll get the idea):
public class CompanyData{
private String name, address, phone;
private int size;
public CompanyData(JsonObject jo){
name = jo.getString("name");
address = jo.getString("address");
phone = jo.getString("phone");
size = jo.getInt("size");
}
// put a bunch of get methods here...
// getName(), getAddress(), etc.
}
then on your 'protected Map doInBackground(String... urls) ' you complete the network operation, create the JsonArray, create a Map<String,CompanyData>, loop through the array creating CompanyData objects and placing them into the Map and return the map to your protected void onPostExecute(Map<String,CompanyData> result) and inside the post execute it's just pass this result to the UI.
happy coding.
I always doing something like this..
...
private ProgressDialog pDialog;
ArrayList<HashMap<String, String>> CompanyList;
JSONParser jParser = new JSONParser();
JSONArray Company = null;
static String url_all_company = "http://your_site/files.php";
....
private class CompanyData extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Load data..");
pDialog.setIndeterminate(false);
pDialog.setCancelable(true);
pDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
CompanyList = new ArrayList<HashMap<String, String>>();
// Building Parameters if any.. to fetching all data, don't declare any param
List<NameValuePair> param = new ArrayList<NameValuePair>();
param.add(new BasicNameValuePair("uid", uid));
// getting JSON string from URL
JSONObject json = jParser.makeHttpRequest(url_all_company, "POST", param);
// Check your log cat for JSON reponse
Log.d("All Company: ", json.toString());
try {
// Checking for SUCCESS TAG
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
// Company found
// Getting Array of Company
Company = json.getJSONArray(TAG_COMPANIES);
// looping through All Company
for (int i = 0; i < Company.length(); i++) {
JSONObject json = Company.getJSONObject(i);
// Storing each json item in variable
String id = json.getString(TAG_GID);
String name = json.getString(TAG_NAME);
String jml = json.getString(TAG_EMPLOYEE);
String deskripsi = json.getString(TAG_DESKRIPSI);
String logo = json.getString(TAG_LOGO);
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(TAG_GID, id);
map.put(TAG_NAME, name);
map.put(TAG_EMPLOYEE, jml);
map.put(TAG_DESKRIPSI, deskripsi);
map.put(TAG_LOGO, logo);
// adding HashList to ArrayList
CompanyList.add(map);
}
} else {
// no CompanyList found
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void args) {
list=(ListView)findViewById(R.id.list);
// Getting adapter by passing data ArrayList
adapter=new LazyAdapter(MainActivity.this, CompanyList);
list.setAdapter(adapter);
pDialog.dismiss();
}
}

Categories

Resources