I am currently using android-async-http library to send a post/get requests. I didn't have any problem before but now i realize that it gives me timeout error if i send this request without image data. (There is no error if i send exact same request by putting image data as well.)
RequestParams params = new RequestParams();
params.add("mail", mail.getText().toString());
params.add("password", pass.getText().toString());
try {
if (!TextUtils.isEmpty(imagePath))
params.put("image", new File(imagePath));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
AsyncHttpClient client = new AsyncHttpClient();
client.setTimeout(60000);
client.post("some_url", params, myResponseHandler);
What is the reason of this?
Thanks in advance.
After comparing requests and responses, i found out that the case was content-type. With image it was posting multipart, and without it something else.
So i got into RequestParams class in library, and made these changes. Now it works fine. For further troubles i am posting changes that i've made.
I put a flag to determine this request should post as multipart or not:
private boolean shouldUseMultiPart = false;
I created a constructor to set this parameter:
public RequestParams(boolean shouldUseMultiPart) {
this.shouldUseMultiPart = shouldUseMultiPart;
init();
}
And then on getEntity() method i applied these lines:
/**
* Returns an HttpEntity containing all request parameters
*/
public HttpEntity getEntity() {
HttpEntity entity = null;
if (!fileParams.isEmpty()) {
...
} else {
if (shouldUseMultiPart) {
SimpleMultipartEntity multipartEntity = new SimpleMultipartEntity();
// Add string params
for (ConcurrentHashMap.Entry<String, String> entry : urlParams
.entrySet()) {
multipartEntity.addPart(entry.getKey(), entry.getValue());
}
// Add dupe params
for (ConcurrentHashMap.Entry<String, ArrayList<String>> entry : urlParamsWithArray
.entrySet()) {
ArrayList<String> values = entry.getValue();
for (String value : values) {
multipartEntity.addPart(entry.getKey(), value);
}
}
entity = multipartEntity;
} else {
try {
entity = new UrlEncodedFormEntity(getParamsList(), ENCODING);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
return entity;
}
Related
I have an app that should send a the phone number and retrieve a value from the database, now I change the query and my code should retrieve values of multiple columns, So where changes should be in my code.
public class JSONTransmitter extends AsyncTask<JSONObject, Void, String>
{
HttpResponse response;
String url = "http://192.168.1.97:89/Derdeery/bankOsman.php";
private AsyncCallback asyncCallback;
public JSONTransmitter(Context context) {
// attach the callback to any context
asyncCallback = (AsyncCallback) context;
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
asyncCallback.onResponse(result);
}
protected String doInBackground(JSONObject... data)
{
JSONObject json = data[0];
HttpClient client = new DefaultHttpClient();
HttpConnectionParams.setConnectionTimeout(client.getParams(), 100000);
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().permitNetwork().build());
JSONObject jsonResponse = null;
HttpPost post = new HttpPost(url);
String resFromServer = "";
try {
StringEntity se = new StringEntity("json=" + json.toString());
post.addHeader("content-type", "application/x-www-form-urlencoded");
post.setEntity(se);
HttpResponse response;
response = client.execute(post);
resFromServer = org.apache.http.util.EntityUtils.toString(response.getEntity());
Log.i("Response from server", resFromServer);
} catch (Exception e) {
e.printStackTrace();
}
return resFromServer;
}
public static interface AsyncCallback {
void onResponse(String res);
}
}
Here is something to consider:
First, in your php code (server-side), query your data perhaps separately. So for instance, you can get those that match column A and then query for those that match column B.
Generate Json for each (A and B accordingly)
Then create a single JSON object that contains the two sets of data like this:
{
"DataFromColumnA" : {},
"DataFromColumnB" : {}
}
Once you have made your HTTP request in your android code, you can get the specific data by getting "DataFromColumnA" json Object and B respectively.
I hope this helps you get your problem solved!
Hey guys I'm struggeling with HTTP Requests in Java/Android. I want to create a new Github issue. So I've looked it up, and almost everybody did it the same way, but I have the problem that AndroidStudio tells me, that all the classes (HttpClient, HttpPost, ResponseHandler) doesn't exist, did I something wrong or why I don't have them?
private class GithubPostIssues extends AsyncTask<String, Void, String> {
private View view;
public GithubPostIssues(View view) {
this.view = view;
}
#Override
protected void onPostExecute(String result) {
Toast.makeText(FeedbackActivity.this, "Feedback/Hilfe gesendet", Toast.LENGTH_SHORT).show();
finish();
}
#Override
protected String doInBackground(String... params) {
return addIssue(view);
}
private String addIssue(View view) {
//here I'm getting some values from the user input and pass them in to the execute method
return execute(title, body, bug, help, question, feature, enhancement, design);
}
private String execute (String title, String body, boolean bug,
boolean help, boolean question, boolean feature,
boolean enhancement, boolean design) {
//Building the JSONOBject to pass in to the Request Body
JSONObject issue = new JSONObject();
JSONArray labels = new JSONArray();
try {
issue.put("title", title);
issue.put("body", body);
labels.put("0 - Backlog");
if (bug) {
labels.put("bug");
}
if (help) {
labels.put("help");
}
if (question) {
labels.put("question");
}
if (feature) {
labels.put("feature");
}
if (enhancement) {
labels.put("enhancement");
}
if (design) {
labels.put("design");
}
issue.put("labels", labels);
return makeRequest("http://requestb.in/uwwzlwuw", issue);
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
private String makeRequest (String uri, JSONObject issue) {
//all these clases aren't found by Android Studio
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(uri);
httpPost.setEntity(new StringEntity(issue));
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("Content-type", "application/json");
ResponseHandler<String> responseHandler = new BasicResponseHandler();
return httpClient.execute(httpPost, responseHandler);
}
}
Try adding this inside gradle:
android {
useLibrary 'org.apache.http.legacy'
I am performing login task and getting data from PHP server in json format. In response, I am getting a 'success' tag that containing User-ID
like this {"message":"You have been successfully login","success":"75"}
I get that value as "uid" in the same activity and move to next page. Now in next page, I want to check user profile. For that, I have to pass that "uid" as 'params' with url and get value from server. But don't understand how to do that.
In next activity page I am creating asyncTask to perform action.
protected String doInBackground(String... args) {
// Building Parameters
List<NameValuePair> params = new ArrayList<NameValuePair>();
// getting JSON string from URL
JSONObject json = jsonParser.makeHttpRequest(PROFILE_URL, "GET",params);
// Check your log cat for JSON reponse
Log.d("Profile JSON: ", json.toString());
try {
// profile json object
profile = json.getJSONObject(TAG_PROFILE);
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
Now I have to set the 'uid' in the place of params.
Use intent to pass data,
Intent intent = new Intent(getBaseContext(), SignoutActivity.class);
intent.putExtra("UID", uId);
startActivity(intent)
Use intent, but if you want to keep your uid for a long time , you can use SharedPrefferences
Method 1:
Class A {
String UID = "3";
public static void main(String[] args){
ClassB.setUid(3);
}
}
Class B {
public static String uid;
public static setUid(String id){
uid = id;
}
}
Method 2:
Intent intent = new Intent(getBaseContext(), SignoutActivity.class);
intent.putExtra("U_ID", uId);
startActivity(intent)
Beware about static variables, programmers dont usually like them and call them evil.
If what you're trying to do is transfer data from one activity to another, try adding an extra to your intent. After you've created the intent to launch the next page, add something like
intent.putExtra("uid", uid);
to add the uid as an extra. And on the next page, you can retrieve this data by
Intent intent = getIntent();
int uid = intent.getIntExtra("uid", defaultvalue);
In case you need to pass parameters along with GET method, you can simply add the respective values to the url:
public void getData(String uid) {
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet("http://www.yoursite.com/script.php?uid=" + uid);
HttpResponse response = httpclient.execute(httpget);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
} catch (IOException e) {
// TODO Auto-generated catch block
}
}
If you want to pass parameters with POST method the code is a bit more complex:
public void postData(String uid) {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://www.yoursite.com/script.php");
try {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>;
nameValuePairs.add(new BasicNameValuePair("uid", uid));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
} catch (IOException e) {
// TODO Auto-generated catch block
}
}
In both cases you can get server response as stream:
InputStream s = response.getEntity().getContent();
The easiest way to get response body as a String is to call:
String body = EntityUtils.toString(response.getEntity());
Of course, there are numerous other ways to achive what you desire.
There are two ways to pass parameters with Get request.
http://myurl.com?variable1=value&variable2=value2
Passing arguments as headers in request.
As HttpClient is now deprecated in the API 22, so you should use the Google Volley https://developer.android.com/training/volley/simple.html
Adding parameters using volley library as
/**
* This method is used to add the new JSON request to queue.
* #param method - Type of request
* #param url - url of request
* #param params - parameters
* #param headerParams - header parameters
* #param successListener - success listener
* #param errorListener - error listener
*/
public void executeJSONRequest(int method, String url, final JSONObject params, final HashMap<String, String> headerParams,
Response.Listener successListener,
Response.ErrorListener errorListener) {
JsonObjectRequest request = new JsonObjectRequest(method, url, params,
successListener, errorListener) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
if (headerParams != null)
return headerParams;
else
return super.getHeaders();
}
};
// Add request to queue.
addRequestToQueue(request);
}
i wrote those threads:
How to manage multiple Async Tasks efficiently in Android
Running multiple AsyncTasks at the same time -- not possible?
but didnt find answer for my question, maybe someone can help..
I have android app which makes Login POST and getting json response,
if the Json is OK i need to POST another data to get another response.
i have extends Async Class which doing the post to the URL:
public class AsyncHttpPost extends AsyncTask<String, String, String> {
private HashMap<String, String> mData = null;
public AsyncHttpPost(HashMap<String, String> data) {
mData = data;
}
#Override
protected String doInBackground(String... params) {
byte[] result = null;
String str = "";
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(params[0]);// in this case, params[0] is URL
try {
ArrayList<NameValuePair> nameValuePair = new ArrayList<NameValuePair>();
Iterator<String> it = mData.keySet().iterator();
while (it.hasNext()) {
String key = it.next();
nameValuePair.add(new BasicNameValuePair(key, mData.get(key)));
}
post.setEntity(new UrlEncodedFormEntity(nameValuePair, "UTF-8"));
HttpResponse response = client.execute(post);
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpURLConnection.HTTP_OK){
result = EntityUtils.toByteArray(response.getEntity());
str = new String(result, "UTF-8");
}
}
catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
catch (Exception e) {
return null;
}
return str;
}
#Override
protected void onPostExecute(String result) {
try {
JSONArray Loginjson = new JSONArray(result);
strStt = Loginjson.getJSONObject(0).getJSONObject("fields").getString("status");
if (strStt.equals("ERR")) {
ErrorMsg("Authentication failed");
} else if (strStt.equals("OK")) {
ErrorMsg("Login OK!!!");
ClientPage();
} else {
ErrorMsg("Connection Error");
}
} catch (JSONException e) {
ErrorMsg("Connection Error");
}
}
}
Now - i need to get another POST if the status is Error. do i need to make another Async class? with the same all procedures ? the issue is only the onPostExecute part is different.. actually the "doInBackground" will be always the same..
any idea how can i easily do multiple posts in the same activity?
Firstly, since your doInBackground() code will always stay the same, I recommend you move it into a general utility class.
Beyond that, you can go one of two ways:
Create a new AsyncTask for each type of request that can call your utility class, and have its own onPostExecute()
Create one AsyncTask that has a flag in it, which can be checked in the onPostExecute() method to see what code needs to be executed there. You will have to pass the flag in in the constructor or as a parameter in execute.
You can use a parameter at AsyncHttpPost constructor/execute or global variable to indicate if it is first or second POST (by other words - a flag). Then just create and execute another instance of AsyncHttpPost in onPostExecute (only if parameter/variable is set as "first POST").
Please can anyone tell me how to make an http post to work in the background with AsyncTask and how to pass the parameters to the AsyncTask? All the examples that I found were not clear enough for me and they were about downloading a file.
I'm running this code in my main activity and my problem is when the code sends the info to the server the app slows down as if it is frozen for 2 to 3 sec's then it continues to work fine until the next send. This http post sends four variables to the server (book, libadd, and time) the fourth is fixed (name)
Thanks in advance
public void SticketFunction(double book, double libadd, long time){
Log.v("log_tag", "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% SticketFunction()");
//HttpClient
HttpClient nnSticket = new DefaultHttpClient();
//Response handler
ResponseHandler<String> res = new BasicResponseHandler();
HttpPost postMethod = new HttpPost("http://www.books-something.com");
try {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(5);
nameValuePairs.add(new BasicNameValuePair("book", book+""));
nameValuePairs.add(new BasicNameValuePair("libAss", libass+""));
nameValuePairs.add(new BasicNameValuePair("Time", time+""));
nameValuePairs.add(new BasicNameValuePair("name", "jack"));
//Encode and set entity
postMethod.setEntity(new UrlEncodedFormEntity(nameValuePairs, HTTP.UTF_8));
//Execute
//manSticket.execute(postMethod);
String response =Sticket.execute(postMethod, res).replaceAll("<(.|\n)*?>","");
if (response.equals("Done")){
//Log.v("log_tag", "!!!!!!!!!!!!!!!!!! SticketFunction got a DONE!");
}
else Log.v("log_tag", "!!!!!!!?????????? SticketFunction Bad or no response: " + response);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
//Log.v("log_tag", "???????????????????? SticketFunction Client Exception");
} catch (IOException e) {
// TODO Auto-generated catch block
//Log.v("log_tag", "???????????????????? IO Exception");
}
}
}
At first,
You put a class like following:
public class AsyncHttpPost extends AsyncTask<String, String, String> {
interface Listener {
void onResult(String result);
}
private Listener mListener;
private HashMap<String, String> mData = null;// post data
/**
* constructor
*/
public AsyncHttpPost(HashMap<String, String> data) {
mData = data;
}
public void setListener(Listener listener) {
mListener = listener;
}
/**
* background
*/
#Override
protected String doInBackground(String... params) {
byte[] result = null;
String str = "";
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(params[0]);// in this case, params[0] is URL
try {
// set up post data
ArrayList<NameValuePair> nameValuePair = new ArrayList<NameValuePair>();
Iterator<String> it = mData.keySet().iterator();
while (it.hasNext()) {
String key = it.next();
nameValuePair.add(new BasicNameValuePair(key, mData.get(key)));
}
post.setEntity(new UrlEncodedFormEntity(nameValuePair, "UTF-8"));
HttpResponse response = client.execute(post);
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == HttpURLConnection.HTTP_OK){
result = EntityUtils.toByteArray(response.getEntity());
str = new String(result, "UTF-8");
}
}
catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
catch (Exception e) {
}
return str;
}
/**
* on getting result
*/
#Override
protected void onPostExecute(String result) {
// something...
if (mListener != null) {
mListener.onResult(result)
}
}
}
Now.
You just write some lines like following:
HashMap<String, String> data = new HashMap<String, String>();
data.put("key1", "value1");
data.put("key2", "value2");
AsyncHttpPost asyncHttpPost = new AsyncHttpPost(data);
asyncHttpPost.setListener(new AsyncHttpPost.Listener(){
#Override
public void onResult(String result) {
// do something, using return value from network
}
});
asyncHttpPost.execute("http://example.com");
First i would not recommend do a Http request in a AsyncTask, you better try a Service instead. Going back to the issue on how to pass parameter into an AsyncTask when you declared it you can defined each Object class of the AsyncTask like this.
public AsyncTask <Params,Progress,Result> {
}
so in your task you should go like this
public MyTask extends<String,Void,Void>{
public Void doInBackground(String... params){//those Params are String because it's declared like that
}
}
To use it, it's quite simple
new MyTask().execute("param1","param2","param3")