When trying to use XMLPullParser the XmlPullParser.END_DOCUMENT event is never called thus code that is suppose to be executed after while loop is never executed. How can I prevent this from happening?
Code Snippet:
int eventType = xpp.getEventType();
if(eventType == XmlPullParser.END_DOCUMENT) {
Log.i("app", "End");
return farmers.getFarmers();
}
while (eventType != XmlPullParser.END_DOCUMENT) {
if(eventType == XmlPullParser.START_DOCUMENT) {
} else if(eventType == XmlPullParser.START_TAG) {
// Do something
} else if(eventType == XmlPullParser.END_TAG) {
// Do something
} else if(eventType == XmlPullParser.TEXT) {
// Do something
}
eventType = xpp.next();
}
if(eventType == XmlPullParser.END_DOCUMENT) {
Log.i("app", "End");
return farmers.getFarmers();
}
return "Some data";
Why is return never called?
Well, you are enclosing the check for XmlPullParser.END_DOCUMENT in a loop that only runs if eventType is not XmlPullParser.END_DOCUMENT, so it will never run that statement.
You need to have
if(eventType == XmlPullParser.END_DOCUMENT) {} outside the loop.
Edit: I saw your edit. Huh, still not detecting the end of the document?.
Try restructuring the loop to use while(true), and put
else if(eventType == XmlPullParser.END_DOCUMENT) {
//Do stuff here
break;
}
inside the loop.
That way, it gets through the whole list, and only leaves the loop when it hits END_DOCUMENT. If loops indefinitely, then I am out of ideas :P.
Related
I make a small test-program for my child. I want to learn his math.
Faced with the problem of reading the question from the XML file
<?xml version="1.0" encoding="utf-8"?>
<questions>
<question>
<vopros>How much will 2+2?</vopros>
<otvet_1>2</otvet_1>
<otvet_2>6</otvet_2>
<otvet_3>8</otvet_3>
<otvet_4 name="pravilno">4</otvet_4>
</question>
<question>
<vopros>How much will 3+3?</vopros>
<otvet_1>12</otvet_1>
<otvet_2>16</otvet_2>
<otvet_3>18</otvet_3>
<otvet_4 name="pravilno">6</otvet_4>
</question>
<question>
<vopros>How much is 4+4?</vopros>
<otvet_1>22</otvet_1>
<otvet_2>26</otvet_2>
<otvet_3>18</otvet_3>
<otvet_4 name="pravilno">8</otvet_4>
</question>
<question>
<vopros>How much is 5+5?</vopros>
<otvet_1>2</otvet_1>
<otvet_2>6</otvet_2>
<otvet_3>8</otvet_3>
<otvet_4 name="pravilno">10</otvet_4>
</question>
</questions>
I need to activate vopros3 and answer options (otvet_1, otvet_2,otvet_3,otvet_4)
Java code that retrieves data from an XML file
try {
XmlPullParser parser = getResources().getXml(R.xml.voprosi);
while (parser.getEventType() != XmlPullParser.END_DOCUMENT) {
if (parser.getEventType() == XmlPullParser.START_TAG
&& parser.getName().equals("question")) {
if(numvopr==3)
{
// ....... here it is necessary to withdraw a question and answers
Question.setText(...);
answ1.setText(...);
answ2.setText(...);
answ3.setText(...);
answ4.setText(...);
}
numvopr++;
}
parser.next();
}
} catch (Throwable t) {
Toast.makeText(this,
"XML Error: " + t.toString(),
Toast.LENGTH_LONG).show();
}
One way to implement as a state machine:
String lastStartTag = "";
// change to desired question - 0-based
int targetQuestion = 3;
while (parser.getEventType() != XmlPullParser.END_DOCUMENT) {
// Count questions and record every START tag
if (parser.getEventType() == XmlPullParser.START_TAG) {
lastStartTag = parser.getName();
if (parser.getName().equals("question")) {
numvopr++;
}
}
// Process text based on whether we are at desired question
// and last processed START tag.
else if (parser.getEventType() == XmlPullParser.TEXT) {
if (numvopr == targetQuestion) {
if (lastStartTag.compareTo("vopros") == 0) {
Question.setText(parser.getText());
}
else if (lastStartTag.compareTo("otvet_1") == 0) {
answ1.setText(parser.getText());
}
else if (lastStartTag.compareTo("otvet_2") == 0) {
answ2.setText(parser.getText());
}
else if (lastStartTag.compareTo("otvet_3") == 0) {
answ3.setText(parser.getText());
}
else if (lastStartTag.compareTo("otvet_4") == 0) {
answ4.setText(parser.getText());
}
}
}
parser.next();
}
A slightly different implementation with switch statement.
int numOfQuestions = 0;
String text = null;
try {
XmlPullParser parser = getResources().getXml(R.xml.test);
while (parser.getEventType() != XmlPullParser.END_DOCUMENT) {
String elementName = parser.getName();
switch (parser.getEventType()) {
case XmlPullParser.START_TAG:
if ("question".equals(elementName)) {
numOfQuestions++;
}
break;
case XmlPullParser.TEXT:
text = parser.getText();
break;
case XmlPullParser.END_TAG:
if (numOfQuestions == 3) {
switch (elementName) {
case "vopros":
Log.i(TAG, "Question: " + text);
break;
case "otvet_1":
Log.i(TAG, "answ1: " + text);
break;
case "otvet_2":
Log.i(TAG, "answ2: " + text);
break;
case "otvet_3":
Log.i(TAG, "answ3: " + text);
break;
case "otvet_4":
Log.i(TAG, "answ4: " + text);
break;
default:
break;
}
}
break;
default:
break;
}
parser.next();
}
} catch (Throwable t) {
Log.e(TAG, "Problem while parsing the xml.", t);
}
I posted something else about this a while ago. Basically, I was trying to establish a Bluetooth connection between an Android phone and an Arduino. This was to get a remote control car working wirelessly.
I decided to get an HC-06 Bluetooth module instead of the HC-08 I had. This seemed to work for part of it. I can send a string from an Android phone to an Arduino but nothing happens. When testing this I have my Arduino hooked up to my computer and have the serial monitor displayed. When I send the string, the Arduino receives this string then activates a certain piece of code. The forward code works and has a serial print line in it, and when the certain string is sent the word forward is printed on the serial monitor. So I know it's being received but it's just not activating the other part of the function for some reason.
Can anybody help?
I'm pretty sure it's the Arduino code so here it is:
if (Serial.available() > 0) {
string = "";
}
while (Serial.available() > 0) {
command = ((byte)Serial.read());
if (command == ':') {
break;
} else {
string += command;
}
delay(1);
}
if (string == "F") {
forward();
}
if (string == "B") {
back();
}
if (string == "R") {
right();
}
if (string == "L") {
left();
}
if (string == "S") {
stop();
}
}
void forward() {
digitalWrite(ENA, HIGH);
digitalWrite(ENB, HIGH);
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
Serial.println("Forward");
}
Let's try this, just remove
if (Serial.available() > 0) {
string = "";
}
And add string = ""; after each cases.
Result : Hope that will help you
while (Serial.available() > 0) {
command = ((byte)Serial.read());
if (command == ':') {
break;
} else {
string += command;
}
delay(1);
}
if (string == "F") {
forward();
string = "";
}
if (string == "B") {
back();
string = "";
}
if (string == "R") {
right();
string = "";
}
if (string == "L") {
left();
string = "";
}
if (string == "S") {
stop();
string = "";
}
}
I'm trying to check an EditText value, but the application crashes.
How can I handle my EditText?
String stra_txt = edit_1.getText().toString();
boolean first = false;
if (stra_txt.equals("1") || stra_txt.equals("0"))
{
first = true;
}
else
{
first = false;
}
if(first = true)
zheg();
else
{System.exit(0);}
this code does not work too:
String stra_txt = edit_1.getText().toString();
if (stra_txt.equals("1") || stra_txt.equals("0"))
{
zheg();
}
else
{
System.exit(0);
}
upd.
I've found solution:
if (edit_1.getText().toString().equals("")){
finish();
}
else
{
zheg();
}
Use try Catch Block its get actual error or app crash
try
{
String stra_txt = edit_1.getText().toString();
boolean first = false;
boolean second = false;
if (stra_txt.equals("1") || stra_txt.equals("0"))
{
first = true;
}
else
{
first = false;
}
if(first = true)
zheg();
else
{System.exit(0);}
}
catch (Exception e)
{
e.printStackTrace();
}
Check whether you have linked your EditText id with XML
EditText edit_1 = (EditText) findViewById(R.id.edit_1);
if you have given this, then there must be a problem with zheg() method.
Please post your logs here.
Try this code
if(edit_1 != null){
String stra_txt = edit_1.getText().toString();
if ((stra_txt.equals("1") || stra_txt.equals("0")){
zheg();
}else{
// System.exit(0);
finish();
}
}
if this prevents your app from getting crashed then probably you may not be initializing the view. Add this line before the above code:
edit_1 = (EditText)findViewById(YOUR_VIEW_ID);
I am parsing xml packet using XmlPullParser. I am able to parse base64encode tag. My issue here is "I am not able to read full base64encode data. Only part of it is able to read".
boolean done = false;
while (!done) {
int eventType = parser.next();
if (eventType == XmlPullParser.START_TAG) {
String elementName = parser.getName();
String namespace = parser.getNamespace();
if(elementName.equals("vCard") && namespace.equals("vcard-temp"))
{
}
// Otherwise, see if there is a registered provider for
// this element name and namespace.
else {
Object provider = ProviderManager.getInstance().getIQProvider(elementName, namespace);
if (provider != null) {
if (provider instanceof IQProvider) {
iqPacket = ((IQProvider)provider).parseIQ(parser);
}
else if (provider instanceof Class) {
iqPacket = (IQ)PacketParserUtils.parseWithIntrospection(elementName,
(Class)provider, parser);
}
}
}
}
else if (eventType == XmlPullParser.END_TAG) {
if (parser.getName().equals("iq")) {
done = true;
}
}else if(eventType == XmlPullParser.TEXT){
String xx = parser.getText();
System.out.println("binaval "+ xx);
}
}
very long string as a response of web service
see this answer here sometimes for the very long string it doesn't work mine was the same case when I posted this question.
I have two activity class of android. The main activity class contains xml parsing and i am trying to pass the data obtain from there to another activity class which is going to put it into listview of all the data. Below the is xml parsing main activity the problem is that, when I run the program it show nullpointer exception . I m stuck here can anyone help me where is the error . Thnx in advance
enter code here
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// setContentView(R.layout.main);
try {
stringXmlContent = getEventsFromAnXML(this);
Intent i=new Intent(LocationSidActivity.this,FacebookData.class);
i.putStringArrayListExtra("language", stringXmlContent);
startActivity(i);
// myXmlContent.setText(stringXmlContent);
} catch (XmlPullParserException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private ArrayList<String> getEventsFromAnXML(Activity activity)
throws XmlPullParserException, IOException {
ArrayList<String> al = new ArrayList<String>();
Resources res = activity.getResources();
XmlResourceParser xpp = res.getXml(R.xml.myxml);
xpp.next();
int eventType = xpp.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_DOCUMENT) {
al.add(xpp.getName());
} else if (eventType == XmlPullParser.START_TAG) {
//if ((xpp.getName()).compareTo("id") != 0) {
al.add(xpp.getName());
//} else {
//eventType = xpp.next();
}
else if (eventType == XmlPullParser.TEXT) {
al.add(xpp.getText());
}
eventType = xpp.next();
}
return al;
}
}
The lines in your parser method getEventsFromAnXML:
if (eventType == XmlPullParser.START_DOCUMENT)
{
al.add(xpp.getName());
}
may end up in a NullPointerException, because there is nothing read yet, and a null value will be added as the first member of your ArrayList.
The XmlPullParser.START_DOCUMENT in API Docs:
Signalize that parser is at the very beginning of the document and
nothing was read yet. This event type can only be observed by calling
getEvent() before the first call to next(), nextToken, or nextTag()).
Also, if the getEventsFromAnXML method is in your Activity class, you should remove the parameter, and simply use this. It is never a good practice to share a Context, it will most often end up in leaks.