Android Is it possible to define a map in an XML file? - android

I was trying to define a static hash table that makes use of resources, but I got stonewalled by the impossibility of accessing resources statically.
Then I realized that the best of all places to define a static map is in the resources files themselves.
How can I define a map in XML?
I believe that if possible it should be similar to the Listpreference mechanism, with entries and entries-values.

A simpler option would be to use two arrays. This has the benefit of not iterating the XML file again, uses less code, and is more straightforward to use arrays of different types.
<string-array name="myvariablename_keys">
<item>key1</item>
<item>key1</item>
</string-array>
<string-array name="myvariablename_values">
<item>value1</item>
<item>value2</item>
</string-array>
Then your java code would look like this:
String[] keys = this.getResources().getStringArray(R.array.myvariablename_keys);
String[] values = this.getResources().getStringArray(R.array.myvariablename_values);
LinkedHashMap<String,String> map = new LinkedHashMap<String,String>();
for (int i = 0; i < Math.min(keys.length, values.length); ++i) {
map.put(keys[i], values[i]);
}

How can I define a map in XML?
<thisIsMyMap>
<entry key="foo">bar</entry>
<entry key="goo">baz</entry>
<!-- as many more as your heart desires -->
</thisIsMyMap>
Put this in res/xml/, and load it using getResources().getXml(). Walk the events to build up a HashMap<String, String>.

You can always embed Json inside your strings.xml file:
res/values/strings.xml
<string name="my_map">{"F":"FOO","B":"BAR"}</string>
And inside your Activity, you can build your Map in the onStart method:
private HashMap<String, String> myMap;
#Override
protected void onStart() {
super.onStart();
myMap = new Gson().fromJson(getString(R.string.my_map), new TypeToken<HashMap<String, String>>(){}.getType());
}
This code needs Google Gson API to work. You can do it using the built-in Json API in the Android SDK.
And As for accessing the Map statically, you can create a static method:
private static HashMap<String, String> method(Context context) {
HashMap<String, String> myMap = new Gson().fromJson(context.getString(R.string.serve_times), new TypeToken<HashMap<String, String>>(){}.getType());
return myMap;
}

The correct answer was mentioned by CommonsWare above, but as XML-parsing is not so simple, as following a simple parser for this purpose:
public static Map<String, String> getHashMapResource(Context context, int hashMapResId) {
Map<String, String> map = new HashMap<>();
XmlResourceParser parser = context.getResources().getXml(hashMapResId);
String key = null, value = null;
try {
int eventType = parser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_TAG) {
if (parser.getName().equals("entry")) {
key = parser.getAttributeValue(null, "key");
if (null == key) {
parser.close();
return null;
}
}
}
else if (eventType == XmlPullParser.END_TAG) {
if (parser.getName().equals("entry")) {
map.put(key, value);
key = null;
value = null;
}
} else if (eventType == XmlPullParser.TEXT) {
if (null != key) {
value = parser.getText();
}
}
eventType = parser.next();
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
return map;
}

Android often works with DefaultsXmlParser.getDefaultsFromXml() which parse next syntax:
<?xml version="1.0" encoding="utf-8"?>
<defaults>
<entry>
<key>api_url</key>
<value>https://</value>
</entry>
<entry>
<key>some_feature_flag</key>
<value>true</value>
</entry>
</defaults>
And read map:
val map = DefaultsXmlParser.getDefaultsFromXml(this, R.xml.my_map)

Related

Accessing all response headers using volley api in android application

