Parsing and displaying XML from httpGet - java

Hopefully someone can help me here. I have a project that I'm doing, yes it is homework so I hope that doesn't hurt my chances of an answer here. I'm supposed to write an app that collects data from bbyopen api. Best Buys web api, it delivers details about stores in your area. Any way I've gotten a response from the server that I'm certain contains the correct information as I've displayed it in logcat using System.out.println(). However, what I would like to do is turn this string into an xml document, parse out the name of the store, it's address and then display it in a text view in a new activity.
Here is the code I'm using to parse the string and put the proper data into an array which is passed to a new activity. I'm certain that nothing is actually passed to the new activity and I'm unsure whether or not the array is even being built. Any help would be greatly appreciated.
public void callback(String serviceResult){
System.out.println(serviceResult);
try {
XmlPullParserFactory parserCreator = XmlPullParserFactory.newInstance();
parserCreator.setNamespaceAware(true);
XmlPullParser parser = parserCreator.newPullParser();
parser.setInput(new StringReader(serviceResult));
int eventType = parser.getEventType();
while (eventType != parser.END_DOCUMENT){
String name = "";
String address = "";
if ((eventType == XmlPullParser.START_TAG)&& (parser.getName().equals("longName"))){
name = parser.getName();
}
if ((eventType == XmlPullParser.START_TAG)&& (parser.getName().equals("address"))){
address = parser.getName();
Store store = new Store(name, address);
arrStore.add(store);
System.out.println(arrStore);
}
else
parser.nextTag();
}
} catch (Exception e) {
}
Intent intent = new Intent(getApplicationContext(),StoreList.class);
intent.getStringArrayListExtra(arrStore.toString(), "key");
startActivity(intent);
}
I then receive the intent in the new activity like this:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_store_list);
getIntent();
ArrayList<String> store = getIntent().getStringArrayListExtra("key");
}
However trying to do a print line on the ArrayList store, in the new activity results in a null pointer error. I suspect that is because the array is empty..?
If it helps here is what the XML that I am receiving looks like and it is being sent as a string the parser.
<stores warnings="Distances are in terms of miles (default)" currentPage="1" totalPages="1" from="1" to="4" total="4" queryTime="0.006" totalTime="0.011" >
<store>
<longName>Best Buy - Toledo II</longName>
<address>1405 Spring Meadows Dr</address>
</store>
<store>
<longName>Best Buy - Perrysburg</longName>
<address>10017 Fremont Pike</address>
</store>
<store>
<longName>Best Buy - Toledo</longName>
<address>4505 Monroe St</address>
</store>
<store>
<longName>Best Buy Mobile - Franklin Park</longName>
<address>5001 Monroe Street</address>
</store>
</stores>

The error is here:
Intent intent = new Intent(getApplicationContext(),StoreList.class);
intent.getStringArrayListExtra(arrStore.toString(), "key");
startActivity(intent);
Try: putStringArrayListExtra().

Related

Make link inside of string clickable: Java

