I have a Problem with my android app. It always crashes, when I push the Button to go to the new Activity.
Error:
FATAL EXCEPTION: main
Process: PID: 15534
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.realliferpgadac.thomas.adacapp/com.realliferpgadac.thomas.adacapp.Feed}: java.lang.ClassCastException: android.widget.TextView cannot be cast to android.view.ViewGroup
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Caused by: java.lang.ClassCastException: android.widget.TextView cannot be cast to android.view.ViewGroup
at android.app.BackStackRecord.configureTransitions(BackStackRecord.java:1244)
at android.app.BackStackRecord.beginTransition(BackStackRecord.java:978)
at android.app.BackStackRecord.run(BackStackRecord.java:707)
at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1535)
at android.app.FragmentController.execPendingActions(FragmentController.java:325)
at android.app.Activity.performStart(Activity.java:6252)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2379)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
at android.app.ActivityThread.-wrap11(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Source code of the activity that crashes: (It should be a RSS Feed)
import android.os.AsyncTask;
import android.os.Bundle;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.app.ListFragment;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import java.io.StringReader;
public class Feed extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_feed);
if (savedInstanceState == null) {
getFragmentManager().beginTransaction()
.add(R.id.tvFeed, new PlaceholderFragment())
.commit();
}
}
//#Override
// public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
//getMenuInflater().inflate(R.menu.main, menu);
//return true;
//}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.tvFeed) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends ListFragment {
// private TextView mRssFeed;
public PlaceholderFragment() {
}
// #Override
// public View onCreateView(LayoutInflater inflater, ViewGroup container,
// Bundle savedInstanceState) {
// View rootView = inflater.inflate(R.layout.fragment_main, container, false);
// mRssFeed = (TextView) rootView.findViewById(R.id.rss_feed);
// return rootView;
// }
#Override
public void onStart() {
super.onStart();
new GetAndroidPitRssFeedTask().execute();
}
private String getAndroidPitRssFeed() throws IOException {
InputStream in = null;
String rssFeed = null;
try {
URL url = new URL("http://www.androidpit.com/feed/main.xml");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
in = conn.getInputStream();
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
for (int count; (count = in.read(buffer)) != -1; ) {
out.write(buffer, 0, count);
}
byte[] response = out.toByteArray();
rssFeed = new String(response, "UTF-8");
} finally {
if (in != null) {
in.close();
}
}
return rssFeed;
}
private class GetAndroidPitRssFeedTask extends AsyncTask<Void, Void, List<String>> {
#Override
protected List<String> doInBackground(Void... voids) {
List<String> result = null;
try {
String feed = getAndroidPitRssFeed();
result = parse(feed);
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
private List<String> parse(String rssFeed) throws XmlPullParserException, IOException {
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
XmlPullParser xpp = factory.newPullParser();
xpp.setInput(new StringReader(rssFeed));
xpp.nextTag();
return readRss(xpp);
}
private List<String> readRss(XmlPullParser parser)
throws XmlPullParserException, IOException {
List<String> items = new ArrayList<>();
parser.require(XmlPullParser.START_TAG, null, "rss");
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
String name = parser.getName();
if (name.equals("channel")) {
items.addAll(readChannel(parser));
} else {
skip(parser);
}
}
return items;
}
private List<String> readChannel(XmlPullParser parser)
throws IOException, XmlPullParserException {
List<String> items = new ArrayList<>();
parser.require(XmlPullParser.START_TAG, null, "channel");
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
String name = parser.getName();
if (name.equals("item")) {
items.add(readItem(parser));
} else {
skip(parser);
}
}
return items;
}
private String readItem(XmlPullParser parser) throws XmlPullParserException, IOException {
String result = null;
parser.require(XmlPullParser.START_TAG, null, "item");
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
String name = parser.getName();
if (name.equals("title")) {
result = readTitle(parser);
} else {
skip(parser);
}
}
return result;
}
// Processes title tags in the feed.
private String readTitle(XmlPullParser parser)
throws IOException, XmlPullParserException {
parser.require(XmlPullParser.START_TAG, null, "title");
String title = readText(parser);
parser.require(XmlPullParser.END_TAG, null, "title");
return title;
}
private String readText(XmlPullParser parser)
throws IOException, XmlPullParserException {
String result = "";
if (parser.next() == XmlPullParser.TEXT) {
result = parser.getText();
parser.nextTag();
}
return result;
}
private void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
if (parser.getEventType() != XmlPullParser.START_TAG) {
throw new IllegalStateException();
}
int depth = 1;
while (depth != 0) {
switch (parser.next()) {
case XmlPullParser.END_TAG:
depth--;
break;
case XmlPullParser.START_TAG:
depth++;
break;
}
}
}
#Override
protected void onPostExecute(List<String> rssFeed) {
if (rssFeed != null) {
setListAdapter(new ArrayAdapter<>(
getActivity(),
android.R.layout.simple_list_item_1,
android.R.id.text1,
rssFeed));
}
}
}
}
}
XML file of the activity that crashes:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.realliferpgadac.thomas.adacapp.Feed">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Text"
android:id="#+id/tvFeed"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
</ScrollView>
</RelativeLayout>
Where is the problem and how can I solve it?
I hope you can help me.
Thank you,
emt
Replace R.id.tvFeed with Framelayout's id or default id android.R.id.content.
if (savedInstanceState == null) {
getFragmentManager().beginTransaction()
.add(android.R.id.content, new PlaceholderFragment())
.commit();
}
and remove the code from the onOptionsItemSelected() method.
if (id == R.id.tvFeed) {
return true;
}
Related
I am trying to make an app where I want my app, on launch, to display a grid of popular movie posters. The movie posters are downloaded from TheMovieDataBase API. I then use Picasso to load the images. For the GridView I am also using a custom adapter. I am not able to understand how to do it. Here is what I have done up till now
MovieFragment.java
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import com.squareup.picasso.Picasso;
import org.json.JSONArray;
import org.json.JSONException;
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.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class MovieFragment extends Fragment {
//ArrayAdapter<String> mMovieAdapter;
String[]movieId,movieTitle,movieOverview,
movieReleaseDate,
moviePosterPath,movieVoteAverage;
public MovieFragment() {
}
MovieAdapter mMovieAdapter;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container, false);
mMovieAdapter = new MovieAdapter(getActivity());
GridView listView = (GridView) rootView.findViewById(R.id.gridView);
listView.setAdapter(mMovieAdapter);
updateMovie();
return rootView;
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
// Inflate the menu; this adds items to the action bar if it is present.
inflater.inflate(R.menu.menu_fragment, menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_refresh) {
updateMovie();
return true;
}
return super.onOptionsItemSelected(item);
}
private void updateMovie() {
FetchMovieTask movieTask = new FetchMovieTask();
movieTask.execute();
}
class FetchMovieTask extends AsyncTask<Void, Void, List<String>> {
private final String LOG_TAG = FetchMovieTask.class.getSimpleName();
#Override
protected List<String> doInBackground(Void... params) {
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
// Will contain the raw JSON response as a string.
String movieJsonStr = null;
try {
URL url = new URL("http://api.themoviedb.org/3/discover/movie?sort_by=popularity.desc&api_key=c20129fdf73b5df3ab44548ad7f73586");
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
// Read the input stream into a String
InputStream inputStream = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
if (inputStream == null) {
// Nothing to do.
return null;
}
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
buffer.append(line + "\n");
}
if (buffer.length() == 0) {
// Stream was empty. No point in parsing.
return null;
}
movieJsonStr = buffer.toString();
} catch (IOException e) {
Log.e(LOG_TAG, "Error ", e);
return null;
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
Log.e(LOG_TAG, "Error closing stream", e);
}
}
}
try {
return getMovieDataFromJson(movieJsonStr);
} catch (JSONException j) {
Log.e(LOG_TAG, "JSON Error", j);
}
return null;
}
private List<String> getMovieDataFromJson(String forecastJsonStr)
throws JSONException {
JSONObject movieJson = new JSONObject(forecastJsonStr);
JSONArray movieArray = movieJson.getJSONArray("results");
List<String> urls = new ArrayList<>();
for (int i = 0; i < movieArray.length(); i++) {
JSONObject movie = movieArray.getJSONObject(i);
urls.add("http://image.tmdb.org/t/p/w185" + movie.getString("poster_path"));
}
return urls;
}
#Override
protected void onPostExecute(List<String> strings) {
mMovieAdapter.replace(strings);
}
}
class MovieAdapter extends BaseAdapter {
private final String LOG_TAG = MovieAdapter.class.getSimpleName();
private final Context context;
private final List<String> urls = new ArrayList<String>();
public MovieAdapter(Context context) {
this.context = context;
Collections.addAll(urls, moviePosterPath);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = new ImageView(context);
}
ImageView imageView = (ImageView) convertView;
String url = getItem(position);
Log.e(LOG_TAG," URL "+url);
Picasso.with(context).load(url).into(imageView);
return convertView;
}
#Override
public int getCount() {
return urls.size();
}
#Override
public String getItem(int position) {
return urls.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
public void replace(List<String> urls) {
this.urls.clear();
this.urls.addAll(urls);
notifyDataSetChanged();
}
}
}
When I run this code it shows a NullPointerException and a RuntimeException
java.lang.RuntimeException: Unable to start activity ComponentInfo
{com.codesetters.verader/com.codesetters.verader.MainActivity}: java.lang.NullPointerException atandroid.app.ActivityThreadperformLaunchActivity(ActivityThread.java:2404)
Caused by: java.lang.NullPointerException atjava.util.Collections.addAll(Collections.java:2582)
How can I resolve them?
Please Help
You're getting this error because you've used moviePosterPath here :
Collections.addAll(urls, moviePosterPath);
but you've not initialized it anywhere. Initialize it with some value and it should solve the error.
The null pointer could be because the String array moviePosterPath is not initialized. and you are ussing it in Collections.addAll
This is how to initialize an array. Anyway I recommend you to use ArrayList
String[] moviePosterPath = new String[N];
I'm following the android xml parsing tutorial (http://developer.android.com/training/basics/network-ops/xml.html#analyze), however when stepping through it, it seems to fail at:
parser.require(XmlPullParser.START_TAG, ns, "rss");
and then ends up dropping to the finally clause. Just wondering if anyone could spot what the issue could be as I've played around with it for hours without much success.
The feed I am trying to read is: http://feeds.bbci.co.uk/news/rss.xml
Any help is greatly appreciated, please find the code below:
package com.proxama.news_bbc;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import android.support.v7.app.ActionBarActivity;
import android.support.v4.app.Fragment;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.util.Xml;
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.ListView;
import android.provider.DocumentsContract.Document;
public class MainActivity extends ActionBarActivity {
private static final String ns = null;
/*
* Only interested in the content of the following XML tags for each news
* item:
*
* item/media:thumbnail item/pubDate item/link item/description item/title
*/
private void skip(XmlPullParser parser) throws XmlPullParserException,
IOException {
if (parser.getEventType() != XmlPullParser.START_TAG) {
throw new IllegalStateException();
}
int depth = 1;
while (depth != 0) {
switch (parser.next()) {
case XmlPullParser.END_TAG:
depth--;
break;
case XmlPullParser.START_TAG:
depth++;
break;
}
}
}
public static class Entry {
public final String title;
public final String link;
public final String summary;
private Entry(String title, String summary, String link) {
this.title = title;
this.summary = summary;
this.link = link;
}
}
// Parses the contents of an entry. If it encounters a title, summary, or
// link tag, hands them off
// to their respective "read" methods for processing. Otherwise, skips the
// tag.
// Processes title tags in the feed.
private String readTitle(XmlPullParser parser) throws IOException,
XmlPullParserException {
parser.require(XmlPullParser.START_TAG, ns, "title");
String title = readText(parser);
parser.require(XmlPullParser.END_TAG, ns, "title");
return title;
}
// Processes link tags in the feed.
private String readLink(XmlPullParser parser) throws IOException,
XmlPullParserException {
String link = "";
parser.require(XmlPullParser.START_TAG, ns, "link");
String tag = parser.getName();
String relType = parser.getAttributeValue(null, "rel");
if (tag.equals("link")) {
if (relType.equals("alternate")) {
link = parser.getAttributeValue(null, "href");
parser.nextTag();
}
}
parser.require(XmlPullParser.END_TAG, ns, "link");
return link;
}
// Processes summary tags in the feed.
private String readSummary(XmlPullParser parser) throws IOException,
XmlPullParserException {
parser.require(XmlPullParser.START_TAG, ns, "summary");
String summary = readText(parser);
parser.require(XmlPullParser.END_TAG, ns, "summary");
return summary;
}
// For the tags title and summary, extracts their text values.
private String readText(XmlPullParser parser) throws IOException,
XmlPullParserException {
String result = "";
if (parser.next() == XmlPullParser.TEXT) {
result = parser.getText();
parser.nextTag();
}
return result;
}
private Entry readEntry(XmlPullParser parser)
throws XmlPullParserException, IOException {
parser.require(XmlPullParser.START_TAG, ns, "item");
String title = null;
String summary = null;
String link = null;
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
String name = parser.getName();
if (name.equals("title")) {
title = readTitle(parser);
} else if (name.equals("summary")) {
summary = readSummary(parser);
} else if (name.equals("link")) {
link = readLink(parser);
} else {
skip(parser);
}
}
return new Entry(title, summary, link);
}
private List readFeed(XmlPullParser parser) throws XmlPullParserException,
IOException {
List entries = new ArrayList();
String xmlContents = parser.toString();
parser.require(XmlPullParser.START_TAG, ns, "rss");
Log.d("className", "Up to here ");
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
String name = parser.getName();
// Starts by looking for the news item tag
if (name.equals("item")) {
entries.add(readEntry(parser));
} else {
skip(parser);
}
}
return entries;
}
private List parseXml(InputStream in) throws XmlPullParserException,
IOException {
try {
XmlPullParser parser = Xml.newPullParser();
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
parser.setInput(in, null);
return readFeed(parser);
} finally {
in.close();
}
}
private String downloadUrl(String myurl) throws IOException {
// TODO allow for internal storage if external is unavailable or full
File root = android.os.Environment.getExternalStorageDirectory();
String Directory = root.getAbsolutePath() + "/xmls";
String xmlFileName = "bbc_news_rss.xml";
String fullXmlPath = Directory + "/" + xmlFileName;
File dir = new File(Directory);
if (dir.exists() == false) {
dir.mkdirs();
}
/*URL url = new URL(myurl);
InputStream is = url.openStream();
OutputStream os = new FileOutputStream(fullXmlPath);
byte[] b = new byte[2048];
int length;
while ((length = is.read(b)) != -1) {
os.write(b, 0, length);
}
is.close();
os.close();*/
URL url = new URL(myurl);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setRequestMethod("GET");
conn.setDoInput(true);
// Starts the query
conn.connect();
InputStream in = conn.getInputStream();
Log.d("className", "Saved XML file to: " + fullXmlPath);
Log.d("className", "Starting to parse XML file: " + fullXmlPath);
//InputStream in = new FileInputStream(fullXmlPath);
try {
parseXml(in);
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return fullXmlPath;
}
// Uses AsyncTask to create a task away from the main UI thread. This task
// takes a
// URL string and uses it to create an HttpUrlConnection. Once the
// connection
// has been established, the AsyncTask downloads the contents of the webpage
// as
// an InputStream. Finally, the InputStream is converted into a string,
// which is
// displayed in the UI by the AsyncTask's onPostExecute method.
private class DownloadWebpageTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... stringUrl) {
try {
Log.d("className", "Downloading url: " + stringUrl[0]);
return downloadUrl(stringUrl[0]);
} catch (IOException e) {
return "Unable to retrieve file.";
}
}
// onPostExecute displays the results of the AsyncTask.
#Override
protected void onPostExecute(String result) {
Log.d("className",
"In onpostexecute and result of downloadUrl is: " + result);
// If the file has been saved correctly, parse it.
if (result != "Unable to retrieve file.") {
Log.d("className", "Creating list view");
createList();
}
}
}
/** Pull in the XML from http://feeds.bbci.co.uk/news/rss.xml */
public void pull_xml(View view) {
ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
// can connect so fetch XML file
Log.d("className", "Successfully connected to network!");
new DownloadWebpageTask()
.execute("http://feeds.bbci.co.uk/news/rss.xml");
} else {
// display error
Log.d("className",
"Unable to connect to network, trying to use a previously saved local xml file");
}
}
public void createList() {
setContentView(R.layout.activity_main);
// Get ListView object from XML
ListView listView = (ListView) findViewById(R.id.listView1);
// Defined Array values to show in ListView
String[] values = new String[] { "Ukraine begins 'anti-terror' action" };
// Define a new Adapter
// First parameter - Context
// Second parameter - Layout for the row
// Third parameter - ID of the TextView to which the data is written
// Forth - the Array of data
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, android.R.id.text1, values);
// Assign adapter to ListView
listView.setAdapter(adapter);
}
// Original classes and methods that came by default with new android
// projects.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// retrieve the XML and create list view
pull_xml(null);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_main, container,
false);
return rootView;
}
}
}
Your code has several mistakes:
DownloadWebpageTask.onPostExecute: here you are trying to compare Strings with != operator. It's wrong, you'll always get false. The correct way is to use equals method:
if ("Unable to retrieve file.".equals(result)) {
Log.d("className", "Creating list view");
createList();
}
createList() method: what's the purpose of calling setContentView(R.layout.activity_main); here if you already did it at the onCreate?
pull_xml(View view) method: what's the purpose of view argument? You are not using it at this method.
parseXml method: please add parser.nextTag()
I am trying to parse a xml file and display the feeds in form of separate cards. This is what my code looks like till now:
package com.bliss.android.helloworld.main;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import com.google.android.glass.app.Card;
import com.google.android.glass.widget.CardScrollAdapter;
import com.google.android.glass.widget.CardScrollView;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.view.ViewGroup;
public class SecondScreen extends Activity {
ArrayList<Card> headlines = new ArrayList<Card>();
ArrayList links = new ArrayList();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
new PostTask().execute("http://feeds.pcworld.com/pcworld/latestnews");
CardScrollView csvCardsView = new CardScrollView(this);
csaAdapter cvAdapter = new csaAdapter();
csvCardsView.setAdapter(cvAdapter);
csvCardsView.activate();
setContentView(csvCardsView);
}
private class PostTask extends AsyncTask<String, Integer, String> {
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected String doInBackground(String... params) {
String url=params[0];
try{
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(false);
XmlPullParser xpp = factory.newPullParser();
boolean insideItem = false;
// Returns the type of current event: START_TAG, END_TAG, etc..
int eventType = xpp.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_TAG) {
if (xpp.getName().equalsIgnoreCase("item")) {
insideItem = true;
} else if (xpp.getName().equalsIgnoreCase("title")) {
if (insideItem){
Card newCard = new Card(SecondScreen.this);
newCard.setText(xpp.nextText());
headlines.add(newCard); //extract the headline
}
} else if (xpp.getName().equalsIgnoreCase("link")) {
if (insideItem)
links.add(xpp.nextText()); //extract the link of article
}
}else if(eventType==XmlPullParser.END_TAG && xpp.getName().equalsIgnoreCase("item")){
insideItem=false;
}
eventType = xpp.next(); //move to next element
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return url;
}
}
private class csaAdapter extends CardScrollAdapter
{
#Override
public int findIdPosition(Object id)
{
return -1;
}
#Override
public int findItemPosition(Object item)
{
return headlines.indexOf(item);
}
#Override
public int getCount()
{
return headlines.size();
}
#Override
public Object getItem(int position)
{
return headlines.get(position);
}
#Override
public View getView(int position, View convertView, ViewGroup parent)
{
return headlines.get(position).toView();
}
}
public InputStream getInputStream(URL url) {
try {
return url.openConnection().getInputStream();
} catch (IOException e) {
return null;
}
}
}
I do not get any error but there is nothing displayed on the card. I cant figure out whats the reason. Is it because of Card(SeconScreen.this). But if I dont put that it gives me an error saying constructor not defined.
I am trying read data from an xml string and set the respective tag element using setter getter method but my xml shows a malformation error in xml file. What am i doing wrong here is my code.
in oncreate..
SAXHelper2 sh = null;
try {
sh = new SAXHelper2(newxml);
} catch (MalformedURLException e) {
e.printStackTrace();
}
sh.parseContent("");
return null;
}
}
/*
*
*/
class SAXHelper2 {
private String data;
StringBuffer chars = new StringBuffer();
public SAXHelper2(String xmlstring) throws MalformedURLException {
this.data = new String(xmlstring);
}
DefaultHandler handler = new DefaultHandler();
public RSSHandler parseContent(String parseContent) {
RSSHandler df = new RSSHandler();
try {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser saxParser = factory.newSAXParser();
saxParser.parse(new InputSource(newxml), new RSSHandler());
} catch (Exception e) {
e.printStackTrace();
}
return df;
}
class RSSHandler extends DefaultHandler {
private ComptePost currentPost = new ComptePost();
StringBuffer chars = new StringBuffer();
public void startElement(String uri, String localName, String qName, Attributes atts) {
chars = new StringBuffer();
if (localName.equalsIgnoreCase("comptes")) {
}
}
DefaultHandler handler = new DefaultHandler() {
#Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
if (localName.equalsIgnoreCase("numCompte")
&& currentPost.getNumComtpe() == null) {
System.out.println("Post: "+currentPost.getNumComtpe());
Log.i("numCompte", currentPost.getNumComtpe());
currentPost.setNumComtpe(chars.toString());
}
if (localName.equalsIgnoreCase("authCompte")
&& currentPost.getAuthCompte() == null) {
currentPost.setAuthCompte(chars.toString());
}
if (localName.equalsIgnoreCase("typeCompte")
&& currentPost.getTypeCompte() == null) {
currentPost.setTypeCompte(chars.toString());
}
if (localName.equalsIgnoreCase("libelleCompte")
&& currentPost.getLibelleCompte()== null) {
currentPost.setLibelleCompte(chars.toString());
}
if (localName.equalsIgnoreCase("soldeCompte")
&& currentPost.getSoldeCompte() == null) {
currentPost.setSoldeCompte(chars.toString());
}
if (localName.equalsIgnoreCase("deviseCompte")
&& currentPost.getDeviseCompte() == null) {
currentPost.setDeviseCompte(chars.toString());
}
if (localName.equalsIgnoreCase("dateSolde")
&& currentPost.getDateSolde()== null) {
currentPost.setDateSolde(chars.toString());
}
if (localName.equalsIgnoreCase("droitVirement")
&& currentPost.getDroitVirement()== null) {
currentPost.setDroitVirement(chars.toString());
}
if (localName.equalsIgnoreCase("carteBancaire")
&& currentPost.getCarteBancaire()== null) {
currentPost.setCarteBancaire(chars.toString());
}
if (localName.equalsIgnoreCase("debitMin")
&& currentPost.getDebitMin()== null) {
currentPost.setDebitMin(chars.toString());
}
if (localName.equalsIgnoreCase("debitMax")
&& currentPost.getDebitMax()== null) {
currentPost.setDebitMax(chars.toString());
}
if (localName.equalsIgnoreCase("creditMin")
&& currentPost.getCreditMin()== null) {
currentPost.setCreditMin(chars.toString());
}
if (localName.equalsIgnoreCase("creditMax")
&& currentPost.getCreditMax()== null) {
currentPost.setCreditMax(chars.toString());
}
if (localName.equalsIgnoreCase("echeanceMax")
&& currentPost.getEcheanceMax()== null) {
currentPost.setEcheanceMax(chars.toString());
}
if (localName.equalsIgnoreCase("comptes")) {
PostList.add(currentPost);
currentPost = new ComptePost();
}
}
#Override
public void characters(char ch[], int start, int length) {
chars.append(new String(ch, start, length));
}
};
}
}
java.io.IOException: Couldn't open
Caused by: java.net.MalformedURLException: Protocol not found:
04-05 15:24:52.699: W/System.err(4784): at org.apache.harmony.xml.ExpatParser.openUrl(ExpatParser.java:760)
04-05 15:24:52.703: W/System.err(4784): at org.apache.harmony.xml.ExpatReader.parse(ExpatReader.java:289)
04-05 15:24:52.707: W/System.err(4784): at javax.xml.parsers.SAXParser.parse(SAXParser.java:390)
04-05 15:24:52.707: W/System.err(4784): at .details.CompteDetails$SAXHelper2.parseContent(CompteDetails.java:222)
04-05 15:24:52.707: W/System.err(4784): at .details.CompteDetails$loadingTask.doInBackground(CompteDetails.java:193)
04-05 15:24:52.710: W/System.err(4784): at .details.CompteDetails$loadingTask.doInBackground(CompteDetails.java:1)
04-05 15:24:52.710: W/System.err(4784): at android.os.AsyncTask$2.call(AsyncTask.java:185)
04-05 15:24:52.710: W/System.err(4784): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306)
04-05 15:24:52.714: W/System.err(4784): at java.util.concurrent.FutureTask.run(FutureTask.java:138)
04-05 15:24:52.714: W/System.err(4784): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088)
04-05 15:24:52.714: W/System.err(4784): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581)
04-05 15:24:52.718: W/System.err(4784): at java.lang.Thread.run(Thread.java:1019)
04-05 15:24:52.718: W/System.err(4784): at java.net.URL.<init>(URL.java:273)
04-05 15:24:52.722: W/System.err(4784): at java.net.URL.<init>(URL.java:157)
04-05 15:24:52.722: W/System.err(4784): at org.apache.harmony.xml.ExpatParser.openUrl(ExpatParser.java:753)
This will work as expected
Type.java
package com.example.test;
public class Type
{
private String lory;
private String car;
public String getLory()
{
return lory;
}
public void setLory(String lory)
{
this.lory = lory;
}
public String getCar()
{
return car;
}
public void setCar(String car)
{
this.car = car;
}
#Override
public String toString()
{
return "Lory : " + this.lory + "\nCar : " + this.car;
}
public String getDetails()
{
String result = "Lory : " + this.lory + "\nCar : " + this.car;
return result;
}
}
SAXXMLHandler.java
package com.example.test;
import java.util.ArrayList;
import java.util.List;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class SAXXMLHandler extends DefaultHandler
{
private List<Type> types;
private String tempVal;
private Type tempType;
public SAXXMLHandler()
{
types = new ArrayList<Type>();
}
public List<Type> getTypes()
{
return types;
}
// Event Handlers
#Override
public void startElement(String uri, String localName, String qualifiedName, Attributes attributes) throws SAXException
{
// reset
tempVal = "";
if ( qualifiedName.equalsIgnoreCase("data") )
{
// create a new instance of type
tempType = new Type();
}
}
#Override
public void characters(char[] ch, int start, int length) throws SAXException
{
tempVal = new String(ch, start, length);
}
#Override
public void endElement(String uri, String localName, String qualifiedName) throws SAXException
{
if ( qualifiedName.equalsIgnoreCase("type") )
{
// add it to the list and create new instance
types.add(tempType);
tempType = new Type();
}
else if ( qualifiedName.equalsIgnoreCase("lory") )
{
tempType.setLory(tempVal);
}
else if ( qualifiedName.equalsIgnoreCase("car") )
{
tempType.setCar(tempVal);
}
}
}
SAXXMLParser.java
package com.example.test;
import java.io.InputStream;
import java.util.List;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.InputSource;
import org.xml.sax.XMLReader;
import android.util.Log;
public class SAXXMLParser
{
public static List<Type> parse(InputStream is)
{
List<Type> types = null;
try
{
// create a XMLReader from SAXParser
XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
// create a SAXXMLHandler
SAXXMLHandler saxHandler = new SAXXMLHandler();
// store handler in XMLReader
xmlReader.setContentHandler(saxHandler);
// the process starts
xmlReader.parse(new InputSource(is));
// get the `Type list`
types = saxHandler.getTypes();
}
catch ( Exception ex )
{
Log.d("XML", "SAXXMLParser: parse() failed");
}
// return Type list
return types;
}
}
SAXParserActivity.java
package com.example.test;
import java.io.ByteArrayInputStream;
import java.util.List;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class SAXParserActivity extends Activity implements OnClickListener
{
Button button;
List<Type> types = null;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
button = (Button) findViewById(R.id.button);
button.setOnClickListener(this);
}
#Override
public void onClick(View v)
{
String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?> <data> <type> <lory>vroom</lory> <car>crack</car> </type> <type> <lory>doom</lory> <car>chack</car> </type> </data>";
types = SAXXMLParser.parse(new ByteArrayInputStream(xml.getBytes()));
Log.d("SSDDSD", "Length : " + "" + types.size());
for ( Type type : types )
{
Log.d("SAXParserActivity", type.toString());
Toast.makeText(getApplicationContext(), type.toString(), Toast.LENGTH_SHORT).show();
}
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dip" >
<Button
android:id="#+id/button"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Parse XML Using SAX" />
</LinearLayout>
You can see the output in both LogCat and Toast.
try with xmlPullParser not Sax! like this:
import java.io.IOException;
import java.io.StringReader;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
public class XmlPullParserCdb {
public static void parse(String dados) throws XmlPullParserException, IOException {
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
XmlPullParser xpp = factory.newPullParser();
xpp.setInput(new StringReader(dados));
int eventType = xpp.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_DOCUMENT) {
System.out.println("Start document");
} else if (eventType == XmlPullParser.END_DOCUMENT) {
System.out.println("End document");
} else if (eventType == XmlPullParser.START_TAG) {
System.out.println("Start tag " + xpp.getName());
} else if (eventType == XmlPullParser.END_TAG) {
System.out.println("End tag " + xpp.getName());
} else if (eventType == XmlPullParser.TEXT) {
System.out.println("Text " + xpp.getText());
}
eventType = xpp.next();
}
}
}
Assume that I have file XML like this :
<?xml version="1.0"?>
<P>
<Content>
<id>1016576</id>
<date>20.08.2012</date>
<placeOfBirth>KUALA LUMPUR</placeOfBirth>
</Content>
<Content>
<id>1016620</id>
<date>20.08.2012</date>
<placeOfBirth>SINGAPORE</placeOfBirth>
</Content>
<Content>
<id>1020907</id>
<date>20.08.2012</date>
<placeOfBirth>SINGAPORE</placeOfBirth>
</Content>
</P>
I want to parse all the text and insert into database table which have _id, date and placeOfBirth column. I've tried this :
Activity activity1 = this;
String str="";
Resources res = activity1.getResources();
XmlResourceParser xmlPharser = res.getXml(R.xml.fileXML);
String id,date,pob;
//database
final databaseHelper myDbHelper = new databaseHelper(this);
myDbHelper.open();
//insert into table while parsing xml
try {
xmlPharser.next();
int eventType = xmlPharser.getEventType();
String event = ""+eventType;
Log.d("Event", event);
while (eventType != XmlPullParser.END_DOCUMENT)
{
if(eventType == XmlPullParser.START_TAG )
{
if( xmlPharser.getName() == "id")
{
id=xmlPharser.getText();
}
else if ( xmlPharser.getName() == "date" )
{
date = xmlPharser.getText();
}
else if ( xmlPharser.getName() == "placeOfBirth" )
{
pob = xmlPharser.getText();
}
myDbHelper.insertData(id,date,pob);
myDbHelper.close();
}
eventType = xmlPharser.next();
}
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
It doesn't get any error LogCat display, but it dosen't test the condition at each START_TAG.
How can I resolve this problem...
All answer would be appreciated..thanks
Parsing XML can get really nasty if you're not careful, specially with this parsers; you could try some other with simpler APIs or clearer ways of going through the hierarchy (ie. JDOM). You should also take a look at the examples at the Android developer's site, it's really straight forward (Parsing XML Data).
All that been said, I fixed it for you. This should work (at least it does for me). Be careful though, it doesn't have any error checking on malformed XML or database stuff.
import java.io.IOException;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import android.app.Activity;
import android.content.res.XmlResourceParser;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
XmlResourceParser parser = getResources().getXml(R.xml.filexml);
final databaseHelper myDbHelper = null;
try {
myDbHelper = new databaseHelper(this);
myDbHelper.open();
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
String name = parser.getName();
if (name.equals("Content")) {
String id = null, date = null, pob = null;
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
name = parser.getName();
if (name.equals("id")) {
id = readText(parser);
} else if (name.equals("date")) {
date = readText(parser);
} else if (name.equals("placeOfBirth")) {
pob = readText(parser);
}
}
myDbHelper.insertData(id,date,pob);
}
}
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (myDbHelper != null) {
myDbHelper.close();
}
}
}
private String readText(XmlPullParser parser) throws IOException,
XmlPullParserException {
String result = "";
if (parser.next() == XmlPullParser.TEXT) {
result = parser.getText();
parser.nextTag();
}
return result;
}
One more comment, change the xml file name to lowercase ;)