while making connection using HttpClient in android from HttpResponse able to get all possible "set-cookie" header value (JESSIONID and XSCRF-TOKEN).Check below screenshot.
Now working with android studio with volley api for connection , i am getting only single value of "set-cookie" header (JESSIONID only).See below :
I have also check https://groups.google.com/forum/#!topic/volley-users/rNTlV-LORzY.
For which have to make change in volley api jar project. But don't know how to edit volley api. If any other solution present kindly guide.
Kindly help to retrieve multiple value of "set-cookie" using volley api.
Problem:
The problem is inside the Volley unfortunately. I had this problem and after many searches i figured out that there is a method called convertHeaders in BasicNetwork class that handles headers like this:
protected static Map<String, String> convertHeaders(Header[] headers) {
Map<String, String> result = new TreeMap<String, String>(String.CASE_INSENSITIVE_ORDER);
for (int i = 0; i < headers.length; i++) {
result.put(headers[i].getName(), headers[i].getValue());
}
return result;
}
You see the result is Map<String, String> which can't contain same keys with different values. so you always have only last cookie.
The standard of cookie setting tells us we should separate cookies with ; for example if you want to contain 2 key-value in a request cookie you should put them like this:
Cookies: k1=v1;k2=v2
Solution:
In your case you have two options.
1 - change your code in Server-Side so that the response contains only 1 Set-Cookie separated key-values by ;. example of your response:
Set-Cookie: JESSIONID=qZtQ...;Path=/;HttpOnly;XSRF-TOKEN=6c65...
2 - get Volley source code and change that buggy method and make a fixed .jar again! this option is my favorite cause you didn't touch the response of server
My implementation of this method is:
protected static Map<String, String> convertHeaders(Header[] headers) {
TreeMap result = new TreeMap(String.CASE_INSENSITIVE_ORDER);
for(int i = 0; i < headers.length; ++i) {
String headerName = headers[i].getName();
if(!result.containsKey(headerName)) {
result.put(headers[i].getName(), headers[i].getValue());
} else {
String value = (String)result.get(headerName);
String mergedValue = value + ";" + headers[i].getValue();
result.remove(headerName);
result.put(headerName, mergedValue);
}
}
return result;
}
There is workaround for this in:
implementation "com.android.volley:volley:1.1.0"
"NetworkResponse (and Cache.Entry) now includes an "allHeaders" field which is the raw list of all headers returned by the server and thus can include duplicates by name."
Source: https://github.com/google/volley/issues/21
Example:
private static final String COOKIE_KEY = "Set-Cookie";
private static final String COOKIE_NAME = "NameOfOneOfTheCookies";
#Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
handleCookies(response);
String parsed;
try {
parsed = new String(response.data, "utf-8");
} catch (UnsupportedEncodingException e) {
parsed = new String(response.data);
}
return Response.success(parsed,
HttpHeaderParser.parseCacheHeaders(response));
}
private void handleCookies(NetworkResponse response) {
for (Header header : response.allHeaders) {
if (header.getName().equals(COOKIE_KEY) && header.getValue().startsWith(COOKIE_NAME)) {
getCookies(response);
}
}
}
private void getCookies(NetworkResponse response) {
ArrayList<String> cookiesList = new ArrayList<>();
for (Header header : response.allHeaders) {
if (header.getName().equals(COOKIE_KEY)) {
cookiesList.add(header.getValue());
}
}
// TODO Do something with the cookiesList
}

Android Volley, duplicate Set-Cookie is overridden

