I am new to android, I tried XML parse with SAX previously but I got Exception in Network,I tried lot with that , But not able to get that, many suggest to use AsyncTask, I tried with that , But again failed, So I tried with DOM now, Again same got some exception in android.os.NetworkOnMainThreadException and gralloc_goldfish error (i.e) Emulator without GPU emulation detected .... help me for this problem. i gng this program for 2 days
Program::XMLParsingDOMExample.java
package com.androidpeople.xml.parsing;
import java.net.URL;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import android.app.Activity;
import android.os.Bundle;
import android.widget.LinearLayout;
import android.widget.TextView;
public class XMLParsingDOMExample extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/** Create a new layout to display the view */
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(1);
/** Create a new textview array to display the results */
TextView name[];
TextView website[];
TextView category[];
try {
URL url = new URL(
"http://www.androidpeople.com/wp-content/uploads/2010/06/example.xml");
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(new InputSource(url.openStream()));
doc.getDocumentElement().normalize();
NodeList nodeList = doc.getElementsByTagName("item");
/** Assign textview array lenght by arraylist size */
name = new TextView[nodeList.getLength()];
website = new TextView[nodeList.getLength()];
category = new TextView[nodeList.getLength()];
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
name[i] = new TextView(this);
website[i] = new TextView(this);
category[i] = new TextView(this);
Element fstElmnt = (Element) node;
NodeList nameList = fstElmnt.getElementsByTagName("name");
Element nameElement = (Element) nameList.item(0);
nameList = nameElement.getChildNodes();
name[i].setText("Name = "
+ ((Node) nameList.item(0)).getNodeValue());
NodeList websiteList = fstElmnt.getElementsByTagName("website");
Element websiteElement = (Element) websiteList.item(0);
websiteList = websiteElement.getChildNodes();
website[i].setText("Website = "
+ ((Node) websiteList.item(0)).getNodeValue());
category[i].setText("Website Category = "
+ websiteElement.getAttribute("category"));
layout.addView(name[i]);
layout.addView(website[i]);
layout.addView(category[i]);
}
} catch (Exception e) {
System.out.println("XML Pasing Excpetion = " + e);
}
/** Set the layout view to display */
setContentView(layout);
}
}
example.xml
<maintag>
<item>
<name>AndroidPeople</name>
<website category="android">www.androidpeople.com</website>
</item>
<item>
<name>iPhoneAppDeveloper</name>
<website category="iPhone">www.iphone-app-developer.com</website>
</item>
</maintag>
i m not able to get output for the above code.. got some exception in android.os.NetworkOnMainThreadException and gralloc_goldfish error (i.e) Emulator without GPU emulation detected .... help me for this problem. i gng this program for 2 days.. Thank in advance
Execute this on a background thread (maybe using an AsyncTask).
A NetworkOnMainThreadException means exactly this - you are running a network call on the main UI thread. This is to encourage us to not make calls that block UI interaction.
url.openStream() is what triggers this.
Related
I'm making an Music player for Android, I want to provide feature for users to get album art of a song from last.fm.
I've got my API key too. Just need help for retrieving the image from Last.fm.
Any help in getting the image url would also be appreciated.
Thanks in advance.
P.S : For more info about my music player, check the link below
https://plus.google.com/u/0/communities/115046175816530349000
I found an solution check below
Add the below AsyncTask loader
public class RetrieveFeedTask extends AsyncTask<String, Void, String> {
protected String doInBackground(String... urls) {
String albumArtUrl = null;
try {
XMLParser parser = new XMLParser();
String xml = parser.getXmlFromUrl(urls[0]); // getting XML from URL
Document doc = parser.getDomElement(xml);
NodeList nl = doc.getElementsByTagName("image");
for (int i = 0; i < nl.getLength(); i++) {
Element e = (Element) nl.item(i);
Log.d(LOG_TAG,"Size = " + e.getAttribute("size") + " = " + parser.getElementValue(e));
if(e.getAttribute("size").contentEquals("medium")){
albumArtUrl = parser.getElementValue(e);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return albumArtUrl;
}
}
Call it as followed :
StringBuilder stringBuilder = new StringBuilder("http://ws.audioscrobbler.com/2.0/");
stringBuilder.append("?method=album.getinfo");
stringBuilder.append("&api_key=");
stringBuilder.append("YOUR_LAST_FM_API_KEY");
stringBuilder.append("&artist=" + URLEncoder.encode("ARTIST_NAME_HERE", "UTF-8"));
stringBuilder.append("&album=" + URLEncoder.encode("ALBUM_NAME_HERE", "UTF-8"));
url = new RetrieveFeedTask().execute(stringBuilder.toString()).get();
You need 2 classes :
1. XmlParser
2. DocElement
Both of which will be available in link below.
Xml parsing tutorial
Please see Last.fm Web Services docs for album.getInfo: http://www.last.fm/api/show/album.getInfo
Here is a sample response, from which you can easily see how to get cover art image url:
<album>
<name>Believe</name>
<artist>Cher</artist>
<id>2026126</id>
<mbid>61bf0388-b8a9-48f4-81d1-7eb02706dfb0</mbid>
<url>http://www.last.fm/music/Cher/Believe</url>
<releasedate>6 Apr 1999, 00:00</releasedate>
<image size="small">...</image>
<image size="medium">...</image>
<image size="large">...</image>
<listeners>47602</listeners>
<playcount>212991</playcount>
<toptags>
<tag>
<name>pop</name>
<url>http://www.last.fm/tag/pop</url>
</tag>
...
</toptags>
<tracks>
<track rank="1">
<name>Believe</name>
<duration>239</duration>
<mbid/>
<url>http://www.last.fm/music/Cher/_/Believe</url>
<streamable fulltrack="0">1</streamable>
<artist>
<name>Cher</name>
<mbid>bfcc6d75-a6a5-4bc6-8282-47aec8531818</mbid>
<url>http://www.last.fm/music/Cher</url>
</artist>
</track>
...
</tracks>
</album>
I have the following XML retreived from webservices.How do i get the value of StructureTransID i.e(254) from the above XML using XPath in android? Can anyone help me on this.
<Response>
−
<NewDataSet>
−
<EnrollmentList>
<Transaction_ID>369</Transaction_ID>
<Transaction_Key>489</Transaction_Key>
<Transaction_Type>ENROLLMENT_INFO</Transaction_Type>
<Corp_ID>2</Corp_ID>
−
<Transaction_Xml>
<EnrollmentInfo><SelectedPackages><Package Id="1-GQGFWG" Category="Medical" CoverageLevel="EMP_CHILDREN" CoverageAmt="355.11" TotalCoverageAmt="710.22" StructureTransID="254" EffectiveDate="01/01/2012" TerminationDate="12/31/2012" /></SelectedPackages><PersonalInfo><EmployeeID>E0211</EmployeeID><FirstName>Michael</FirstName><MiddleName /><LastName>Keaton</LastName><DateOfBirth>10/21/1975</DateOfBirth><Gender>M</Gender><SSN>123456789</SSN><Email>mkeaton#designllc.com</Email><AddressLine1>33 Park Street</AddressLine1><AddressLine2 /><AddressLine3 /><City>Jacksonville</City><State>FL</State><ZipCode>32220</ZipCode><HomePhone>(111) 222-4444</HomePhone><WorkPhone>(913) 244-8188</WorkPhone><Dependents><Dependent><FirstName>Alisha</FirstName><MiddleName /><LastName>Jones</LastName><DateOfBirth>1/13/2009</DateOfBirth><Gender>F</Gender><Relationship>Dependent</Relationship><AddressLine1>33 Park Street</AddressLine1><AddressLine2 /><AddressLine3 /><City>Jacksonville</City><State>FL</State><ZipCode>32220</ZipCode><HomePhone /><MedicareNumber /><PartA_EffectiveDate /><PartB_EffectiveDate /><IsFullTimeStudent>False</IsFullTimeStudent><CollegeName /><ExpectedGraduationDate /><CreditHours /></Dependent></Dependents></PersonalInfo><WorkInfo><Class>A004</Class><DateOfHire>05/01/2010</DateOfHire><Designation>Associate</Designation><WorkLocation>Canton</WorkLocation></WorkInfo><SelectedPackages /></EnrollmentInfo>
</Transaction_Xml>
<Active_Ind>1</Active_Ind>
<Effective_Date>2012-01-01T00:00:00+05:30</Effective_Date>
<Status>CO</Status>
<Created_On>2011-12-20T00:47:20.187+05:30</Created_On>
<Created_By>msmith</Created_By>
<Modified_On>2012-02-10T17:50:15.647+05:30</Modified_On>
<Modified_By>mkeaton</Modified_By>
<Termination_Date>2012-12-31T00:00:00+05:30</Termination_Date>
<Comments>Change in employment status</Comments>
<Task_ID>636</Task_ID>
<User_ID>489</User_ID>
<Import_ID>476</Import_ID>
<Corp_ID1>2</Corp_ID1>
<Employee_ID>E0211</Employee_ID>
<Login>mkeaton</Login>
<Password>cGFzc3dvcmQ=</Password>
<Full_Nm>Michael Keaton</Full_Nm>
<First_Nm>Michael</First_Nm>
<Middle_Nm/>
<Last_Nm>Keaton</Last_Nm>
<DOB>1975-10-21T00:00:00+05:30</DOB>
<Address_1>33 Park Street</Address_1>
<Address_2/>
<Address_3/>
<City>Jacksonville</City>
<State>FL</State>
<Postal_Code>32220</Postal_Code>
<Home_Phone_No>(111) 222-4444</Home_Phone_No>
<Work_Phone_No>(913) 244-8188</Work_Phone_No>
<Cell_Phone_No/>
<Email_Addr>mkeaton#designllc.com</Email_Addr>
<Login_Attempts_Cnt>0</Login_Attempts_Cnt>
<Login_Locked_Ind>0</Login_Locked_Ind>
<Allow_Internet_Use>1</Allow_Internet_Use>
<Active_Ind1>1</Active_Ind1>
<Hired_Dt>2010-05-01T00:00:00+05:30</Hired_Dt>
<Designation>Associate</Designation>
<Work_Location>Canton</Work_Location>
<SubGroup_ID>0001</SubGroup_ID>
<Created_On1>2011-12-20T00:44:04.577+05:30</Created_On1>
<Created_By1>msmith</Created_By1>
<Modified_On1>2012-02-10T17:50:10.343+05:30</Modified_On1>
<Modified_By1>mkeaton</Modified_By1>
<SSN>123456789</SSN>
<Class>A004</Class>
<Status1>A</Status1>
<EULA>1</EULA>
<Gender>M</Gender>
<ReAssignedToCobra>false</ReAssignedToCobra>
<ClassDesc>A004 - Management</ClassDesc>
</EnrollmentList>
</NewDataSet>
</Response>
I have tried this code in Java it works fine,but the same concept does not retreive the value in android.
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class XML {
private NodeList nodelist;
private static Element ele;
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException, XPathExpressionException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder;
Document doc = null;
builder = factory.newDocumentBuilder();
doc = builder.parse("/home/stella/person.xml");
ele = doc.getDocumentElement();
XPathFactory factor = XPathFactory.newInstance();
XPath xpath = factor.newXPath();
XPathExpression expr = xpath.compile("//Package");
Object result = expr.evaluate(doc, XPathConstants.NODESET);
NodeList nodes = (NodeList) result;
for (int i = 0; i < nodes.getLength(); i++)
{
Node currentItem = nodes.item(i);
String key = currentItem.getAttributes().getNamedItem("StructureTransID").getNodeValue();
String value = currentItem.getTextContent();
System.out.printf("%1s = %2s\n", key, value);
}
}
}
I copied your XML file to Notepad and tried to save it but it reported that "This file contains characters in Unicode format which will be lost if you save this file as an ANSI encoded text file.". I let it proceed and then copied your program to a new Android project and it works! i.e. it does load your XML file and extract the "254" value.
I then went back to the XML file and attempted to identify the weird characters and it led me to the 3 characters that look like minus signs, located at:
<Response>
−
<NewDataSet>
−
...
−
<Transaction_Xml>
...
This got me to think that these characters aren't minus signs, but, perhaps some weird encoding which is preventing it from working with the XML parser on Android. These characters, if correct, may need to be edited or migrated to an encoding that works with Android, perhaps UTF-8?
Anyhow, I think this should give enough pointers on where to look.
I am using the following code by the Android-people-XMLParsing example for parsing XML file and it is working perfectly fine..
but it retrieve the data in TextView i want to put this data in a ListView..
I tried by creating CustomAdapter and by changing the Activity into the ListActivity..but nothing works..i can see only a blank screen..Can anyone help me to do this...
Thanks!!
package com.androidpeople.xml.parsing;
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.graphics.Color;
import android.os.Bundle;
import android.widget.LinearLayout;
import android.widget.TextView;
public class XMLParsingExample extends Activity {
/** Create Object For markerList Class */
mymarkers markerList =null;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
/** Create a new layout to display the view */
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(1);
/** Create a new textview array to display the results */
TextView name[];
TextView address[];
TextView city[];
try {
/** Handling XML */
SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
/** Send URL to parse XML Tags */
URL sourceUrl = new URL("xxxxxxxxx");
/** Create handler to handle XML Tags ( extends DefaultHandler ) */
MyXMLHandler myXMLHandler = new MyXMLHandler();
xr.setContentHandler(myXMLHandler);
xr.parse(new InputSource(sourceUrl.openStream()));
} catch (Exception e) {
System.out.println("XML Pasing Excpetion = " + e);
}
/** Get result from MyXMLHandler SitlesList Object */
markerList = MyXMLHandler.markerList;
/** Assign textview array lenght by arraylist size */
name = new TextView[markerList.getName().size()];
address = new TextView[markerList.getaddress().size()];
city = new TextView[markerList.getCity().size()];
/** Set the result text in textview and add it to layout */
for (int i = 0; i < markerList.getName().size(); i++) {
name[i] = new TextView(this);
name[i].setText("Name = "+markerList.getName().get(i));
address[i] = new TextView(this);
address[i].setText("address = "+markerList.getaddress().get(i));
city[i] = new TextView(this);
city[i].setText("city = "+markerList.getCity().get(i));
System.out.println("count33..."+markerList.getCity().size());
city[i].setBackgroundColor(Color.WHITE);
layout.addView(name[i]);
layout.addView(address[i]);
layout.addView(city[i]);
//layout.addView(border[i]);
}
/** Set the layout view to display */
setContentView(layout);
}
}
I've answered a very similar question few days back that you might want to check. You could check the question Android: Sax parsing to a listview and check the accepted answer. Follow the instruction until getView() part and you should be ok.
In summary here is what you need to do:
Use DOM instead of SAX, it's simpler and perfect for ListView
Implement an Adapter that extends BaseAdapter passing the root element to this adapter
Implement getView in the adapter to add the TextView that you want
Again I've laid out the steps in the Android: Sax parsing to a listview. Let me know if you have any further questions
I am parsing a xml from an url.The url is has mobile IMEI no and searchstring based on my application. i put my xml parsing code in android project it does not work. but if i run as separate java program it is working. please help me.
Log.e("rsport-", "function1");
try{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setIgnoringComments(true);
factory.setCoalescing(true); // Convert CDATA to Text nodes
factory.setNamespaceAware(false); // No namespaces: this is default
factory.setValidating(false); // Don't validate DTD: also default
DocumentBuilder parser = factory.newDocumentBuilder();
Log.e("rsport-", "function2");
Document document = parser.parse("http://demo.greatinnovus.com/restingspot/search?userid=xxxxxxxxxxxxxxxx&firstname=a&lastname=a");
Log.e("rsport-","function3");
NodeList sections = document.getElementsByTagName("Searchdata");
int numSections = sections.getLength();
for (int i = 0; i < numSections; i++)
{
Element section = (Element) sections.item(i);
if(section.hasChildNodes()==true){
NodeList section1=section.getChildNodes();
for(int j=0;j<section1.getLength();j++){
if(section1.item(j).hasChildNodes()==true) {
for(int k=0;k<section1.item(j).getChildNodes().getLength();k++)
xmlvalue=String.valueOf(section1.item(j).getChildNodes().item(k).getNodeValue()).trim();
arl.add(xmlvalue);
}
}
}
}
}
}
catch(Exception e){}
System.out.println("id"+id+" searchdatacount"+searchdatacount);
System.out.println("---------");
ListIterator<String> litr = arl.listIterator();
while (litr.hasNext()) {
String element = litr.next();
Log.e("rsport-", "elememt");
}
after the Log.e("rsport-", "function2"); does not work.
Refer my blog, i had gave Detailed explanation, http://sankarganesh-info-exchange.blogspot.com/2011/04/parsing-data-from-internet-and-creating.html, and make sure , that you had add the Internet permission in your Manifest file.
If you had gone through Myblog, then you will able to notice that you did the following line as wrong
Document document = parser.parse("http://demo.greatinnovus.com/restingspot/search?userid=xxxxxxxxxxxxxxxx&firstname=a&lastname=a");
use like this
URL url =new URL("http://demo.greatinnovus.com/restingspot/search?userid=xxxxxxxxxxxxxxxx&firstname=a&lastname=a");
Document document= parser.parse(new InputSource(url.openStream()));
im new to android development and im trying to build my first app which looks for a online generated xml file to display information. In the first activity i created a ListView with all the entries from an XML file, as soon as i click on an entry it passes the id and goes to the 2nd activity which should access another XML file with the details. However i keep getting this error when trying to fetch the XML for the details:
java.lang.ClassCastException:
org.apache.harmony.xml.dom.ElementImpl
Any ideas whats wrong? Here is the source for the "details" activity:
package en.android.itleaked.com;
import java.io.InputStream;
import java.net.URL;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.sax.Element;
import android.widget.ImageView;
import android.widget.TextView;
public class showReleases extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.releasedetails);
getFeed();
}
public void getFeed() {
Bundle extras = getIntent().getExtras();
try {
URL url2 = new URL("http://www.it-leaked.com/app/details.php?id=" + extras.getString("id"));
DocumentBuilderFactory dbf2 = DocumentBuilderFactory.newInstance();
DocumentBuilder db2 = dbf2.newDocumentBuilder();
Document doc2 = db2.parse(new InputSource(url2.openStream()));
doc2.getDocumentElement().normalize();
NodeList nodeList2 = doc2.getElementsByTagName("item");
String relTitle[] = new String[nodeList2.getLength()];
String relCover[] = new String[nodeList2.getLength()];
for (int i = 0; i < nodeList2.getLength(); i++) {
Node node2 = nodeList2.item(i);
Element fstElmnt2 = (Element) node2;
NodeList nameList2 = ((Document) fstElmnt2).getElementsByTagName("title");
Element nameElement2 = (Element) nameList2.item(0);
nameList2 = ((Node) nameElement2).getChildNodes();
relTitle[i] = ((Node) nameList2.item(0)).getNodeValue();
NodeList coverList2 = ((Document) fstElmnt2).getElementsByTagName("cover");
Element coverElement2 = (Element) coverList2.item(0);
coverList2 = ((Node) coverElement2).getChildNodes();
relCover[i] = ((Node) coverList2.item(0)).getNodeValue();
}
TextView txtView = (TextView)findViewById(R.id.TextView01);
txtView.setText(relTitle[0]);
ImageView imgView =(ImageView)findViewById(R.id.ImageView01);
Drawable drawable = LoadImageFromWebOperations(relCover[0]);
imgView.setImageDrawable(drawable);
}
catch (Exception e) {
TextView txtView2 = (TextView)findViewById(R.id.TextView02);
txtView2.setText("Error: " + e);
}
}
private Drawable LoadImageFromWebOperations(String url)
{
try
{
InputStream is = (InputStream) new URL(url).getContent();
Drawable d = Drawable.createFromStream(is, "src name");
return d;
}catch (Exception e) {
System.out.println("Exc="+e);
return null;
}
}
}
Here is the URL for the XML with an attached id so you can see what it looks like:
http://www.it-leaked.com/app/details.php?id=50969
Any ideas whats going on? By the way i added the number 2 to every variable which has something to do with the XML parsing / fetching just to make sure theres no conflict with the other activity, but im still getting the same error..
I hope you can help me out.
Thanks in advance
This question is a little old but I believe the ClassCastException is due to attempting to cast the elements in the nodelist to android.sax.Element type rather than org.w3c.dom.Element; check the imports.
Looking at your exception (which is java.lang.ClassCastException) the problem is in casting some class to another.
In your code i didn't understand the reason casting Element to Document - Element has getElementsByTagName method which you are using. Look here: http://developer.android.com/reference/org/w3c/dom/Element.html
It is the root of all evil. Element and Document both implementing Node interface, but Document isn't implements Element - that's why Element can't be cast to Document.
Anyway, expcetion line number can determine the exact error position.