Auto Refresh Listview When Data in XML changed from server - java

This is my code that parsing XML from server and display in List view. I want auto refresh to display list view when data is changed from server.
package com.wafik;
import java.io.InputStream;
import java.net.URL;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.widget.ListView;
public class vctcs extends Activity {
/** Called when the activity is first created. */
private ListView listView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
listView = (ListView) findViewById(R.id.listview);
bindDataToListing();
}
public void bindDataToListing() {
try {
SAXParserFactory saxparser = SAXParserFactory.newInstance();
SAXParser parser = saxparser.newSAXParser();
XMLReader xmlReader = parser.getXMLReader();
ParsingClass pc = new ParsingClass();
xmlReader.setContentHandler(pc);
URL url=new URL("my url");
InputStream is=url.openStream(); // Use this InputStream to parse
xmlReader.parse(new InputSource(is));
BindingData bindingData = new BindingData(this, pc.name,
pc.address, pc.qua,pc.qua2);
listView.setAdapter(bindingData);
} catch (Exception e) {
e.getMessage();
}
}
}
Parsing XML
package com.wafik;
import java.util.ArrayList;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class ParsingClass extends DefaultHandler {
ArrayList<String> name = new ArrayList<String>();
ArrayList<String> address = new ArrayList<String>();
ArrayList<String> qua = new ArrayList<String>();
ArrayList<String> qua2 = new ArrayList<String>();
#Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
super.startElement(uri, localName, qName, attributes);
if (localName.equalsIgnoreCase("time")) {
tempStore = "";
} else if (localName.equalsIgnoreCase("street_name")) {
tempStore = "";
} else if (localName.equalsIgnoreCase("intersection_no")) {
tempStore = "";
} else if (localName.equalsIgnoreCase("traffic_state")) {
tempStore = "";
}else{
tempStore = "";
}
}
#Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
super.endElement(uri, localName, qName);
if (localName.equalsIgnoreCase("time")) {
name.add(tempStore);
} else if (localName.equalsIgnoreCase("street_name")) {
address.add(tempStore);
} else if (localName.equalsIgnoreCase("intersection_no")) {
qua.add(tempStore);
}else if (localName.equalsIgnoreCase("traffic_state")) {
qua2.add(tempStore);
}
tempStore = "";
}
private String tempStore = "";
#Override
public void characters(char[] ch, int start, int length)
throws SAXException {
super.characters(ch, start, length);
tempStore += new String(ch, start, length);
}
}
Binding Data
package com.wafik;
import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.text.Html;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
public class BindingData extends BaseAdapter {
ArrayList<String> time;
ArrayList<String> street_name;
ArrayList<String> intersection_no;
ArrayList<String> traffic_state;
LayoutInflater inflater;
public BindingData() {
}
public BindingData(Activity act, ArrayList<String> name,
ArrayList<String> add, ArrayList<String> qua,ArrayList<String> qua2) {
this.time = name;
this.street_name = add;
this.intersection_no = qua;
this.traffic_state = qua2;
inflater = (LayoutInflater) act
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public int getCount() {
return time.size();
}
#Override
public Object getItem(int position) {
return null;
}
#Override
public long getItemId(int position) {
return 0;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
Holder holder;
if (convertView == null) {
holder = new Holder();
convertView = inflater.inflate(R.layout.listrow, null);
holder.txttime = (TextView) convertView.findViewById(R.id.name);
holder.txtstreet_name = (TextView) convertView.findViewById(R.id.address);
holder.txtintersection_no = (TextView) convertView.findViewById(R.id.quali);
holder.txttraffic_state = (TextView) convertView.findViewById(R.id.quali2);
convertView.setTag(holder);
} else {
holder = (Holder) convertView.getTag();
}
holder.txttime.setText(Html.fromHtml("<b>Time : </b>" + time.get(position)));
holder.txtstreet_name.setText(Html.fromHtml("<b>Street Name : </b>"
+ street_name.get(position)));
holder.txtintersection_no.setText(Html.fromHtml("<b>Intersection No : </b>"
+ intersection_no.get(position)));
holder.txttraffic_state.setText(Html.fromHtml("<b>Traffic State : </b>"
+ traffic_state.get(position)));
return convertView;
}
private class Holder {
TextView txttime, txtstreet_name, txtintersection_no,txttraffic_state;
}
}

First you need an object to hold all these values like time, streername, etc. then pass a list of that object, then make an add item method in your adapter that updates the list with new xml the call notifyDataSetChanged() to update your listview like this:
//Binding Data
public void addItem(YourItem item){
this.yourItemList.add(item);
notifyDataSetChanged();
}
//YourItem
public class YourItem{
private String time;
private String street_name;
private String intersection_no;
private String traffic_state;
public YourItem(String time, String street_name, String intersection_no, String traffic_state) {
this.time = time;
this.street_name = street_name;
this.intersection_no = intersection_no;
this.traffic_state = traffic_state;
}
//Getters and Setters for your object fields
}

you have to notify the list adapter that the data has changed if you want instance change in the list view, so every time the server data is changed you should call ...
bindingData.notifyDataSetChanged();

Related

Download Web Content - long downloading

I've been learning Java for a few months. Nowadays I'm creating an app which downloads web content and shows the data in a ListView. The problem is that everything takes a very long time - about 25 second from the launch of the app to fill the list with elements. What is more, there is no difference between it running on a real device or an Android emulator.
In my opinion, the Java code is not bad because most of it is from my course on Udemy.
How can I improve this? Where is the problem?
Reports from logcat and AVD setting [ss]:
Here's my code below:
MainActivity.java
package com.example.user.legionisciapp;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ListView;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class MainActivity extends AppCompatActivity {
ListView listView;
List<News> newsList = new ArrayList<>();
ArrayList<String> titles = new ArrayList<>();
ArrayList<String> desc = new ArrayList<>();
ArrayList<String> urls = new ArrayList<>();
public class DownloadTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... strings) {
URL url;
HttpURLConnection connection = null;
String result = "";
try {
url = new URL(strings[0]);
connection = (HttpURLConnection) url.openConnection();
InputStream inputStream = connection.getInputStream();
InputStreamReader reader = new InputStreamReader(inputStream);
int data = reader.read();
while (data != -1) {
char current = (char) data;
result += current;
data = reader.read();
}
return result;
} catch (Exception e) {
e.printStackTrace();
return "Failed";
}
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
DownloadTask downloadTask = new DownloadTask();
try {
String result = downloadTask.execute("https://www.legionisci.com").get();
String[] resultSplit = result.split("<div id=\"mecze\">");
result = resultSplit[0];
resultSplit = result.split("<div id=\"listanewsow\">");
result = resultSplit[1];
Pattern p = Pattern.compile("class=\"b\" title=\"(.*?)\">");
Matcher m = p.matcher(result);
while (m.find()) {
titles.add(m.group(1));
}
p = Pattern.compile("></a>(.*?)</div>");
m = p.matcher(result);
while (m.find()) {
desc.add(m.group(1));
}
p = Pattern.compile("alt=\"\" class=\"zl\" /></a>(.*?)<");
m = p.matcher(result);
while (m.find()) {
urls.add("https://www.legionisci.com" + m.group(1));
}
} catch (Exception e) {
e.printStackTrace();
}
listView = findViewById(R.id.listView);
for (int i = 0; i < 4; i++) {
newsList.add(new News(R.drawable.ll, titles.get(i), desc.get(i)));
NewsListAdapter newsListAdapter = new NewsListAdapter(this, R.layout.news_list, newsList);
listView.setAdapter(newsListAdapter);
}
}
}
News.java
package com.example.user.legionisciapp;
public class News {
int image;
String title, desc;
public News(int image, String title, String desc) {
this.image = image;
this.title = title;
this.desc = desc;
}
public int getImage() {
return image;
}
public String getTitle() {
return title;
}
public String getDesc() {
return desc;
}
}
NewsListAdapter.class
package com.example.user.legionisciapp;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.List;
public class NewsListAdapter extends ArrayAdapter<News> {
Context ctx;
int resource;
List<News> newsList;
public NewsListAdapter (Context ctx, int resource, List<News> newsList){
super(ctx, resource, newsList);
this.ctx = ctx;
this.resource = resource;
this.newsList = newsList;
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(ctx);
View view = inflater.inflate(R.layout.news_list, null);
TextView title = view.findViewById(R.id.tvTitle);
TextView desc = view.findViewById(R.id.tvDesc);
ImageView image = view.findViewById(R.id.thumb);
News news = newsList.get(position);
title.setText(news.getTitle());
desc.setText(news.getDesc());
image.setImageDrawable(ctx.getResources().getDrawable(news.getImage()));
return view;
}
}
You can't do something like this:
String result = downloadTask.execute("https://www.legionisci.com").get();
That is not the right way to use an AsyncTask! The problem is that the async task is executed in a background thread but if you do .get() the main thread is paused until the async task finishes his job. So this is the reason of the long wait at startup.
What you have to do is:
Starting the task this way
downloadTask.execute("https://www.legionisci.com");
Using the onPostExecute(String result) method (executed on the main thread) to get the result and update the UI .
More on this:
https://developer.android.com/reference/android/os/AsyncTask

