I want to add the default search app widget to a view inside my app. Just like the homescreen but without any dragging and I only want the workspace to be 4x1 big.
How can I do this? I have looked inside the sources for the launcher but its a lot to understand and remove because I want it as simple as possible...
I know that I can get the Component name of the widget like this:
private ComponentName getSearchWidgetProvider() {
SearchManager searchManager = (SearchManager) mContext.getSystemService(Context.SEARCH_SERVICE);
ComponentName searchComponent = null;
searchManager.getSearchableInfo(searchComponent);
if (searchComponent == null) return null;
return getProviderInPackage(searchComponent.getPackageName());
}
private ComponentName getProviderInPackage(String packageName) {
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(mContext);
List<AppWidgetProviderInfo> providers = appWidgetManager.getInstalledProviders();
if (providers == null) return null;
final int providerCount = providers.size();
for (int i = 0; i < providerCount; i++) {
ComponentName provider = providers.get(i).provider;
if (provider != null && provider.getPackageName().equals(packageName)) {
return provider;
}
}
return null;
}
So how can I add it inside a view (lets say a LinearView) in the easiest way...
Thanks!
Use AppWidgetHost. I actually needed this to store and read the packagename of the widget. See, we both helped out. AppWidgetHost can be implemented to be added to LnearLayout. I woud use RelativeLayout if I was you, since RelativeLayout allows custom areas, per se if you wanted it centered, then you can. Unless you use LinearLayout inside a RelativeLayout.
Here is how it is implemented:
You can edit this and change it to the way you like. The call "appWidgetId", is the int given for each widget. You can store that, then have your app check if the file that is stored exists, read it, convert the text to string, then convert the string to int.
Storing info:
String path="/sdcard/widget.txt";
//You can change the path to whatever you want it to be
File f=new File(path);
try{
FileWriter fw=new FileWriter(f);
fw.write("whatever text");
fw.flush();
fw.close();
}catch(IOException e){
e.printStackTrace();
}
Now to read the file, you must call a StringBuilder, BufferedReader, and String line to get the info.
File f=new File("/sdcard/widget.txt");
//the path must be where you stored the files
StringBuilder sb=new StringBuilder();
try{
BufferedReader br=new BufferedReader(new FileReader(f));
String line;
while((line=br.readLine())!=null){
sb.append(line);
sb.append('\n');
}
br.close();
}catch(IOException e){
e.printStackTrace();
}
Now all you need is get the text into a string:
String widId=sb.toStrng();
And then convert that String to int:
int wid=Integer.parseInt(widId);
Now you impement that ID inside this code:
public void createWidget(Intent data) {
Bundle extras = data.getExtras();
int appWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
AppWidgetProviderInfo appWidgetInfo = mAppWidgetManager.getAppWidgetInfo(appWidgetId);
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(rl.getWidth(), rl.getHeight()/3);
lp.topMargin = numWidgets * (rl.getHeight()/3);
AppWidgetHostView hostView = mAppWidgetHost.createView(getActivity().getApplicationContext(), appWidgetId, appWidgetInfo);
hostView.setAppWidget(widID,appWidgetInfo);
rl.addView(hostView, lp);
hostView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
numWidgets ++;
}
This will add the selected widget to the layout.
Related
please help me I am trying to get text from stack of notifications. I am getting following error.
java.lang.NoSuchFieldException: No field mActions in class
Landroid/app/Notification$BuilderRemoteViews; (declaration of
'android.app.Notification$BuilderRemoteViews' appears in
/system/framework/framework.jar)
I am using NotificationListenerService and
private List<String> getMessages(Notification notification) {
RemoteViews views = notification.bigContentView;
if (views == null) views = notification.contentView;
if (views == null) return null;
List<String> text = new ArrayList<String>();
try {
Field field = views.getClass().getDeclaredField(Constants.ACTIONS);
field.setAccessible(true);
#SuppressWarnings("unchecked")
ArrayList<Parcelable> actions = (ArrayList<Parcelable>) field.get(views);
for (Parcelable p : actions) {
Parcel parcel = Parcel.obtain();
p.writeToParcel(parcel, 0);
parcel.setDataPosition(0);
int tag = parcel.readInt();
if (tag != 2) continue;
parcel.readInt();
String methodName = parcel.readString();
if (methodName == null) {
continue;
} else if (methodName.equals(Constants.SET_TEXT)) {
parcel.readInt();
methodName.getBytes();
String gettingText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(parcel).toString().trim();
text.add(gettingText);
} else if (methodName.equals(Constants.SET_TIME)) {
parcel.readInt();
String gettingText = new SimpleDateFormat("h:mm a").format(new Date(parcel.readLong()));
text.add(gettingText);
}
parcel.recycle();
}
} catch (Exception e) {
Log.e("NotificationClassifier", e.toString());
}
return text;
}
This is working fine in android 4,5 but's its getting crash on Android 7, Getting error like mAction field not available.
Please any one help me to solve this, I am stuck from two days.
Thank you
You are using reflection to access method names and you are not switching the code for multiple platforms. The fields/methods that you are trying to access, change over time on multiple versions of the OS, so if you really want to have the reflection, you have to study what changes they were.
Generally, reflection should really be last resort, since on Android, the base code varies from version to version, and even from manufacturer to manufacturer.
I am new in Android, and I´m making an app and I want to focus on the secure of the app, I found this link, in it says "keep sensitive information in RAM for the minimum time possible by setting it to null after use." and later it says "avoid the use of Java’s String class to hold sensitive information. Instead use char arrays or byte arrays. The reason for this is because Strings are immutable"
In my app I have a code similar to this (this code just checks a PIN the users enters and compares it with another one in the internal storage):
public class Class extends Activity implements OnClickListener{
private static final String fileName = "FilePin";
private Button button;
private EditText editText = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_example);
editText = (editText) findViewById(R.id.editText);
button = (Button) findViewById(R.id.button);
button.setOnClickListener(this);
}
#Override
public void onClick(View v){
if (readPin()) {
textView.setText(new char[]{' '}, 0, 0);
Intent intent = new Intent(this, OtherClass.class);
startActivity(intent);
}
}
// this method read the file where the PIN the user create is save in the internal storage
public boolean readPin(){
StringBuilder stringBuilder = null;
StringBuilder inputString;
try {
BufferedReader inputReader = new BufferedReader(new InputStreamReader
(openFileInput(fileName)));
stringBuilder = new StringBuilder();
while ((inputString = new StringBuilder(inputReader.readLine())) != null) {
stringBuilder.append(inputString);
}
inputReader.close();
} catch (Exception e) {
e.printStackTrace();
}
inputString = new StringBuilder("");
assert stringBuilder != null;
boolean comparePin = compare(stringBuilder);
stringBuilder = new StringBuilder("");
return comparePin;
}
// this method compare the PIN saved with the PIN the users enters
private boolean compare(StringBuilder pinSaved){
if (!editText.getText().toString().equals(pinSaved.toString())) {
Toast.makeText(getBaseContext(), "the PIN it´s incorrect"
, Toast.LENGTH_SHORT).show();
pinSaved = new StringBuilder("");
return false;
}
else {
pinSaved = new StringBuilder("");
return true;
}
}
}
For what I read in the previews link I didn´t use String instead I use StringBuilder because StringBuilder are mutable and after I use it a change the value to "stringBuilder = new StringBuilder("");", I didn´t use char[] because I don´t know how to save the editText to a char[] variable or how to save the PIN saved in the file in a char[] variable and I didn´t find examples about how to use char[] in those cases.
My questions are: this case is secure for an android app or is it better to change to char[] variables?, Is StringBuffer class insecure for Android? How can I save the editText value in a char[]? How Can I save a file in a char[] variable?
stringBuilder = new StringBuilder("");
The above is weaker than zeroing out a char[]. The original StringBuilder, along with is internal buffer, will stay in memory. At some point, the garbage collector will mark the memory as free, and later still, something might overwrite it.
Zeroing out a char[] gives you more control over when the secret is overwritten.
Also, StringBuilder comes with logic that automatically copies its internal char[] buffer when it needs more room. You need to be careful to make sure it never does this. A plain char[] is inconvenient because you can't resize it, but it's good in this case, because any attempt to copy it is explicit.
See Java: convert a char[] to a CharSequence for how to get your char[] into a form that you can pass to EditText.setText.
I have an Android broadcast receiver (using Eclipse if it matters) that is started by a service that is suppose to check if an online data version is updated. If so, I want to trigger a notification in the notification bar.
Everything seems to work OK, however, the results it gets from SharedPreferences are just not reliable. The broadcast receiver is suppose to get the current value stored in the SharedPreferences and compare it to a value it gets from a web url. If it compares the value and sees an update has been made (i.e. the value in at the url is greater than the stored value) it triggers a notification and also updates the value stored in the SharedPreferences. The broadcast receiver checks this update once per day and this only is intended to notify the users, nothing more.
The code I am using to do this seems to work. But here and there, it pulls a default value from the SharedPreferences and triggers an update notification even though nothing has changed.
I realize that I may be trying to do too much in the onReceive of the broadcast receiver, however I am very confused on how to fire an activity to do the work from the broadcastreceiver.
Does anyone have any code examples of the best way to implement this? I have searched and searched but I cannot seem to find clear steps to do this either way. Here is what I have:
public class AlarmReceiver extends BroadcastReceiver {
public static JSONArray myJArray2;
public static InputStream is = null;
public static final String URL_DatabaseVersion = "http://www.mysite.com/mobile/version.php";
public static NotificationManager nm;
public static Boolean updated = false;
public static int latestVersion = 0;
public static int internalVersion = 2;
public static final String PREFS_NAME = "MyPrefsFile";
#Override
public void onReceive(Context context, Intent intent) {
updated = false;
SharedPreferences settings = context.getSharedPreferences(PREFS_NAME, 0);
internalVersion = settings.getInt("dataversion", 1);
InputStream is = null;
String result = "";
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("",""));
try{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(URL_DatabaseVersion);
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
}catch(Exception e){
}
try{
BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null)
{
sb.append(line + "\n");
}
is.close();
result=sb.toString();
}catch(Exception e){
}
try{
JSONArray myJArray = new JSONArray(result);
myJArray2 = myJArray;
}catch(JSONException e){
}
int mode = Activity.MODE_PRIVATE;
SharedPreferences mySharedPreferences = context.getSharedPreferences("MyPrefsFile",mode);
SharedPreferences.Editor editor = mySharedPreferences.edit();
editor.putInt ("dataversion", latestVersion);
editor.commit();
if (!Arrays.asList(myJArray2).contains(null))
{
try{
for(int i=0;i<myJArray2.length();i++)
{
JSONObject json_data = myJArray2.getJSONObject(i);
latestVersion = json_data.getInt("title");
if (internalVersion < latestVersion)
{
updated = true;
}
else
{
updated = false;
}
}
}
catch(Exception e)
{}
finally
{}
}
else
{
updated = false;
}
if (updated)
{
nm = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
CharSequence from = "Database Updated";
CharSequence message = "I: " + internalVersion + " L: " + latestVersion + "Click to open.";
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, new Intent(), 0);
Notification notif = new Notification(R.drawable.icon, "Database Updated", System.currentTimeMillis());
notif.setLatestEventInfo(context, from, message, contentIntent);
nm.notify(1, notif);
}
}
}
Yes, I am probably trying to do way too much in a BroadcastReceiver and that might be causing the issue, however I cannot figure out how to do this any other way. When I log the results of this code, the first time through it works great. Second time through the internalVersion comes up 0. The value it gets from the URL is ALWAYS correct, it is the internalVersion, the one it pulls from SharedPreferences which is wrong many times.
Any thoughts? Sorry so long. Thanks.
Corey
SharedPreference.Editor.commit() is a blocking call. This will take time and could result in likely ANRs.
Use apply() on API 9 and up and thread this off before while storing the expected value locally on older API versions, move this code to a service, and log your exceptions so you can debug appropriately for race conditions like this.
You should write/commit your changes only when you realize, something has changed - that is in the "if (updated)" branch. And you should not use static members but commit the value you read from the server.
Say your Receiver has been started anew (in a new process). In this case static values are starting with their initial values, so latestversion is "0". You commit this value.
Next run you read the "0". Now internalversion is lower than the server version - even if no change has happened.
Try by using:
int mode = Context.MODE_PRIVATE;
instead of
int mode = Activity.MODE_PRIVATE;
It'll start saving values in SharedPreferences.
new to the community. been up all night trying to flesh out the underlying html reading system that's at the core of my app's functionally. I could really use a fresh pair of eyes on this one.
Problem: While trying to return a string to be displayed on my app's home activity, I've run into an issue where I'm almost certain that the data was taken in correctly, cleaned up into XML via "Html Cleaner" (http://htmlcleaner.sourceforge.net/), and pulled through Jaxen (opensource Xpath) the result should display some text. Problem is of course, dispite my efforts I've yet to figure out exactly why it wont. My code follows below.
As a test I'm trying to pull the word "maps" from the http://www.google.com home page which is inside an tag with the hyperlink "http://maps.google.com/maps?hl=en&tab=wl" (which i'm using to uniquely identify the tag):
public class home extends Activity {
TextView text1;
//** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
text1 = (TextView)findViewById(R.id.text1);
text1.setText(LoadHTMLFromURL("http://www.google.com"));
}
private String LoadHTMLFromURL(String url)
{
try
{
// Load data from URL
InputStream is = (InputStream) new URL(url).getContent(); //generate
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
StringBuilder stringBuilder = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null)
{
stringBuilder.append(line + "");
}
is.close();
String HTMLout = stringBuilder.toString();
// Clean up HTML input.
//Initialize HTML Cleaner.
HtmlCleaner cleaner = new HtmlCleaner();
// This next line Cleans the html and exports it to a Tagnode named "node"
TagNode node = cleaner.clean(HTMLout);
// This is the xpath parsing info
String SearchTerm = "//a[#href='http://maps.google.com/maps?hl=en&tab=wl']";
Object[] info_nodes = node.evaluateXPath(SearchTerm);
TagNode info_node = (TagNode) info_nodes[0];
String info = info_node.getChildren().iterator().next().toString().trim();
return info;
}
catch (Exception e)
{
System.out.println( "Inside: home.LoadHTMLFromURL()" + "Exc="+e);
return null;
}
}
}
I apologize for the clutter, and lack of neatness in the code, still a mid to low range programer in a "learn as you go" stage of my ability. Any advice is appreciated.
side note: I ran a string containing some hand made simple XML to test if it would read the info, and it worked perfectly but not on xml generated from html webpages.
Ok, I believe the issue was my search term. my xpath term was typed wrong.
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();
}