Trying to use Volley lib as a network wrapper for my android application. I have a connection up and running, but the problem is that every time there is multiple "Set-Cookie" headers in the response Volley uses Map that cannot have duplicate keys, and will only store the last Set-cookie header and overwrite the rest.
Is there a workaround for this issue?
Is there another lib to use?
I tried overiding classes to fix this but when I had to edit NetworkResponse, I was descending too far down the rabbithole. So I decided to just edit Volley directly to grab all response headers in an array and not a Map.
My fork is on GitHub and I included an example usage activity.
I made changes to NetworkResponse.java, BasicNetwork.java and HurlStack.java as detailed in this commit.
Then to use in your actual apps you do something like this
protected Response<String> parseNetworkResponse(NetworkResponse response) {
// we must override this to get headers. and with the fix, we should get all headers including duplicate names
// in an array of apache headers called apacheHeaders. everything else about volley is the same
for (int i = 0; i < response.apacheHeaders.length; i++) {
String key = response.apacheHeaders[i].getName();
String value = response.apacheHeaders[i].getValue();
Log.d("VOLLEY_HEADERFIX",key + " - " +value);
}
return super.parseNetworkResponse(response);
}
It's a dirty little hack but seems to work well for me at the moment.
The first thing you need is to modify BasicNetwork.convertHeaders method to make it support multiple map values. Here is example of modified method:
protected static Map<String, List<String>> convertHeaders(Header[] headers) {
Map<String, List<String>> result = new TreeMap<String, List<String>>(String.CASE_INSENSITIVE_ORDER);
for (int i = 0; i < headers.length; i++) {
Header header = headers[i];
List<String> list = result.get(header.getName());
if (list == null) {
list = new ArrayList<String>(1);
list.add(header.getValue());
result.put(header.getName(), list);
}
else list.add(header.getValue());
}
return result;
}
Next thing you need is to modify DiskBasedCache.writeStringStringMap and DiskBasedCache.readStringStringMap methods. They should support multiple values. Here are modified methods along with helper methods:
static void writeStringStringMap(Map<String, List<String>> map, OutputStream os) throws IOException {
if (map != null) {
writeInt(os, map.size());
for (Map.Entry<String, List<String>> entry : map.entrySet()) {
writeString(os, entry.getKey());
writeString(os, joinStringsList(entry.getValue()));
}
} else {
writeInt(os, 0);
}
}
static Map<String, List<String>> readStringStringMap(InputStream is) throws IOException {
int size = readInt(is);
Map<String, List<String>> result = (size == 0)
? Collections.<String, List<String>>emptyMap()
: new HashMap<String, List<String>>(size);
for (int i = 0; i < size; i++) {
String key = readString(is).intern();
String value = readString(is).intern();
result.put(key, parseNullStringsList(value));
}
return result;
}
static List<String> parseNullStringsList(String str) {
String[] strs = str.split("\0");
return Arrays.asList(strs);
}
static String joinStringsList(List<String> list) {
StringBuilder ret = new StringBuilder();
boolean first = true;
for (String str : list) {
if (first) first = false;
else ret.append("\0");
ret.append(str);
}
return ret.toString();
}
And last thing is HttpHeaderParser class. You should make its parseCacheHeaders method support multiple values. Use the following helper method for this:
public static String getHeaderValue(List<String> list) {
if ((list == null) || list.isEmpty()) return null;
return list.get(0);
}
And the latest thing to modify is a bunch of places to replace
Map<String, String>
to
Map<String, List<String>>
Use your IDE to do this.
Question pretty old, but if helps someone. In newest volley you have:
protected Response<String> parseNetworkResponse(NetworkResponse response)
{
List<Header> headers = response.allHeaders;
String sessionId = null;
for (Header header : headers)
{
// header.getName();
// header.getValue();
}
return super.parseNetworkResponse(response);
}
You can override Network class of volley. Looking at performRequest and convertHeaders methods of BasicNetwork might help. Then, passing your Network implementation to the contructor of RequestQueue like:
new RequestQueue(new NoCache(), new YourOwnNetwork());

XML object storage