Custom listView adapter, model, JSONParsing not working

I'm designing a listview that displays food information list from php server.
the url I passed is a php file after I convert it to json file. the list is not shown and whent I press refresh from menu I keep getting
(app stopped working) ..
here is FoodView.java Activity
import android.content.Context;
import android.os.AsyncTask;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.w3c.dom.Text;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import alsaad.layla.mysqldemo.Models.FoodModel;
import static android.R.attr.resource;
import static android.content.Context.LAYOUT_INFLATER_SERVICE;
public class FoodView extends AppCompatActivity {
private ListView lvFood;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_food_view);
lvFood = (ListView) findViewById(R.id.lvFood);
}
public class JSONTask extends AsyncTask<String, String, List<FoodModel>> {
#Override
protected List<FoodModel> doInBackground(String... params) {
HttpURLConnection httpURLConnection = null;
BufferedReader reader = null;
try {
URL url = new URL(params[0]);
httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.connect();
InputStream inputStream = httpURLConnection.getInputStream();
reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuffer buffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
buffer.append(line);
}
String finalJson = buffer.toString();
JSONArray parentArray = new JSONArray(finalJson);
List<FoodModel> foodModelList = new ArrayList<>();
for (int i = 0; i < parentArray.length(); i++) {
JSONObject finalObject = parentArray.getJSONObject(i);
FoodModel foodModel = new FoodModel();
foodModel.setFood(finalObject.getString("name"));
//foodModel.setStatus(finalObject.getString("status"));
foodModel.setAmount(finalObject.getInt("amount"));
foodModel.setDescription(finalObject.getString("description"));
foodModel.setDate(finalObject.getInt("exDate"));
foodModelList.add(foodModel);
}
return foodModelList;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} finally {
if (httpURLConnection != null) {
httpURLConnection.disconnect();
}
}
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(List<FoodModel> result) {
super.onPostExecute(result);
FoodAdapter adapter = new FoodAdapter(getApplicationContext(), R.layout.row, result);
lvFood.setAdapter(adapter);
}}
public class FoodAdapter extends ArrayAdapter {
private List<FoodModel> foodModelList;
private int resource;
private LayoutInflater inflater;
public FoodAdapter(Context context, int resource, List<FoodModel> objects) {
super(context, resource, objects);
foodModelList = objects;
this.resource = resource;
inflater = (LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = inflater.inflate(resource, null);
}
ImageView ivIcon;
TextView foodName, txt_amount, txt_desc, txt_date, txt_status;
ivIcon = (ImageView) convertView.findViewById(R.id.ivIcon);
foodName = (TextView) convertView.findViewById(R.id.foodName);
txt_amount = (TextView) convertView.findViewById(R.id.txt_amount);
txt_desc = (TextView) convertView.findViewById(R.id.txt_desc);
// txt_status = (TextView) convertView.findViewById(R.id.txt_status);
txt_date = (TextView) convertView.findViewById(R.id.txt_date);
foodName.setText(foodModelList.get(position).getFood());
txt_amount.setText("Amount: " + foodModelList.get(position).getAmount());
txt_desc.setText(foodModelList.get(position).getDescription());
// txt_status.setText(foodModelList.get(position).getStatus());
txt_date.setText("Date: " + foodModelList.get(position).getDate());
return convertView;
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.navigation_drawer, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_refresh) {
new JSONTask().execute("http://10.0.3.2/MySqlDemo/food.php");
return true;
}
return super.onOptionsItemSelected(item);
}
}
FoodModel.java
public class FoodModel {
private String food;
//private enum status;
private int amount;
private String image;
private String description;
private int date;
public int getDate() {
return date;
}
public void setDate(int date) {
this.date = date;
}
public String getFood() {
return food;
}
public void setFood(String food) {
this.food = food;
}
//public String getStatus() {
// return status;
// }
// public void setStatus(String status) {
// this.status = status;
//}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public int getAmount() {
return amount;
}
public void setAmount(int amount) {
this.amount = amount;
}
}
the logcat error:
02-20 05:06:08.084 4514-4514/alsaad.layla.mysqldemo E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.NullPointerException
at android.widget.ArrayAdapter.getCount(ArrayAdapter.java:330)
at android.widget.ListView.setAdapter(ListView.java:462)
at alsaad.layla.mysqldemo.FoodView$JSONTask.onPostExecute(FoodView.java:128)
at alsaad.layla.mysqldemo.FoodView$JSONTask.onPostExecute(FoodView.java:54)
at android.os.AsyncTask.finish(AsyncTask.java:631)
at android.os.AsyncTask.access$600(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:644)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5041)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)
It seems like you are getting an exception in your for loop that's why it goes into an exception and returns null, so it shows a null pointer exception. Please replace getString() with optSting() and getInt() with optInt().
Solution:- Please put break point in your for loop and find it out otherwise use below option.
for (int i = 0; i < parentArray.length(); i++) {
JSONObject finalObject = parentArray.getJSONObject(i);
FoodModel foodModel = new FoodModel();
foodModel.setFood(finalObject.optString("name"));
//foodModel.setStatus(finalObject.optString("status"));
foodModel.setAmount(finalObject.optInt("amount"));
foodModel.setDescription(finalObject.optString("description"));
foodModel.setDate(finalObject.optInt("exDate"));
foodModelList.add(foodModel);
}
return null; replace with return new ArrayList<>(); to get from crash.
The method getCount() within the ArrayAdater returns the lenght of the object list atached to the adapter:
/**
* {#inheritDoc}
*/
public int getCount() {
return mObjects.size();
}
As you are using a custom ArrayAdapter i think you must Override this function to make it returns the size of your own objects list:
public int getCount() {
return foodModelList.size();
}
Why are you using ArrayAdapter instead i would suggest you to use BaseAdapter
It is the issue when you object is not able to get instance of ArrayAdpter and hence returning null pointer exception at getCount()