I am creating a messaging system in Java using android studio.
People can send messages back and forth. But if they send a link, it just shows up as regular text. I want the part that is the link to show up as a clickable link and the rest just text.
I checked all day on this site and others but no seems to do this in the way I'm trying too. Most of the answers I see are people using a TexView to accomplish their goal. I'm using a string. Can someone please help me figure this out ?
private void showMessages(){
DatabaseReference userMessageKeyRef = RootRef.child("Messages").child(messageSenderID).child(messageReceiverID);
userMessageKeyRef.addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(#NonNull DataSnapshot snapshot) {
for (DataSnapshot snapshot1 : snapshot.getChildren()) {
Messages messages = new Messages();
String strMessage = snapshot1.child("message").getValue().toString();
String strFrom = snapshot1.child("from").getValue().toString();
String strType = snapshot1.child("type").getValue().toString();
messages.setMessage(strMessage);
messages.setFrom(strFrom);
messages.setType(strType);
messagesList.add(messages);
// Pattern for recognizing a URL, based off RFC 3986
final Pattern urlPattern = Pattern.compile(
"(?:^|[\\W])((ht|f)tp(s?):\\/\\/|www\\.)"
+ "(([\\w\\-]+\\.){1,}?([\\w\\-.~]+\\/?)*"
+ "[\\p{Alnum}.,%_=?&#\\-+()\\[\\]\\*$~#!:/{};']*)",
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);
// separate input by spaces ( URLs don't have spaces )
String [] parts = strMessage.split("\\s+");
// get every part
for( String item : parts ) {
if(urlPattern.matcher(item).matches()) {
//it's a good url
System.out.print(""+ item + " " );
} else {
// it isn't a url
System.out.print(item + " ");
}
}
}
messageAdapter = new MessageAdapter(ChatActivity.this,messagesList);
userMessagesList.setAdapter(messageAdapter);
}
#Override
public void onCancelled(#NonNull DatabaseError error) {
}
});
}
There are two common ways to do this. One, like you have done, is to add html to the string. The second is to use the TextView's auto link mask feature.
Using HTML
Once you have identified URLs in your incoming string and added the appropriate html tags to turn them into links, you just need to use HtmlCompat when you go to actually display it in the TextView. You also need to make sure to call setMovementMethod or you won't be able to click the link. The advantage of using HTML is that you can have the link text be a readable phrase instead of a URL.
String txt = "This is www.google.com";
TextView link = findViewById(R.id.link);
link.setMovementMethod(LinkMovementMethod.getInstance());
link.setText(HtmlCompat.fromHtml(txt,HtmlCompat.FROM_HTML_MODE_LEGACY));
If you choose to go this route, your existing code just needs to be modified a bit to save the HTML string in the messages list passed to the adapter, then add the TextView calls above inside the adapter when you set the text.
String [] parts = strMessage.split("\\s+");
// replace URL parts with html links
for( int i = 0; i < parts.length; ++i ) {
if(urlPattern.matcher(parts[i]).matches()) {
parts[i] = "" + parts[i] + "";
}
}
// re-join parts back into a single string
String htmlMessage = String.join(" ", parts);
// save a list of html strings to pass to your adapter
htmlMessageStrings.add(htmlMessage);
Using Link Mask
This method doesn't require you to edit the string at all. If you use Linkify.ALL it also recognizes things like web links, emails, phone numbers, and physical addresses - not just web links. If you only want it to recognize web links use Linkify.WEB_URLS instead. This requires a lot less code on your part - you no longer have to try to parse the string for links.
String txt = "This is www.google.com"; // no need to modify the string
TextView link = findViewById(R.id.link);
link.setAutoLinkMask(Linkify.ALL); // or Linkify.WEB_URLS
link.setText(txt);
You can also add android:autoLink="all" to the TextView XML definition instead of calling it in-code.
Both methods produce this output

Android queryIntentActivities always return empty list

I'm trying to get a list of all applications that are capable of sending text messages.
I found several solutions on that suggest to use the PackageManager.
I think that the Intent to be used is ACTION_SEND, but when i run my code i always receive an empty List.
This is my code:
Intent mainIntent = new Intent(Intent.ACTION_SEND, null);
List<ResolveInfo> pkgAppsList = getApplicationContext().getPackageManager().queryIntentActivities( mainIntent, PackageManager.GET_RESOLVED_FILTER);
int size = pkgAppsList.size();
int i = 0;
Log.i(TAG, "Size: " + size);
for(ResolveInfo infos : pkgAppsList){
String name = infos.activityInfo.applicationInfo.loadLabel(getPackageManager()).toString();
Log.i(TAG, "name: " + name);
}
Any idea?
You haven't set the MIME type for the Intent. For example:
mainIntent.setType("text/plain");
That will produce results. However, be mindful that this won't exactly return "applications capable of sending text messages", rather those that can accept a text, not necessarily for the purpose of sending a message (as an example, the Google Translate app is capable of receving text).

Search on images.google.com from Android app

I am developing an android application for the first time.
I am able to do a www.google.com search with this code:
public void onSearchClick(View v) {
try {
Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
String term = editText.getText().toString();
intent.putExtra(SearchManager.QUERY, term);
startActivity(intent);
} catch (Exception ex) {
}
}
But is it also possible to do a search like that on images.google.com (with a word that was filled in the editText-widget)?
Thanks in advance.
a bit late to the party.
I was trying to do much the same thing, stumbled on this Android: Google Images Search Results
,and found that the following query should be more "elegant" - but of course no guarantee that Google would not change it -:
Take "cheetah" as an example for query,
https://www.google.com/search?tbm=isch&q=cheetah
should do the trick.
This should have come close to Shashank Kadne's suggestion in the comment above.
I don't find an elegant way. But you can use this :) intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://images.google.com/search?num=10&hl=en&site=&tbm=isch&source=hpā€Œā€‹&biw=1366&bih=667&q=cars&oq=cars&gs_l=img.3..0l10.748.1058.0.1306.4.4.0.0.0.0.165ā€Œā€‹.209.2j1.3.0...0.0...1ac.1.8RNsNEqlcZc")); where q='Your_search_text'

Android Java Text to Speech Viewing Extra String Information

