Indeterminate Progress-Bar Situation - android

I added a progressbar as indeterminate state and put in a class extends asynctask.
In doInBackground method, i added one method (say m_one) with volley-library.
In m_one(), i have called method m_two();.
In m_two(), i have called m_three();.
Now, the problem is, progressbar only works till m_one() executes and then progressbar visibility goes invisible and remaining methods executes in background thread.
How do i keep rotating progressbar until all the methods done receiving data using volley request?

Try this code.
private static final String TAG = "LoginActivity.this";
Button button_login;
Context context;
ProgressBar progressBar;
//some variables for accepting the volley response data
DBUtils dbUtils;
Calendar calendar_2;
public SimpleDateFormat dateFormat;
public SimpleDateFormat timeformat;
Date date;
TreeSet<Integer> idSet;
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
button_login = findViewById(R.id.btn_login);
context = getApplicationContext();
progressBar = findViewById(R.id.progress_id_1);
calendar_2 = Calendar.getInstance();
dbUtils = new DBUtils(this);
//clear the db tables on start of app
dbUtils.ClearTables();
date = Calendar.getInstance().getTime();
Log.e(TAG, "\n current time: " + date);
dateFormat = new SimpleDateFormat("dd-MM-yyyy");
idSet = new TreeSet<>();
//Login button click event ********************
button_login.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
checkNetwork();
}
});
}
private void checkNetwork() {
progressBar.setVisibility(View.VISIBLE);
ConnectivityManager conMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = conMgr.getActiveNetworkInfo();
try {
if (netInfo != null) {
NetworkInfo.State state = conMgr.getActiveNetworkInfo().getState();
if (state == NetworkInfo.State.CONNECTED) {
Log.e(TAG, "nw info: " + netInfo.getExtraInfo());
Log.e(TAG, "Network Connected ");
method1();
Thread.sleep(3000);
} else {
Log.e(TAG, "Network Disconnected");
}
} else if (netInfo == null) {
Log.e(TAG, "Network Not Found !");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// ********************************************
// ********************************************
//to get the response of requested url
public void method1() {
try {
//url without api for login session
URL loginURL = new URL(your url 1);
HttpURLConnection urlconnect = (HttpURLConnection) loginURL.openConnection();
;
//http connection for webpage permission
//type of request get / post...
urlconnect.setRequestMethod("POST");
//allow the post request for user
urlconnect.setDoOutput(true);
/*
Singleton_Volley is the class for volley initialize
you can skip Singleton_Volley class..its correct
*/
// Get a RequestQueue in required page
RequestQueue queue = Singleton_Volley.getInstance(this.getApplicationContext()).
getRequestQueue();
// Request a string response from the provided URL.(my case, url)
StringRequest stringRequest = new StringRequest(Request.Method.POST, "" + loginURL.toString(),
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
//accept the data from request and set in our views like list,text, etc...
try {
/* your response data stored in variables first and then stored in sqlite you have to consider this strictly, make sure you also have array in response to wait for a while */
method2();
} catch (Exception e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//popup an error message...(Toast)
}
})
} ;
// Add the request to the RequestQueue.
Singleton_Volley.getInstance(this).addToRequestQueue(queue.add(stringRequest));
} catch(
IOException e)
{
e.printStackTrace();
} catch(
JSONException e)
{
e.printStackTrace();
}
}
public void method2() {
try {
url_2 = new URL(your url 2);
HttpURLConnection urlconnect = (HttpURLConnection)
url_2.openConnection();
;
//http connection for webpage permission
//type of request get / post...
urlconnect.setRequestMethod("POST");
//allow the post request for user
urlconnect.setDoOutput(true);
RequestQueue contactQueue = Singleton_Volley.getInstance(this).
getRequestQueue();
// Request a string response from the provided URL.(in my case, url_2)
StringRequest stringRequest = new StringRequest(Request.Method.GET, "" + url_2.toString(),
new Response.Listener<String>() {
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
public void onResponse(String response) {
//accept the data from request and set in our views like list,text, etc...
try {
/*
your response data stored in variables first and then stored in sqlite
you have to consider this strictly
make sure you also have array in response to wait for a while
*/
method3(); //method3() called here
} catch (Exception e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//popup an error messege...(Toast)
Toast.makeText(LoginActivity.this, "" + error, Toast.LENGTH_SHORT).show();
}
})
} ;
// Add the request to the RequestQueue.
Singleton_Volley.getInstance(this).addToRequestQueue(contactQueue.add(stringRequest));
} catch(Exception e){
e.printStackTrace();
}
}
// ********************************************
// ********************************************
private void method3(){
try{
URL url_3=new URL(your url 3);
HttpURLConnection urlconnect=(HttpURLConnection)url_3.openConnection();
;
//http connection for webpage permission
//type of request get / post...
urlconnect.setRequestMethod("POST");
//allow the post request for user
urlconnect.setDoOutput(true);
RequestQueue stageQueue=Singleton_Volley.getInstance(this).
getRequestQueue();
// Request a string response from the provided URL.(in my case, url_3)
StringRequest stringRequest=new StringRequest(Request.Method.GET,""+url_3.toString(),
new Response.Listener<String>(){
#RequiresApi(api = Build.VERSION_CODES.O)
#Override
public void onResponse(String response){
//accept the data from request and set in our views like list,text, etc...
try{
progressBar.setVisibility(View.GONE);
/*
make sure you also have array in response to wait for a while
*/
}catch(Exception ex){
ex.printStackTrace();
}
}
},new Response.ErrorListener(){
#Override
public void onErrorResponse(VolleyError error){
//popup an error messege...(Toast)
}
})
};
// Add the request to the RequestQueue.
Singleton_Volley.getInstance(this).addToRequestQueue(stageQueue.add(stringRequest));
}catch(Exception ec){
ec.printStackTrace();
}
startActivity(new Intent(LoginActivity.this,Page2.class));
}
}
}}
Please manage the closing } and it should work.