java.lang.ClassCastException: java.lang.Integer cannot be cast to java.util.HashMap [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I have looked through numerous questions that are very similar to mine and have tried all the fixes that the other questions recommended to no avail. So I decided I'd post my own question in hopes that someone can help.
NewsActivity:
import android.app.ActionBar;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.media.Image;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserFactory;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
public class NewsActivity extends Activity {
private String xmlData;
private ListView listView;
private ArrayList<News> allNews;
private Image newsImage;
public final static String ITEM_TITLE = "newsTitle";
public final static String ITEM_DATE = "newsDate";
public final static String ITEM_DESCRIPTION = "newsDescription";
public final static String ITEM_IMGURL = "newsImageURL";
public Map<String, ?> createItem(String title, String date, String url) {
Map<String,String> item = new HashMap<>();
item.put(ITEM_TITLE, title);
item.put(ITEM_DATE, date);
item.put(ITEM_IMGURL, url);
return item;
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActionBar bar = getActionBar();
bar.setBackgroundDrawable(new ColorDrawable(Color.parseColor("#f8f8f8")));
bar.setDisplayShowHomeEnabled(false);
bar.setDisplayShowTitleEnabled(true);
bar.setDisplayUseLogoEnabled(false);
bar.setTitle("News");
setContentView(R.layout.news_layout);
Bundle newsBundle = getIntent().getExtras();
xmlData = newsBundle.getString("xmlData");
final ArrayList<News> newsData = getNewsData(xmlData);
allNews = new ArrayList<News>();
List<Map<String, ?>> data = new LinkedList<Map<String, ?>>();
for(int i = 0; i < newsData.size(); i++) {
News currentNews = newsData.get(i);
String newsTitle = currentNews.getNewsTitle();
String newsDate = currentNews.getNewsDate();
String newsDescription = currentNews.getNewsDescription();
String newsImageURL = currentNews.getNewsImageUrl();
data.add(createItem(newsTitle, newsDate, newsImageURL));
allNews.add(currentNews);
}
listView = (ListView) findViewById(R.id.news_list);
LazyNewsAdapter adapter = new LazyNewsAdapter(this, newsData);
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Map<String, String> item = (HashMap<String, String>) parent.getItemAtPosition(position); //**ERROR IS HERE: java.lang.ClassCastException: java.lang.Integer cannot be cast to java.util.HashMap** //
String title = item.get(ITEM_TITLE);
String url = item.get(ITEM_IMGURL);
String date = item.get(ITEM_DATE);
Iterator<News> itp = allNews.iterator();
News currentNews = null;
while (itp.hasNext()) {
currentNews = itp.next();
if (title == currentNews.getNewsTitle() && url == currentNews.getNewsImageUrl() && date == currentNews.getNewsDate())
break;
}
String newsTitle = currentNews.getNewsTitle();
String newsDescription = currentNews.getNewsDescription();
String newsUrl = currentNews.getNewsImageUrl();
String newsDate = currentNews.getNewsDate();
Intent detailnewsScreen = new Intent(getApplicationContext(), DetailNewsActivity.class);
detailnewsScreen.putExtra("newsTitle", newsTitle);
detailnewsScreen.putExtra("newsDescription", newsDescription);
detailnewsScreen.putExtra("url", newsUrl);
detailnewsScreen.putExtra("newsDate", newsDate);
startActivity(detailnewsScreen);
}
});
}
private ArrayList<News> getNewsData(String src) {
ArrayList<News> newsList = new ArrayList<>();
News currentNews = new News();
String newsTitle = new String();
String newsDate = new String();
String newsUrl = new String();
String newsDescription = new String();
try {
StringReader sr = new StringReader(src);
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
XmlPullParser xpp = factory.newPullParser();
xpp.setInput(sr);
int eventType = xpp.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
String name = null;
switch (eventType) {
case XmlPullParser.START_TAG:
name = xpp.getName();
if (name.equals("news")) {
currentNews = new News();
}
else if (name.equals("ntitle")) {
newsTitle = xpp.nextText();
newsTitle = newsTitle.trim();
}
else if (name.equals("ndate")) {
newsDate = xpp.nextText();
newsDate = newsDate.trim();
}
else if (name.equals("nimage")) {
newsUrl = xpp.nextText();
newsUrl = newsUrl.trim();
}
else if (name.equals("ndescription")) {
newsDescription = xpp.nextText();
newsDescription = newsDescription.trim();
}
break;
case XmlPullParser.END_TAG:
name = xpp.getName();
if (name.equals("news")) {
currentNews.setNewsTitle(newsTitle);
currentNews.setNewsDate(newsDate);
currentNews.setNewsImageUrl("http://www.branko-cirovic.appspot.com/iWeek/news/images/" + newsUrl);
currentNews.setNewsDescription(newsDescription);
newsList.add(currentNews);
}
break;
}
eventType = xpp.next();
}
}
catch (Exception e){
e.printStackTrace();
}
return newsList;
}
}
LazyNewsAdapter:
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.ArrayList;
public class LazyNewsAdapter extends BaseAdapter {
private Activity activity;
private ArrayList<News> listData;
private LayoutInflater inflater = null;
public LazyNewsAdapter(Activity activity, ArrayList<News> listData) {
this.activity = activity;
this.listData = listData;
inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public int getCount() {
return listData.size();
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
News newsItem = listData.get(position);
View view = convertView;
if(convertView == null)
view = inflater.inflate(R.layout.news_cell, null);
TextView newsTitle = (TextView) view.findViewById(R.id.newsTitle);
TextView newsDate = (TextView) view.findViewById(R.id.newsDate);
ImageView image = (ImageView) view.findViewById(R.id.newsImage);
newsTitle.setText(newsItem.getNewsTitle());
newsDate.setText(newsItem.getNewsDate());
String url = newsItem.getNewsImageUrl();
ImageLoader imageLoader = new ImageLoader(activity, 600, R.mipmap.placeholder);
imageLoader.displayImage(url, image);
return view;
}
}
The error that I am getting has a comment next to it in the NewsActivity. It seems to be trying to cast an integer to a HashMap for some reason. I have multiple other classes that use this exact method and have no issue, but for this NewsActivity I am getting this error.
Any suggestions?
Thanks so much!
your version of getItem is returning an int
public Object getItem(int position) {
return position;
}
that's why you can't cast to parent.getItemAtPosition(position); to Map<String, String>. Second your Adapter's subclass knows objects of type News. You getItem should return the News at position
public Object getItem(int position) {
return listData.get(position);
}
and you should cast the returned value of parent.getItemAtPosition(position); to News. Change
Map<String, String> item = (HashMap<String, String>) parent.getItemAtPosition(position);
with
News item = (News) parent.getItemAtPosition(position);
then use item to access its content
My guess is that the position passed into NewsActivity.onItemClick() is wrong. The line parent.getItemAtPosition() returns an Object which you are casting, but if the position is wrong you will be getting the wrong Object, potentially with a different type which cannot be cast to a hashmap, hence the error.

Android Google Place API java.lang.NullPointerException error

Im trying to add the name of the resturaunt and the category onto a card view via custom adapter. How ever when ever i run the program i keep getting a java null pointer exception. Im a little bit startled by this, i have been looking through the web but have found no luck. Thanks in advance!
//Main:
package com.example.rifatrashid.compass;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.widget.ListView;
import android.widget.TextView;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.ByteArrayBuffer;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.BufferedInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Rifat Rashid on 2/23/2015.
*/
public class chooseactivity extends ActionBarActivity{
private ListView listView1;
ArrayList<Places> venuesList;
final String GOOGLE_KEY = "AIzaSyD72cNSZ6PoMFwvDe-ihUDNcTrAnuMynuE";
TextView t1;
final String latitude = "40.7463956";
final String longitude = "-73.9852992";
PlacesAdapter adapter1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.chooselocation);
new googleplaces().execute();
/*Places place_data[] = new Places[]{
new Places("Lunch", "Mandarin Cuisine"),
new Places("Brunch", "Fredmeyer"),
new Places("Supplies", "Target")
};
*/
/*
PlacesAdapter adapter = new PlacesAdapter(this, R.layout.listview_item_row, place_data);
listView1 = (ListView) findViewById(R.id.listView);
listView1.setAdapter(adapter);
*/
}
class googleplaces extends AsyncTask<View, Void, String> { //Line54
String temp;
#Override
protected String doInBackground(View... urls) {
temp = makeCall("https://maps.googleapis.com/maps/api/place/search/json?location=" + latitude + "," + longitude + "&radius=100&sensor=true&key=" + GOOGLE_KEY);
return "";
}
#Override
protected void onPreExecute() {}
#Override
protected void onPostExecute(String result) {
if (temp == null) {
//Error coce exception
} else {
venuesList = (ArrayList<Places>) parseGoogleParse(temp);
List<String> listTitle = new ArrayList<>();
//List<Places> gPlace = new ArrayList<>();
Places[] place_data = new Places[100];
for (int i = 0; i < venuesList.size(); i++) {
//listTitle.add(i, venuesList.get(i).getName() + "\nOpen Now: " + venuesList.get(i).getOpenNow() + "\n(" + venuesList.get(i).getCategory() + ")");
new Places(venuesList.get(i).getCategory().toString(), venuesList.get(i).getName().toString()); //Line77
//gPlace.add(new Places(venuesList.get(i).getCategory(), "y"));
}
adapter1 = new PlacesAdapter(chooseactivity.this, R.layout.listview_item_row, place_data);
listView1 = (ListView) findViewById(R.id.listView);
listView1.setAdapter(adapter1);
}
}
}
public static String makeCall(String url) {
// string buffers the url
StringBuffer buffer_string = new StringBuffer(url);
String replyString = "";
// instanciate an HttpClient
HttpClient httpclient = new DefaultHttpClient();
// instanciate an HttpGet
HttpGet httpget = new HttpGet(buffer_string.toString());
try {
// get the responce of the httpclient execution of the url
HttpResponse response = httpclient.execute(httpget);
InputStream is = response.getEntity().getContent();
// buffer input stream the result
BufferedInputStream bis = new BufferedInputStream(is);
ByteArrayBuffer baf = new ByteArrayBuffer(20);
int current = 0;
while ((current = bis.read()) != -1) {
baf.append((byte) current);
}
// the result as a string is ready for parsing
replyString = new String(baf.toByteArray());
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(replyString);
// trim the whitespaces
return replyString.trim();
}
private static ArrayList<Places> parseGoogleParse(final String response) {
ArrayList<Places> temp = new ArrayList<>();
try {
JSONObject jsonObject = new JSONObject(response);
if (jsonObject.has("results")) {
JSONArray jsonArray = jsonObject.getJSONArray("results");
for (int i = 0; i < jsonArray.length(); i++) {
Places poi = new Places();
if (jsonArray.getJSONObject(i).has("name")) {
poi.setName(jsonArray.getJSONObject(i).optString("name"));
poi.setRating(jsonArray.getJSONObject(i).optString("rating", " "));
if (jsonArray.getJSONObject(i).has("opening_hours")) {
if (jsonArray.getJSONObject(i).getJSONObject("opening_hours").has("open_now")) {
if (jsonArray.getJSONObject(i).getJSONObject("opening_hours").getString("open_now").equals("true")) {
poi.setOpenNow("YES");
} else {
poi.setOpenNow("NO");
}
}
} else {
poi.setOpenNow("Not Known");
}
if (jsonArray.getJSONObject(i).has("types")) {
JSONArray typesArray = jsonArray.getJSONObject(i).getJSONArray("types");
for (int j = 0; j < typesArray.length(); j++) {
poi.setCategory(typesArray.getString(j) + ", " + poi.getCategory());
}
}
}
temp.add(poi);
}
}
} catch (Exception e) {
e.printStackTrace();
return new ArrayList<Places>();
}
return temp;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu items for use in the action bar
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_main, menu);
return super.onCreateOptionsMenu(menu);
}
}
Heres my Places Class:
package com.example.rifatrashid.compass;
/**
* Created by Rifat Rashid on 2/23/2015.
*/
public class Places {
public String category;
public String name;
public String rating;
public String open;
public Places(){
super();
}
public Places(String category, String name){
super();
this.category = "";
this.name = "";
this.rating = "";
this.open = "";
}
public String getCategory(){
return category;
}
public String getOpen(){
return open;
}
public String getName(){
return name;
}
public void setName(String name) {
this.name = name;
}
public void setRating(String rating) {
this.rating = rating;
}
public void setOpenNow(String openNow) {
this.open = openNow;
}
public void setCategory(String s) {
}
public String getOpenNow() {
return open;
}
}
My custom adapter class:
package com.example.rifatrashid.compass;
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;
/**
* Created by Rifat Rashid on 2/23/2015.
*/
public class PlacesAdapter extends ArrayAdapter<Places> {
Context context;
int layoutResourceId;
Places[] data;
//List<Places> data;
public PlacesAdapter(Context context, int layoutResourceId, Places[] data) {
super(context, layoutResourceId, data);
this.layoutResourceId = layoutResourceId;
this.context = context;
this.data = data;
}
public View getView(int position, View convertView, ViewGroup parent){
View row = convertView;
PlacesHolder holder = null;
if(row == null){
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new PlacesHolder();
holder.titleTxt = (TextView) row.findViewById(R.id.placeTitle);
holder.sub = (TextView) row.findViewById(R.id.placeCategory);
row.setTag(holder);
}else{
holder = (PlacesHolder) row.getTag();
}
Places place = data[position];
holder.titleTxt.setText(place.getName());
holder.sub.setText(place.getCategory());
return row;
}
static class PlacesHolder{
TextView titleTxt, sub;
}
}
Error:
02-26 17:05:30.530 9757-9757/com.example.rifatrashid.compass E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.example.rifatrashid.compass, PID: 9757
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String java.lang.String.toString()' on a null object reference
at com.example.rifatrashid.compass.chooseactivity$googleplaces.onPostExecute(chooseactivity.java:77)
at com.example.rifatrashid.compass.chooseactivity$googleplaces.onPostExecute(chooseactivity.java:54)
at android.os.AsyncTask.finish(AsyncTask.java:632)
at android.os.AsyncTask.access$600(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:898)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:693)
As your error log says, you have a problem with a line in your onPostExecute method in your googleplaces class of your chooseactivity activity. (Line 77)
Specifically, one of the elements that you're trying to call toString() on is null.
new Places(venuesList.get(i).getCategory().toString(), venuesList.get(i).getName().toString()); //Line77
To fix the error (but not necessarily your process), wrap this in an if statement that checks to see if the element is null. Like this, for example:
if (venuesList.get(i) != null && venuesList.get(i).getCategory() != null && venuesList.get(i).getName() != null) {
new Places(venuesList.get(i).getCategory().toString(), venuesList.get(i).getName().toString()); //Line77
}
Now this won't actually fix your code, just prevent this error from occurring. What you should really do is in Android Studio, put a breakpoint on Line 77 so that when you debug, you can see exactly which element is null and track back why that might be the case and how you can intercept it in the future.