I've been running through many of the text to speech examples available for Android and I have an issue that I assume is really simple, but I cannot for the life of me work it out!
I simply want to be able to view the output of EXTRA_AVAILABLE_VOICES (for example) which according to this link is returned in an ArrayList. There are many examples of how to deal with such output programmatically, but for the benefit of my learning and understanding, I want to see the actual returned data for myself.
My project is set up exactly as the android developers example from here
// We now return the list of available and unavailable voices
// as well as the return code.
Intent returnData = new Intent();
returnData.putStringArrayListExtra(
TextToSpeech.Engine.EXTRA_AVAILABLE_VOICES, available);
returnData.putStringArrayListExtra(
TextToSpeech.Engine.EXTRA_UNAVAILABLE_VOICES, unavailable);
setResult(result, returnData);
finish();
}
Ideally I'd like to have the output displayed after the 'constant value' in a simple TextView from a string, but I can't achieve that, neither can I get it in a ListView despite my many efforts... Please can someone help me solve this!
Once I know how to view the returned data, I can then go on to follow the examples of how to deal with it correctly.
I've not included any the code I've already tried, as I can't find an example anywhere and it's been pure guess work (which I be embarrassed to show!)
Thanks in advance.
For anyone who is ever stuck with the same thing, I used the code below, edited from the sample found here:
ArrayList<String> available = data
.getStringArrayListExtra("availableVoices");
Log.v("languages count", String.valueOf(available.size()));
Iterator<String> iter = available.iterator();
while (iter.hasNext()) {
String lang = iter.next();
Locale locale = new Locale(lang);
Log.v(TAG, "language: " + lang);
Log.v(TAG, "language locale: " + locale.toString());
TextView LocaleResults = (TextView) getView().findViewById(
R.id.textViewConfig);
LocaleResults.append("\nAvailable Engine Language: " + lang);
}
ArrayList<String> unavailable = data
.getStringArrayListExtra("unavailableVoices");
Log.v("languages count", String.valueOf(unavailable.size()));
Iterator<String> iteru = unavailable.iterator();
while (iteru.hasNext()) {
String ulang = iteru.next();
Locale ulocale = new Locale(ulang);
Log.v(TAG, "ulanguage: " + ulang);
Log.v(TAG, "ulanguage locale: " + ulocale.toString());
TextView LocaleResults = (TextView) getView().findViewById(
R.id.textViewConfig);
LocaleResults.append("\nUnavailable Engine Language: " + ulang);
}

Android: Adding .xml resources to an array

UPDATE:
So I tried the AssetManager way and ended up with this:
...
...
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
XmlPullParser xrp = factory.newPullParser();
AssetManager assmgr = context.getAssets();
xrp.setInput(assmgr.open("levels/level_1.xml"), null);
//Object attributes
String type = null;
int x = 0;
int y = 0;
double angleRads = 0;
int eventType = xrp.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_DOCUMENT) {
} else if (eventType == XmlPullParser.START_TAG) {
if (xrp.getName().equals("Position")) {
while (!xrp.getName().equals("X")) { <----NULLPOINTER EXCEPTION HERE
eventType = xrp.next();
}
...
...
Now this code used to work fine when xrp was a XmlResourceParser but now I get this error message:
06-01 05:13:56.797: ERROR/AndroidRuntime(946): Caused by: java.lang.NullPointerException
06-01 05:13:56.797: ERROR/AndroidRuntime(946): at com.stickfigs.blockball.BlockBallView$BlockBallThread.initLevel(BlockBallView.java:342)
I don't understand why this isn't working anymore, I marked the line where the nullpointerexception is happening in the code above with an arrow.
=== vvvOLDvvv ===
In my res/xml/ folder I have a bunch of files called level_#.xml (ex: level_1.xml, level_2.xml, level_21.xml) and I have a spinner widget that I want to populate with the id names of all of the .xml files in this folder that follow the naming convention level_#.xml and only those.
I think I figured out how to set up the widget:
Spinner lsSpinner = (Spinner) findViewById(R.id.levelselect_spinner);
String levels[] = {"level_1","level_2","level_55"};
ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, levels);
spinnerArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
lsSpinner.setAdapter(spinnerArrayAdapter);
Now I just need to generate levels[] dynamically like I explained before...
How do I go about doing this?
The straightforward answer is
String[] levels = new String[LEVELS];
for (int i=0; i< LEVELS; i++) {
int j = i+1;
levels[i] = new String ("level_"+j);
}
But I have the feeling that that's not what you want.
If you want a reference to the actual ID of each level_XX.xml, then you will need to do it manually, since each R.layout.levelXX is an actual int and there is no possible way to secure consecutive numbering for them (even if the names you use are consecutive).
Since the previous question has been solved, I think it is better to create another question to let folks help you. But in the name of convenience please allow me to answer you here.
What do you think if xrp.getName() will never equal to "X"? Will xrp goto next until null? I suggest you make a breakpoint here and have a check.
By the way, I saw you are struggling in xml in android, I may suggest you use some ext library which may let life easier. Like this: http://brainflush.wordpress.com/2009/05/19/the-force-unleashed-xmlxpath-on-android-using-dom4j-and-jaxen/
Hope this may help.
Have a look at AssetManager: http://developer.android.com/reference/android/content/res/AssetManager.html#list(java.lang.String)
And then you can new a file and getName()
Link: http://developer.android.com/reference/java/io/File.html#getName()
Hope this helps.

Categories