I have a class that implements a listener so that when another class that has an async tasks has been completed then the data can be returned with the use of this listener. The async task is being completed but the listener is not passing the data when it's obtained in the post execute function.
Async Task
Public class AdFetcher extends AsyncTask<String,Void,String>
{
private HTTPListener listener;
//sets the listeners
public AdFetcher(HTTPListener listener)
{
this.listener = listener;
}
#Override
protected String doInBackground(String... uri) {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
String responseString = null;
try {
response = httpclient.execute(new HttpGet(uri[0]));
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpStatus.SC_OK){
ByteArrayOutputStream out = new ByteArrayOutputStream();
response.getEntity().writeTo(out);
out.close();
responseString = out.toString();
} else{
//Closes the connection.
response.getEntity().getContent().close();
throw new IOException(statusLine.getReasonPhrase());
}
} catch (ClientProtocolException e) {
//TODO Handle problems..
} catch (IOException e) {
//TODO Handle problems..
}
return responseString;
}
#Override
protected void onPostExecute(String result)
{
//Tries to deserialization and if there is an exception then its added to the Stack Trace.
try
{
JSONObject data = new JSONObject(result);
if(listener==null)
throw new NullPointerException();
//Calls onComplete function in the class/Activity that implemented the listener.
listener.onComplete(data);
}
catch (JSONException e)
{
e.printStackTrace();
}
}
}
Listener
public interface HTTPListener{
/**
* Callback function that must be implemented
* to get result from HTTP worker thread.
* #param result
*/
public void onComplete (JSONObject result);
}//end HttpListener interface
Class Implementing the listener
public class AdManager implements HTTPListener
{
//will store the current context of the application.
private Context context;
private Utility utils;
private String url;
private WebView client;
public AdManager(Context context,WebView client)
{
this.client = client;
this.context = context;
}
public void getAd()
{
utils = new Utility();
url = utils.BuildUrl();
new AdFetcher(this).execute(url);
}
public void onComplete(JSONObject result)
{
try
{ Log.e("RESULTS",result.getString("adtype"));
if(result.getString("error") == "null")
{
if(result.getString("adtype") == "banner")
{ //loads the banner image in the webview.
String html = "<img src=\""+result.getString("adimage")+"\">";
String mime = "text/html";
String encoding = "utf-8";
client.setVisibility(View.VISIBLE);
client.getSettings().setJavaScriptEnabled(true);
client.loadDataWithBaseURL(null, html, mime, encoding, null);
}
}
}
catch (JSONException e)
{
e.printStackTrace();
}
}
}
Related
this code is ok for get data from server but if my API is POST Method how to pass params to server by POSt Request and fetch data. code is here, please let me know
public class GetTripTeportData extends AsyncTask<String, Integer,String> {
#Override
protected void onPreExecute() {...}
#Override
protected String doInBackground(String... params) {
String responseBodyText = null;
OkHttpClient client = new OkHttpClient();
try {
Request request = new Request.Builder().url(excelApi).build();
Response response = null;
response = client.newCall(request).execute();//.....
responseBodyText = response.body().string();
JSONObject resultData = new JSONObject(responseBodyText);
JSONArray itemArray = resultData.getJSONArray("data");
for (int i=0; i<itemArray.length();i++){
JSONObject jobject = itemArray.getJSONObject(i);
String iduser = jobject.getString("id");
String vehicleno = jobject.getString("vehicleno");
String startdate = jobject.getString("startdate");
allList.add(new ExcelReportAdminResponse(iduser,vehicleno,startdate));
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
#Override
public void run() {
}
});
return responseBodyText;
}
#Override
protected void onPostExecute(String s) {......}
}
To post data with default http client with async task you can do as below:
First create network utility class as below:
public class NetworkUtilities {
public static String postData(String Url, String message ){
try {
URL url = new URL(Url);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000); /*milliseconds*/
conn.setConnectTimeout(15000); /* milliseconds */
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setFixedLengthStreamingMode(message.getBytes().length);
conn.setRequestProperty("Content-Type", "application/json;charset=utf-8");
conn.setRequestProperty("X-Requested-With", "XMLHttpRequest");
conn.connect();
OutputStream os = new BufferedOutputStream(conn.getOutputStream());
os.write(message.getBytes());
os.flush();
InputStream is = conn.getInputStream();
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
catch (Exception e){
Log.e("Exception: " , e.toString());
}
finally {
// os.close();
//is.close();
//conn.disconnect();
}
return "";
}
}
Then write async task to call that postData() method from NetworkUtilities class as below:
private class PostDataAsync extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
return NetworkUtilities.postData(params[0], params[1]);
}
#Override
protected void onPostExecute(String result) {
Log.e("Data response: ", result);
}
#Override
protected void onPreExecute() {
// TODO: Loader and stuff to add later here.
}
#Override
protected void onProgressUpdate(Void... values) {
}
}
Then to call that async task means to call api do as below:
String message = "";
try {
JSONObject jsonBody = new JSONObject();
jsonBody.put("user_id", session.getSession());
message = jsonBody.toString();
} catch (Exception e) {
Log.e("JSON error: ", e.toString());
}
PostDataAsync postData = new PostDataAsync();
postData.execute("YOUR_POST_API_URL_HERE", message);
By using this way you can be able to post data with async task.
For POST call with JSON body
final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
RequestBody body = RequestBody.create(JSON, /*YOUR JSON REQUEST*/ jsonString);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
try {
Response response = client.newCall(request).execute();
} catch(IOException io){
// do something
}
I'm trying to create a library for my apps, in all my apps have push notification.
I would like to take this package and create a library
In GCM do I have any limitations? Because it looks like it gets the package name to generate ID_TOKEN
I have an APP that has a package with the classes I use for PUSH notification, it works perfectly!
Now I've migrated this package and created a library, because so all other apps are just pointing the lib and it will be working.
Only that for some reason he does not call the lib, I've done everything and I can not.
The code to register the ID in GCM and start the service is this below:
Intent intent = new Intent(this, RegistrationIntentService.class);
startService(intent);
This code above is in my MainActivity
I thought that by doing so he would already call the library
EDIT:
I am using Eclipse and GCM
My class `RegistrationIntentService`
public class RegistrationIntentService extends IntentService {
private static final String TAG = "RegServicePush";
String newRegID = "";
String GetEmail = "";
public RegistrationIntentService() {
super(TAG);
}
#Override
protected void onHandleIntent(Intent intent) {
try {
InstanceID instanceID = InstanceID.getInstance(this);
String token = instanceID.getToken(Constants.GCM_SENDER_ID, GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
// TODO: Implement this method to send any registration to your
// app's servers.
sendRegistrationToServer(token, email);
} catch (Exception e) {
Log.d(TAG, "Failed to complete token refresh", e);
}
// Notify UI that registration has completed, so the progress indicator
// can be hidden.
}
private void sendRegistrationToServer(String token, String email) {
//MainActivity.newRegID = token;
WebServerRegistrationTask webServer = new WebServerRegistrationTask();
webServer.execute();
}
public class WebServerRegistrationTask extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
SharedPreferences sharedPreferences = PreferenceManager
.getDefaultSharedPreferences(RegistrationIntentService.this);
URL url = null;
try {
url = new URL(Constants.WEB_SERVER_URL);
} catch (MalformedURLException e) {
e.printStackTrace();
sharedPreferences.edit().putString(Constants.PREF_GCM_REG_ID, "").apply();
}
Map<String, String> dataMap = new HashMap<String, String>();
dataMap.put("regID", newRegID);
dataMap.put("appID", Constants.APP_ID);
StringBuilder postBody = new StringBuilder();
Iterator<Map.Entry<String, String>> iterator = dataMap.entrySet().iterator();
while (iterator.hasNext()) {
Entry<String, String> param = (Entry<String, String>) iterator.next();
postBody.append(param.getKey()).append('=').append(param.getValue());
if (iterator.hasNext()) {
postBody.append('&');
}
}
String body = postBody.toString();
byte[] bytes = body.getBytes();
HttpURLConnection conn = null;
try {
conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setFixedLengthStreamingMode(bytes.length);
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
OutputStream out = conn.getOutputStream();
out.write(bytes);
out.close();
String response = "";
InputStream is = null;
try {
is = conn.getInputStream();
int ch;
StringBuffer sb = new StringBuffer();
while ((ch = is.read()) != -1) {
sb.append((char) ch);
}
response = sb.toString();
} catch (IOException e) {
throw e;
} finally {
if (is != null) {
is.close();
}
}
int status = conn.getResponseCode();
if (status == 200) {
if (response.equals("1")) {
sharedPreferences.edit().putString(Constants.PREF_GCM_REG_ID, newRegID).apply();
Intent registrationComplete = new Intent(Constants.SERVER_SUCCESS);
LocalBroadcastManager.getInstance(RegistrationIntentService.this)
.sendBroadcast(registrationComplete);
}
} else {
throw new IOException("Request failed with error code " + status);
}
} catch (ProtocolException pe) {
pe.printStackTrace();
sharedPreferences.edit().putString(Constants.PREF_GCM_REG_ID, "").apply();
} catch (IOException io) {
io.printStackTrace();
sharedPreferences.edit().putString(Constants.PREF_GCM_REG_ID, "").apply();
} finally {
if (conn != null) {
conn.disconnect();
}
}
return null;
}
}
}
I got requirement to make asynchronous http call in my bolt.
In this bolt only async http call to be made and after getting response it should insert to elastic search.
i followed the this link here is pseudocode.
public void prepare(Map arg0, TopologyContext context,
OutputCollector collector) {
httpclient = HttpAsyncClients.createDefault();
httpclient.start();
_collector = collector;
}
public void execute(Tuple tuple) {
try{
if( !isTickTuple(tuple) ) {
data = (data)tuple.getValueByField("source");
httpCall(data,"http://");
}
}catch(Exception e){
logger.warn(e.getMessage());
if(logger.isDebugEnabled())logger.debug(e.getMessage(),e);
}finally{
_collector.ack(tuple);
}
}
public void httpCall(String data,String url) {
HttpPost postRequest = new HttpPost(url);
HttpEntity httpEntity = null;
//CloseableHttpAsyncClient httpclient = HttpAsyncClients.createDefault();
postRequest.addHeader("content-type", "application/json");
postRequest.setEntity(httpEntity);
HttpAsyncRequestProducer producer = HttpAsyncMethods.create(postRequest);
AsyncCharConsumer<HttpResponse> consumer = new AsyncCharConsumer<HttpResponse>() {
HttpResponse response;
#Override
protected void onResponseReceived(final HttpResponse response) {
this.response = response;
}
#Override
protected void onCharReceived( CharBuffer buf, IOControl ioctrl) throws IOException {
// Do something useful
}
#Override
protected void releaseResources() {
}
#Override
protected HttpResponse buildResult( HttpContext context) {
return this.response;
}
};
httpclient.execute(producer, consumer, new FutureCallback<HttpResponse>() {
#Override
public void completed(HttpResponse response) {
int responseCode = response.getStatusLine().getStatusCode();
if(logger.isDebugEnabled())logger.debug("Response code::"+responseCode );
if (responseCode == HttpServletResponse.SC_OK) {
HttpEntity entity = response.getEntity();
try {
String data = EntityUtils.toString(entity, "UTF-8");
if(logger.isDebugEnabled())logger.debug("Response string");
updatedata(data);
} catch (ParseException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
if(logger.isDebugEnabled())logger.debug("completed Method:::: "+response.toString());
}
#Override
public void failed(Exception ex) {
if(logger.isDebugEnabled())logger.debug("!!! Async http request failed!", ex);
}
#Override
public void cancelled() {
if(logger.isDebugEnabled())logger.debug("Async http request canceled!");
}
});
}
here response code(200) is printing in log but the logger after this line
String data = EntityUtils.toString(entity, "UTF-8");
is not printing. Can any body provide link or code with better approach.
Updated:
i added logger inside onCharReceived method Its printing the Response now chunk by chunk.
Can anyone tell how to get complete response or should use other library.
I'm trying to get data through web services, So that I'm using below shown asynctask calls. It gives me a null point exception as shown in the below screen shot. What can be the issue?
Activity class
new PickupAsyncTask(getApplicationContext(), null).execute();
Asynctask class
public class PickupAsyncTask extends AsyncTask<String, Integer, JSONArray> {
private OnTaskCompleted listener;
private JSONArray responseJson = null;
private Context contxt;
private Activity activity;
public PickupAsyncTask(Context context, OnTaskCompleted listener) {
// API = apiURL;
this.contxt = context;
this.listener = listener;
}
// async task to accept string array from context array
#Override
protected JSONArray doInBackground(String... params) {
String path = null;
String response = null;
HashMap<String, String> request = null;
JSONObject requestJson = null;
DefaultHttpClient httpClient = null;
HttpPost httpPost = null;
StringEntity requestString = null;
ResponseHandler<String> responseHandler = null;
try {
path = "http://xxxxxxxxxxxxxxx/LocationService.svc/StreetDetails";
new URL(path);
} catch (MalformedURLException e) {
e.printStackTrace();
}
try {
// set the API request
request = new HashMap<String, String>();
request.entrySet().iterator();
// Store locations in JSON
requestJson = new JSONObject(request);
httpClient = new DefaultHttpClient();
httpPost = new HttpPost(path);
requestString = new StringEntity(requestJson.toString());
// sets the post request as the resulting string
httpPost.setEntity(requestString);
httpPost.setHeader("Content-type", "application/json");
// Handles the response
responseHandler = new BasicResponseHandler();
response = httpClient.execute(httpPost, responseHandler);
responseJson = new JSONArray(response);
System.out.println("*****JARRAY*****" + responseJson.length());
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
return responseJson;
}
#Override
protected void onPostExecute(JSONArray result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
listener.onTaskCompleted(responseJson); //line 101
}
}
OnTaskCompleted.java
public interface OnTaskCompleted {
void onTaskCompleted(JSONArray responseJson);
}
listener is null. Introduce a check to verify that listener is not null before calling any methods on it.
Edit
If you want to handle the task completion, pass an anonymous object of OnTaskCompleted to PickupAsyncTask constructor as follows:
new PickupAsyncTask(context, new OnTaskCompleted() {
#Override
public void onTaskCompleted(JsonArray response) {
//Handle the task completion
}
}).execute();
My app is currently crashing whenever it cannot connect to the server. How do I handle this, and instead let the user know that the server is down and to try again.
private void sendPostRequest(String givenEmail, String givenPassword) {
class SendPostRequestTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
String emailInput = params[0];
String passwordInput = params[1];
String jsonUserInput = "{email: " + emailInput + ", password: "
+ passwordInput + "}";
try {
HttpClient httpClient = new DefaultHttpClient();
// Use only the web page URL as the parameter of the
// HttpPost argument, since it's a post method.
HttpPost httpPost = new HttpPost(SERVER_URL);
// We add the content that we want to pass with the POST
// request to as name-value pairs
json = new JSONObject(jsonUserInput);
jsonString = new StringEntity(json.toString());
httpPost.setEntity(jsonString);
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("Content-type", "application/json");
HttpParams httpParameters = httpPost.getParams();
// Set the timeout in milliseconds until a connection is established.
int timeoutConnection = 1000;
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
// Set the default socket timeout (SO_TIMEOUT)
// in milliseconds which is the timeout for waiting for data.
int timeoutSocket = 1000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
// HttpResponse is an interface just like HttpPost.
// Therefore we can't initialize them
HttpResponse httpResponse = httpClient.execute(httpPost);
// According to the JAVA API, InputStream constructor does
// nothing.
// So we can't initialize InputStream although it is not an
// interface
InputStream inputStream = httpResponse.getEntity()
.getContent();
InputStreamReader inputStreamReader = new InputStreamReader(
inputStream);
BufferedReader bufferedReader = new BufferedReader(
inputStreamReader);
StringBuilder stringBuilder = new StringBuilder();
String bufferedStrChunk = null;
while ((bufferedStrChunk = bufferedReader.readLine()) != null) {
stringBuilder.append(bufferedStrChunk);
}
return stringBuilder.toString();
} catch (ClientProtocolException cpe) {
Log.i(LOGIN, "ClientProtocolException");
cpe.printStackTrace();
} catch (ConnectTimeoutException e) {
e.printStackTrace();
} catch (IOException ioe) {
Log.i(LOGIN, "IOException");
ioe.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
Log.i(LOGIN, result);
try {
serverResponse = new JSONObject(result);
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if ((serverResponse.has("status"))
&& (serverResponse.get("status").toString()
.equals("200"))) {
Toast.makeText(getApplicationContext(), "SUCCESS!",
Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(),
"Incorrect Email/Password!!!",
Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
SendPostRequestTask sendPostRequestTask = new SendPostRequestTask();
sendPostRequestTask.execute(givenEmail, givenPassword);
}
LogCat Error Log
11-11 16:26:14.970: I/R.id.login_button(17379): IOException
11-11 16:26:14.970: W/System.err(17379): org.apache.http.conn.HttpHostConnectException: Connection to http://* refused
11-11 16:26:14.980: W/System.err(17379): at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:183)
I can see that you are already catching the Exceptions and have a String as parameter type to onPostExecute. From inside the exceptions, you can pass a string like "error" to the onPostExecute, whenever an error occurs. Inside the onPostExecute you can check:
if the string is equal to "error":
then create a Alert dialog box from within `onPostExecute` and show it.
else:
continue as desired
Ideally a boolean would do the trick but since you already have a string, you can also use that. Otherwise you can have a struct with a string and a boolean and then pass it to onPostExecute. Hope it gives you the idea.
Or you can create new Object
public class AsyncTaskResult<T> {
private T result;
private Exception error;
public T getResult() {
return result;
}
public Exception getError() {
return error;
}
public AsyncTaskResult(T result) {
super();
this.result = result;
}
public AsyncTaskResult(Exception error) {
super();
this.error = error;
}
public void setError(Exception error) {
this.error = error;
}
}
and pass it to onPostExecute
return new AsyncTaskResult<String>(result)
or
return new AsyncTaskResult<String>(exception)
in onPostExecute you may check exception exists or not
asynctaskresult.getError() != null
You can use droidQuery to simplify everything and include HTTP error handling:
$.ajax(new AjaxOptions().url("http://www.example.com")
.type("POST")
.dataType("json")
.header("Accept", "application/json")
.header("Content-type", "application/json")
.timeout(1000)
.success(new Function() {
#Override
public void invoke($ d, Object... args) {
Toast.makeText(this, "SUCCESS!", Toast.LENGTH_SHORT).show();
JSONObject serverResponse = (JSONObject) args[0];
//handle response
}
})
.error(new Function() {
#Override
public void invoke($ d, Object... args) {
AjaxError error = (AjaxError) args[0];
//toast shows the error code and reason, such as "Error 404: Page not found"
Toast.makeText(this, "Error " + error.status + ": " + error.reason, Toast.LENGTH_SHORT).show();
}
}));