I am trying to add markers from JSON Parsing. but the markers are not showing in the map. Can anyone please help me? Here is my code:
MainActivity.java
package com.hasibhasan.sampletask;
import java.util.ArrayList;
import org.json.JSONArray;
import org.json.JSONObject;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
public class MainActivity extends ActionBarActivity {
private GoogleMap googlemap;
private static String TAG_POSTS = "posts";
private static String TAG_DRIVER = "driver";
private static String TAG_ID = "id";
private static String TAG_LATITUDE = "lat";
private static String TAG_LONGITUDE = "lon";
private static String TAG_DATETIME = "recorded_datetime";
private static String TAG_USERID = "user_id";
private static String TAG_STATE = "cabby_state";
private static String TAG_VTYPE = "vehicleType";
private static String TAG_DRIVERNAME = "driver_name";
private static String TAG_PICNAME = "pic_name";
private static String TAG_RATING = "rating";
private static String TAG_CARMODEL = "car_model";
private static String TAG_NUMBERSIT = "number_sit";
private static String TAG_DISTANCE = "distance";
private static String TAG_OPERATOR = "operator";
private static String TAG_NEARESTDISTANCE = "nearest_distance";
private static String TAG_NDISTANCE = "distance";
private static String TAG_TIME = "time";
private static String TAG_CARMODELS = "car_models";
ArrayList<Taxi> taxi;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
taxi = new ArrayList<Taxi>();
new ParseJSONTask().execute();
googlemap = ((MapFragment) getFragmentManager().findFragmentById(
R.id.map)).getMap();
}
private class ParseJSONTask extends AsyncTask<Void, Void, Void> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params) {
WebServiceHandler webServiceHandler = new WebServiceHandler();
String jsonstr = webServiceHandler
.getJSONData("http://54.186.247.213/unicabi/mobileservice/CurrentLocationService.php");
try {
JSONObject jsonObject = new JSONObject(jsonstr);
JSONArray postJson = jsonObject.getJSONArray(TAG_POSTS);
for (int i = 0; i < postJson.length(); i++) {
Taxi aTaxi = new Taxi();
JSONObject postObject = postJson.getJSONObject(i);
aTaxi.lat = postObject.getString(TAG_LATITUDE);
aTaxi.lon = postObject.getString(TAG_LONGITUDE);
aTaxi.driver_name = postObject.getString(TAG_DRIVERNAME);
taxi.add(aTaxi);
double lati = Double.parseDouble(aTaxi.lat);
double lon = Double.parseDouble(aTaxi.lon);
googlemap.addMarker(new MarkerOptions().title(
aTaxi.driver_name).position(new LatLng(lati, lon)));
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
}
}
}
Taxi. java (the model class)
package com.hasibhasan.sampletask;
public class Taxi {
public String posts = "";
public String success = "";
public String driver = "";
public String id = "";
public String lat = "";
public String lon = "";
public String recorded_datetime = "";
public String vehicleType = "";
public String driver_name = "";
public String pic_name = "";
public String rating = "";
public String car_model = "";
public String number_sit = "";
public String distance = "";
public String operator = "";
public String nearest_distance = "";
public String car_models = "";
}
Webservicehandler.java
package com.hasibhasan.sampletask;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
public class WebServiceHandler {
public WebServiceHandler() {
}
public String getJSONData(String url) {
String response = null;
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
HttpEntity httpEntity = null;
HttpResponse httpResponse = null;
try {
httpResponse = httpclient.execute(httpGet);
httpEntity = httpResponse.getEntity();
response = EntityUtils.toString(httpEntity);
} catch (Exception e) {
e.printStackTrace();
}
return response;
}
}
Pass the array of MarkerOptions to your onPostExecute method which runs on the UI thread. You can add the markers to your map there. Example:
private class ParseJSONTask extends AsyncTask<Void, Void, List<MarkerOptions>> {
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected List<MarkerOptions> doInBackground(Void... params) {
WebServiceHandler webServiceHandler = new WebServiceHandler();
String jsonstr = webServiceHandler
.getJSONData("http://54.186.247.213/unicabi/mobileservice/CurrentLocationService.php");
try {
JSONObject jsonObject = new JSONObject(jsonstr);
JSONArray postJson = jsonObject.getJSONArray(TAG_POSTS);
List<MarkerOptions> markers = new ArrayList<MarkerOptions>();
for (int i = 0; i < postJson.length(); i++) {
Taxi aTaxi = new Taxi();
JSONObject postObject = postJson.getJSONObject(i);
aTaxi.lat = postObject.getString(TAG_LATITUDE);
aTaxi.lon = postObject.getString(TAG_LONGITUDE);
aTaxi.driver_name = postObject.getString(TAG_DRIVERNAME);
taxi.add(aTaxi);
double lati = Double.parseDouble(aTaxi.lat);
double lon = Double.parseDouble(aTaxi.lon);
markers.add(new MarkerOptions().title(aTaxi.driver_name).
position(new LatLng(lati, lon)));
return markers;
}
} catch (Exception e) {
e.printStackTrace();
}
return new ArrayList<MarkerOptions>();
}
#Override
protected void onPostExecute(List<MarkerOptions> markers) {
super.onPostExecute(markers);
for (MarkerOptions marker : markers) {
googlemap.addMarker(marker);
}
}
}
You are trying to update the UI from a non-UI thread. This not allowed and should normaly throw an exception. You should better use an custom listener to pass the taxi list to your UI thread from your onPostExecute method.
Make a custom Listener:
public interface ParsingFinishedListener{
public abstract void onParsingFinished(List<MarkerOptions> markers;
}
Add a constructor to your asyncTask like this:
public ParseJsonTask(ParsingFinishedListener l){
this.mParsingFinisedListener = l;
}
And in onPostExecute return the list:
#Override
protected void onPostExecute(List<MarkerOptions> markers) {
super.onPostExecute(markers);
mParsingFinishedListener.onParsingFinished(markers);
}
And rewrite your onCreate method:
#Override
public void onCreate(Bundele savedInstance){
super.onCreate(savedInstance);
setContentView(R.layout.activity_main);
googlemap = ((MapFragment) getFragmentManager().findFragmentById(
R.id.map)).getMap();
taxi = new ArrayList<Taxi>();
new ParseJSONTask().execute(new ParsingFinishedListener(){
#Override
public void onParsingFinished(List<MarkerOptions> m){
for (MarkerOptions marker : markers) {
googlemap.addMarker(marker);
}
}
);
Related
I am trying to somehow get my returned JSON from an API into individual strings.
My code here gets information about a movie from the API: http://www.omdbapi.com/?t=Buffy&type=series&plot=short&apikey=8dc1b08d
It returns the JSON. However I need to get some value, such as "Buffy the Vampire Slayer" from the "Title" into a String variable.
News
package com.example.project21.stepbystep;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class WalkNews extends AppCompatActivity implements AsyncResponse{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_walk_news);
Button btnGet = (Button) findViewById(R.id.btnGet);
final GetMethod getRequest = new GetMethod(this);
btnGet.setOnClickListener(new View.OnClickListener(){
public void onClick(View v)
{
getRequest.execute("http://www.omdbapi.com/?t=Buffy&type=series&plot=short&apikey=8dc1b08d");
}
});
}
public void processFinish(String output){
TextView viewGet = (TextView) findViewById(R.id.txtGet);
viewGet.setText(output);
}
}
GetMethod
package com.example.project21.stepbystep;
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
public class GetMethod extends AsyncTask<String , Void ,String> {
String server_response;
private AsyncResponse delegate ;
protected GetMethod(AsyncResponse delegate) {
this.delegate = delegate;
}
#Override
protected String doInBackground(String... strings) {
delegate=delegate;
URL url;
HttpURLConnection urlConnection = null;
try {
url = new URL(strings[0]);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.connect();
int responseCode = urlConnection.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK) {
server_response = readStream(urlConnection.getInputStream());
Log.v("CatalogClient", server_response);
return server_response;
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String s) {
// super.onPostExecute(s);
delegate.processFinish(server_response);
}
// Converting InputStream to String
private String readStream(InputStream in) {
BufferedReader reader = null;
StringBuffer response = new StringBuffer();
try {
reader = new BufferedReader(new InputStreamReader(in));
String line = "";
while ((line = reader.readLine()) != null) {
response.append(line);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return response.toString();
}
}
Async Response
package com.example.project21.stepbystep;
public interface AsyncResponse {
void processFinish(String output);
}
You should parse json string into map or pojo data model
you can use android built in module JSONObject or you can use GSON open source library form google
https://github.com/google/gson
Create the Model class for the data you got from ApI like below: try this
public class DataObject {
private String title;
private String year;
private String rated;
private String genre;
private String director;
private String writer;
private String actors;
private String plot;
private String language;
private String country;
private String awards;
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getYear() {
return year;
}
public void setYear(String year) {
this.year = year;
}
public String getRated() {
return rated;
}
public void setRated(String rated) {
this.rated = rated;
}
public String getGenre() {
return genre;
}
public void setGenre(String genre) {
this.genre = genre;
}
public String getDirector() {
return director;
}
public void setDirector(String director) {
this.director = director;
}
public String getWriter() {
return writer;
}
public void setWriter(String writer) {
this.writer = writer;
}
public String getActors() {
return actors;
}
public void setActors(String actors) {
this.actors = actors;
}
public String getPlot() {
return plot;
}
public void setPlot(String plot) {
this.plot = plot;
}
public String getLanguage() {
return language;
}
public void setLanguage(String language) {
this.language = language;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getAwards() {
return awards;
}
public void setAwards(String awards) {
this.awards = awards;
}
}
public DataObject processFinish(String output){
TextView viewGet = (TextView) findViewById(R.id.txtGet);
DataObject object = parseJson(output);
if(object != null){
viewGet.setText(object.getTitle);
}
}
public DataObject parseJson(String output){
DataObject dataObject = null;
if(output != null){
try {
JSONObject jsonObject = new JSONObject(output);
String title = jsonObject.getString("Title");
String year = jsonObject.getString("Year");
String rated = jsonObject.getString("Rated");
dataObject = new DataObject();
dataObject.setTitle(title);
dataObject.setYear(year);
dataObject.setRated(rated);
} catch (Exception e) {
e.printStackTrace();
}
} else {
Toast.makeText(context, "Didn't get data from json",Toast.LENGTH_SHORT).show();
}
return dataObject;
}
Everything appears correctly on the screen until I fill in updateDisplay() method with code to update my textViews using setText/get.
The app does not crash prior to entering the setText/get code to update from the DarkSky API, but once entered the app crashes and tells me to try again.
I believe everything is entered correctly, but for some reason the app won't take the information. ALSO, I am using the recent version of OkHTTP in cradle, so the issue doesn't lie there. (Permissions are also used)
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import butterknife.BindView;
import butterknife.ButterKnife;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class MainActivity extends AppCompatActivity {
public static final String TAG = MainActivity.class.getSimpleName();
private CurrentWeather mCurrentWeather;
#BindView(R.id.timeLabel) TextView mTimeLabel;
#BindView(R.id.tempLabel) TextView mTempLabel;
#BindView(R.id.humidityValue) TextView mHumidityValue;
#BindView(R.id.precipValue) TextView mPrecipValue;
#BindView(R.id.summaryLabel) TextView mSummaryLabel;
#BindView(R.id.iconImageView) ImageView mIconImageView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
String apiKey = "MY KEY";
double latitude = 37.8267;
double longitude = -122.4233;
String forecastURL = ("https://api.darksky.net/forecast/" + apiKey +
"/" + latitude + "," + longitude);
if (isNetworkAvailable()) {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(forecastURL)
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
}
#Override
public void onResponse(Call call, Response response) throws IOException {
try {
String jsonData = response.body().string();
Log.v(TAG, jsonData);
if (response.isSuccessful()) {
mCurrentWeather = getCurrentDetails(jsonData);
runOnUiThread(new Runnable() {
#Override
public void run() {
updateDisplay();
}
});
} else {
alertUserAboutError();
}
}
catch (IOException | JSONException e) {
Log.e(TAG, "Exception caught: ", e);
}
}
});
}
else {
Toast.makeText(this, R.string.network_unavailable_message,
Toast.LENGTH_LONG).show(); // CHALLENGE: Turn into dialog
}
Log.d(TAG, "Main UI code is running!");
}
private void updateDisplay() {
mSummaryLabel.setText(mCurrentWeather.getSummary());
mTempLabel.setText(mCurrentWeather.getTemperature() + "");
}
private CurrentWeather getCurrentDetails(String jsonData) throws JSONException {
JSONObject forecast = new JSONObject(jsonData);
String timezone = forecast.getString("timezone");
Log.i(TAG, "From JSON: " + timezone);
JSONObject currently = forecast.getJSONObject("currently");
CurrentWeather currentWeather = new CurrentWeather();
currentWeather.setHumidity(currently.getDouble("humidity"));
currentWeather.setTime(currently.getLong("time"));
currentWeather.setIcon(currently.getString("icon"));
currentWeather.setPrecipChance(currently.getDouble("precipProbability"));
currentWeather.setSummary(currently.getString("summary"));
currentWeather.setTemperature(currently.getInt("temperature"));
currentWeather.setTimeZone(timezone);
Log.d(TAG, currentWeather.getFormattedTime());
return currentWeather;
}
private boolean isNetworkAvailable() {
ConnectivityManager manager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = manager.getActiveNetworkInfo();
boolean isAvailable = false;
if (networkInfo != null && networkInfo.isConnected()) {
isAvailable = true;
}
return isAvailable;
}
private void alertUserAboutError() {
AlertDialogFragment dialog = new AlertDialogFragment();
dialog.show(getFragmentManager(), "error_dialog");
}
}
package tricksterantics.com.catsndogs;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
public class CurrentWeather {
private String mIcon;
private long mTime;
private double mTemperature;
private double mHumidity;
private double mPrecipChance;
private String mSummary;
public String getTimeZone() {
return mTimeZone;
}
public void setTimeZone(String timeZone) {
mTimeZone = timeZone;
}
private String mTimeZone;
public String getIcon() {
return mIcon;
}
public void setIcon(String icon) {
mIcon = icon;
}
public int getIconId() {
// clear-day, clear-night, rain, snow, sleet, wind, fog, cloudy, partly-cloudy-day, or partly-cloudy-night.
int iconId = R.drawable.clear_day;
if (mIcon.equals("clear-day")) {
iconId = R.drawable.clear_day;
}
else if (mIcon.equals("clear-night")) {
iconId = R.drawable.clear_night;
}
else if (mIcon.equals("rain")) {
iconId = R.drawable.rain;
}
else if (mIcon.equals("snow")) {
iconId = R.drawable.snow;
}
else if (mIcon.equals("sleet")) {
iconId = R.drawable.sleet;
}
else if (mIcon.equals("wind")) {
iconId = R.drawable.wind;
}
else if (mIcon.equals("fog")) {
iconId = R.drawable.fog;
}
else if (mIcon.equals("cloudy")) {
iconId = R.drawable.cloudy;
}
else if (mIcon.equals("partly-cloudy-day")) {
iconId = R.drawable.partly_cloudy;
}
else if (mIcon.equals("partly-cloudy-night")) {
iconId = R.drawable.cloudy_night;
}
return iconId;
}
public long getTime() {
return mTime;
}
public void setTime(long time) {
mTime = time;
}
public String getFormattedTime () {
SimpleDateFormat formatter = new SimpleDateFormat("h:mm a");
formatter.setTimeZone(TimeZone.getTimeZone(getTimeZone()));
Date dateTime = new Date(getTime() * 1000);
String timeString = formatter.format(dateTime);
return timeString;
}
public double getTemperature() {
return (int) Math.round(mTemperature);
}
public void setTemperature(double temperature) {
mTemperature = temperature;
}
public double getHumidity() {
return mHumidity;
}
public void setHumidity(double humidity) {
mHumidity = humidity;
}
public int getPrecipChance() {
double precipPercentage = mPrecipChance * 100;
return (int) Math.round(precipPercentage);
}
public void setPrecipChance(double precipChance) {
mPrecipChance = precipChance;
}
public String getSummary() {
return mSummary;
}
public void setSummary(String summary) {
mSummary = summary;
}
}
Edit:
Added an image of the stack trace
Stack trace
Got rid of the Butterknife format I was using (BindVIew) and opted for this, everything now works and is retrieving updated information from the API:
public class MainActivity extends AppCompatActivity {
public static final String TAG = MainActivity.class.getSimpleName();
private CurrentWeather mCurrentWeather;
private TextView mTimeLabel;
private TextView mTempLabel;
private TextView mHumidityValue;
private TextView mPrecipValue;
private TextView mSummaryLabel;
private ImageView mIconImageView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTimeLabel = (TextView) findViewById(R.id.timeLabel);
mTempLabel = (TextView) findViewById(R.id.tempLabel);
mHumidityValue = (TextView) findViewById(R.id.humidityValue);
mPrecipValue = (TextView) findViewById(R.id.precipValue);
mSummaryLabel = (TextView) findViewById(R.id.summaryLabel);
This is my MainActivity.java :
package example.com.getdata;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONObject;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
public static final String JSON_URL = "http://172.31.131.52:8081/application/status";
private Button buttonGet;
private ListView listView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buttonGet = (Button) findViewById(R.id.button2);
}
private void sendRequest(){
StringRequest stringRequest = new StringRequest(JSON_URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
showJSON(response);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(MainActivity.this,error.getMessage(),Toast.LENGTH_LONG).show();
}
});
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
private void showJSON(String json) {
Product product = new Product(json);
ArrayList<JSONObject> listItems= product.parseJSON();
listView = (ListView) findViewById(R.id.list_view);
CustomList customerList = new CustomList(this,R.layout.list_view_layout,R.id.textViewName, listItems);
//customerList.notifyDataSetChanged();
listView.setAdapter(customerList);
}
public void clickHere(View v) {
sendRequest();
}
}
Product.java
package example.com.getdata;
import android.util.Log;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import static com.android.volley.VolleyLog.TAG;
public class Product {
public String productName;
public String description;
public int priceInDollars;
//public int productID;
public static final String KEY_Name = "productName";
public static final String KEY_Desc = "description";
//public static final String KEY_ID= "ProductID";
public static final String KEY_Price ="priceInDollars" ;
private JSONArray users = null;
private String json;
public Product(String json){
this.json =json;
}
protected ArrayList<JSONObject> parseJSON(){
JSONArray jsonArray=null;
ArrayList<JSONObject> aList=new ArrayList<JSONObject>();
try {
jsonArray = new JSONArray(json);
Log.d("Debugging...", jsonArray.toString());
if(jsonArray != null) {
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jo = jsonArray.getJSONObject(i);
productName = jo.getString(KEY_Name);
description = jo.getString(KEY_Desc);
priceInDollars = jo.getInt(KEY_Price);
aList.add(jsonArray.getJSONObject(i));
// productID = jo.getInt(KEY_ID);
}
return aList;
}
else {
Log.d(TAG, "parseJSON: Null condition");
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
}
CustomList.java
package example.com.getdata;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
public class CustomList extends ArrayAdapter<String> {
private ArrayList<JSONObject> list;
private int vg;
private Activity context;
public CustomList(Activity context,int vg, int id, ArrayList<JSONObject> list ) {
super(context,R.layout.list_view_layout, id);
this.vg = vg;
this.context = context;
this.list=list;
// this.productID=productID;
}
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View listViewItem = inflater.inflate(vg, parent, false);
TextView textViewName = (TextView) listViewItem.findViewById(R.id.textViewName);
TextView textViewDescription = (TextView) listViewItem.findViewById(R.id.textViewDescription);
TextView textViewPrice = (TextView) listViewItem.findViewById(R.id.textViewPrice);
// TextView textViewID = (TextView) listViewItem.findViewById(R.id.textViewID);
try {
textViewName.setText(list.get(position).getString("productName"));
textViewDescription.setText(list.get(position).getString("description"));
textViewPrice.setText(list.get(position).getString("priceInDollars"));
}
catch (JSONException e) {
e.printStackTrace();
}
// textViewID.setText(productID);
return listViewItem;
}
}
I have tried and searched for answers online and I am still not able to figure out the problem. I am unable to see the list of objects. Through debugging, I am sure that the objects are read into the json objects, still I am not able to display the objects in a listView.
Any help is appreciated.
You need to crate constructor with all variables of Product class and put all values in Product class object and add into ArrayList .
See Product Class :
public class Product {
public String productName;
public String description;
public int priceInDollars;
//public int productID;
public static final String KEY_Name = "productName";
public static final String KEY_Desc = "description";
//public static final String KEY_ID= "ProductID";
public static final String KEY_Price ="priceInDollars" ;
private JSONArray users = null;
private String json;
public Product(String productName, String json, JSONArray users, int priceInDollars, String description) {
this.productName = productName;
this.json = json;
this.users = users;
this.priceInDollars = priceInDollars;
this.description = description;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public static String getKEY_Name() {
return KEY_Name;
}
public static String getKEY_Price() {
return KEY_Price;
}
public String getJson() {
return json;
}
public void setJson(String json) {
this.json = json;
}
public JSONArray getUsers() {
return users;
}
public void setUsers(JSONArray users) {
this.users = users;
}
public static String getKEY_Desc() {
return KEY_Desc;
}
public int getPriceInDollars() {
return priceInDollars;
}
public void setPriceInDollars(int priceInDollars) {
this.priceInDollars = priceInDollars;
}
}
And When your are parsing your data you need to change like below code:
protected ArrayList<Product> parseJSON(){
JSONArray jsonArray=null;
ArrayList<Product> aList=new ArrayList<Product>();
try {
jsonArray = new JSONArray(json);
Log.d("Debugging...", jsonArray.toString());
if(jsonArray != null) {
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jo = jsonArray.getJSONObject(i);
String productName = jo.optString(KEY_Name);
String description = jo.optString(KEY_Desc);
String priceInDollars = jo.optInt(KEY_Price);
Product product = new Product(productName,json,
jsonArray.getJSONObject(i),priceInDollars,description);
aList.add(product);
// productID = jo.getInt(KEY_ID);
}
return aList;
}
else {
Log.d(TAG, "parseJSON: Null condition");
}
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
Also you need to change in Adapter class where you have passes ArrayList<JsonArray> in this case you have to pass ArrayList<Product>.
You missed
#override
public int getCount()
{
return list.size();
}
and make sure you either "setAdapter" on your listview after getting the json or call "notifydatasetchanged" method
Use
super(context,R.layout.list_view_layout, list);
instead of
super(context,R.layout.list_view_layout, id);
Make sure getCount() is properly implemented in Adapterclass:
#Override
public int getCount(){
return list.size();
}
Extend the CustomList class as:
type JSONObject
instead of
type String
My application cannot read data from a server, but I can't find the error in my code or its error log. In fact, after checking my API, the link works fine. INTERNET and WRITE_EXTERNAL_STORAGE permission are already set in the manifest.
My code:
package com.berthojoris.bacaberita;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
import org.json.JSONArray;
import org.json.JSONObject;
import android.app.AlertDialog;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import com.berthojoris.bacaberita.adapter.BeritaAdapter;
import com.berthojoris.bacaberita.bean.BeritaBean;
import com.berthojoris.bacaberita.lib.Constants;
import com.berthojoris.bacaberita.lib.ImageLoader;
import com.berthojoris.bacaberita.lib.JSONParser;
import com.berthojoris.bacaberita.lib.Utils;
import com.berthojoris.bacaberita.sqlite.UtilBerita;
public class Berita extends ListActivity {
ProgressDialog dialog;
private static String urlBerita = "http://newapi.bacaberita.com/berita";
public ImageLoader imageLoader;
private JSONParser jParser;
Toast msg;
TextView notfound;
JSONArray contacts = null;
ArrayList<BeritaBean> AmbilDataBean = new ArrayList<BeritaBean>();
BeritaAdapter adapter;
UtilBerita UtilBerita;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dialog = new ProgressDialog(this);
UtilBerita = new UtilBerita(this);
imageLoader = new ImageLoader(this.getApplicationContext());
notfound = (TextView) findViewById(R.id.notfound);
notfound.setVisibility(View.GONE);
getListView().setVisibility(View.VISIBLE);
AmbilDataBean = new ArrayList<BeritaBean>();
adapter = new BeritaAdapter(this, AmbilDataBean);
setListAdapter(adapter);
Utils.setPolicyThread();
// Creating JSON Parser Instance
jParser = new JSONParser();
Log.e("Berita Activity", "TOTAL SIZE DATABASE : "
+ UtilBerita.ReadBerita().size());
if (UtilBerita.ReadBerita().size() < 1) {
Log.e("Berita Activity", "DATABASE KOSONG. JALANKAN ASYNC");
new async().execute();
} else {
AmbilDataBean = UtilBerita.ReadBerita();
adapter.setItem(AmbilDataBean);
Log.e("Berita Activity", "DATABASE DIAMBIL");
}
setTimerRefresh();
}// Tutup onCreate
private class async extends AsyncTask<Void, Void, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
AmbilDataBean = new ArrayList<BeritaBean>();
dialog.setMessage("Please wait...");
dialog.setCanceledOnTouchOutside(false);
dialog.show();
}
#Override
protected String doInBackground(Void... params) {
String jsonContent = jParser.getJSONDataFromUrl(urlBerita);
Log.e("Berita Activity", "PROSES BACKGROUND DIJALANKAN");
return jsonContent;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if (result.length() > 0) {
dialog.dismiss();
// parsing disini
JSONObject json = null;
try {
json = new JSONObject(result);
try {
// Getting Array of Contacts
contacts = json.getJSONArray(Constants.TAG_ITEM);
// looping through All Contacts
for (int i = 0; i < contacts.length(); i++) {
JSONObject c = contacts.getJSONObject(i);
// Storing each json item in variable
String id = c.getString(Constants.TAG_MenuID);
String judul = c.getString(Constants.TAG_Title);
//String img = c.getString(Constants.TAG_Link);
String desk = c.getString(Constants.TAG_Post);
String date = c.getString(Constants.TAG_Created);
BeritaBean mb = new BeritaBean();
mb.setID(id);
mb.setTitle(judul);
//mb.setLink("http://" + img);
mb.setPost(desk);
mb.setCreated(date);
AmbilDataBean.add(mb);
}
adapter.setItem(AmbilDataBean);
Log.e("Berita Activity",
"PROSES SELESAI. DATA AKAN DITAMPILKAN");
} catch (Exception e) {
dialog.dismiss();
Toast.makeText(getBaseContext(),
"Connection Error. Please try again...",
Toast.LENGTH_SHORT).show();
}
// selecting single ListView item
ListView lv = getListView();
// Launching new screen on Selecting Single ListItem
lv.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent,
View view, int position, long id) {
}
});
} catch (Exception e) {
dialog.dismiss();
Toast.makeText(getBaseContext(),
"Connection Error. Please try again...",
Toast.LENGTH_SHORT).show();
}
} // Tutup if (result.length() > 0)
else {
dialog.dismiss();
Toast.makeText(getBaseContext(),
"Data Not Found. Please try again...",
Toast.LENGTH_SHORT).show();
}
if (AmbilDataBean.size() < 1) {
notfound.setVisibility(View.VISIBLE);
getListView().setVisibility(View.GONE);
} else {
for (BeritaBean bean : AmbilDataBean) {
if (UtilBerita.getDetailWhereID(bean.getID()).getID() == null) {
Log.e("Berita Activity",
"Insert database : " + bean.getID());
UtilBerita.CreateData(bean);
} else {
Log.e("Berita Activity",
"Update database : " + bean.getID());
UtilBerita.UpdateBerita(bean);
}
}
notfound.setVisibility(View.GONE);
getListView().setVisibility(View.VISIBLE);
}
} // Tutup onPostExecute
} // Tutup private class async extends AsyncTask
// =========================================================================================================================
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
new AlertDialog.Builder(this)
.setIcon(android.R.drawable.ic_dialog_alert)
.setMessage(R.string.really_quit)
.setPositiveButton(R.string.yes,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog,
int which) {
finish();
}
}).setNegativeButton(R.string.no, null).show();
return true;
} else {
return super.onKeyDown(keyCode, event);
}
}
// =========================================================================================================================
// Declare the timer
Timer timer = null;
final Handler handler = new Handler();
public void setTimerRefresh() {
timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
handler.post(new Runnable() {
public void run() {
Log.e("Main Activity", "RUNNING TASK...");
new async().execute();
}
});
}
}, 1000 * 60 * 1, 1000 * 25);
}
#Override
public void onBackPressed() {
super.onBackPressed();
finish();
}
#Override
protected void onDestroy() {
super.onDestroy();
if (timer != null) {
timer.cancel();
timer = null;
}
if (UtilBerita != null)
UtilBerita.Close();
}
}
== UPDATE ==
My Constants class :
package com.berthojoris.bacaberita.lib;
public class Constants {
public static final String TAG_ITEM = "items";
public static final String TAG_MenuID = "Menu_ID";
public static final String TAG_IsDisplay = "IsDisplay";
public static final String TAG_CategoryName = "CategoryName";
public static final String TAG_CategoryID = "Category_ID";
public static final String TAG_ContentID = "Content_ID";
public static final String TAG_Title = "Title";
public static final String TAG_Post = "Post";
public static final String TAG_Link = "Link";
public static final String TAG_Meta = "Meta";
public static final String TAG_CreatedBy = "CreatedBy";
public static final String TAG_Created = "Created";
public static final String TAG_StartDisplay = "StartDisplay";
public static final String TAG_Counter = "counter";
}
You have to retrieve jsonArray from the jsonObject items. But in your code you have not used items anywhere. Try this way:
String jsonStr = new ConnectionService().connectionGet("http://newapi.bacaberita.com/berita","");
JSONObject jsonObject = new JSONObject(jsonStr);
System.out.println("..........JSON OBJECT.............");
System.out.println(jsonObject); // full json Object
JSONArray jsonArray = jsonObject.getJSONArray("items");
System.out.println("..........JSON ARRAY PARSING.............");
for(int i=0;i<jsonArray.length();i++)
{
String menu_id = jsonArray.getJSONObject(i).getString("Menu_ID");
String is_display = jsonArray.getJSONObject(i).getString("IsDisplay");
System.out.println("MENU_ID: "+menu_id);
System.out.println("IsDisplay: "+is_display);
}
The methods used in above example are as follows:
public static String connectionGet(String url, String parameter) throws MalformedURLException, ProtocolException, IOException {
URL url1 = new URL(url);
HttpURLConnection request1 = (HttpURLConnection) url1.openConnection();
request1.setRequestMethod("GET");
request1.connect();
String responseBody = convertStreamToString(request1.getInputStream());
return responseBody;
}
private static String convertStreamToString(InputStream is) {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder();
String line = null;
try {
while ((line = reader.readLine()) != null) {
sb.append(line).append("\n");
}
} catch (IOException e) {
} finally {
try {
is.close();
} catch (IOException e) {
}
}
return sb.toString();
}
This is my sample code, where I make a json parsing class to parse data from a given link.
package com.billosuch.listviewblogpost;
import java.util.ArrayList;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.ListView;
public class ListViewBlogPost extends Activity {
// url to make request
private static String url = "http://api.androidhive.info/contacts/";
// JSON Node names
private static final String TAG_CONTACTS = "contacts";
private static final String TAG_ID = "id";
private static final String TAG_NAME = "name";
private static final String TAG_EMAIL = "email";
private static final String TAG_ADDRESS = "address";
private static final String TAG_GENDER = "gender";
private static final String TAG_PHONE = "phone";
private static final String TAG_PHONE_MOBILE = "mobile";
private static final String TAG_PHONE_HOME = "home";
private static final String TAG_PHONE_OFFICE = "office";
// contacts JSONArray
JSONArray contacts = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ArrayList<SearchResults> searchResultss = new ArrayList<SearchResults>();
final ListView lv1 = (ListView) findViewById(R.id.ListView01);
JSONParser jparser = new JSONParser();
JSONObject json = jparser.getJSONFromUrl(url);
// looping through All Contacts
Log.d("*********oSR", "B4 TRy");
try {
contacts = json.getJSONArray(TAG_CONTACTS);
for (int i = 0; i < contacts.length(); i++) {
SearchResults oSR = new SearchResults();
JSONObject c = contacts.getJSONObject(i);
oSR.setId(c.getString(TAG_ID));
oSR.setName(c.getString(TAG_NAME));
oSR.setEmail(c.getString(TAG_EMAIL));
oSR.setAddress(c.getString(TAG_ADDRESS));
oSR.setGender(c.getString(TAG_GENDER));
JSONObject phone = c.getJSONObject(TAG_PHONE);
oSR.setPhone_mobile(phone.getString(TAG_PHONE_MOBILE));
oSR.setPhone_home(phone.getString(TAG_PHONE_HOME));
oSR.setPhone_office(phone.getString(TAG_PHONE_OFFICE));
searchResultss.add(oSR);
Log.d("*********oSR", oSR.getName());
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.d("*********oSR", "AFTER TRy");
lv1.setAdapter(new MyCustomBaseAdapter(this, searchResultss));
}
}
This code showing me warning to do this in Asyntask. I want it to be supported on ICS and JellyBean.
Skipped 391 frames! The application may be doing too much work on its main thread.
You should use a asynctask for this purpose and move the network related code to doinBackground()
http://developer.android.com/reference/android/os/AsyncTask.html.
Load your asynctask on the UI thread as
new TheTask().execute()
Asynctask Class.
class TheTask extends AsyncTask<Void,Void,Void>
{
protected void onPreExecute()
{ super.onPreExecute();
//display progressdialog.
}
protected void doInBackground(Void ...params)
{
//Network related opearaiton. Do not update ui here
return null;
}
protected void onPostExecute(Void result)
{
super.onPostExecute(result);
//dismiss progressdialog.
//update ui
}
}
You can pass the URL to the conbstructor of the asynctask or directly to doInbackground()
You are currently making a server request in the UI thread. While the app waits for the server response, your UI freezes and that's a bad user experience. Use an AsyncTask in order to load your data in another thread and update the UI when you get the server response.
here is an example
Change your code like below
package com.billosuch.listviewblogpost;
import java.util.ArrayList;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.ListView;
public class ListViewBlogPost extends Activity {
// url to make request
private static String url = "http://api.androidhive.info/contacts/";
// JSON Node names
private static final String TAG_CONTACTS = "contacts";
private static final String TAG_ID = "id";
private static final String TAG_NAME = "name";
private static final String TAG_EMAIL = "email";
private static final String TAG_ADDRESS = "address";
private static final String TAG_GENDER = "gender";
private static final String TAG_PHONE = "phone";
private static final String TAG_PHONE_MOBILE = "mobile";
private static final String TAG_PHONE_HOME = "home";
private static final String TAG_PHONE_OFFICE = "office";
final ListView lv1;
ArrayList<SearchResults> searchResultss;
// contacts JSONArray
JSONArray contacts = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
searchResultss = new ArrayList<SearchResults>();
lv1 = (ListView) findViewById(R.id.ListView01);
new MyAsync(Youractivity.this).execute();
}
public class MyAsync extends AsyncTask<Void, Integer, Void> {
public MyAsync(Activity activity) {
this.activity = activity;
context = activity;
dialog = new ProgressDialog(context);
}
/** progress dialog to show user that the backup is processing. */
private ProgressDialog dialog;
/** application context. */
private Activity activity;
private Context context;
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... params) {
// TODO Auto-generated method stub
JSONParser jparser = new JSONParser();
JSONObject json = jparser.getJSONFromUrl(url);
// looping through All Contacts
Log.d("*********oSR", "B4 TRy");
try {
contacts = json.getJSONArray(TAG_CONTACTS);
for (int i = 0; i < contacts.length(); i++) {
SearchResults oSR = new SearchResults();
JSONObject c = contacts.getJSONObject(i);
oSR.setId(c.getString(TAG_ID));
oSR.setName(c.getString(TAG_NAME));
oSR.setEmail(c.getString(TAG_EMAIL));
oSR.setAddress(c.getString(TAG_ADDRESS));
oSR.setGender(c.getString(TAG_GENDER));
JSONObject phone = c.getJSONObject(TAG_PHONE);
oSR.setPhone_mobile(phone.getString(TAG_PHONE_MOBILE));
oSR.setPhone_home(phone.getString(TAG_PHONE_HOME));
oSR.setPhone_office(phone.getString(TAG_PHONE_OFFICE));
searchResultss.add(oSR);
Log.d("*********oSR", oSR.getName());
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.d("*********oSR", "AFTER TRy");
return null;
}
#Override
protected void onPostExecute(Void result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
lv1.setAdapter(new MyCustomBaseAdapter(this, searchResultss));
}
}
}
Make LongOperation class like this.
private class LongOperation extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
JSONParser jparser = new JSONParser();
JSONObject json = jparser.getJSONFromUrl(url);
// looping through All Contacts
Log.d("*********oSR", "B4 TRy");
try {
contacts = json.getJSONArray(TAG_CONTACTS);
for (int i = 0; i < contacts.length(); i++) {
SearchResults oSR = new SearchResults();
JSONObject c = contacts.getJSONObject(i);
oSR.setId(c.getString(TAG_ID));
oSR.setName(c.getString(TAG_NAME));
oSR.setEmail(c.getString(TAG_EMAIL));
oSR.setAddress(c.getString(TAG_ADDRESS));
oSR.setGender(c.getString(TAG_GENDER));
JSONObject phone = c.getJSONObject(TAG_PHONE);
oSR.setPhone_mobile(phone.getString(TAG_PHONE_MOBILE));
oSR.setPhone_home(phone.getString(TAG_PHONE_HOME));
oSR.setPhone_office(phone.getString(TAG_PHONE_OFFICE));
searchResultss.add(oSR);
Log.d("*********oSR", oSR.getName());
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
lv1.setAdapter(new MyCustomBaseAdapter(this, searchResultss));
//might want to change "executed" for the returned string passed into onPostExecute() but that is upto you
}
#Override
protected void onPreExecute() {
}
#Override
protected void onProgressUpdate(Void... values) {
}
}
You can use async task like this...
package com.billosuch.listviewblogpost;
import java.util.ArrayList;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.ListView;
public class ListViewBlogPost extends Activity {
// url to make request
private static String url = "http://api.androidhive.info/contacts/";
// JSON Node names
private static final String TAG_CONTACTS = "contacts";
private static final String TAG_ID = "id";
private static final String TAG_NAME = "name";
private static final String TAG_EMAIL = "email";
private static final String TAG_ADDRESS = "address";
private static final String TAG_GENDER = "gender";
private static final String TAG_PHONE = "phone";
private static final String TAG_PHONE_MOBILE = "mobile";
private static final String TAG_PHONE_HOME = "home";
private static final String TAG_PHONE_OFFICE = "office";
// contacts JSONArray
JSONArray contacts = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ArrayList<SearchResults> searchResultss = new ArrayList<SearchResults>();
final ListView lv1 = (ListView) findViewById(R.id.ListView01);
new MyTask().execute(url);
class MyTask extends AsyncTask<String, Void, String> {
ProgressDialog pDialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(SocialActivity.this);
pDialog.setMessage("Loading...");
pDialog.setCancelable(true);
pDialog.show();
}
#Override
protected String doInBackground(String... params) {
JSONParser jparser = new JSONParser();
JSONObject json = jparser.getJSONFromUrl(params[0]);
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if (null != pDialog && pDialog.isShowing()) {
pDialog.dismiss();
}
if (null == result || result.length() == 0) {
showToast("No data found from web!!!");
YourActivity.this.finish();
} else {
try {
contacts = json.getJSONArray(TAG_CONTACTS);
for (int i = 0; i < contacts.length(); i++) {
SearchResults oSR = new SearchResults();
JSONObject c = contacts.getJSONObject(i);
oSR.setId(c.getString(TAG_ID));
oSR.setName(c.getString(TAG_NAME));
oSR.setEmail(c.getString(TAG_EMAIL));
oSR.setAddress(c.getString(TAG_ADDRESS));
oSR.setGender(c.getString(TAG_GENDER));
JSONObject phone = c.getJSONObject(TAG_PHONE);
oSR.setPhone_mobile(phone.getString(TAG_PHONE_MOBILE));
oSR.setPhone_home(phone.getString(TAG_PHONE_HOME));
oSR.setPhone_office(phone.getString(TAG_PHONE_OFFICE));
searchResultss.add(oSR);
Log.d("*********oSR", oSR.getName());
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Log.d("*********oSR", "AFTER TRy");
lv1.setAdapter(new MyCustomBaseAdapter(this, searchResultss));
}
}