Related

Handle Multiple request in Android volley

I am trying to hit multiple request using Volley and i am getting response for all the request. my problem is how to identify the response is belong to which API.
mQueue = CustomVolleyRequest.getInstance(this.getApplicationContext())
.getRequestQueue();
final CustomJSONObjectrequest jsonRequest = new CustomJSONObjectrequest(Request.Method
.GET, url,
new JSONObject(), this, this); //
jsonRequest.setTag(REQUEST_TAG);
final CustomJSONObjectrequest jsonRequest2 = new CustomJSONObjectrequest(Request.Method
.GET, url2,
new JSONObject(), this, this);
jsonRequest2.setTag(REQUEST_TAG);
mButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mQueue.add(jsonRequest);
mQueue.add(jsonRequest2); // Both the request will have different API request
}
});
}
#Override
public void onErrorResponse(VolleyError error) {
mTextView.setText(error.getMessage());
}
#Override
public void onResponse(Object response) {
// How to identify, which response is belong to which api request
mTextView.setText("Response is: " + response);
}
Create a Generic Volley class and a Interface, Use the interface to get success and failure responds.
Step 1 Create a separate Volley class
Step 2 Create a interface for accessing the response from volley class
Step 3 create new object for
the class and send required parameters
new PostVolleyJsonRequest(TestVolley.this, TestVolley.this(interfcae), "Submit", url, params);
Context of the class
Interface for sending Success and failure responds
Type of request to identify on success
url (mandatory)
Param (optional) for GET no need
Generic volley class
public class PostVolleyJsonRequest {
private String type;
private Activity act;
private VolleyJsonRespondsListener volleyJsonRespondsListener;
private String networkurl;
private JSONObject jsonObject = null;
private JSONObject params;
public PostVolleyJsonRequest(Activity act, VolleyJsonRespondsListener volleyJsonRespondsListener, String type, String netnetworkUrl,JSONObject params) {
this.act = act;
this.volleyJsonRespondsListener = volleyJsonRespondsListener;
this.type = type;
this.networkurl = netnetworkUrl;
this.params = params;
sendRequest();
}
private void sendRequest() {
Log.d("url", "url" + networkurl);
JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request.Method.POST,networkurl,params,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.e("response", "response " + response);
volleyJsonRespondsListener.onSuccessJson(response, type);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
try {
NetworkResponse response = error.networkResponse;
Log.e("response", "response " + response);
if (response != null) {
int code = response.statusCode;
String errorMsg = new String(response.data);
Log.e("response", "response" + errorMsg);
try {
jsonObject = new JSONObject(errorMsg);
} catch (JSONException e) {
e.printStackTrace();
}
String msg = jsonObject.optString("message");
volleyJsonRespondsListener.onFailureJson(code, msg);
} else {
String errorMsg = error.getMessage();
volleyJsonRespondsListener.onFailureJson(0, errorMsg);
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
jsObjRequest.setRetryPolicy(new DefaultRetryPolicy(
600000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
RequestQueue requestqueue = Volley.newRequestQueue(act);
requestqueue.add(jsObjRequest);
}
}
Use the interface to get responds message
public interface VolleyJsonRespondsListener {
public void onSuccessJson(JSONObject result, String type);
public void onFailureJson(int responseCode, String responseMessage);
}
In your class where you want to include multiple request
public class TestVolley extends AppCompatActivity implements VolleyJsonRespondsListener{
//Your class code goes here
//network request
try {
//parameters
//Context,Interface,Type(to indentify your responds),URL,parameter for your request
//request 1
new PostVolleyJsonRequest(TestVolley.this, TestVolley.this, "Submit", url, params);
//request 2
new PostVolleyJsonRequest(TestVolley.this, TestVolley.this, "AccessData", url_2, params_2);
} catch (Exception e) {
e.printStackTrace()
}
//Methods from Interface
#Override
public void onSuccessJson(JSONObject result, String type) {
//Based on the Type you send get the responds and parse it
switch (type) {
case "Submit":
try {
parseSubmit(result);
} catch (Exception e) {
e.printStackTrace();
}
break;
case "AccessData":
try {
parseAccessData(result);
} catch (Exception e) {
e.printStackTrace();
}
break;
}
You can do something like this for a single request. Same can be applied to the second request. This way you know which request is giving you the response.
final CustomJSONObjectrequest jsonRequest = new CustomJSONObjectrequest(Request.Method
.GET, url,
new JSONObject(), this, new Response.Listener<Object>() {
#Override
public void onResponse(Object response) {
// How to identify, which response is belong to which api request
mTextView.setText("Response is: " + response);
});
EDITED :
You can start with making an interface like :
public interface VolleyResponse {
void onResponse(JSONObject object, String tag);
void onError(VolleyError error, String tag);
}
Then you can make a custom handler for volley request like:
public class CustomJSONObjectRequest implements Response.Listener<JSONObject>, Response.ErrorListener {
private VolleyResponse volleyResponse;
private String tag;
private JsonObjectRequest jsonObjectRequest;
public CustomJSONObjectRequest(int method, String url, JSONObject jsonObject, String tag, VolleyResponse volleyResponse) {
this.volleyResponse = volleyResponse;
this.tag= tag;
jsonObjectRequest = new JsonObjectRequest(method, url, jsonObject, this, this);
}
#Override
public void onResponse(JSONObject response) {
volleyResponse.onResponse(response, tag);
}
#Override
public void onErrorResponse(VolleyError error) {
volleyResponse.onError(error, tag);
}
public JsonObjectRequest getJsonObjectRequest() {
return jsonObjectRequest;
}
}
And to call it in your class use it like:
CustomJSONObjectRequest request1 = new CustomJSONObjectRequest(Request.Method.GET, url,
new JSONObject(), "YOUR REQUEST TAG", this);
Make sure to let your class implement the VolleyResponse interface that will get you the response and your tag.
#Override
public void onResponse(JSONObject object, String tag) {
Log.i("Response :", object.toString() + " " + tag);
}
#Override
public void onError(VolleyError error, String tag) {
}
To add the request to the volley queue you can use:
mQueue.add(request1.getJsonObjectRequest());
PS : this code is not tested but it should work.

OkHttp and Retrofit, refresh token with concurrent requests

In my application I implemented Retrofit to call WebServices and I'm using OkHttp to use Interceptor and Authenticator. Some requests need token, and I have implemented Authenticator interface to handle the refresh (following the official documentation). But I have the following issue : time to time in my app I have to call more than one request at once. Because of that, for one of them I will have the 401 error.
Here is my code for request calls :
public static <S> S createServiceAuthentication(Class<S> serviceClass, boolean hasPagination) {
final String jwt = JWT.getJWTValue(); //Get jwt value from Realm
if (hasPagination) {
Gson gson = new GsonBuilder().
registerTypeAdapter(Pagination.class, new PaginationTypeAdapter()).create();
builder =
new Retrofit.Builder()
.baseUrl(APIConstant.API_URL)
.addConverterFactory(GsonConverterFactory.create(gson));
}
OkHttpClient.Builder httpClient =
new OkHttpClient.Builder();
httpClient.addInterceptor(new AuthenticationInterceptor(jwt));
httpClient.authenticator(new Authenticator() {
#Override
public Request authenticate(Route route, Response response) throws IOException {
if (responseCount(response) >= 2) {
// If both the original call and the call with refreshed token failed,
// it will probably keep failing, so don't try again.
return null;
}
if (jwt.equals(response.request().header("Authorization"))) {
return null; // If we already failed with these credentials, don't retry.
}
APIRest apiRest = createService(APIRest.class, false);
Call<JWTResponse> call = apiRest.refreshToken(new JWTBody(jwt));
try {
retrofit2.Response<JWTResponse> refreshTokenResponse = call.execute();
if (refreshTokenResponse.isSuccessful()) {
JWT.storeJwt(refreshTokenResponse.body().getJwt());
return response.request().newBuilder()
.header(CONTENT_TYPE, APPLICATION_JSON)
.header(ACCEPT, APPLICATION)
.header(AUTHORIZATION, "Bearer " + refreshTokenResponse.body().getJwt())
.build();
} else {
return null;
}
} catch (IOException e) {
return null;
}
}
});
builder.client(httpClient.build());
retrofit = builder.build();
return retrofit.create(serviceClass);
}
private static int responseCount(Response response) {
int result = 1;
while ((response = response.priorResponse()) != null) {
result++;
}
return result;
}
The issue is simple, the first request will refresh the token successfully but others will failed because they will try to refresh a token already refreshed. The WebService return an error 500. Is there any elegant solution to avoid this ?
Thank you !
If I understand your issue, some requests are sent while the token is being updated, this gives you an error.
You could try to prevent all the requests while a token is being updated (with a 'synchronized' object) but this will not cover the case of an already sent request.
Since the issue is difficult to avoid completely, maybe the right approach here is to have a good fallback behavior. Handling the error you get when you've made a request during a token update by re-running the request with the updated token for instance.
Write Service.
public class TokenService extends Service {
private static final String TAG = "HelloService";
private boolean isRunning = false;
OkHttpClient client;
JSONObject jsonObject;
public static String URL_LOGIN = "http://server.yoursite";
String phone_number, password;
#Override
public void onCreate() {
Log.i(TAG, "Service onCreate");
jsonObject = new JSONObject();
client = new OkHttpClient();
SharedPreferences pref_phone = getSharedPreferences("Full_Phone", MODE_PRIVATE);
phone_number = pref_phone.getString("Phone", "");
SharedPreferences pref_password = getSharedPreferences("User_Password", MODE_PRIVATE);
password = pref_password.getString("Password", "");
isRunning = true;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "Service onStartCommand");
try {
jsonObject.put("phone_number", phone_number);
jsonObject.put("password", password);
} catch (JSONException e) {
e.printStackTrace();
}
new Thread(new Runnable() {
#Override
public void run() {
for (; ; ) {
try {
Thread.sleep(1000 * 60 * 2);
} catch (Exception e) {
}
if (isRunning) {
AsyncTaskRunner myTask = new AsyncTaskRunner();
myTask.execute();
} else {
Log.d("CHECK__", "Check internet connection");
}
}
}
}).start();
return Service.START_STICKY;
}
#Override
public IBinder onBind(Intent arg0) {
Log.i(TAG, "Service onBind");
return null;
}
#Override
public void onDestroy() {
isRunning = false;
Log.i(TAG, "Service onDestroy");
}
String post(String url, JSONObject login) {
try {
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, login.toString());
okhttp3.Request request = new okhttp3.Request.Builder()
.url(url)
.post(body)
.build();
okhttp3.Response response = client.newCall(request).execute();
try {
return response.body().string();
} catch (IOException e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
String response;
private class AsyncTaskRunner extends AsyncTask<String, String, String> {
#Override
protected void onPreExecute() {
}
#Override
protected String doInBackground(String... params) {
try {
response = post(
URL_LOGIN, jsonObject);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
Log.d("---OKHTTP---", response);
}
}
}

How to make volley calls synchronous

In my application, I'm using volley for networking. Now the backend team have made some changes in web-service call, which is before every api call I need to call one more service(oauth service) which will provide access token in it's JSON response. This access token is then used in my actual service(login service) call as a query in url. Means I need to make two calls, one after the other.
Implemented this change in my code i.e For eg say login service:
step 1) Call oauth service which gives access token.
step 2) Use this access token in url as a query for login service.
Now the problem is the calls are not in sync, I receive access token in response after login call thus getting an error
Login service call:
public void onClickLogin(View v) {
// Tag used to cancel the request
String tagJSONobj = "json_obj_req";
String url;
if(Constants.RUN_AUTH_API) {
authAuthentication = new AuthAuthentication(tinyDB, SignInActivity.this);
authAuthentication.getAuthToken();
url = https://abc.xyz.com/Services/api/UserValidation/userValidate.do?access_token= + tinyDB.getString(Constants.MY_SHARED_PREF_AUTH_TOKEN);
}else
{
url = Constants.SIGNIN_URL;
}
showDialog();
JSONObject object = new JSONObject();
try {
object.put("userName", name);
object.put("password", password);
object.put("appType", "MOB APP");
} catch (JSONException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.POST, url, object,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
hidePDialog();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
hidePDialog();
System.out.print("error is" + error.getMessage());
error.printStackTrace();
Toast.makeText(SignInActivity.this, getResources().getString(R.string.login_service_error_message), Toast.LENGTH_SHORT).show();
}
}) ;
// Adding request to request queue
AppController.getInstance().addToRequestQueue(jsonObjReq, tagJSONobj);
}
}
OAuth service call:
public class AuthAuthentication {
private static final String TAG = AuthAuthentication.class.getSimpleName();
private TinyDB tinyDB;
private Context context;
public AuthAuthentication(TinyDB tinyDB, Context context){
this.tinyDB = tinyDB;
this.context = context;
}
public void getAuthToken() {
String tag_json_obj = "json_obj_req";
String url = https://abc.xyz.com/Services/oauth/token?grant_type=password&client_id=restapp&client_secret=restapp&username=admin&password=admin";
JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.GET,
url, "",
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
Log.d(TAG, " Response" + response.toString());
tinyDB.putString(Constants.MY_SHARED_PREF_AUTH_TOKEN, "" + response.getString(AppTags.TAG_AUTH_TOKEN));
} catch (JSONException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
Toast.makeText(context, context.getResources().getString(R.string.unable_to_process), Toast.LENGTH_SHORT).show();
}
});
// Adding request to request queue
AppController.getInstance().addToRequestQueue(jsonObjReq, tag_json_obj);
}
}
Call OAuthsevice firstly on login button click and OnResponse method call login Api
OAuth service call:
public class AuthAuthentication {
private static final String TAG = AuthAuthentication.class.getSimpleName();
private TinyDB tinyDB;
private Context context;
public AuthAuthentication(TinyDB tinyDB, Context context){
this.tinyDB = tinyDB;
this.context = context;
}
public void getAuthToken() {
String tag_json_obj = "json_obj_req";
String url = https://abc.xyz.com/Services/oauth/token?grant_type=password&client_id=restapp&client_secret=restapp&username=admin&password=admin";
JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.GET,
url, "",
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
Log.d(TAG, " Response" + response.toString());
tinyDB.putString(Constants.MY_SHARED_PREF_AUTH_TOKEN, "" + response.getString(AppTags.TAG_AUTH_TOKEN));
onClickLogin();/// here to peform login
} catch (JSONException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
Toast.makeText(context, context.getResources().getString(R.string.unable_to_process), Toast.LENGTH_SHORT).show();
}
});
// Adding request to request queue
AppController.getInstance().addToRequestQueue(jsonObjReq, tag_json_obj);
}
UPDATE
if OAUTH will call multiple time we need is OAUTH key for diferent API...
Create This class in utility folder
public interface VolleyResponse {
void processFinish(String output);
}
just change you class constructor like this..
public class AuthAuthentication {
private static final String TAG = AuthAuthentication.class.getSimpleName();
private TinyDB tinyDB;
private Context context;
private VolleyResponse delegate;
public AuthAuthentication(TinyDB tinyDB, Context context,VolleyResponse delegate){
this.tinyDB = tinyDB;
this.context = context;
this.delegate= delegate;
}
--------
-------
}
In OnResponse method of AuthAuthentication class
#Override
public void onResponse(JSONObject response) {
try {
Log.d(TAG, " Response" + response.toString());
tinyDB.putString(Constants.MY_SHARED_PREF_AUTH_TOKEN, "" + response.getString(AppTags.TAG_AUTH_TOKEN));
//send response of volley
delegate.processFinish(tinyDB); //it will broadcast your response
} catch (JSONException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
and use this as you want. suppose you have to use in login click
login.setOnClickListerner(new View.OnClickListenr(){
#Override
public void onClick(View view){
AuthAuthentication auth= new AuthAuthentication(tinyDB,mContext,new VolleyResponse() {
#Override
public void processFinish(String output) {
//output conatins response
loginApicall();
}
}.getAuthToken(); ///if not work then auth.getAuthToken
}
});

Android. Making a synchronous Request with RequestFuture get() and AsyncTask

i think i need some help with android volley. I am trying to make a simple HTTP request and wait for the response, because i need the response data for further processing. I have been trying for three days now, but wasn't able to get it done yet.
Basically i want to click a button -> make a request -> get a response -> handle it -> make a new request depending on the previous response -> handle the secon response -> and then show the results on my activity.
Is started the request in an AsysncTask as recommended but it always times out without response. I hope you can help me.
public class Connection extends AsyncTask<Object, Void, String>{
private static RequestQueue queue;
#Override
protected String doInBackground(Object... params) {
String response = null;
Context context = (Context) params[0];
String url = (String) params[1];
queue = getQueue(context.getApplicationContext());
RequestFuture<String> future = RequestFuture.newFuture();
StringRequest request = new StringRequest(Request.Method.GET, url, future, future);
queue.add(request);
try {
response = future.get(5, TimeUnit.SECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
return response;
}
private static RequestQueue getQueue(Context context) {
if (queue == null) {
queue = Volley.newRequestQueue(context.getApplicationContext());
}
return queue;
}
}
The call is started from an extra Thread:
public class MyThread extends Thread {
#Override
public synchronized void start() {
super.start();
String url = UrlRequestGenerator.buildUrl(originLat, originLong, context); // context from calling activity
try {
response = new HAFASConnection().execute(context, url).get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
System.out.println(response);
}
}
I did that recently but in the same thread. You could check first in the same thread if it works. If it doesn't, it means it could come from your url.
RequestQueue queue = Volley.newRequestQueue(getBaseContext());
String url ="http://....";
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
finish();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyError r = error;
}
});
queue.add(stringRequest);
If it goes on onErrorResponse, check your url and your server.

How do you use the Android Volley API?

I am thinking of implementing the Android Volley library in my next projects (Google IO presentation about Volley).
However, I haven't found any serious API for that library.
How do I upload files, do POST/GET requests, and add a Gson parser as a JSON parser using Volley?
Source code
Edit: finally here it is an official training about "Volley library"
I found some examples about Volley library
6 examples by Ognyan Bankov :
Simple request
JSON request
Gson request
Image loading
with newer external HttpClient (4.2.3)
With Self-Signed SSL Certificate.
one good simple example by Paresh Mayani
other example by Hardik Trivedi
(NEW) Android working with Volley Library by Ravi Tamada
Unfortunately there is no documentation for a Volley library like JavaDocs until now. Only repo on github and several tutorials across the Internet. So the only good docs is source code :) . When I played with Volley I read this tutorial.
About post/get you can read this : Volley - POST/GET parameters Hope this helps
This is an illustration for making a POST request using Volley. StringRequest is used to get response in the form of String.
Assuming your rest API returns a JSON. The JSON response from your API is received as String here, which you can covert again to JSON and process it further. Added comments in code.
StringRequest postRequest = new StringRequest(Request.Method.POST, "PUT_YOUR_REST_API_URL_HERE",
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
final JSONObject jsonObject = new JSONObject(response);
// Process your json here as required
} catch (JSONException e) {
// Handle json exception as needed
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
String json = null;
NetworkResponse response = error.networkResponse;
if(response != null && response.data != null){
switch(response.statusCode) {
default:
String value = null;
try {
// It is important to put UTF-8 to receive proper data else you will get byte[] parsing error.
value = new String(response.data, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
json = trimMessage(value, "message");
// Use it for displaying error message to user
break;
}
}
loginError(json);
progressDialog.dismiss();
error.printStackTrace();
}
public String trimMessage(String json, String key){
String trimmedString = null;
try{
JSONObject obj = new JSONObject(json);
trimmedString = obj.getString(key);
} catch(JSONException e){
e.printStackTrace();
return null;
}
return trimmedString;
}
}
) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<>();
params.put("abc", "pass abc");
params.put("xyz", "pass xyz");
// Pass more params as needed in your rest API
// Example you may want to pass user input from EditText as a parameter
// editText.getText().toString().trim()
return params;
}
#Override
public String getBodyContentType() {
// This is where you specify the content type
return "application/x-www-form-urlencoded; charset=UTF-8";
}
};
// This adds the request to the request queue
MySingleton.getInstance(YourActivity.this)
.addToRequestQueue(postRequest);
// Below is MySingleton class
public class MySingleton {
private static MySingleton mInstance;
private RequestQueue mRequestQueue;
private static Context mCtx;
private MySingleton(Context context) {
mCtx = context;
mRequestQueue = getRequestQueue();
}
public static synchronized MySingleton getInstance(Context context) {
if (mInstance == null) {
mInstance = new MySingleton(context);
}
return mInstance;
}
public RequestQueue getRequestQueue() {
if (mRequestQueue == null) {
// getApplicationContext() is key, it keeps you from leaking the
// Activity or BroadcastReceiver if someone passes one in.
mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());
}
return mRequestQueue;
}
public <T> void addToRequestQueue(Request<T> req) {
getRequestQueue().add(req);
}
}
Just add volley.jar library to your project.
and then
As per Android documentation :
// Instantiate the RequestQueue.
RequestQueue queue = Volley.newRequestQueue(this);
String url ="http://www.google.com";
// Request a string response from the provided URL.
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
// process your response here
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//perform operation here after getting error
}
});
// Add the request to the RequestQueue.
queue.add(stringRequest);
For more help refer How to user Volley
In simple way
private void load() {
JsonArrayRequest arrayreq = new JsonArrayRequest(ip.ip+"loadcollege.php",
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
Album a;
try {
JSONArray data = new JSONArray(response.toString());
for (int i = 0; i < data.length(); i++) {
JSONObject c = data.getJSONObject(i);
one = c.getString("cname").split(",");
two=c.getString("caddress").split(",");
three = c.getString("image").split(",");
four = c.getString("cid").split(",");
five = c.getString("logo").split(",");
a = new Album(one[0].toString(),two[0].toString(),ip.ip+"images/"+ three[0].toString(),four[0].toString(),ip.ip+"images/"+ five[0].toString());
albumList.add(a);
}
adapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
},
// The final parameter overrides the method onErrorResponse() and passes VolleyError
//as a parameter
new Response.ErrorListener() {
#Override
// Handles errors that occur due to Volley
public void onErrorResponse(VolleyError error) {
Log.e("Volley", "Error");
}
}
);
// Adds the JSON array request "arrayreq" to the request queue
requestQueue.add(arrayreq);
}
Before testing all of the above answers, include
compile 'com.android.volley:volley:1.0.0'
in your gradle file and don't forgot to add the Internet permission to your Manifest file.
Use this class. It provides you an easy way to connect to the database.
public class WebRequest {
private Context mContext;
private String mUrl;
private int mMethod;
private VolleyListener mVolleyListener;
public WebRequest(Context context) {
mContext = context;
}
public WebRequest setURL(String url) {
mUrl = url;
return this;
}
public WebRequest setMethod(int method) {
mMethod = method;
return this;
}
public WebRequest readFromURL() {
RequestQueue requestQueue = Volley.newRequestQueue(mContext);
StringRequest stringRequest = new StringRequest(mMethod, mUrl, new Response.Listener<String>() {
#Override
public void onResponse(String s) {
mVolleyListener.onRecieve(s);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
mVolleyListener.onFail(volleyError);
}
});
requestQueue.add(stringRequest);
return this;
}
public WebRequest onListener(VolleyListener volleyListener) {
mVolleyListener = volleyListener;
return this;
}
public interface VolleyListener {
public void onRecieve(String data);
public void onFail(VolleyError volleyError);
}
}
Example usage:
new WebRequest(mContext)
.setURL("http://google.com")
.setMethod(Request.Method.POST)
.readFromURL()
.onListener(new WebRequest.VolleyListener() {
#Override
public void onRecieve(String data) {
}
#Override
public void onFail(VolleyError volleyError) {
}
});
private void userregister() {
final ProgressDialog pDialog = new ProgressDialog(this);
pDialog.setMessage("Loading...");
pDialog.show();
RequestQueue queue = Volley.newRequestQueue(SignupActivity.this);
String url = "you";
StringRequest stringRequest = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
pDialog.cancel();
try {
JSONObject jsonObject= new JSONObject(response.toString());
Log.e("status", ""+jsonObject.getString("status"));
if(jsonObject.getString("status").equals("success"))
{
String studentid=jsonObject.getString("id");
Intent intent=new Intent(SignupActivity.this, OTPVerificationActivity.class);
startActivity(intent);
finish();
}
} catch (JSONException e) {
e.printStackTrace();
}
Log.e("String ", ""+response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("password", input_password.getText().toString());
params.put("cpassword", input_reEnterPassword.getText().toString());
params.put("email", input_email.getText().toString());
params.put("status", "1");
params.put("last_name", input_lastname.getText().toString());
params.put("phone", input_mobile.getText().toString());
params.put("standard", input_reStandard.getText().toString());
params.put("first_name", input_name.getText().toString());
params.put("refcode", input_reReferal.getText().toString());
params.put("created_at","");
params.put("update_at", "");
params.put("address", input_address.getText().toString());
return params;
}
};
// Add the request to the RequestQueue.
queue.add(stringRequest);
Get full code here

Categories

Resources