I realize this is an easy issue usually, but I've been looking at other similar questions on this site and others and have not been able to fix the code, nor seeing exactly where the error is coming from. What seems to be my problem is calling an OnClickListener assigned to a button, but then again I could be wrong. I had basically straight copied this code (with minimal changes) from another application where this had worked. This fact baffles me a little bit more. Thanks in advance for your help with this relatively easy question.
Code:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.update_activity);
final Handler handler;
handler = new Handler();
final EditText getCustID = (EditText) findViewById(R.id.customer);
final EditText custvar1 = (EditText) findViewById(R.id.var1);
final EditText custvar2 = (EditText) findViewById(R.id.var2);
final EditText custvar3 = (EditText) findViewById(R.id.var3);
class sendGET implements Runnable
{
private String url;
public sendGET(String mUrl)
{
url = mUrl;
}
public void run()
{
try
{
//Declare HttpClient and HttpGet
HttpClient client = new DefaultHttpClient();
HttpGet httpget = new HttpGet(url);
//Run HttpGet
client.execute(httpget);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class getCustomerData implements Runnable
{
public void run()
{
try
{
InputStream stream = null;
XMLparser xmlParser = new XMLparser();
List<Customer> customers = null;
String parseUrl = URL + getCustID.getText().toString();
try
{
stream = downloadUrl(parseUrl);
customers = xmlParser.parse(stream);
}
finally
{
stream.close();
}
final Customer data = customers.get(0);
handler.post(new Runnable() {
public void run() {
custvar1.setText(String.valueOf(data.var1));
custvar2.setText(String.valueOf(data.var2));
custvar3.setText(String.valueOf(data.var3));
}
});
}
catch (IOException e)
{
//return getResources().getString(R.string.connection_error);
}
catch (XmlPullParserException e)
{
//return getResources().getString(R.string.xml_error);
}
}
private Customer readCustomer(XmlPullParser parser) throws XmlPullParserException, IOException
{
parser.require(XmlPullParser.START_TAG, null, "customer");
String custID = null;
String var1 = null;
String var2 = null;
String var3 = null;
while(parser.next() != XmlPullParser.END_TAG)
{
if (parser.getEventType() != XmlPullParser.START_TAG)
{
continue;
}
String name = parser.getName();
if (name.equals("CustID"))
{
custID = readCustID(parser);
} else if (name.equals("custvar1"))
{
var1 = readVar1(parser);
} else if (name.equals("custvar2"))
{
var2 = readVar2(parser);
} else if (name.equals("custvar3"))
{
var3 = readVar3(parser);
} else
{
skip(parser);
}
}
return new Customer(custID, var1, var2, var3);
}
private String readCustID(XmlPullParser parser) throws IOException, XmlPullParserException
{
parser.require(XmlPullParser.START_TAG, null, "CustID");
final String custID = readText(parser);
parser.require(XmlPullParser.END_TAG, null, "CustID");
return custID;
}
private String readVar1(XmlPullParser parser) throws IOException, XmlPullParserException
{
parser.require(XmlPullParser.START_TAG, null, "custvar1");
String var1 = readText(parser);
parser.require(XmlPullParser.END_TAG, null, "custvar1");
return var1;
}
private String readVar2(XmlPullParser parser) throws IOException, XmlPullParserException
{
parser.require(XmlPullParser.START_TAG, null, "custvar2");
String var2 = readText(parser);
parser.require(XmlPullParser.END_TAG, null, "custvar2");
return var2;
}
private String readVar3(XmlPullParser parser) throws IOException, XmlPullParserException
{
parser.require(XmlPullParser.START_TAG, null, "custvar3");
String var3 = readText(parser);
parser.require(XmlPullParser.END_TAG, null, "custvar3");
return var3;
}
private String readText(XmlPullParser parser) throws IOException, XmlPullParserException
{
String result = "";
if (parser.next() == XmlPullParser.TEXT)
{
result = parser.getText();
parser.nextTag();
}
return result;
}
private void skip(XmlPullParser parser) throws IOException, XmlPullParserException
{
if (parser.getEventType() != XmlPullParser.START_TAG)
{
throw new IllegalStateException();
}
int depth = 1;
while (depth != 0)
{
switch (parser.next()) {
case XmlPullParser.END_TAG:
depth --;
case XmlPullParser.START_TAG:
depth++;
break;
}
}
}
class XMLparser
{
public List<Customer> parse(InputStream in) throws XmlPullParserException, IOException {
try
{
XmlPullParser parser = Xml.newPullParser();
parser.setInput(in, null);
parser.nextTag();
return readXML(parser);
} finally {
in.close();
}
}
private List<Customer> readXML(XmlPullParser parser) throws XmlPullParserException, IOException
{
List<Customer> custData = new ArrayList<Customer>();
parser.require(XmlPullParser.START_TAG, null, "xml");
while (parser.next() != XmlPullParser.END_TAG)
{
if (parser.getEventType() != XmlPullParser.START_TAG)
{
continue;
}
String name = parser.getName();
//Look for customer tag
if (name.equals("customer"))
{
custData.add(readCustomer(parser));
}
else
{
skip(parser);
}
}
return custData;
}
}
private InputStream downloadUrl(String urlString) throws IOException
{
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000);
conn.setConnectTimeout(15000);
conn.setRequestMethod("GET");
conn.setDoInput(true);
//start the query
conn.connect();
InputStream stream = conn.getInputStream();
return stream;
}
}
final Button getData = (Button) findViewById(R.id.getData);
getData.setOnClickListener(new View.OnClickListener(){
public void onClick(View v)
{
//Declare and start thread
final Runnable mGetData = new getCustomerData();
final Thread getData = new Thread(mGetData);
getData.start();
}
});
final Button submit = (Button) findViewById(R.id.Submit);
submit.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//set url
String url = "**removed**";
url += "var1=" + custvar1.getText().toString() + "&var2=" + custvar2.getText().toString() + "&var3=" + custvar3.getText().toString();
//Declare and start thread
final Runnable mConnect = new sendGET(url);
final Thread Connect = new Thread(mConnect);
Connect.start();
}
});
}
public class Customer
{
public final String custID;
public final String var1;
public final String var2;
public final String var3;
private Customer()
{
custID = null;
var1 = null;
var2 = null;
var3 = null;
}
private Customer(String custID, String var1, String var2, String var3)
{
this.custID = custID;
this.var1 = var1;
this.var2 = var2;
this.var3 = var3;
}
}
Logcat Error:
01-09 19:20:53.478: W/dalvikvm(911): threadid=11: thread exiting with uncaught exception (group=0x40a13300)
01-09 19:20:53.478: E/AndroidRuntime(911): FATAL EXCEPTION: Thread-99
01-09 19:20:53.478: E/AndroidRuntime(911): java.lang.NullPointerException
01-09 19:20:53.478: E/AndroidRuntime(911): at us.rns.editdata.UpdateActivity$1getCustomerData.run(UpdateActivity.java:90)
01-09 19:20:53.478: E/AndroidRuntime(911): at java.lang.Thread.run(Thread.java:856)
01-09 19:20:54.408: W/IInputConnectionWrapper(911): showStatusIcon on inactive InputConnection
Your downloadUrl method is failing.
InputStream stream = null;
XMLparser xmlParser = new XMLparser();
List<Customer> customers = null;
String parseUrl = URL + getCustID.getText().toString();
try
{
stream = downloadUrl(parseUrl);
customers = xmlParser.parse(stream);
}
finally
{
stream.close();
}
The stream object is set to null, then you assign stream = downloadUrl(parseUrl).
The downloadUrl method fails, without having assigned anything to stream.
You then try to close the stream in the finally clause.
private InputStream downloadUrl(String urlString) throws IOException
{
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000);
conn.setConnectTimeout(15000);
conn.setRequestMethod("GET");
conn.setDoInput(true);
//start the query
conn.connect();
InputStream stream = conn.getInputStream();
return stream;
}
Put a breakpoint on this method, and debug through it. Please return with the exact line it is breaking on. I suspect it is conn.connect(); or InputStream stream = conn.getInputStream();
I would also do this in the finally clause:
finally
{
if(stream != null)
stream.close();
}
It could also be the following:
You need to move all of these:
final EditText getCustID = (EditText) findViewById(R.id.customer);
final EditText custvar1 = (EditText) findViewById(R.id.var1);
final EditText custvar2 = (EditText) findViewById(R.id.var2);
final EditText custvar3 = (EditText) findViewById(R.id.var3);
final Button getData = (Button) findViewById(R.id.getData);
final Button submit = (Button) findViewById(R.id.Submit);
into onResume, rather than onCreate()
Related
I created XML parsing RSS reader,but it is only reading the last 3 nodes (which is title,link and description ).i want to know which lines of code making this trick(i mean reading the last nodes).if i want to read the first three nodes from this rss site,what i should i actually do ?
i am a nuwbie . can anyone post the answer as code?
public class HandleXML {
private String title = "title";
private String link = "link";
private String description = "description";
private String title1 = "title";
private String link1 = "link";
private String description1 = "description";
private String urlString = null;
private XmlPullParserFactory xmlFactoryObject;
public volatile boolean parsingComplete = true;
public HandleXML(String url){
this.urlString = url;
}
public String getTitle(){
return title;
}
public String getLink(){
return link;
}
public String getDescription(){
return description;
}
public void parseXMLAndStoreIt(XmlPullParser myParser) {
int event;
String text=null;
try {
event = myParser.getEventType();
while (event != XmlPullParser.END_DOCUMENT) {
String name=myParser.getName();
switch (event){
case XmlPullParser.START_TAG:
break;
case XmlPullParser.TEXT:
text = myParser.getText();
break;
case XmlPullParser.END_TAG:
if(name.equals("title")){
title = text;
}
else if(name.equals("link")){
link = text;
}
else if(name.equals("description")){
description = text;
}
else{
}
break;
}
event = myParser.next();
}
parsingComplete = false;
}
catch (Exception e) {
e.printStackTrace();
}
}
public void fetchXML(){
Thread thread = new Thread(new Runnable(){
#Override
public void run() {
try {
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setRequestMethod("GET");
conn.setDoInput(true);
// Starts the query
conn.connect();
InputStream stream = conn.getInputStream();
xmlFactoryObject = XmlPullParserFactory.newInstance();
XmlPullParser myparser = xmlFactoryObject.newPullParser();
myparser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
myparser.setInput(stream, null);
parseXMLAndStoreIt(myparser);
stream.close();
}
catch (Exception e) {
}
}
});
thread.start();
}
}
It is this part of the code that is responsible to read the elements you mentioned above .
if(name.equals("title")){
title = text;
}
else if(name.equals("link")){
link = text;
}
else if(name.equals("description")){
description = text;
}
else{
// Write similar conditions for the other tags that you want to parse.
}
You are using a while loop in order to process the document.
Within that loop your code reads all the title, link and description nodes.
The problem is that it overrides the variables every time, hence what you get is the last title, link and description.
If you would like to read only the firs title, link and description you could do something like:
Initialise variables like this:
private String title;
private String link;
private String description;
Than:
if(name.equals("title") && title != null){
title = text;
}
else if(name.equals("link") && link != null){
link = text;
}
else if(name.equals("description") && description != null){
description = text;
}
EDIT (try this, warning: I haven't tested it)
public class HandleXML {
public volatile boolean parsingComplete = true;
private String title;
private String link;
private String description;
private String urlString = null;
private XmlPullParserFactory xmlFactoryObject;
public HandleXML(String url) {
this.urlString = url;
}
public String getTitle() {
return title;
}
public String getLink() {
return link;
}
public String getDescription() {
return description;
}
public void parseXMLAndStoreIt(XmlPullParser myParser) {
int event;
String text = null;
try {
event = myParser.getEventType();
while (event != XmlPullParser.END_DOCUMENT) {
String name = myParser.getName();
switch (event) {
case XmlPullParser.START_TAG:
break;
case XmlPullParser.TEXT:
text = myParser.getText();
break;
case XmlPullParser.END_TAG:
if (name.equals("title") && title != null) {
title = text;
}
else if (name.equals("link") && link != null) {
link = text;
}
else if (name.equals("description") && description != null) {
description = text;
}
break;
}
event = myParser.next();
}
parsingComplete = false;
}
catch (Exception e) {
e.printStackTrace();
}
}
public void fetchXML() {
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
try {
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setRequestMethod("GET");
conn.setDoInput(true);
// Starts the query
conn.connect();
InputStream stream = conn.getInputStream();
xmlFactoryObject = XmlPullParserFactory.newInstance();
XmlPullParser myparser = xmlFactoryObject.newPullParser();
myparser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
myparser.setInput(stream, null);
parseXMLAndStoreIt(myparser);
stream.close();
}
catch (Exception e) {
// TODO: 27/07/2017 handle exception
}
}
});
thread.start();
}
}
This question already has answers here:
How can I fix 'android.os.NetworkOnMainThreadException'?
(66 answers)
Closed 6 years ago.
The purpose of the class below is to get text from different articles of different news websites. The version below is designed for Android, but it throws a NetworkOnMainThread Exception when run. When I used an earlier version of this class, made specifically to run on a computer, it worked fine, but I'm not really sure how network I/O works on Android. I've seen some other answers to questions about this topic, but I don't understand why in Android the program throws an exception but on a desktop it works fine. Can anyone explain?
package com.example.user.helloworld;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
public class ArticleReceiver {
private ArrayList<Article> newsArticles = new ArrayList<>();
private ArrayList<String> newsLinks = new ArrayList<>();
public ArticleReceiver(int numArticles, String link) {
if (numArticles != 0) {
receiveNewsArticles(numArticles, link);
}else{
System.out.println("ERROR: numArticles request for " + link + " cannot equal 0.");
}
}
private void receiveNewsArticles(int numArticles, String urlAddress) {
URL rssUrl = null;
// if connected to Internet
if (true){//isInternetAvailable()) {
try {
// gather links
rssUrl = new URL(urlAddress);
BufferedReader in = new BufferedReader(new InputStreamReader(rssUrl.openStream()));
String line;
// fix bbc trash urls
if (urlAddress.equals(Main.BBC_URL)) {
numArticles++;
}
while ((line = in.readLine()) != null && newsLinks.size() <= numArticles) {
if (line.contains("<link>")) {
// find links through tags
int firstPos = line.indexOf("<link>");
String temp = line.substring(firstPos);
temp = temp.replace("<link>", "");
int lastPos = temp.indexOf("</link>");
temp = temp.substring(0, lastPos);
newsLinks.add(temp);
}
}
in.close();
// test if there are links and if there is remove first
// unnecessary
// link
if (!newsLinks.isEmpty()) {
if (urlAddress.equals(Main.BBC_URL)) {
newsLinks.remove(0);
newsLinks.remove(0);
}else if(urlAddress.equals(Main.CNN_URL) || urlAddress.equals(Main.FOX_URL) || urlAddress.equals(Main.ESPN_URL)){
newsLinks.remove(0);
}
} else {
System.out.println("ERROR: No Found Articles. Check If You Have Wifi.");
}
// gather articles from HTML "section" or "p" tag of article using Jsoup
for (String newsLink : newsLinks) {
// get webpage
Document doc = Jsoup.connect(newsLink).get();
// get article from different websites
String article = null;
if (urlAddress.equals(Main.FOX_URL)) {
Elements element = doc.select("p");
article = element.text();
} else if (urlAddress.equals(Main.CNN_URL)) {
Elements element = doc.select("section");
article = element.text();
} else if (urlAddress.equals(Main.BBC_URL)) {
Elements element = doc.select("p");
article = element.text();
}else if(urlAddress.equals(Main.ESPN_URL)){
Elements element = doc.select("p");
article = element.text();
}
newsArticles.add(new Article(article, Main.SUMMARY_SENTENCES));
}
} catch (IOException e) {
e.printStackTrace();
}
} else {
System.out.println("ERROR: No internet connection established.");
return;
}
}
public ArrayList<Article> getArticles() {
return newsArticles;
}
public Article getArticle(int i) {
if (newsArticles.size() <= i) {
return null;
} else {
return newsArticles.get(i);
}
}
//The method below does not recognize the "getSystemService" method, and when the method is no longer present there is a NetworkOnMainThreadException
private boolean isInternetAvailable() {
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
}
You need to execute web service connections asynchronous.
What I use in my projects is have a class ApiConnection and with interface get response. Example:
Apiconnection class
public class APIConnection extends AsyncTask<Object, String, Void> {
private final String TAG = "API-CONNECTION";
private StringBuilder sbuilder;
private JSONObject json;
private APIConnectionInterface mInterface;
protected int httpResponseCode = 0;
private String entity = null, url;
private APIConnectionType mmode;
private boolean DEBUG = BuildConfig.DEBUG;
private String[][] headers;
/**
Constructor For APIConnection
*/
public APIConnection(APIConnectionInterface thisdelegate, APIConnectionType mode, String murl, String entity) {
this.mInterface = thisdelegate;
this.mmode = mode;
this.url = murl;
this.entity = entity;
initHeaders();
}
private void initHeaders(){
headers = new String[][]{
{"token", "MY_TOKEN"},
{"Content-Type", "application/json;charset=utf-8"},
{"user-agent", "android"},
{"Accept-Language", "es"}
};
}
#Override
protected Void doInBackground(Object... params) {
BufferedReader buffer = null;
InputStreamReader in = null;
OutputStream os = null;
int timeoutConnection = 30000, timeoutSocket = 20000;
try{
sbuilder = new StringBuilder();
url = convertURL(url);
if (entity==null)entity="{}";
URL u = new URL(url);
HttpURLConnection conn;
if (url.startsWith("https://"))
conn = (HttpsURLConnection) u.openConnection();
else
conn = (HttpURLConnection) u.openConnection();
conn.setReadTimeout(timeoutConnection);
conn.setConnectTimeout(timeoutSocket);
for (String[] arr : headers){ conn.addRequestProperty(arr[0], arr[1]); }
/*GET*/if (mmode == APIConnectionType.GET) {
conn.setDoInput(true);
conn.setRequestMethod(mmode.toString());
httpResponseCode = conn.getResponseCode();
in = new InputStreamReader(
httpResponseCode == HttpURLConnection.HTTP_OK ? conn.getInputStream() : conn.getErrorStream(),"UTF-8");
/*OTHER*/} else if (mmode == APIConnectionType.POST || mmode == APIConnectionType.PUT ||
mmode == APIConnectionType.PATCH || mmode == APIConnectionType.DELETE) {
conn.setRequestMethod(mmode.toString());
conn.setDoOutput(true);
byte[] outputInBytes = entity.getBytes("UTF-8");
os = conn.getOutputStream();
os.write( outputInBytes );
httpResponseCode = conn.getResponseCode();
in = new InputStreamReader(
httpResponseCode == HttpURLConnection.HTTP_OK ? conn.getInputStream() : conn.getErrorStream(), "UTF-8");
}
if (in!=null){
buffer=new BufferedReader(in);
String line;
while ((line = buffer.readLine()) != null) {
sbuilder.append(line);
}
}else {
sbuilder.append("");
}
}
catch(IOException e) {
if (DEBUG)Log.d(TAG, "onBackground Exception " + e.getMessage());
sbuilder= new StringBuilder();
httpResponseCode = 0;
cancel(true);
return null;
} finally {
if (buffer != null) {
try {
buffer.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
if (os!=null){
try {
os.flush();
} catch (IOException e) {
e.printStackTrace();
}
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
#Override
protected void onPostExecute(Void result){
try{
if (DEBUG) timelapse_e = System.currentTimeMillis();
if (sbuilder != null) {
json = new JSONObject(sbuilder.toString());
}
if (sbuilder != null){
sbuilder.setLength(0);
sbuilder.trimToSize();
}
sbuilder = null;
GoRunning();
hideDialog();
}
catch(RuntimeException e) {
if (DEBUG)Log.d(TAG, "PostExecute RuntimeException " + e.getMessage());
cancel(true);
}
catch(Exception e) {
if (DEBUG)Log.d(TAG, "PostExecute Exception " + e.getMessage());
cancel(true);
}
}
#Override protected void onCancelled() {
if (mInterface != null) mInterface.onCancelled(APIConnection.this);
super.onCancelled();
}
#Override protected void onPreExecute() {
super.onPreExecute();
if (DEBUG) timelapse_s = System.currentTimeMillis();
if (mInterface != null) mInterface.onStartLoading(APIConnection.this);
}
public void GoRunning(){
if (mInterface != null) try {
mInterface.onDataArrival(APIConnection.this, json, httpResponseCode);
} catch (JSONException e) {
onCancelled();
e.printStackTrace();
}
}
/**
* Hide Dialog (Progress dialog) if is showing and activity NOT Finishing
*/
private void hideDialog() {
if (mInterface != null) mInterface.onFinishedLoading(APIConnection.this);
}
/** <b>convertURL(String str);</b><br/>
* replaces any special characters to <b>%??</b><br/>
* Replacements actived:<br/>
* "{Space}" ==> "%20"
* #param str URL to encode
* #return url encoded
*/
public static String convertURL(String str) {
return str.trim().replace(" ", "%20");
// .replace("&", "%26")
// .replace(",", "%2c").replace("(", "%28").replace(")", "%29")
// .replace("!", "%21").replace("=", "%3D").replace("<", "%3C")
// .replace(">", "%3E").replace("#", "%23").replace("$", "%24")
// .replace("'", "%27").replace("*", "%2A").replace("-", "%2D")
// .replace(".", "%2E").replace("/", "%2F").replace(":", "%3A")
// .replace(";", "%3B").replace("?", "%3F").replace("#", "%40")
// .replace("[", "%5B").replace("\\", "%5C").replace("]", "%5D")
// .replace("_", "%5F").replace("`", "%60").replace("{", "%7B")
// .replace("|", "%7C").replace("}", "%7D"));
}
public interface APIConnectionInterface {
void onDataArrival(APIConnection apiConnection, JSONObject json, int httpResponseCode) throws JSONException;
void onStartLoading(APIConnection apiConnection);
void onFinishedLoading(APIConnection apiConnection);
void onCancelled(APIConnection apiConnection);
}
public enum APIConnectionType {
GET("GET"),
POST("POST"),
PUT("PUT"),
PATCH("PATCH"),
DELETE("DELETE");
private String methodName;
APIConnectionType(String methodName){this.methodName = methodName;}
#Override public String toString() {return methodName;}
}
}
And then from any Activity or Fragment I can call the web service async
like this:
new APIConnection(new APIConnection.APIConnectionInterface() {
#Override public void onDataArrival(APIConnection apiConnection, JSONObject json, int httpResponseCode) {
try {
if (isHttpResponseOk(httpResponseCode, json)){//200 or 201
JSONObject obj = json.getJSONObject("results");
// do things with json
}
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override public void onStartLoading(APIConnection apiConnection) {showProgressDialog();}
#Override public void onFinishedLoading(APIConnection apiConnection) {hideProgressDialog();}
#Override public void onCancelled(APIConnection apiConnection) {hideProgressDialog();}
}, APIConnection.APIConnectionType.GET, MyApp.API_URL + "/master_data/", null).execute();
The only thing you need is to adapt the response to other object you need.
I hope that helps
when i test my app in emulator(android 5.0) ,it runs successfully and get the picture i want and the getRequestCode is 200.but when i run it in my galaxy s3 and moto xt889,this error occoured.and the getRequestCode is 404.
public class DownloadService {
private static String TAG = "DownloadService";
public static final int IO_BUFFER_SIZE = 8 * 1024;
private static final String CACHE_FILENAME_PREFIX = "cache_";
private static ExecutorService SINGLE_TASK_EXECUTOR = null;
private static ExecutorService LIMITED_TASK_EXECUTOR = null;
private static final ExecutorService FULL_TASK_EXECUTOR = null;
private static final ExecutorService DEFAULT_TASK_EXECUTOR;
private Pattern p;
private Matcher m;
private static Object lock = new Object();
static {
// SINGLE_TASK_EXECUTOR = (ExecutorService)
// Executors.newSingleThreadExecutor();
LIMITED_TASK_EXECUTOR = (ExecutorService) Executors
.newFixedThreadPool(1);
// FULL_TASK_EXECUTOR = (ExecutorService)
// Executors.newCachedThreadPool();
DEFAULT_TASK_EXECUTOR = LIMITED_TASK_EXECUTOR;
};
DownloadStateListener listener;
private String downloadPath;
private List<String> listURL;
// 下载个数
private int size = 0;
private Context context;
public interface DownloadStateListener {
public void onFinish();
public void onFailed();
}
public DownloadService(String downloadPath, List<String> listURL,
DownloadStateListener listener, Context context) {
this.context = context;
this.downloadPath = downloadPath;
this.listURL = listURL;
this.listener = listener;
p = Pattern.compile(".*com/(.*)");
}
public void setDefaultExecutor() {
}
public void startDownload() {
File downloadDirectory = new File(downloadPath);
if (!downloadDirectory.exists()) {
downloadDirectory.mkdirs();
}
for (final String url : listURL) {
try {
DEFAULT_TASK_EXECUTOR.execute(new Runnable() {
#Override
public void run() {
downloadBitmap(url);
}
});
} catch (RejectedExecutionException e) {
e.printStackTrace();
Log.e(TAG, "thread pool rejected error");
listener.onFailed();
} catch (Exception e) {
e.printStackTrace();
listener.onFailed();
}
}
}
private void downloadBitmap(String urlString) {
Matcher m = p.matcher(urlString);
OutputStream fos=null;
m.find();
HttpURLConnection urlConnection = null;
BufferedOutputStream out = null;
try {
fos = context.openFileOutput(m.group(1), Context.MODE_PRIVATE);
final URL url = new URL(urlString);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.getResponseCode();
Log.d("dfdf", urlConnection.getResponseCode()+"");
final InputStream in = new BufferedInputStream(
urlConnection.getInputStream(), IO_BUFFER_SIZE);
out = new BufferedOutputStream(fos, IO_BUFFER_SIZE);
int b;
while ((b = in.read()) != -1) {
out.write(b);
}
statDownloadNum();
} catch (final IOException e) {
Log.e(TAG, "download " + urlString + " error");
e.printStackTrace();
listener.onFailed();
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (out != null) {
try {
out.close();
fos.close();
} catch (final IOException e) {
Log.e(TAG, "Error in downloadBitmap - " + e);
}
}
}
}
private void statDownloadNum() {
synchronized (lock) {
size++;
if (size == listURL.size()) {
Log.d(TAG, "download finished total " + size);
DEFAULT_TASK_EXECUTOR.shutdownNow();
listener.onFinish();
}
}
}
}
the error is
java.io.FileNotFoundException: http://dnight-math.stor.sinaapp.com/理综1_img030.jpg
at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:186)
at util.DownloadService.downloadBitmap(DownloadService.java:159)
at util.DownloadService.access$0(DownloadService.java:136)
at util.DownloadService$1.run(DownloadService.java:114)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
at java.lang.Thread.run(Thread.java:841)
why this error will happen when i use real phone?
This happens because server returns an HTTP.4xx or HTTP.5xx error. You should use HttpURLConnection.getErrorStream() method if you want to get error page.
Something like this:
InputStream inputStream = null;
try {
inputStream = urlConnection.getInputStream();
} catch(FileNotFoundException e) {
inputStream = urlConnection.getErrorStream();
}
I'm try make an application chatbot in Android. I use Pandorabots as Chatbot server. To connect between Device Android with the Server. I use pandorabot XML-RPC API, and i use xml-rpc library from android-xmlrpc. so this my code:
public class MainActivity extends Activity {
private EditText editOne;
private TextView textOne;
private Button ButtonOne;
private XMLRPCClient server;
private URI uri;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
uri = URI.create("http://www.pandorabots.com/pandora/talk-xml?botid=e80e92407e341007");
server = new XMLRPCClient(uri);
editOne = (EditText) findViewById(R.id.editText1);
textOne = (TextView) findViewById(R.id.textView1);
ButtonOne = (Button) findViewById(R.id.button1);
textSatu.setText(getDataMethod("hi"));
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
private String getDataMethod(String num) {
String text = "";
try {
Log.w("Running server.call", "prosess");
Object[] data = (Object[]) server.call("input", num);
Log.w("server.call Run", "finish");
Log.w("Run HashMap", "prosess");
for(Object o: data) {
HashMap map = (HashMap) o;
Log.w("HashMap Berjalan", "Error");
text = text + "'that' => " + map.get("that") + "\n\n";
}
} catch (XMLRPCException e) {
Log.w("XMLRPC Test", "Error", e);
text = "XMLRPC error";
}
return text;
}
}
But i got error. It's say :org.xmlpull.v1.XmlPullParserException: expected: START_TAG {null}methodResponse (position:START_TAG #1:45 in java.io.InputStreamReader#41174280)
can anyone help me? please.
here is a solution that does not require XMLRPCClient. The important thing is to capture the customer ID on the first interaction with the bot, and then send the value of custid back with each subsequent transaction. The bot uses the custid to remember the local variables associated with a conversation thread, such as name, age, gender, topic etc.
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URI;
import java.net.URLEncoder;
public class PandorabotsTalkAPI {
public String defaultCustid = "0";
public String custid = defaultCustid;
public String responseFailed = "RESPONSE FAILED";
public String defaultBotId = "f5d922d97e345aa1";
public String defaultHost = "www.pandorabots.com";
public String askPandorabots(String input) {
return askPandorabots(input, defaultHost, defaultBotId);
}
public String askPandorabots(String input, String host, String botid) {
//System.out.println("Entering askPandorabots with input="+input+" host ="+host+" botid="+botid);
String responseContent = pandorabotsRequest(input, host, botid);
if (responseContent == null) return responseFailed;
else return pandorabotsResponse(responseContent, host, botid);
}
public String responseContent(String url) throws Exception {
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet();
request.setURI(new URI(url));
InputStream is = client.execute(request).getEntity().getContent();
BufferedReader inb = new BufferedReader(new InputStreamReader(is));
StringBuilder sb = new StringBuilder("");
String line;
String NL = System.getProperty("line.separator");
while ((line = inb.readLine()) != null) {
sb.append(line).append(NL);
}
inb.close();
return sb.toString();
}
public String spec(String host, String botid, String custid, String input) {
//System.out.println("--> custid = "+custid);
String spec = "";
try {
if (custid.equals("0")) // get custid on first transaction with Pandorabots
spec = String.format("%s?botid=%s&input=%s",
"http://" + host + "/pandora/talk-xml",
botid,
URLEncoder.encode(input, "UTF-8"));
else spec = // re-use custid on each subsequent interaction
String.format("%s?botid=%s&custid=%s&input=%s",
"http://" + host + "/pandora/talk-xml",
botid,
custid,
URLEncoder.encode(input, "UTF-8"));
} catch (Exception ex) {
ex.printStackTrace();
}
//System.out.println(spec);
return spec;
}
public String pandorabotsRequest(String input, String host, String botid) {
try {
String spec = spec(host, botid, custid, input);
//System.out.println("Spec = "+spec);
String responseContent = responseContent(spec);
return responseContent;
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
}
public String pandorabotsResponse (String xmlRpcResponse, String host, String botid) {
String botResponse = responseFailed;
try {
int n1 = xmlRpcResponse.indexOf("<that>");
int n2 = xmlRpcResponse.indexOf("</that>");
if (n2 > n1)
botResponse = xmlRpcResponse.substring(n1+"<that>".length(), n2);
n1 = xmlRpcResponse.indexOf("custid=");
if (n1 > 0) {
custid = xmlRpcResponse.substring(n1+"custid=\"".length(), xmlRpcResponse.length());
n2 = custid.indexOf("\"");
if (n2 > 0) custid = custid.substring(0, n2);
else custid = defaultCustid;
}
if (botResponse.endsWith(".")) botResponse = botResponse.substring(0, botResponse.length()-1); // snnoying Pandorabots extra "."
} catch (Exception ex) {
ex.printStackTrace();
}
return botResponse;
}
}
I am very new to Java/Android programming and need a little help with a part of code that I am writing. I have been following the "Parsing XML Data" article with no success.
The intent from "MainActivity.java" sends the string with XML text to my "ParsingXMLStringActivity.java" that I like to parse. Here is the string I successfully get over to the activity.
<action><app>survo</app><parameters><id>5666</id><p_t>205</p_t></parameters></action>
Now if wrote the public class XmlParser within the following "ParsingXMLStringActivity.java"
public class ParsingXMLStringActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_parsing_xmlstring);
// Get the message from the intent
Intent intent = getIntent();
String receivedXMLstring = intent.getStringExtra(MainActivity.Authorize.XML_STRING);
System.out.println("STRING:"+receivedXMLstring);
InputStream in_stream;
try {
in_stream = new ByteArrayInputStream(receivedXMLstring.getBytes("UTF-8"));
System.out.println("STREAM:"+ in_stream);
XmlParser XmlParser = new XmlParser();
System.out.println("XmlParser:"+ XmlParser);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} // OnCreate
public class XmlParser {
public final String ns = null;
public List<Entry> parse (InputStream in_stream) throws XmlPullParserException, IOException {
try {
XmlPullParser parser = Xml.newPullParser();
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, false);
parser.setInput(in_stream, null);
parser.nextTag();
return readAction(parser);
} finally {
in_stream.close();
}
} // Public List Parse
private List<Entry> readAction(XmlPullParser parser) throws XmlPullParserException, IOException {
List<Entry> action = new ArrayList<Entry>();
parser.require(XmlPullParser.START_TAG, ns, "action");
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
String name = parser.getName();
// Starts by looking for the entry tag
if (name.equals("action")) {
action.add(readParameters(parser));
} else {
skip(parser);
}
}
System.out.println("ACTION: "+action);
return action;
} // Public List ReadAction
private void skip(XmlPullParser parser) throws XmlPullParserException, IOException {
if (parser.getEventType() != XmlPullParser.START_TAG) {
throw new IllegalStateException();
}
int depth = 1;
while (depth != 0) {
switch (parser.next()) {
case XmlPullParser.END_TAG:
depth--;
break;
case XmlPullParser.START_TAG:
depth++;
break;
}
}
} //Private Void Skip
public class Entry {
public final String id;
public final String pt;
private Entry(String id, String pt) {
this.id = id;
this.pt = pt;
}
} // public static class Entry
private Entry readParameters(XmlPullParser parser) throws XmlPullParserException, IOException {
parser.require(XmlPullParser.START_TAG, ns, "entry");
String id = null;
String pt = null;
while (parser.next() != XmlPullParser.END_TAG) {
if (parser.getEventType() != XmlPullParser.START_TAG) {
continue;
}
String name = parser.getName();
if (name.equals("id")) {
id = readId(parser);
System.out.println("ID: "+ id);
} else if (name.equals("p_t")) {
pt = readPT(parser);
System.out.println("P_T: "+ pt);
}
else {
skip(parser);
}
}
return new Entry(id, pt);
} // Private Entry
// Processes title tags in the feed.
private String readId(XmlPullParser parser) throws IOException, XmlPullParserException {
parser.require(XmlPullParser.START_TAG, ns, "id");
String id = readText(parser);
parser.require(XmlPullParser.END_TAG, ns, "id");
System.out.println(id);
return id;
}
private String readPT(XmlPullParser parser) throws IOException, XmlPullParserException {
parser.require(XmlPullParser.START_TAG, ns, "p_t");
String pt = readText(parser);
parser.require(XmlPullParser.END_TAG, ns, "p_t");
System.out.println(pt);
return pt;
}
private String readText(XmlPullParser parser) throws IOException, XmlPullParserException {
String result = "";
if (parser.next() == XmlPullParser.TEXT) {
result = parser.getText();
parser.nextTag();
}
System.out.println(result);
return result;
}
}
The System.out.println("ID: "+ id); are not giving any information to the LogCat and I have set break points to check if the parser is even started but it does not seem to start the parsing process with the string I supply.
Does someone have an idea and can tell me what part I am missing???
Kind regards, Ben