I'm really new working with Android, so there's a lot that's confusing me. I've looked at what seems like 100 tutorials and examples of how to get information from a web service on Android, but what I need is something for a guy that doesn't have a clue. Here are a couple of things in particular that I'm not getting:
I don't know what to do with XML files.. meaning, once I do the Java work, is that all that needs to be done? or does anything need to be changed in the XML files?
Seems like maybe I'm supposed to create a new class for some of these tutorials, but I'm not sure, and if so, I'm not sure what to do once I've made the class
I want to retrieve the information in JSON format. For right now as long as I can get just that information that's fine, I can learn how to work with JSON later.
It seems like kSoap2 is the best way to do this. I have the jar file that's needed to work with it
I've delved a little into phonegap, so if there's an answer that uses that, then I can work with that
My web service is working properly, and is essentially the same as what I've seen in a number of tutorials, so there's no problem there.
If anyone can point me to a tutorial that will help me out to learn ALL that I need to know to create a sample app that gets information from my web service, or if anyone is willing to walk me through it, I would greatly appreciate it!
Thanks in advance!
Initially you have to make an http connection so that you can get the response from your api be it xml response or json response. You can use the following code for it.
Keep the class separate than activity. :-
public class Response {
String get_url, response;
Activity activity;
public Response(String url){
this.get_url = url;
}
public String getResponse(){
InputStream in = null;
byte[] data = new byte[1000];
try {
URL url = new URL(get_url);
URLConnection conn = url.openConnection();
conn.connect();
/* conn.*/
in = conn.getInputStream();
Log.d("Buffer Size +++++++++++++", ""+in.toString().length());
BufferedReader rd = new BufferedReader(new InputStreamReader(in),in.toString().length());
String line;
StringBuilder sb = new StringBuilder();
while ((line = rd.readLine()) != null) {
sb.append(line);
}
rd.close();
response = sb.toString();
in.read(data);
Log.d("INPUT STREAM PROFILE RESPONSE",response);
in.close();
} catch (IOException e1) {
Log.d("CONNECTION ERROR", "+++++++++++++++++++++++++++");
// TODO Auto-generated catch block
e1.printStackTrace();
}
return response;
}
}
You may call the class in your activity like this :-
Response res = new Response("your_url");
String getResponse = res.getResponse();
So here you get the response from the api.
Now Lets make the parser
//Extend the class with Default Handler
public class XMLParser extends DefaultHandler {
//You must have basic knowledge about Array List and setter/getter methods
// This is where the data will be stored
ArrayList<Item> itemsList;
Item item;
String data;
String type;
private String tempVal;
//Create the Constructor
public XMLParser(String data){
itemsList = new ArrayList<Item>();
this.data = data;
}
public byte parse(){
SAXParserFactory spf = null;
SAXParser sp = null;
InputStream inputStream = null;
try {
inputStream = new ByteArrayInputStream(data.getBytes());
spf = SAXParserFactory.newInstance();
if (spf != null) {
sp = spf.newSAXParser();
sp.parse(inputStream, this);
}
}
/*
* Exceptions need to be handled MalformedURLException
* ParserConfigurationException IOException SAXException
*/
catch (Exception e) {
System.out.println("Exception: " + e);
e.printStackTrace();
} finally {
try {
if (inputStream != null)
inputStream.close();
} catch (Exception e) {
}
}
if (itemsList != null && itemsList.size() > 0) {
// //Log.d("Array List Size",""+tipsList.get(4).getTitle());
return 1;
} else {
return 0;
}
}
public ArrayList<Item> getItemList(){
return itemsList;
}
// Here you can check for the xml Tags
#Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
if(localName.equalsIgnoreCase("item")){
item = new Item();
Log.d("Working", "+++++++++++++++++++++++");
}
}
//tempVal is the variable which stores text temporarily and you
// may save the data in arraylists
public void characters(char[] ch, int start, int length)
throws SAXException {
tempVal = new String(ch, start, length);
}
#Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
if(localName.equalsIgnoreCase("item")){
itemsList.add(item);
Log.d("Working in endelement", "+++++++++++++++++++++++");
item.setTitle(tempVal);
}
}
Combining all this :-
Now lets see the activity
public void oncreate(){
// Do something or mostly the basic code
// Call the class to initate the connection and get the data
FetchList fl = new FetchList();
fl.execute();
}
//Always better to use async task for these purposes
public class FetchList extends asyncTask<Void,Void,Byte>{
doinbackground{
// this was explained in first step
Response res = new Response("url");
String response = res.getResponse();
XmlParser xml = new XmlParser(response);
ArrayList<item> itemList = xml.getItemList();
xml.parse();
}
}
Well that is all to it.
Related
I am storing the data that I parsed from the JSON that is returned by my API request into the Firebase database.
submitButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String APIURL = "https://api.github.com/users/" + idInput.getText().toString();
String repoURL = "https://api.github.com/users/" + idInput.getText().toString() + "/repos";
new JSONTask().execute(APIURL);
//new JSONTask().execute(repoURL);
String parsedUserID = idInput.getText().toString();
SM.sendDataToProfile(parsedUserID);
viewPager.setCurrentItem(1);
//addUser(parsedUserID);
}
});
When the button is clicked, it calls a new JSONTask (asynctask) on the APIURL.
JSONTask
public class JSONTask extends AsyncTask<String, String, String> {
#Override
// Any non-UI thread process is running in this method. After completion, it sends the result to OnPostExecute
protected String doInBackground(String... params) {
HttpURLConnection connection = null;
BufferedReader reader = null;
try {
// Pass in a String and convert to URL
URL url = new URL(params[0]);
connection = (HttpURLConnection) url.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
// Reads the data line by line
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer strBuffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
strBuffer.append(line);
}
// If we are able to get the data do below :
String retreivedJson = strBuffer.toString();
return retreivedJson;
// When we are not able to retreive the Data
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (connection != null) {
// close both connection and the reader
connection.disconnect();
}
try {
if (reader != null) {
reader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
And it does parsing in another function.
My question is, as you can see on my setOnClickListener, I tried to make two JSONTask on two different URLs because the first URL gives me the information of the user and the second URL (repoURL) gives me the information of the user's repositories. I tried to fetch the repo info of the user and store it into the DB, but it seems like this is a wrong approach.
What is a right way to call two separate AsyncTasks on two different URLs?
EDIT
private void addUserRepo(final String githubID, final String[] repoList) {
DatabaseReference users = databaseReference.child("users");
users.addListenerForSingleValueEvent(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
List list = new ArrayList<String>(Arrays.asList(repoList));
databaseReference.child("users").child(githubID).child("Repos").setValue(list);
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
}
Using data parsed from
public void formatJSONArray(String results){
try {
JSONArray jsonArray = new JSONArray(results);
RepoInfo[] repoList = new RepoInfo[jsonArray.length()];
for(int i = 0; i < jsonArray.length(); i++){
JSONObject jsonObject=jsonArray.getJSONObject(i);
if(jsonObject.optString("name") != null) {
repoList[i].setRepoName(jsonObject.getString("name"));
//repoNameList.add(jsonObject.getString("name"));
}
if(jsonObject.optString("description") != null) {
repoList[i].setDescription(jsonObject.getString("description"));
//descriptionList.add(jsonObject.getString("description"));
}
if(jsonObject.optJSONObject("owner") != null){
JSONObject ownerObject=jsonObject.getJSONObject("owner");
if(ownerObject.optString("login")!=null) {
repoList[i].setOwner(ownerObject.getString("login"));
//userNameList.add(ownerObject.getString("login"));
}
}
}
} catch (JSONException jsonException){
}
}
The response of two different URLs will surely not be similar. So you need different parse methods for them.
One lazy way would be to use two different AsyncTasks subclasses for two different urls.
Another way would be to store a flag inside the asynctask indicating whether it is dealing with user or repo.
public class JSONTask extends AsyncTask <String , String , String> {
boolean fetchingRepo;
#Override
protected String doInBackground (String... params) {
fetchingRepo = params[0].endsWith("/repos");
//other statements
}
Now inside onPostExecute:
if(fetchingRepo){
//parse one way
} else {
//parse another way
}
So here in Java I've written a typical class, to send json to a rest server. (I'll include the whole class below for clarity.) So that's a file "Fetcher.java"
Now for the callback you need an interface. The interface is trivial, just one function with a string.
public interface FetcherInterface {
public void fetcherDone(String result);
}
Annoyingly you need a whole file for that, "FetcherInterface.java"
So this interface is nothing but "one callback with a string". Often all you need is just "one callback with no arguments".
In fact ........ are there some sort of standard interfaces I can use, or something like that?
It seems kind of annoying to have to put in a whole interface for such a simple "standard" interface.
What's the deal on this? What's the javaly solution?
It seems you CAN NOT put it in the same file:
Perhaps I misunderstand something there. If you could put it in the same file, that would be convenient at least.
(Lambdas are not yet practically available. Anyway, sometimes you want an interface.)
Just for clarity, here's how you call the class
JSONObject j = new JSONObject();
try {
j.put("height", 2.1);
j.put("width", 2.5);
j.put("command", "blah");
} catch (JSONException e) {
e.printStackTrace();
}
new Fetcher("mobile/login", j, new FetcherInterface() {
#Override
public void fetcherDone(String result) {
Log.d("DEV","all done");
doSomething(result);
}
}
).execute();
or indeed
public class HappyClass extends Activity implements FetcherInterface {
...
private void someCall() {
JSONObject j = new JSONObject();
try {
j.put("height", 2.1);
j.put("width", 2.5);
j.put("command", "blah");
} catch (JSONException e) {
e.printStackTrace();
}
new Fetcher("mobile/data", j, this).execute();
devBlank();
}
#Override
public void fetcherDone(String result) {
Log.d("DEV","all done" +result);
doSomething(result);
}
Here's the whole class... Fetcher.java file
public class Fetcher extends AsyncTask<Void, Void, String> {
private String urlTail;
private JSONObject jsonToSend;
private FetcherInterface callback;
// initializer...
Fetcher(String ut, JSONObject toSend, FetcherInterface cb) {
urlTail = ut;
jsonToSend = toSend;
callback = cb;
}
#Override
protected String doInBackground(Void... params) {
HttpURLConnection urlConnection = null; // declare outside try, to close in finally
BufferedReader reader = null; // declare outside try, to close in finally
String rawJsonResultString = null;
String json = jsonToSend.toString();
Log.d("DEV","the json string in Fetcher is " +json);
try {
URL url = new URL("https://falcon.totalfsm.com/" + urlTail);
Log.d("DEV","the full URL in Fetcher is " +url);
// open a json-in-the-body type of connection.......
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("POST");
urlConnection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
urlConnection.setDoOutput(true);
urlConnection.setDoInput(true);
urlConnection.setConnectTimeout(5000);
// urlConnection.setDoOutput(false); // can be important?
urlConnection.connect();
OutputStream os = urlConnection.getOutputStream();
os.write(json.getBytes("UTF-8"));
os.close();
// annoyingly, you have to choose normal versus error stream...
InputStream inputStream;
int status = urlConnection.getResponseCode();
if (status != HttpURLConnection.HTTP_OK)
inputStream = urlConnection.getErrorStream();
else
inputStream = urlConnection.getInputStream();
if (inputStream == null) { // nothing to do.
return null;
}
StringBuffer buffer = new StringBuffer();
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) { // adding newlines makes debugging easier
buffer.append(line + "\n");
}
if (buffer.length() == 0) { // stream was empty
return null;
}
rawJsonResultString = buffer.toString();
return rawJsonResultString;
} catch (IOException e) {
Log.e("PlaceholderFragment", "Error ", e);
return null;
} finally{
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
Log.e("PlaceholderFragment", "Error closing stream", e);
}
}
}
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
Log.d("DEV", "Fetcher done");
if (s==null) {
Log.d("DEV","applying anti-null measures in Fetcher!");
s = "message from app communications layer: 'null' returned from servers for that call at " +urlTail;
}
callback.fetcherDone(s);
}
}
I feel bad answering my own question, but as there were no other answers this info may be helpful.
DaveNewton and Rowtang have supplied the exact answers here:
(Point 1) If you want a genuinely public interface, it goes in its own file. That's how Java works. There's no alternative.
(Point 2) Normally, use protected interface and declare the interface inside the class. It can then be used throughout the app.
So...
public class Fetcher extends AsyncTask<Void, Void, String> {
protected interface FetcherInterface {
public void fetcherDone(String result);
}
private String urlTail;
private JSONObject jsonToSend;
private FetcherInterface callback;
Fetcher(String ut, JSONObject toSend, FetcherInterface cb) {
urlTail = ut;
jsonToSend = toSend;
callback = cb;
}
#Override
protected String doInBackground(Void... params) {
....
(c# programmers would maybe call it "IFetcher".)
I am following the tutorials from Tutplus and youtube on Android WeatherApp creation. Please find my code below. I am trying to connect to OpenWeatherMap and get JSON weather data. Here are my problems:
Its not working.
Is this the right way to create the URL for accessing OpenWeatherMap.
When I registered with the OpenWeatherMap, it gave me a KEY. I am not sure what to do with that. I used it in my code, after getting the httpurlconnection from the server for setting "x-api-key". Don't know if its needed or am doing it
when i get the inputstream, the reader is null and the application hangs after that.
Here is the code:
public class WeatherGrabber {
private static final String TAG = "WeatherGrabber";
private static final String CURRENT_WEATHER_URL =
"http://api.openweathermap.org/data/2.5/weather?q=%s&mode=json";
private static BufferedReader reader;
private static final String my_key = "307ec986e69c22c9a24a1bcf9edd21ea";
public static String loadCurrentWeather(Context context, String city) {
String data = null;
try{
URL web_url = new URL(String.format(CURRENT_WEATHER_URL, city) );
HttpURLConnection conn = (HttpURLConnection)
web_url.openConnection();
conn.addRequestProperty("x-api-key", my_key);
reader = new BufferedReader(new
InputStreamReader(conn.getInputStream()));
String inputLine;
StringBuffer json = new StringBuffer();
while((inputLine = reader.readLine() )!= null){
json.append(inputLine).append("\n");
}
data = json.toString();
}catch (IOException e){
e.printStackTrace();
}finally {
try {
if (in != null)
in.close();
}catch (Exception e) {
e.printStackTrace();
}
}
return data;
}// end of loadCurrentWeather() method
}
You can't run network requests directly on the main thread. You need to use AsyncTask class to do this.
Create a class in you activity
private class LoadCurrentWeatherAsync extends AsyncTask<Void, Void, String>{
#Override
protected String doInBackground(Void... params) {
try {
//Call to your function here
return loadCurrentWeather(MainActivity.this, "newyork");
} catch (Exception e){
return e.toString();
}
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
//Do what ever you what with this output
Log.d("data", s);
}
}
Then call it inside your activity onCreate method
new LoadCurrentWeatherAsync().execute();
Also make sure that you have enabled the internet permissions in AndroidManifest.xml . Inside the manifest tag insert
<uses-permission android:name="android.permission.INTERNET" />
It's ok
They use the api key to track whether request is from free or paid plan.
I suspect that's because you are sending the network request on main thread. Try the above code
(i'm trying to say hello, but the site keeps deleting it oO)... !
Here is my question : I found out how to send a request to a webservice using ksoap, but i still cannot figure out where to add my XML to the request !
Here is my code :
public static SoapObject soap () throws IOException, XmlPullParserException {
SoapObject request = new SoapObject (NAMESPACE, METHOD_NAME);
/* HERE IS THE PROBLEM */
request.addProperty(toto, HERE IS MY XML);
SoapSerializationEnvelope envelope = new SoapSerializationEnvelope (
SoapEnvelope.VER11);
envelope.setOutputSoapObject (request);
HttpTransportSE androidHttpTransport = new HttpTransportSE (URL);
androidHttpTransport.debug = true;
androidHttpTransport.call (SOAP_ACTION, envelope);
SoapObject soapResult = (SoapObject) envelope.getResponse ();
return soapResult;
}
If i delete the "request.addProperty line", it reaches the server, but it does nothing, because i need to send my XML. If someone know how to do that, it would definitely make my day !!
Thanks you for reading this !
Maybe it doesn't help you with this particular issue, but I would not recommended using ksoap. I wasted so much time getting it to work and after that I wrote my SOAP client with few hours and it works without problem.
It's easy:
public static HashMap<String, Object> callSOAPServer(StringBuffer soap /* YOUR XML GOES HERE*/,String action) {
HashMap<String, Object> xMap = new HashMap<String, Object>();
byte[] result = null;
byte[] data = new byte[1024*1024];
HttpClient httpclient = new DefaultHttpClient(); /* Your probably need to edit client for your needs, like timeout, scheme, etc */
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
DataInputStream is = null;
boolean download = true;
HttpPost httppost = new HttpPost(/* YOUR URL GOES HERE */ );
httppost.setHeader("soapaction", action);
httppost.setHeader("Content-Type", "text/xml; charset=utf-8");
try {
HttpEntity entity = new StringEntity(soap.toString(),HTTP.UTF_8);
httppost.setEntity(entity);
HttpResponse response = httpclient.execute(httppost);
HttpEntity r_entity = response.getEntity();
if (r_entity != null) {
result = new byte[(int) r_entity.getContentLength()];
size = result.length;
if (r_entity.isStreaming()) {
is = new DataInputStream(r_entity.getContent());
while((count = is.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, count);
total +=count;
}
}
buffer.flush();
result = buffer.toByteArray();
data = null;
buffer = null;
}
} catch (Exception e) {
e.printStackTrace();
result = null;
}
if(result !=null){
try {
String sb;
String sn;
sb = new String(result, "UTF-8");
sn = sb.replace("&", "AMP"); //Precaution for SAX parser
result = sn.getBytes();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
xMap.put(STATUS, "OK");
xMap.put(SOAP, result);
}else{
if(xMap.get(STATUS) == null) {
xMap.put(STATUS, "ERROR");
}
}
httpclient.getConnectionManager().shutdown();
return xMap;
}
Here is parser:
public ArrayList< HashMap<String,String>> parseSoap (byte[] soapResult,String soapFunctionName, String... args) {
ArrayList< HashMap<String,String>> xMap = new ArrayList< HashMap<String,String>>();
if(soapResult == null) xMap.put(STATUS, "Where is stuff to handle");
byte[] initReqrepsonse = soapResult;
ByteArrayInputStream bais = new ByteArrayInputStream(initReqrepsonse);
SAXParserFactory spf = SAXParserFactory.newInstance();
try {
SAXParser sp = spf.newSAXParser();
XMLReader xr = sp.getXMLReader();
if(soapFunctionName.equals(NEWS)) { /*IF YOU USE MULTIPLE SOAP FUNCTION, YOU NEED TO DETERMINE WHICH IS WHICH...*/
NewsXMLHandler myXMLHandler = new NewsXMLHandler(); /*..BECAUSE HERE YOU NEED TO SPECIFY FIELDS WHICH YOU WANT TO RETRIEVE FROM XML*/
xr.setContentHandler(myXMLHandler);
xr.parse(new InputSource(bais));
xMap.put(SOAP_OUTPUT, myXMLHandler.getOutput());
myXMLHandler = null;
}
sp = null;
xr = null;
} catch (Exception e) {
e.printStackTrace();
}
spf = null;
return xMap;
}
And for that thing (NewsXMLHandler) which determines which fields you want to parse:
public class NewsXMLHandler extends DefaultHandler {
public NewsXMLHandler() {}
private ArrayList< HashMap<String,String> > data;
private HashMap<String,String> dataHash;
private final StringBuilder mStringBuilder = new StringBuilder();
private boolean bStore = false;
ArrayList< HashMap<String,String>> getOutput() {
return data;
}
#Override
public void startDocument() throws SAXException
{
data = new ArrayList< HashMap<String,String> >();
}
#Override
public void endDocument() throws SAXException
{
}
#Override
public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
mStringBuilder.setLength(0);
bStore = true;
try {
//HERE YOU NEED TO SPECIFY WHICH IS ROOT NODE OF XML FROM SOAP, IN MY EXPERIENCE ITS OUT
if(localName.equalsIgnoreCase("out")) {
dataHash = new HashMap<String,String>();
}
} catch (Exception e)
{
Log.d("error in startElement", e.getStackTrace().toString());
}
}
#Override
public void endElement(String namespaceURI, String localName, String qName) throws SAXException
{
bStore = false;
//HERE IT IS, JUST WRITE NAME OF NODE WHICH YOU WANT TO USE FOR YOUR APPLICATION
if (localName.equalsIgnoreCase("your node name"))
{
dataHash.put("your node name", mStringBuilder.toString().trim());
}
if (localName.equalsIgnoreCase("your node name 2"))
{
dataHash.put("your node name 2", mStringBuilder.toString().trim());
}
// CONTINUE WITH THOSE IFS UNTIL YOU HAVE ALL FIELDS WHICH YOU NEED COVERED
// HERE YOU WRAP ALL OF THOSE HIGHER NODE AND SAVE TO ARRAYLIST, SO IF THERE ARE MORE OF THEM, YOU GET THEM ALL - AGAIN ITS NAME OF ROOT NODE
if(localName.equalsIgnoreCase("out")) {
data.add(dataHash);
dataHash = null;
}
}
#Override
public void characters(char ch[], int start, int length)
{
if (bStore)
{
mStringBuilder.append(ch, start, length);
if(mStringBuilder.length() == 0) mStringBuilder.setLength(0);
}
}
}
And here goes the usage. As it seems you alredy figured out, you can't execute URL request on main thread. You just need to use AsyncTask, Service, IntentService, etc. I am not going to cover it here. I like to use IntentService and save entries to database.
So lets say, you wrap those two static function in class SOAPHandler:
HashMap<String, Object> SOAPResponse = SOAPHandler.callSOAPSERVER(/*YOUR XML REQUEST HERE*/, /*NAME OF SOAP METHOD ON SERVER*/)
ArrayList< HashMap<String,String>> parsedEntries = SOAPHandler.parseSoap(SOAPResponse, NEWS, NULL);
foreach(HashMap<String,String> hash : parsedEntries) {
String entryOne = hash.get("your node name");
String entryTwo = hash.get("your node name 2");
//HERE YOU HAVE YOUR STRINGS, DO WHATEVER WITH THEM
}
Here is Basic KSOAP Android tutorial, which should greatly assist with understanding how to use KSOAP to consume a web service.
What is important to note, is that you will not be able to send a raw xml packet using KSOAP but that the parameters need to be passed as PropertyInfo class instances.
HTH
I'm trying to see how works an Asynctask class in android. In particular i want reveal in real time the status of the class for see when it is running and when it has finished. For do this, i have created a class that extend the main activity and another class that is the asynctaks class.
This is my main class:
public class PhotoManagement extends Activity{
private String numberOfSelectedPhotos;
private Bitmap currentImage;
private String initConfiguration = "http://www.something.com";
private String response;
private ArrayList<String> formatPhotoList = new ArrayList<String>(); //create a list that will contains the available format of the photos downloaded from the server
private ArrayList<String> pricePhotoList = new ArrayList<String>(); //create a list that will contains the available price for each format of the photos
DownloadWebPageTask webPage = new DownloadWebPageTask();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
protected void onResume(){
super.onResume();
webPage.execute(initConfiguration);
if(webPage.getStatus() == AsyncTask.Status.PENDING){
Log.i("STATUS","PENDING");
}
if(webPage.getStatus() == AsyncTask.Status.RUNNING){
Log.i("","RUNNING");
}
if(webPage.getStatus() == AsyncTask.Status.FINISHED){
Log.i("","FINISHED");
}
}
}
As you can see i want only see the passages of the status with a simple log.
And here there is the asynctask class.
private class DownloadWebPageTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... urls) {
for (String url : urls) {
DefaultHttpClient client = new DefaultHttpClient(); //create a new http client
HttpGet httpGet = new HttpGet(url); //create a new http request passing a valid url
try {
HttpResponse execute = client.execute(httpGet); //try to execute the http get request
InputStream content = execute.getEntity().getContent(); //prepare the input stream to read the bytes of the request
BufferedReader buffer = new BufferedReader(
new InputStreamReader(content));
String s = "";
while ((s = buffer.readLine()) != null) {
response += s; //until is present a line to read, the response variable store the value of the lines
}
} catch (Exception e) {
Log.i("MyApp", "Download Exception : " + e.toString()); //Print the error if something goes wrong
}
}
return response; //return the response
}
#Override
protected void onPostExecute(String result) {
result = doInBackground(initConfiguration); //take the result from the DownloadWebPageTask class
result = result.replace("null", "");
Log.i("RESULT",""+result);
//find the price and format value from the result using XmlPullParser
try {
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
factory.setNamespaceAware(true);
XmlPullParser xpp = factory.newPullParser();
xpp.setInput( new StringReader ( result ) );
int attributeNumber = xpp.getAttributeCount();
int eventType = xpp.getEventType();
String currentTag = null;
while(eventType != XmlPullParser.END_DOCUMENT){
if(eventType == XmlPullParser.START_TAG) {
currentTag = xpp.getName();
if (currentTag.equals("product")){
xpp.getAttributeValue(null, "name");
formatPhotoList.add(xpp.getAttributeValue(null, "name"));
Log.i("FORMAT PHOTO",""+xpp.getAttributeValue(null, "name"));
}
}
eventType = xpp.next();
}
} catch (XmlPullParserException e) {
e.printStackTrace();
Log.i("","ERROR XML PULL PARSER");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.i("","ERROR IOEXCEPTION");
}
}
}
}
As you can see i have implemented also the method onPostExecute that should be called when the asynctask method has finished to execute the instructions right?
So at this point i don't understand why my log RUNNING and my log FINISHED never appear on the log cat.
What i'm doing wrong?
I'm tried to follow this topic Android, AsyncTask, check status? but in my case it isn't working.
Thanks
Problem :
You are creating object like
DownloadWebPageTask webPage = new DownloadWebPageTask();
But you are calling asynctask on different object,
new DownloadWebPageTask().execute(initConfiguration);
Solution :
It should be like
webPage.execute(initConfiguration);
#Override
protected void onResume(){
super.onResume();
new DownloadWebPageTask().execute(initConfiguration);
here do like this
#Override
protected void onResume(){
super.onResume();
webPage.execute(initConfiguration);
You didn't implement webPage.execute(), add it
Most probably the task hasn't finished or even started yet. As you probably know the AsyncTask is doing it's (background) work on a different thread, so your onResume is running in parallel with it. You can either use the task's get() method to wait for it to finish and get the result of the doInBackground() method and then query for it's status or notify your activity from the task's onPostExecute() method to let it know (and log) that it has finished. I don't recommend you the first option because it will actually block the UI thread and will make your usage of AsyncTask pointless.