I'm making an application in which I want to read an XML from a URL. The original URL I have to read from is: http://geowebservice.azurewebsites.net/Api/Geo
I've had a lot of difficulties with finding a good example of how to read XML files from a URL in android... After a couple of hours I've found a tutorial of which I succeeded to create a working version: http://www.androidhive.info/2011/11/android-xml-parsing-tutorial/!
The only problem I still encounter is that when I change the URL in my code, I'm unable to get the XML... It's very strange. The app does not crash, it just doesn't get the XML. In my code example below, I change the url from: http://api.androidhive.info/pizza/?format=xml (working) to http://nbalarm.mounirelfassi.com/sitemapindo.xml?format=xml (not working)! Both actually look the same and I have no idea why I'm unable to get the XML with the second file/ url. This problem also occured when I tried to edit the working version to a version that wanted to receive the values of my own api.
MY CODE: MAINACTIVITY
import android.app.ListActivity;
import android.content.Intent;
import android.os.AsyncTask;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import java.util.ArrayList;
import java.util.HashMap;
public class AndroidXMLParsingActivity extends ListActivity {
// All static variables
static final String URL = "http://api.androidhive.info/pizza/?format=xml";
// XML node keys
static final String KEY_ITEM = "item"; // parent node
static final String KEY_ID = "id";
static final String KEY_NAME = "name";
static final String KEY_COST = "cost";
static final String KEY_DESC = "description";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_android_xmlparsing);
new loadmore().execute();
/*// Selecting single ListView item
ListView lv = (ListView) findViewById(R.id.list);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView parent, View view,int position, long id) {
// Getting values from selected ListItem
String name = ((TextView) view.findViewById(R.id.name)).getText().toString();
String cost = ((TextView) view.findViewById(R.id.cost)).getText().toString();
String description = ((TextView) view.findViewById(R.id.description)).getText().toString();
// Starting new intent
Intent in = new Intent(getApplicationContext(), SingleMenuItemActivity.class);
in.putExtra(KEY_NAME, name);
in.putExtra(KEY_COST, cost);
in.putExtra(KEY_DESC, description);
startActivity(in);
}
});*/
}
public class loadmore extends AsyncTask<String, Integer, ArrayList<HashMap<String, String>>> {
ArrayList<HashMap<String, String>> menuItems = new ArrayList<HashMap<String, String>>();
@Override
protected ArrayList<HashMap<String, String>> doInBackground(
String... params) {
XMLParser parser = new XMLParser();
String xml = parser.getXmlFromUrl(URL); // getting XML
Document doc = parser.getDomElement(xml); // getting DOM element
NodeList nl = doc.getElementsByTagName(KEY_ITEM);
// Looping through all item nodes <item>
for (int i = 0; i < nl.getLength(); i++) {
// Creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
Element e = (Element) nl.item(i);
// Adding each child node to HashMap key => value
map.put(KEY_ID, parser.getValue(e, KEY_ID));
map.put(KEY_NAME, parser.getValue(e, KEY_NAME));
map.put(KEY_COST, "Rs." + parser.getValue(e, KEY_COST));
map.put(KEY_DESC, parser.getValue(e, KEY_DESC));
// Adding HashList to ArrayList
menuItems.add(map);
}
return null;
}
@Override
protected void onPostExecute(ArrayList<HashMap<String, String>> result) {
// Adding menuItems to ListView
ListAdapter adapter = new SimpleAdapter(AndroidXMLParsingActivity.this, menuItems,
R.layout.list_item,
new String[] { KEY_NAME, KEY_DESC, KEY_COST }, new int[] {
R.id.name, R.id.description, R.id.cost });
setListAdapter(adapter);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_android_xmlparsing, 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();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
MY CODE: XMLPARSER CLASS
import android.util.Log;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
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 org.xml.sax.SAXException;
import java.io.IOException;
import java.io.StringReader;
import java.io.UnsupportedEncodingException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
public class XMLParser {
public String getXmlFromUrl(String url) {
String xml = null;
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
xml = EntityUtils.toString(httpEntity);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// return XML
return xml;
}
public Document getDomElement(String xml){
Document doc = null;
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder db = dbf.newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(xml));
doc = db.parse(is);
} catch (ParserConfigurationException e) {
Log.e("Error: ", e.getMessage());
return null;
} catch (SAXException e) {
Log.e("Error: ", e.getMessage());
return null;
} catch (IOException e) {
Log.e("Error: ", e.getMessage());
return null;
}
// return DOM
return doc;
}
public String getValue(Element item, String str) {
NodeList n = item.getElementsByTagName(str);
return this.getElementValue(n.item(0));
}
public final String getElementValue( Node elem ) {
Node child;
if( elem != null){
if (elem.hasChildNodes()){
for( child = elem.getFirstChild(); child != null; child = child.getNextSibling() ){
if( child.getNodeType() == Node.TEXT_NODE ){
return child.getNodeValue();
}
}
}
}
return "";
}
}
My manifest file has asked for Internet Acces, and my layout-files are doing well too.
The main reason I'm trying to get a working XML reader app is because I need to get the values of an XML on an API: http://geowebservice.azurewebsites.net/Api/Geo So if any of You knows how to get those values or can lead me to a place where I can find examples that make me easily get those values, feel free to help me.
I'm an adebt in android. I've tried a lot of things I've seen on the internet so far, and didn't even manage to get a working example. Now I've got one, I'm so disappointed in myself that I even can't make it work with another URL.
0 comments:
Post a Comment