Background:
I am new to android programming. I want to simply do an http get request to a local server.
I want to pass this request a name as a parameter and want to get a return in json. This issue that I cannot execute it on the main thread. How can I do this?
Here is what I tried:
main class:
itemsAdapter.add(get.getName(device.getName()));
Seperate class in same file:
private class httpGet extends AsyncTask<Editable, Void, Integer> {
protected String doInBackground(Editable... params) {
Editable editable = params[0];
return getName(editable.toString());
}
final String getName(String btName) {
HttpResponse response = null;
String result = "";
try {
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet();
URI website = new URI("http://192.168.1.105/getName.php?q=" + btName);
request.setURI(website);
response = client.execute(request);
// Convert String to json object
JSONObject json = new JSONObject(response.toString());
// get LL json object
JSONObject json_Name = json.getJSONObject("Name");
// get value from LL Json Object
name = json_Name.getString("value"); //<< get value here
} catch (URISyntaxException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
// Do something to recover ... or kill the app.
}
return result;
}
protected void onPostExecute(Integer result) {
// here you have the result
}
I am not sure if this is even a good way to do this task. I also have no idea how I would call it.
AsyncTask allows you to perform a background operation in a different thread without manipulating threads/handlers.
It should be this way:
private class httpGet extends AsyncTask<ParamForDoInBackground, ParamForOnProgressUpdate, ParamForOnPostExecute> {
protected Long doInBackground(ParamForDoInBackground... urls) {
// do the request here
}
protected void onProgressUpdate(ParamForOnProgressUpdate progress) {
// if you need to show any progress of the
// request from doInBackground
}
protected void onPostExecute(ParamForOnPostExecute result) {
// this method will run when doInBackground
// is done executing
}
}
Then you can execute an AsyncTask:
new httpGet().execute(ParamForDoInBackground);
You can use the following as a reference: AndroidBackgroundProcessing and Android Developer AsyncTask
You should learn how the asyncTask work. Inside DoInBackground you should to put the code referent to the HTTPRequest. I recommend to use methods to improve the understanding of code. Here is an example of one of my apps:
public String query(String uri) {
HttpClient cliente = new DefaultHttpClient();
HttpContext contexto = new BasicHttpContext();
HttpPost httpPost = new HttpPost(uri);
HttpResponse response = null;
String resultado=null;
try {
List<NameValuePair> params = new ArrayList<NameValuePair>(2);
params.add(new BasicNameValuePair("dato", cod_restaurante));
httpPost.setEntity(new UrlEncodedFormEntity(params));
response = cliente.execute(httpPost, contexto);
HttpEntity entity = response.getEntity();
resultado = EntityUtils.toString(entity, "UTF-8");
} catch (Exception e) {
// TODO: handle exception
}
return resultado;
}
private class MyAsyncTask extends AsyncTask<String, Integer, String>{
#Override
protected String doInBackground(String... params)
{
result=query(params[0]);
return result;
}
protected void onPostExecute(final String resultadoDoInBackground)
{
//here put the code to modify the UI
}
}
Then in your activity onCreate() method you execute the Asynktask.
new MyAsyncTask().execute(" ");
You can read more about AsyncTask here:
AsyncTask Android Developer
Related
I need to send a string obtained from EditText in android to the PHP to be used as an id to query the database. So, I got the string from EditText as follows:
childIDVal = childID.getText().toString();
Toast.makeText(getApplicationContext(),childIDVal,Toast.LENGTH_LONG).show();
// To do : transfer data to PHP
transferToPhp(childIDVal);
So, what should my transferToPhp() contain? And also the php code is:
<?php
if( isset($_POST["ChildID"]) ) {
$data = json_decode($_POST["ChildID"]);
$data->msg = strrev($data->msg);
echo json_encode($data);
}
Is it okay? I am a newbie to both android and Php, so i need some help right now. Thanks!
I' m offering you to use AsyncTask which reaches PHP file existing in your server using HttpClient:
/*Sending data to PHP and receives success result*/
private class AsyncDataClass extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
HttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, 5000);
HttpConnectionParams.setSoTimeout(httpParameters, 5000);
HttpClient httpClient = new DefaultHttpClient(httpParameters);
HttpPost httpPost = new HttpPost(params[0]);
String jsonResults = "";
try {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
// SENDING PARAMETERS WITH GIVEN NAMES
nameValuePairs.add(new BasicNameValuePair("paramName_1", params[1]));
nameValuePairs.add(new BasicNameValuePair("paramName_2", params[2]));
// ...
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpClient.execute(httpPost);
jsonResults = inputStreamToString(response.getEntity().getContent()).toString();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return jsonResults;
}
// DO SOMETHING BEFORE PHP RESPONSE
#Override
protected void onPreExecute() {
super.onPreExecute();
}
// DO SOMETHING AFTER PHP RESPONSE
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if(result.equals("") || result.equals(null)){
return;
}
// Json response from PHP
String jsonResult = returnParsedJsonObject(result);
// i.e.
if (jsonResult.equals("some_response") {
// do something
}
}
// READING ANSWER FROM PHP
private StringBuilder inputStreamToString(InputStream is) {
String rLine = "";
StringBuilder answer = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(is));
try {
while ((rLine = br.readLine()) != null) {
answer.append(rLine);
}
} catch (IOException e) {
e.printStackTrace();
}
return answer;
}
}
// GET ALL RETURNED VALUES FROM PHP
private String returnParsedJsonObject(String result){
JSONObject resultObject;
String returnedResult = "0";
try {
resultObject = new JSONObject(result);
returnedResult = resultObject.getString("response");
String value1 = resultObject.getString("value1");
String value2 = resultObject.getString("value2");
//...
// do something with retrieved values
} catch (JSONException e) {
e.printStackTrace();
}
return returnedResult;
}
To send some parameters use:
AsyncDataClass asyncRequestObject = new AsyncDataClass();
asyncRequestObject.execute("server_url", param1, param2,...);
Hope it helps you.
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();
So I am trying to post to this api: http://www.idmypill.com/api/id/ in my android program. This is my service handler class:
public class ServiceHandler
{
static String response = null;
public final static int GET = 1;
public final static int POST = 2;
public ServiceHandler() {
}
/**
* Making service call
* #url - url to make request
* #method - http request method
* */
public String makeServiceCall(String url, int method) {
return this.makeServiceCall(url, method, null);
}
/**
* Making service call
* #url - url to make request
* #method - http request method
* #params - http request params
* */
public String makeServiceCall(String url, int method,
List<NameValuePair> params)
{
try {
// http client
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpEntity httpEntity = null;
HttpResponse httpResponse = null;
android.os.Debug.waitForDebugger();
// Checking http request method type
if (method == POST)
{
HttpPost httpPost = new HttpPost(url);
httpPost.setHeader("Content-type", "application/json");
// adding post params
if (params != null)
{
httpPost.setEntity(new UrlEncodedFormEntity(params));
}
httpResponse = httpClient.execute(httpPost);
} else if (method == GET) {
// appending params to url
if (params != null) {
String paramString = URLEncodedUtils
.format(params, "utf-8");
url += "?" + paramString;
}
HttpGet httpGet = new HttpGet(url);
httpResponse = httpClient.execute(httpGet);
}
httpEntity = httpResponse.getEntity();
response = EntityUtils.toString(httpEntity);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return response;
}
}
The response I am getting is: Response:(1990): > {"errors": null, "results": [], "success": false}
My main activity that is calling my service handler looks like:
public class QueryAPI extends Activity
{
private ProgressDialog pDialog;
// URL to get contacts JSON
private static String url = "http://www.idmypill.com/api/id/api";
Bitmap pillPicture;
List<NameValuePair> nameValuePair = new ArrayList<NameValuePair>(2);
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
Intent QueryAPI = getIntent();
pillPicture = (Bitmap) QueryAPI.getParcelableExtra("PillImage");
nameValuePair.add(new BasicNameValuePair("api_key", "AIzaSyAdxxOjmh_nx4dKP_uJhtKy3cr32jrs7C8"));
nameValuePair.add(new BasicNameValuePair("image", "pillPicture"));
new GetPillInfo().execute();
}
private class GetPillInfo extends AsyncTask<Void, Void, Void>
{
#Override
protected void onPreExecute()
{
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(QueryAPI.this);
pDialog.setMessage("Please wait...");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected Void doInBackground(Void... arg0)
{
android.os.Debug.waitForDebugger();
// Creating service handler class instance
ServiceHandler sh = new ServiceHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(url, ServiceHandler.POST, nameValuePair);
Log.d("Response: ", "> " + jsonStr);
if (jsonStr != null)
{
try
{
JSONObject jsonObj = new JSONObject(jsonStr);
Log.d("JSON", jsonObj.toString());
} catch (JSONException e) {
e.printStackTrace();
}
} else
{
Log.e("ServiceHandler", "Couldn't get any data from the url");
}
return null;
}
#Override
protected void onPostExecute(Void result)
{
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
}
}
}
The python example the website gives look like this:
# highly suggested to use the requests package
# http://www.python-requests.org/en/latest/
import requests
# read in the image and construct the payload
image = open("example.jpg").read()
data = {"api_key": "KH8hdoai0wrjB0LyeA3EMu5n4icwyOQo"}
files = {"image": open("example.jpg")}
# fire off the request
r = requests.post("http://www.idmypill.com/api/id/",
data = data,
files = files)
# contents will be returned as a JSON string
print r.content
I am not familiar with Python and very new to using Http request so an advice would be great.
The api wants a MultiPartEntity containing a text value with key api_key and a image file with key image.
Android does not natively support MultiPart Uploads but you can archive it with Apache's HTTP Library which is actually an updated version of Android's HTTP Library since they are the same thing.
Once you have the library installed, which is simply adding the dependency in gradle then modify your code for something similar:
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addTextBody("api_key", yourAPIKey);
builder.addBinaryBody("image", inputStream); // Flexible here, see below
httpPost.setEntity(builder.build());
httpResponse = httpClient.execute(httpPost);
The .addBinaryBody() actually has various ways of receiving the image, you can either pass a File a InputStream or the full byte[] array of the image.
You are not returning any result.The return method was Void.That's why you were unable to see any result in Log.
Change your AsyncTask to
private class GetPillInfo extends AsyncTask
{
#Override
protected void onPreExecute()
{
super.onPreExecute();
// Showing progress dialog
pDialog = new ProgressDialog(QueryAPI.this);
pDialog.setMessage("Please wait...");
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected String doInBackground(String... arg0)
{
android.os.Debug.waitForDebugger();
// Creating service handler class instance
ServiceHandler sh = new ServiceHandler();
// Making a request to url and getting response
String jsonStr = sh.makeServiceCall(url, ServiceHandler.POST, nameValuePair);
Log.d("Response: ", "> " + jsonStr);
if (jsonStr != null)
{
try
{
JSONObject jsonObj = new JSONObject(jsonStr);
Log.d("JSON", jsonObj.toString());
} catch (JSONException e) {
e.printStackTrace();
}
} else
{
Log.e("ServiceHandler", "Couldn't get any data from the url");
}
return null;
}
#Override
protected void onPostExecute(String result)
{
super.onPostExecute(result);
// Dismiss the progress dialog
if (pDialog.isShowing())
pDialog.dismiss();
}
}
}
I try to update a string variable with data from a mysql database.
Example:
String str should grab a value from a mysql db using php. This is done and works perfectly.
But str should grab these values every 10 seconds, so it has to run in a loop.
And exactly this is the problem.
Connecting via httppost and getting entities blocks the UI, so it skip frames.
To solve this i used: Services, AsyncTasks and Runnables but always frame skipping.
This is the latest thing i tried:
public class AsyncStatus extends AsyncTask<String, String, String>{
HttpResponse response;
String str;
HttpPost httppost;
HttpClient httpclient;
List<NameValuePair> nameValuePairs;
Handler mHandler=null;
#Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
//Build the connection only once, to save performance
getStrFirst();
//Loop started
final Runnable mUpdateUI = new Runnable() {
public void run() {
System.out.println("called");
try {
//to avoid "already consumed exceptions"
response = httpclient.execute(httppost);
//get the content
str = EntityUtils.toString(response.getEntity());
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
str = str.replaceAll("\\D", "");
mHandler.postDelayed(this, 10000); // 10 seconds
}
};
mHandler.post(mUpdateUI);
return null;
}
public void getStrfirst(){
nameValuePairs = new ArrayList<NameValuePair>();
try
{
httpclient = new DefaultHttpClient();
httppost = new HttpPost("http://lunation.square7.ch/msqlcount.php");
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
response = httpclient.execute(httppost);
str = EntityUtils.toString(response.getEntity());
LOGCAT:
09-11 12:12:41.185: I/System.out(10874): called
09-11 12:12:41.975: I/Choreographer(10874): Skipped 51 frames! The application may be doing too much work on its main thread.
09-11 12:12:51.990: I/System.out(10874): called
EDIT:
I call the AsyncTask with:
AsyncStatus assi= new AsyncStatus();
assi.execute("nothing");
Why does this message appear, this isn't the main thread?
Thank you for any advice
I have noticed that my http requests tend to take alot of time compared apps communicating with same server. It makes my app feel sluggish and I was wondering if there is a better way of making these requests and updating the UI.
At the moment I use this method to make post requests
public String postRequest(List<NameValuePair> nameValuePairs, String method_name) {
String result = "";
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://www.mysite.com/api/"+method_name);
httppost.setHeader("Accept", "application/json");
httppost.setHeader("Authorization", "Basic somestuff");
try {
// Add your data
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(httppost);
BufferedReader rd = new BufferedReader(new InputStreamReader(
response.getEntity().getContent()));
result = rd.readLine();
return result;
} catch (ClientProtocolException e) {
} catch (IOException e) {
}
return null;
}
And in my UI thread (i.e my Fragment classes) I use this in an Async Task like this
class MakeRequest extends AsyncTask<Integer, Integer, String> {
protected String doInBackground(Integer... counter) {
String result = "";
String method_name = "";
try {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("id", value));
nameValuePairs.add(new BasicNameValuePair("name", name));
method_name = "petition/setPetition";
result = fixr.postRequest(nameValuePairs, method_name);
JSONObject jsonFile = new JSONObject(result);
if(!jsonFile.has("error")){
//Parse JSON using GSON
return "success";
}else{
return jsonFile.getString("error");
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
protected void onPostExecute(String jsonResult) {
try {
if(jsonResult != null){
//update UI
}else{
//Error message
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
I'd like to optimize this so users can have a really smooth experience on my application. I'm open to using third party http libraries or is there also an argument against using AysncTasks and maybe the runOnUiThread() instead.
Volley Library is better, http, https etc.
https://developers.google.com/live/shows/474338138
very mini sample here:https://github.com/ogrebgr/android_volley_examples/blob/master/src/com/github/volley_examples/Act_SimpleRequest.java
Try Volley mate! I changed from AsyncTasks to Volley library and i am pretty pleased from the overall experience!
Volley Library