I've created an XML pull-parser which pulls details of an xml out:
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
XmlPullParser xpp = factory.newPullParser();
xpp.setInput(new InputStreamReader(response3.getEntity().getContent()));
int eventType = xpp.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
if(eventType == XmlPullParser.START_DOCUMENT) {
System.out.println("Start 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();
}
This searches through the XML correctly pulling out different tags etc.
My problem is now that I wish to store these. The basic structure is that it stores a series of cards, each with an attribute list. The outer tag would be something like <card> and inside there would be many attributes such as <resourceid>, <price> etc.
I wish to store each card in an easy to retrieve manner. I was thinking of using SQlite but have very little experience with it.Is it possible to do this as the parser steps through?
Added my class here
public class SecondActivity {
String resourceid;
String startprice;
String currentbid;
String buynowprice;
String expires;
public String getResourceId(){
return this.resourceid;
}
public String getStartPrice(){
return this.startprice;
}
public String getCurrentBid(){
return this.currentbid;
}
public String getBuyNowPrice(){
return this.buynowprice;
}
public String getExpires(){
return this.expires;
}
public void setResourceId(String resourceidin){
this.resourceid = resourceidin;
}
public void setStartPrice(String startpricein){
this.startprice = startpricein;
}
public void setCurrentBid(String currentbidin){
this.currentbid = currentbidin;
}
public void setBuyNowPrice(String buynowpricein){
this.buynowprice = buynowpricein;
}
public void setExpires(String expiresin){
this.expires = expiresin;
}
}
I now just call each statement i.e. the set inside where the parser finds the tag values, I then call a store, passing it this object? How do I then clear all values inside object?
Thanks for all the help, most appreciated.
Trying to find the start of the card as defined by
added this to my code:
else if(eventType == XmlPullParser.START_TAG) {
if (xpp.getName() == "auctionInfo"){
this.setMyflag(1);
System.out.println("IN THE IF FLAG IS SET TO 1");
}
System.out.println("Start tag "+xpp.getName());
Unfortunately it never enters the if, and I am stumped as to why!
Sure you can. For some input about how to use SQLite in Android, see here.
You could (for example) create a class which holds the informations for one of your <card>-tags (to build something like a data-package for one card) and then perform the Database-Inserts in another method which takes an Object of this class and processes it.
Your <card>-element will have multiple child-elements or attributes. Those are the fields you for your new class. When the parser finds one of those Child-Elements/Attributes, you set the corresponding field in your class.
When the parser finds the next <card>-element, you first call your storeCardInDB()-method (or whatever you call it) and pass it the filled out Object.
The method will take the fields from your Object, bind them to a PreparedStatement (for example) and send it to the Database.
This is done for every <card>-element in your XML-File.
Okay, there is a difference in comparing two ints and two Strings. If you want to know if the content of a String matches the content of another String, you'll need to use the equals()-method:
if ( xpp.getName().equals("auctionInfo") ) {[...]}
Here is a nice article which should clear the background of this behavior.

destroyActivity() Bug in LocalActivityManager class in Android issue

I have a Tab Activity and with in Tab, im using Activity Group. and using LocalActivityManger,
im trying to destroy an Activty using the following function call provided in LocalActivityManger class
manager.destroyActivity(mIdList.get(index), true);
in the code. but later i found that there is a bug in Android impl for this
The exact source of the problem is in the following chunk of code in LocalActivityManager.java:
public Window destroyActivity(String id, boolean finish) {
LocalActivityRecord r = mActivities.get(id);
Window win = null;
if (r != null) {
win = performDestroy(r, finish);
if (finish) {
mActivities.remove(r);
}
}
return win;
}
The variable mActivities is the hashmap containing the activity records and it uses the id passed into startActivity() as the key. In this method, the object passed in for the key is a LocalActivityRecord instead of the id string. This results in the hashmap not finding the entry and thus not removing it.
More info refer this link. http://code.google.com/p/android/issues/detail?id=879More
and i found a work around for this issue and im using following function to fix the problem.
public boolean destroy(String id) {
if(manager != null){
manager.destroyActivity(id, false);
try {
final Field mActivitiesField = LocalActivityManager.class.getDeclaredField("mActivities");
if(mActivitiesField != null){
mActivitiesField.setAccessible(true);
#SuppressWarnings("unchecked")
final Map<String, Object> mActivities = (Map<String, Object>)mActivitiesField.get(manager);
if(mActivities != null){
mActivities.remove(id);
}
final Field mActivityArrayField = LocalActivityManager.class.getDeclaredField("mActivityArray");
if(mActivityArrayField != null){
mActivityArrayField.setAccessible(true);
#SuppressWarnings("unchecked")
final ArrayList<Object> mActivityArray = (ArrayList<Object>)mActivityArrayField.get(manager);
if(mActivityArray != null){
for(Object record : mActivityArray){
final Field idField = record.getClass().getDeclaredField("id");
if(idField != null){
idField.setAccessible(true);
final String _id = (String)idField.get(record);
if(id.equals(_id)){
mActivityArray.remove(record);
break;
}
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
return false;
}
now the problem is, this fix is working fine in Android API versions 2.1,2.2 and 2.3 but i tested in 3.0 . but it is failing there. no exceptions.
I want to know in which API version this bug has been fixed.
And also what fix can i make for this so that it will work fine in all the API versions after 2.1 .
Thank u

Store static data in Android - custom resource?

I'm new to Android development, and I've been playing around with it a bit. I was trying to create a program that has a small database-like collection of never-changing data. In C#, my currently best language, I'd use a List of a custom class and serialize that to an xml file, then read that into my application at runtime. I found the /xml resource folder in Android, but I'm not sure how I would go about doing what I'm envisioning. What would be the best way to go about doing this?
The data will never need to change. Example:
Blob | A | B
----------------
Blob 1 | 23 | 42
Blob 2 | 34 | 21
I know that's laid out like a table, but using a database doesn't really make sense to me because the data will never change, and I would need a way to store it to initially populate the database anyway.
So basically I'm looking for a way to store somewhat-complex static data in my application. Any ideas?
EDIT: I also saw the /raw folder. So I could store things in /res/raw or /res/xml. But I'm not sure what would be the best way to store/parse the data...
I think this is the BEST solution and i am already using this one to store Static-data in my every project.
For that...
You can do one thing, make one xml file namely "temp.xml" ..and store the data in temp.xml as follows:
<?xml version="1.0" encoding="utf-8"?>
<rootelement1>
<subelement> Blob 1
<subsubelement> 23 </subsubelement>
<subsubelement> 42 </subsubelement>
</subelement>
<subelement>Blob 2
<subsubelement> 34 </subsubelement>
<subsubelement> 21 </subsubelement>
</subelement>
</rootelement1>
and then use XML PullParser technique to parse data.
You can have coding samples of PullParsing technique on Example , refer this example for better idea.
Enjoy!!
The best way is to use the Android Resource Heirarchy.
In the res/values/ directory, you can store any number of key-value pairs for several basic data types. In your app, you would refer to them using an autogenerated resource id (name based on your resource's key). See the link above for more documentation and details.
Android also supports raw datafiles. You could store your data in the file directory under res/raw/yourfile.dat
You you create your data in whatever text based format you want and then read it on activity startup using the resource access apis.
I have used Simple for xml parsing in the past. I think it has the least amount of code if you know what to expect in xml, which in your case you do.
http://simple.sourceforge.net/
According to the doc, /xml is the way to go.
Providing Resources
xml/ Arbitrary XML files that can be read at run-time by calling
Resources.getXML().
Various XML configuration files must be saved here, such as a searchable configuration.
Documentation for getXML()
I also made a working example:
the XML structure:
<?xml version="1.0" encoding="utf-8"?>
<quizquestions>
<quizquestion>
<header_image_src>ic_help_black_24dp</header_image_src>
<question>What is the Capital of U.S.A.?</question>
<input_type>Radio</input_type>
<answer correct="false">New York City</answer>
<answer correct="true">Washington D.C.</answer>
<answer correct="false">Chicago</answer>
<answer correct="false">Philadelphia</answer>
</quizquestion>
<quizquestion>
<header_image_src>ic_help_black_24dp</header_image_src>
<question>What is the family name of the famous dutch painter Vincent Willem van .... ?</question>
<input_type>EditText</input_type>
<answer correct="true">Gogh</answer>
</quizquestion>
</quizquestions>
the Java class to hold parsed data:
public class QuizQuestion {
private int headerImageResId;
private String question;
private String inputType;
private ArrayList<String> answers;
private ArrayList<Boolean> answerIsCorrect;
private ArrayList<Integer> correctAnswerIndexes;
/**
* constructor for QuizQuestion object
*/
QuizQuestion() {
headerImageResId = 0;
question = null;
inputType = null;
answers = new ArrayList<>();
answerIsCorrect = new ArrayList<>();
correctAnswerIndexes = new ArrayList<>();
}
public void setHeaderImageResId(int headerImageResId) {
this.headerImageResId = headerImageResId;
}
public int getHeaderImageResId() {
return headerImageResId;
}
void setQuestion(String question) {
this.question = question;
}
public String getQuestion() {
return question;
}
void setInputType(String inputType) {
this.inputType = inputType;
}
public String getInputType() {
return inputType;
}
void addAnswer(String answer, boolean isCorrect)
{
if (isCorrect)
correctAnswerIndexes.add(answers.size());
answers.add(answer);
answerIsCorrect.add(isCorrect);
}
public ArrayList<String> getAnswers() {
return answers;
}
public String getAnswer(int index)
{
// check index to avoid out of bounds exception
if (index < answers.size()) {
return answers.get(index);
}
else
{
return null;
}
}
public int size()
{
return answers.size();
}
}
the parser itself:
/**
* Created by bivanbi on 2017.02.23..
*
* class to parse xml resource containing quiz data into ArrayList of QuizQuestion objects
*
*/
public class QuizXmlParser {
public static String lastErrorMessage = "";
/**
* static method to parse XML data into ArrayList of QuizQuestion objects
* #param activity is the calling activity
* #param xmlResourceId is the resource id of XML resource to be parsed
* #return null if parse error is occurred or ArrayList of objects if successful
* #throws XmlPullParserException
* #throws IOException
*/
public static ArrayList<QuizQuestion> parse(Activity activity, int xmlResourceId)
throws XmlPullParserException, IOException
{
String logTag = QuizXmlParser.class.getSimpleName();
Resources res = activity.getResources();
XmlResourceParser quizDataXmlParser = res.getXml(R.xml.quiz_data);
ArrayList<String> xmlTagStack = new ArrayList<>();
ArrayList<QuizQuestion> quizQuestions = new ArrayList<>();
QuizQuestion currentQuestion = null;
boolean isCurrentAnswerCorrect = false;
quizDataXmlParser.next();
int eventType = quizDataXmlParser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT)
{
// begin document
if(eventType == XmlPullParser.START_DOCUMENT)
{
Log.d(logTag,"Begin Document");
}
// begin tag
else if(eventType == XmlPullParser.START_TAG)
{
String tagName = quizDataXmlParser.getName();
xmlTagStack.add(tagName);
Log.d(logTag,"Begin Tag "+tagName+", depth: "+xmlTagStack.size());
Log.d(logTag,"Tag "+tagName+" has "+quizDataXmlParser.getAttributeCount()+" attribute(s)");
// this is a beginning of a quiz question tag so create a new QuizQuestion object
if (tagName.equals("quizquestion")){
currentQuestion = new QuizQuestion();
}
else if(tagName.equals("answer"))
{
isCurrentAnswerCorrect = quizDataXmlParser.getAttributeBooleanValue(null,"correct",false);
if (isCurrentAnswerCorrect == true) {
Log.d(logTag, "Tag " + tagName + " has attribute correct = true");
}
else
{
Log.d(logTag, "Tag " + tagName + " has attribute correct = false");
}
}
}
// end tag
else if(eventType == XmlPullParser.END_TAG)
{
String tagName = quizDataXmlParser.getName();
if (xmlTagStack.size() < 1)
{
lastErrorMessage = "Error 101: encountered END_TAG "+quizDataXmlParser.getName()+" while TagStack is empty";
Log.e(logTag, lastErrorMessage);
return null;
}
xmlTagStack.remove(xmlTagStack.size()-1);
Log.d(logTag,"End Tag "+quizDataXmlParser.getName()+", depth: "+xmlTagStack.size());
// reached the end of a quizquestion definition, add it to the array
if (tagName.equals("quizquestion")){
if (currentQuestion != null)
quizQuestions.add(currentQuestion);
currentQuestion = null;
}
}
// text between tag begin and end
else if(eventType == XmlPullParser.TEXT)
{
String currentTag = xmlTagStack.get(xmlTagStack.size()-1);
String text = quizDataXmlParser.getText();
Log.d(logTag,"Text: "+text+", current tag: "+currentTag+", depth: "+xmlTagStack.size());
if (currentQuestion == null) {
Log.e(logTag,"currentQuestion is not initialized! text: "+text+", current tag: "+currentTag+", depth: "+xmlTagStack.size());
continue;
}
if (currentTag.equals("header_image_src"))
{
int drawableResourceId = activity.getResources().getIdentifier(text, "drawable", activity.getPackageName());
currentQuestion.setHeaderImageResId(drawableResourceId);
}
else if (currentTag.equals("question"))
{
currentQuestion.setQuestion(text);
}
else if (currentTag.equals("answer"))
{
currentQuestion.addAnswer(text, isCurrentAnswerCorrect);
}
else if (currentTag.equals("input_type"))
{
currentQuestion.setInputType(text);
}
else
{
Log.e(logTag,"Unexpected tag "+currentTag+" with text: "+text+", depth: "+xmlTagStack.size());
}
}
eventType = quizDataXmlParser.next();
}
Log.d(logTag,"End Document");
return quizQuestions;
}
}
and finally, calling the parser:
// read quiz data from xml resource quiz_data
try {
quizQuestions = QuizXmlParser.parse(this,R.xml.quiz_data);
Log.d("Main","QuizQuestions: "+quizQuestions);
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
quizQuestions = null;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
quizQuestions = null;
}
if (quizQuestions == null)
{
Toast.makeText(this,"1001 Failed to parse Quiz XML, sorry", Toast.LENGTH_LONG).show();
finish();
}

Categories

Resources