ListViewActivity with Custom Adapter doesn' t work

Dear Stackoverflow Comunitiy,
I'd like to have a ListView getting filled by an BackgroundTask.
This is my actual Code
HomeActivity:
package com.example.instaemgnew;
import java.util.ArrayList;
import android.app.ListActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import com.example.instaemgnew.classes.Beitrag;
import com.example.instaemgnew.classes.beitragLoader;
import com.example.instaemgnew.classes.listViewHomeActivitiyAdapter;
public class HomeActivity extends ListActivity {
listViewHomeActivitiyAdapter adapter;
ArrayList<Beitrag> beitraege = new ArrayList<Beitrag>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
adapter = new listViewHomeActivitiyAdapter(this, beitraege);
setListAdapter(adapter);
Log.e("TestPoint 1", "Adapter Set");
new beitragLoader(this).execute();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_home, menu);
return true;
}
public void addToListView(Beitrag toAddBeitrag){
beitraege.add(toAddBeitrag);
adapter.notifyDataSetChanged();
}
}
BackgroundTask:
package com.example.instaemgnew.classes;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import com.example.instaemgnew.HomeActivity;
import android.content.Context;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Environment;
import android.util.Log;
import android.widget.ArrayAdapter;
public class beitragLoader extends AsyncTask<String, String, String>{
//Array List für die Beiträge
ArrayList<Beitrag> beitraege;
//User Daten
/*mail = userManager.getMail();
grade = String.valueOf(userManager.getGrade());
school = userManager.getSchool();*/
String mail = "simon-frey#gmx.de";
String grade = String.valueOf(334);
String school = "EMG";
//JSONParser
JSONParser jsonParser = new JSONParser();
//ArrayList mit Beitrag Objekten
ArrayList<Beitrag> beitraegeList;
// Onlinedaten
private static final String SERVER_URL = "http://yooui.de/InstaEMGTest/";
private static final String PASSWORD = "8615daf406f7e2b313494f0240";
//Context
private final HomeActivity homeActivity;
//Konstruktor
public beitragLoader(HomeActivity homeActivity){
this.homeActivity = homeActivity;
Log.e("TestPoint 2", "Created beitragLoader");
}
#Override
protected void onPreExecute() {
super.onPreExecute();
//TODO: Test for InternetConnection
Log.e("TestPoint 3", "PreExectute");
}
/**
* getting All products from url
* */
protected String doInBackground(String... args) {
beitraegeList = new ArrayList<Beitrag>();
String SQLUrl = SERVER_URL + "testBeiträgeAbrufen.php";
String token = getMD5Hash("password" + "data");
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("token", token));
//TODO: params.add(new BasicNameValuePair("page", skipBeitraege))
params.add(new BasicNameValuePair("grade", grade));
params.add(new BasicNameValuePair("school", school));
JSONObject json = jsonParser.makeHttpRequest(SQLUrl, "GET", params);
if (json == null) {
// Server offline
}
Log.e("TestPoint 3,5", "FetchedJSON");
try {
JSONArray beitraege = json.getJSONArray("beitraege");
// looping through All Products
for (int i = 0; i < beitraege.length(); i++) {
Beitrag tempBeitrag = null;
Log.e("TestPoint 3,6", "StartLoop");
JSONObject c = beitraege.getJSONObject(i);
//HDImagesURLList ArrayList
ArrayList<String> HDImagesURLList = new ArrayList<String>();
// Storing each json item in variable
String id = c.getString("ID");
String url = c.getString("url");
String titel = c.getString("titel");
String tags = c.getString("tags");
String onlineDate = c.getString("onlineDate");
Log.e("TestPoint 3,7", "Stored JSON Items");
//Fetching previewImage
try {
Log.e("TestPoint 3,8", "TryImageDownload");
InputStream in = new java.net.URL(url).openStream();
String fileName = "InstaEMG" + String.valueOf(System.currentTimeMillis())+".jpg";
Log.e("imageUri", url);
Log.e("fileName", fileName);
FileOutputStream fileOutput = new FileOutputStream(new File(Environment.getExternalStorageDirectory(),fileName));
byte[] buffer = new byte[1024];
int bufferLength = 0;
while ((bufferLength = in.read(buffer)) > 0 ) {
fileOutput.write(buffer, 0, bufferLength);
Log.e("File Output", String.valueOf(bufferLength));
}
//Fill HDImagesURLList
//TODO
// creating newBeitrag
tempBeitrag = new Beitrag(Integer.parseInt(id), titel, onlineDate, fileName, HDImagesURLList);
// adding Beitrag to ArrayList
beitraegeList.add(tempBeitrag);
Log.e("TestPoint 4", "NewBeitragSet");
} catch (MalformedURLException e) {
Log.e("Exceptrion", "URL Exception");
} catch (IOException e) {
Log.e("Exceptrion", "IO Exception");
}
homeActivity.addToListView(tempBeitrag);
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} return null;
}
/**
* After completing background Safe to MainActivity
* **/
protected void onPostExecute() {
Log.e("TestPoint 5", "PostExecutre");
// homeActivity.updateListView(beitraegeList);
}
/**
* Methode zum Errechnen eines MD5Hashs
*
* #param string
* String welcher kodiert werden soll
* #return MD5 Hash des Strings, bei Fehler der ursprüngliche String.
*/
private String getMD5Hash(String string) {
try {
MessageDigest md5 = MessageDigest.getInstance("MD5");
md5.update(string.getBytes());
byte[] result = md5.digest();
StringBuffer hexString = new StringBuffer();
for (int i = 0; i < result.length; i++) {
if ((0xff & result[i]) < 0x10) {
hexString.append("0" + Integer.toHexString((0xFF & result[i])));
} else {
hexString.append(Integer.toHexString(0xFF & result[i]));
}
}
string = hexString.toString();
} catch (NoSuchAlgorithmException e1) {
e1.printStackTrace();
}
return string;
};
}
and the BaseAdapter:
package com.example.instaemgnew.classes;
import java.util.ArrayList;
import com.example.instaemgnew.R;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class listViewHomeActivitiyAdapter extends BaseAdapter {
private final Context context;
private ArrayList<Beitrag> beitraege;
private final LayoutInflater layoutInflater;
public listViewHomeActivitiyAdapter(Context context, ArrayList<Beitrag> beitraege) {
super();
this.beitraege = beitraege;
this.context = context;
this.layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
//Allgemeien Layout Vorgaben
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View rowView = inflater.inflate(R.layout.single_beitrag_row_layout, parent, false);
if (convertView == null) {
convertView = layoutInflater.inflate(R.layout.single_beitrag_row_layout, null);
}
//getViews
TextView titelView = (TextView) rowView.findViewById(R.id.beitragTitel);
ImageView beitragImageView = (ImageView) rowView.findViewById(R.id.beitragImg);
/*
* TODO: Tags anzeigen und suchen lassen (Wunschfunktion)
* TextView tagsView = (TextView) rowView.findViewById(R.id.beitragTags);
*/
//setTitel From Object
titelView.setText(beitraege.get(position).getTitel());
//setPreviewImage From Object
beitragImageView.setImageBitmap(beitraege.get(position).getPreviewImage());
//setOnClickListener on PreviewImage for PopOutGallery
beitragImageView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//TODO: PopOut Gallery
}
});
return rowView;
}
#Override
public int getCount() {
return beitraege.size();
}
#Override
public Object getItem(int position) {
return beitraege.get(position);
}
#Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
}
In my opinion the Bug have to be in the BaseAdapter, but I don't know where it could be.
Sincerly and thankful,
Simon
To fill listView in doInBackground you need to use Handler, or runOnUiThread, because this is not UI thread.
homeActivity.runOnUiThread(new Runnable()
{
public void run()
{
homeActivity.addToListView(tempBeitrag);
}});
adapter = new listViewHomeActivitiyAdapter(this, beitraege);
beitraege is not populated with any data.
Edit:
Instead of calling this from doInbackground. Use a Interface as a call back to the activity and then populate listview.
public void addToListView(Beitrag toAddBeitrag){
beitraege.add(toAddBeitrag);
adapter.notifyDataSetChanged();
}
How do I return a boolean from AsyncTask?
Instead of boolen value its arraylist in your case.
Then use the below and set the adapter your listview
adapter = new listViewHomeActivitiyAdapter(this, beitraege);

Categories

Resources