I am starting then 4 post after each other. But I catch only response from 3 of the 4 posts.
Can somebody explain to me why? I tried it also with get and it has the same problem. Am I doing the posts to quick after each other?
Resclient class:
public class RestClient {
private static AsyncHttpClient client = new AsyncHttpClient();
public static void post(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {
client.post(url, params, responseHandler);
}
}
Webservice resolver:
public class WSBeer extends WSBase {
public WSBeer(OnWSRequestCompleted listener, Context context) {
super(listener, context);
}
public void getAll(String date) throws JSONException {
Tools.LOG_DEBUG("GetAllBeer");
RequestParams params = new RequestParams();
params.add("date", date);
RestClient.post(url, params, new JsonHttpResponseHandler() {
#Override
public void onSuccess(JSONObject response) {
Tools.LOG_DEBUG("WSBeer onSucces: " + response);
listener.onRestTaskCompleted(Constants.FUNCTION_DB_BEER, response);
}
#Override
public void onFailure(Throwable e, JSONArray errorResponse) {
Tools.LOG_DEBUG("WSBeer getAll: " + errorResponse);
handleError(e, errorResponse, null);
}
#Override
public void onFailure(Throwable e, JSONObject errorResponse) {
Tools.LOG_DEBUG("WSBeer getAll: " + errorResponse);
handleError(e, null, errorResponse);
}
});
}
}
SyncHandler class:
public class SyncHandler implements OnWSRequestCompleted {
private OnSyncListener listener;
private Context context;
private WSBeer wsBeer;
public SyncHandler(OnSyncListener listener, Context context) {
this.listener = listener;
this.context = context;
}
#Override
public void onRestTaskCompleted(int function, JSONObject response) {
switch (function) {
case Constants.FUNCTION_DB_BEER:
List<Beer> beerList = null;
try {
beerList = ResponseBeer.getAll(response);
} catch (IOException e) {
Tools.LOG_ERROR(e);
}
Tools.LOG_DEBUG("Beers");
if (beerList != null) {
new SaveBeerHelper(listener).execute(beerList.toArray(new Beer[beerList.size()]));
}
break;
}
}
public void syncBeer() {
wsBeer = new WSBeer(this, context);
try {
Tools.LOG_DEBUG("Start loading beer...");
String date = getSyncDate(Constants.FUNCTION_DB_BEER);
wsBeer.getAll(date);
} catch (JSONException e) {
e.printStackTrace();
}
}
private String getSyncDate(int databaseId) {
SyncData syncData = Shared.dbRepo.syncRepository.getById(databaseId);
if (syncData != null) {
Tools.LOG_DEBUG("SyncData: " + syncData.getSyncDate().toString());
return syncData.getSyncDate().toString();
} else {
new SyncData(databaseId).Save(Shared.dbRepo);
}
Tools.LOG_DEBUG("SyncData: ");
return "";
}
}
WEBSERVICE ACTION:
public function bierenAction()
{
$this->view->status = 204; //Nog geen content
if ($this->getRequest()->isPost()){
$date = $this->postParam('date');
if ($date != "") {
$bieren = self::$proxyBier->getBierenByUpdated($date);
} else {
$bieren = self::$proxyBier->getBieren();
}
} else {
$bieren = self::$proxyBier->getBieren();
}
$this->view->data = $bieren;
$this->view->status = 200; //Alles oke
$this->view->ajax();
}
Also you can use this instead https://github.com/leonardoxh/AsyncOkHttpClient this library just use OkHttpClient instead of Apache librarys, and this library is the base codes for Loopj AsyncHttpClient 2.0 (where the library will be re implemented with Square OkHttp)
I used the newer version of async-http library
compile 'com.loopj.android:android-async-http:1.4.5-SNAPSHOT'
and everything works like a charm :)
Related
I get a result by using okhttp3 get method.
And Now, I want to return the result to MainActivity.
I tried using intent, but I'm failed.
Also I read this okhttp3 how to return value from async GET call. But I confused about where I have to write that code.
public interface GetLastIdCallback {
void lastId(String id);
}
my MainActivity:
getMaskInfo info = new getMaskInfo(this);
info.requestGet(latitude, longitude);
getMaskInfo Activity (I want to return JSONObject or JSONArray):
package com.example.buymaskapp;
public class getMaskInfo {
OkHttpClient client = new OkHttpClient();
public static Context mContext;
public getMaskInfo(Context context){
mContext = context;
}
public void requestGet(double lat, double lng){
String url = "https://8oi9s0nnth.apigw.ntruss.com/corona19-masks/v1/storesByGeo/json";
HttpUrl.Builder urlBuilder = HttpUrl.parse(url).newBuilder();
urlBuilder.addEncodedQueryParameter("lat", Double.toString(lat));
urlBuilder.addEncodedQueryParameter("lng", Double.toString(lng));
urlBuilder.addEncodedQueryParameter("m", "1000");
String requestUrl = urlBuilder.build().toString();
Request request = new Request.Builder().url(requestUrl).build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
Log.d("error", "Connect Server Error is " + e.toString());
}
#Override
public void onResponse(Call call, Response response) throws IOException {
try{
JSONObject jsonObject = new JSONObject(response.body().string());
JSONArray totalStore = jsonObject.getJSONArray("stores");
System.out.println(jsonObject);
}catch (JSONException e){
//
}
}
});
}
}
Instead of returning void from requestGet() method, return a LiveData
public LiveData<JSONObject> requestGet(double lat, double lng) {
LiveData<JSONObject> result = MutableLiveData<JSONObject>();
/* reqeust builder & url builder code here */
client.newCall(request).enqueue(new Callback() {
/* override other methods here */
public void onResponse(Call call, Response response) throws IOException {
try{
JSONObject jsonObject = new JSONObject(response.body().string());
((MutableLiveData) result).postValue(jsonObject);
}catch (JSONException e){
/* catch and do something */
}
}
});
return result;
}
Observe the livedata in mainactivity
info.requestGet(latitude, longitude).observe(getViewLifeCycleOwner, new Observer() {
#Override
public void onCanged(JSONObject result) {
/* code to use result */
}
});
Otherwise, you can also implement interface on mainactivity and use its instance in getMaskInfo or in requestGet method to send back data.
Create a callback in MainActivity:
public void onResult(JSONArray stores)
or whatever you want to return from the call. Since you now know that your mContext is actually MainActivity, you can make a cast and call that method
((MainActivity)mContext).onResult(totalStore).
If you need to use getMaskInfo with other activities as well, you can put method onResult into an interface, make MainActivity implement that interface and pass the interface as an argument to getMaskInfo.
Interface class
public interface GetLastIdCallback {
void lastId(String id);
void getJSONCallback(JSONObject object);
}
Update the onResponse function
#Override
public void onResponse(Call call, Response response) throws IOException {
try{
JSONObject jsonObject = new JSONObject(response.body().string());
JSONArray totalStore = jsonObject.getJSONArray("stores");
System.out.println(jsonObject);
((GetLastIdCallback )(mContext)).getJSONCallback(jsonObject); //Return here
}catch (JSONException e){
//
}
}
});
Calling activity must implement GetLastIdCallback interface
public class Main2Activity extends AppCompatActivity implements GetLastIdCallback{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
}
#Override
public void lastId(String id) {
}
#Override
public void getJSONCallback(JSONObject object) {
//Here you can use response according to your requirements
}
}
I get the data from API such as printer name, model and status and displaying in the listview in array adapter.In my program I am testing if the printer is idle or not and showing by using green(idle) and red (busy) circles in the listview , but my issue is that the state has to be constantly checked and get updated to display on screen green or red circle, for this case I was checking out into handler and timers and tried to implement it but unsuccessfully - nothing worked. I am unsure which one is better to use and how , since I am using array adapter.
If you have any insights, please let me know.
My adapter class:
public class NsdServiceInfoAdapter extends ArrayAdapter<PrinterNew> {
private Context mContext;
private List<PrinterNew> services;
private InetAddress hostAddress;
//Creating new constructor with parameters such as this class(context), layout id (list item layout Id) and data model.
public NsdServiceInfoAdapter(#NonNull Context context, int layoutId, List<PrinterNew> list) {
super(context, layoutId, list);
mContext = context;
services = list;
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull
ViewGroup parent) {
View listItem = convertView;
//Checking if view is empty then we inflate our list layout.
if (listItem == null)
listItem =
LayoutInflater.from(mContext).inflate(R.layout.list_item, parent, false);
//Getting data's position in the data set.
final PrinterNew currentService = services.get(position);
final ImageView i = listItem.findViewById(R.id.status_circle);
TextView t = listItem.findViewById(R.id.TextView_serviceName);
final TextView r = listItem.findViewById(R.id.TextView_serviceIP);
r.setText(currentService.getPrinterModel());
t.setText(currentService.getPrinterName());
if (currentService.isIdle()) {
i.setColorFilter(Color.rgb(42, 187, 155));
} else {
i.setColorFilter(Color.rgb(240, 52, 52));
}
return listItem;
}
}
My printer class
public PrinterNew() {
}
public String getPrinterName() {
return printerName;
}
public void setPrinterName(String printerName) {
this.printerName = printerName;
}
public String getPrinterModel() {
return printerModel;
}
public String getPrinterInformation() {
return this.printInformation;
}
public void setPrinterInformation(String url, Context context, final VolleyCallback callback) {
Log.d("API", "Currently calling URL " + url);
RequestQueue queue = Volley.newRequestQueue(context);
queue.add(new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d("API", "Print information" + response);
String temp = response.substring(2, response.length() - 2);
byte msgArray[];
try {
msgArray = temp.getBytes("ISO-8859-1");
state = msgArray[0];
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
printInformation = response;
callback.onSuccess(printInformation);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("API", "Print information nope ");
callback.onFailure(error);
}
}));
}
public String getMenuInformation() {
return menuInformation;
}
public void setMenuInformation(String url, Context context, final VolleyCallback callback) {
Log.d("API", "Currently calling URL " + url);
RequestQueue queue = Volley.newRequestQueue(context);
queue.add(new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
String temp = response.substring(2, response.length() - 2);
Log.d("API", "Current menu" + response);
byte msgArray[];
try {
msgArray = temp.getBytes("ISO-8859-1");
currentMenu = msgArray[0];
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
menuInformation = response;
callback.onSuccess(menuInformation);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("API", "Current menu Nope ");
callback.onFailure(error);
}
}));
}
public boolean isIdle() {
if (state == -1 && currentMenu == 0) {
return true;
} else {
return false;
}
}
public void setPrinterService(NsdServiceInfo service) {
this.printerService = service;
}
public NsdServiceInfo getPrinterService() {
return this.printerService;
}
public interface VolleyCallback {
void onSuccess(String result);
void onFailure(Object response);
}
public void setPrinterModel(String url, Context context, final VolleyCallback callback) {
Log.d("API", "Currently calling URL " + url);
RequestQueue queue = Volley.newRequestQueue(context);
queue.add(new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("API", "printer model nope ");
callback.onFailure(error);
}
}));
}
}
use recyclerview.
to refresh your list whenever there is data change in the list with recyclerview, you need to user adapter.notifyDataSetChanged()
but catch here is you need to get exact object in the list, the update it then refresh it with above line.
Hope this helps.
I have created a separate class in which I have defined all about volley and in another activity, I have directly pass URL, CONTEXT and Get Response...
but in my NavDrawerActivity.java how do I call the subCategoryJSON(); method without writing my volley code again as I have done with mainCategoryJSON(); method in which I just simply pass the URL, method type.
Also is this a correct approach I am doing or there need to be some modification in the code, what I want is that wherever I am using API in my project and using volley for it, I don't have to write code again and again just simply pass the URL,method type
VolleyResponseListener.java
public interface VolleyResponseListener {
void onResponse(String response, String tag);
void onError(VolleyError error, String tag);
}
CustomStringRequestVolley.java
public class CustomStringRequestVolley {
private String url;
private String tag;
Context ctx;
private VolleyResponseListener volleyResponseListener;
public CustomStringRequestVolley(String url, String tag,Context ctx,VolleyResponseListener volleyResponseListener){
this.url = url;
this.tag = tag;
this.ctx=ctx;
this.volleyResponseListener = volleyResponseListener;
sendRequest();
}
private void sendRequest() {
final ProgressDialog pDialog = new ProgressDialog(ctx);
pDialog.setMessage("Loading ...");
pDialog.show();
StringRequest stringRequest = new StringRequest(Request.Method.GET,url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.e("catresponse", "response " + response);
if (pDialog.isShowing()) {
pDialog.dismiss();
}
volleyResponseListener.onResponse(response, tag);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
stringRequest.setRetryPolicy(new DefaultRetryPolicy(
5000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
VolleySingleton.getInstance(ctx).addToRequestQueue(stringRequest);
}
}
NavDrawerActivity.java
public class NavDrawerActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener, VolleyResponseListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_nav_drawer);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mainCategoryJSON();
subCategoryJSON();
}
private void mainCategoryJSON() {
CustomStringRequestVolley request1 = new CustomStringRequestVolley(URLs.categoryURL, "TAG1", this, this);
}
#Override
public void onResponse(String response, String tag) {
switch (tag) {
case "TAG1":
try {
Log.i("Responseeeeeezaq :", response.toString() + " " + tag);
JSONObject obj = new JSONObject(response);
JSONArray productArray = obj.getJSONArray("categories");
for (int i = 0; i < productArray.length(); i++) {
JSONObject productObject = productArray.getJSONObject(i);
CategoryModelClass categoryModelClass = new CategoryModelClass();
categoryModelClass.setCategoryID(productObject.getInt("Category-Id"));
categoryModelClass.setCategoryName(productObject.getString("Category-Name"));
categoryModelClass.setCategoryImg(productObject.getString("Category-Image"));
categoryArrayList.add(categoryModelClass);
Log.d("zpuyi", String.valueOf(categoryArrayList));
}
categoryAdapter.notifyDataSetChanged();
} catch (Exception e) {
e.printStackTrace();
}
break;
}
}
#Override
public void onError(VolleyError error, String tag) {
VolleyLog.e("Error: ", error.getMessage());
}
private void subCategoryJSON() {
StringRequest stringRequest = new StringRequest(Request.Method.GET, URLs.subcategoryURL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d("subcategoryJsonResponse", response.toString());
try {
JSONObject obj = new JSONObject(response);
JSONArray productArray = obj.getJSONArray("sub-categories");
for (int i = 0; i < productArray.length(); i++) {
JSONObject productObject = productArray.getJSONObject(i);
SubCategoryModelClass subCategoryModelClass = new SubCategoryModelClass();
subCategoryModelClass.setSubCategory_Id(productObject.getInt("Subcategories-Id"));
subCategoryModelClass.setCat_id(productObject.getInt("categories-Id"));
subCategoryModelClass.setSubCategory_Name(productObject.getString("Subcategories-Name"));
subCategoryModelClass.setSubCategory_Img(productObject.getString("Subcategories-Image"));
subCategoryModelClassList.add(subCategoryModelClass);
Log.d("subCategoryArraylist", String.valueOf(subCategoryModelClassList));
}
for (int i = 0; i < subCategoryModelClassList.size(); i++) {
subcategory_id = subCategoryModelClassList.get(i).getSubCategory_Id();
category_id = subCategoryModelClassList.get(i).getCat_id();
subcategory_name = subCategoryModelClassList.get(i).getSubCategory_Name();
// subcategory_desc = subCategoryModelClassList.get(i).getSubCategory_Desc();
subcategory_image = subCategoryModelClassList.get(i).getSubCategory_Img();
Log.d("fdsaff", subcategory_image);
SQLiteDatabase database = dbHelper.getWritableDatabase();
dbHelper.insertSubCategoryProduct(subcategory_id, category_id, subcategory_name, "https://www.ecrm.sample.in/app/img/"+subcategory_image, database);
dbHelper.close();
}
subCategoryAdapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.e("Error: ", error.getMessage());
}
});
VolleySingleton.getInstance(getApplicationContext()).addToRequestQueue(stringRequest);
}
}
You have written the answer correctly but you are not implementing the written custom volley class code in the activity class.
First Define the interface class for the Volley as below,
Now implement the volley interface in the java class where you have written the custom volley class as below:
CustomStringRequestVolley.java
public class CustomStringRequestVolley implements volleyCallback {
public Context context;
public CustomStringRequestVolley(Context context) {
this.context = context;
}
public interface volleyCallback {
void onSuccess(String result);
void onError(String error);
}
public void callGetServer(String URL, final
volleyCallback callback){
if (!checkInternetConnection(context)) {
showNoInternetDialogue(context);
return;
}
RequestQueue requestQueue = Volley.newRequestQueue(context);
StringRequest stringRequest = new StringRequest(Request.Method.GET, URL, new
Response.Listener<String>() {
#Override
public void onResponse(String response) {
callback.onSuccess(response);
}
}, error -> {
if (error.networkResponse == null){
if (error.getClass().equals(TimeoutError.class)){
Toast.makeText(context, "Timeout.Please try again",
Toast.LENGTH_SHORT).show();
}else if (error.getClass().equals(NoConnectionError.class)){
Toast.makeText(context, "Timeout.Please try again", Toast.LENGTH_SHORT).show();
}else if (error.getClass().equals(NetworkError.class)) {
Toast.makeText(context, "Network Error.Please try again", Toast.LENGTH_SHORT).show();
}else if (error.getClass().equals(ParseError.class)){
Toast.makeText(context, "Parse error", Toast.LENGTH_SHORT).show();
}else if (error.getClass().equals(ServerError.class)){
Toast.makeText(context, "Server Error.Please try again", Toast.LENGTH_SHORT).show();
}
else {
parseVolleyError(error);
}
}
}
) {
#Override
protected Map<String, String> getParams() {
return new HashMap<>();
}
#Override
public Map<String, String> getHeaders() {
Map<String, String> headers = new HashMap<>();
headers.put("Content-Type", "application/x-www-form-urlencoded");
return headers;
}
};
//setting up the retry policy for slower connections
int socketTimeout = 120000;//120000 milli seconds - change to what you want
RetryPolicy policy = new DefaultRetryPolicy(socketTimeout,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
stringRequest.setRetryPolicy(policy);
requestQueue.add(stringRequest);
}
}
Now use this Custom volley class in every activity you required. It reduces you
boilerplate code
NavDrawerActivity.java
CustomStringRequestVolley customStringRequestVolley;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_starting_point_navigation);
customStringRequestVolley = new CustomStringRequestVolley(this);
}
private void subCategoryJSON() {
customStringRequestVolley.callGetServer(URLs.subcategoryURL,new volleyCallback() {
#Override
public void onSuccess(String result) {
try {
JSONObject obj = new JSONObject(response);
JSONArray productArray = obj.getJSONArray("sub-categories");
for (int i = 0; i < productArray.length(); i++) {
JSONObject productObject = productArray.getJSONObject(i);
SubCategoryModelClass subCategoryModelClass = new SubCategoryModelClass();
subCategoryModelClass.setSubCategory_Id(productObject.getInt("Subcategories-Id"));
subCategoryModelClass.setCat_id(productObject.getInt("categories-Id"));
subCategoryModelClass.setSubCategory_Name(productObject.getString("Subcategories-Name"));
subCategoryModelClass.setSubCategory_Img(productObject.getString("Subcategories-Image"));
subCategoryModelClassList.add(subCategoryModelClass);
Log.d("subCategoryArraylist", String.valueOf(subCategoryModelClassList));
}
for (int i = 0; i < subCategoryModelClassList.size(); i++) {
subcategory_id = subCategoryModelClassList.get(i).getSubCategory_Id();
category_id = subCategoryModelClassList.get(i).getCat_id();
subcategory_name = subCategoryModelClassList.get(i).getSubCategory_Name();
// subcategory_desc = subCategoryModelClassList.get(i).getSubCategory_Desc();
subcategory_image = subCategoryModelClassList.get(i).getSubCategory_Img();
Log.d("fdsaff", subcategory_image);
SQLiteDatabase database = dbHelper.getWritableDatabase();
dbHelper.insertSubCategoryProduct(subcategory_id, category_id, subcategory_name, "https://www.ecrm.sample.in/app/img/"+subcategory_image, database);
dbHelper.close();
}
subCategoryAdapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public void onError(String error) {
//show error code
}
});
}
Let me know after you try this #Abhishek
The first request done successfully but second request in queue return null , when setting break point and start debugging the second request get it's value successfully
class ListLoader extends AsyncTask<Void,Void,MerchantCategories[]>
{
MerchantCategories[] data;
protected void onPreExecute() {
progressBar.setVisibility(View.VISIBLE);
}
#Override
protected MerchantCategories[] doInBackground(Void... params) {
Gson g = new Gson();
gcm = GoogleCloudMessaging.getInstance(getApplicationContext());
try {
regid = gcm.register(PROJECT_NUMBER);
String msg="";
msg = "Device registered, registration ID=" + regid;
Log.i("GCM", msg);
EgxServices.getJsonFrom("http://inareg.com/APIs/RegisterAndroidDevice?registrationID="+regid,(Activity) c);
} catch (IOException e) {
e.printStackTrace();
}
MerchantCategories[] categs=g.fromJson(EgxServices.getJsonFrom("http://inareg.com/APIs/ListMerchantCategories",(Activity) c),MerchantCategories[].class);
return categs;
}
protected void onPostExecute(MerchantCategories[] response) {
if(response == null) {
progressBar.setVisibility(View.GONE);
}
else{
progressBar.setVisibility(View.GONE);
MerchantCategoriesAdp adp =new MerchantCategoriesAdp(c,R.layout.lst_merchant_categories,response);
drawerList.setAdapter(adp);
// Log.i("INFO", response);
// responseView.setText(response);
}
}
}
This method which i used to initialize a new request and return JSON String
public static String getJsonFrom(final String urlStr, Activity context) {
final Context c = context;
final SharedValue value = new SharedValue();
String result="";
StringRequest request = new StringRequest(Request.Method.GET,urlStr,new Response.Listener<String>(){
#Override
public void onResponse(String response) {
value.setResult(response);
}
},new Response.ErrorListener(){
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(c, "No Internet Connection",
Toast.LENGTH_LONG).show();
}
});
Volley.newRequestQueue(c).add(request);
return value.getResult();
}
as you can see that first request
EgxServices.getJsonFrom("http://inareg.com/APIs/RegisterAndroidDevice?registrationID="+regid,(Activity) c);
run successfully but the second one ,
EgxServices.getJsonFrom("http://inareg.com/APIs/ListMerchantCategories",(Activity) c);
always return null value ...
i need to know why ?????!!!
Try this :
request.setShouldCache(false);
before Volley.newRequestQueue(c).add(request);
public void getTestDats(String unique_id) {
final String tag = "testList";
String url = Constants.BASE_URL + "test_module.php";
Map<String, String> params = new HashMap<String, String>();
params.put("user_id", SharedPreferenceUtil.getString(Constants.PrefKeys.PREF_USER_ID, "1"));
params.put("unique_id", unique_id);//1,2,3,4,5
DataRequest loginRequest = new DataRequest(Method.POST, url, params, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
switch (response.optInt("unique_id")) {
case 1:
//task 1
break;
case 2:
//task 2
break;
default:
//nothing
}
}
}, new ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//I want to know which unique_id request is failed
}
});
loginRequest.setRetryPolicy(new DefaultRetryPolicy(20000, 0, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
AppController.getInstance().addToRequestQueue(loginRequest, tag);
}
I'm trying to identity which request is failed with having unique_id.
I'm calling getTestDats("1") function with unique_id. And function called 10 times and all the api call in addToRequestQueue.
When API go into Success part its working as per code.
But when API go into Error part I didn't identity the request.
Is there any way to know my request param so I can retry with particular unique_id request.
set a field in loginRequest and in onErrorResponse access the field like loginRequest.getUniqueId()
Alternatively, create a seperate class that implements Response.Listener and ErrorListener
Response Listener class:
public class MyReponseListener implements Response.Listener<JSONOBject>{
private long uniqId;
public MyResponseListener(long uniqId){
this.uniqId = uniqId;
}
#Override
public void onResponse(JSONObject response) {
System.out.println("response for uniqId " + uniqId);
// do your other chit chat
}
}
ErrorListener class:
public class MyErrorListener implements ErrorListener{
private long uniqId;
public MyErrorListener(long uniqId){
this.uniqId = uniqId;
}
#Override
public void onErrorResponse(VolleyError error) {
System.out.println("Error for uniqId : " + uniqId);
}
}
Now call it like:
DataRequest loginRequest = new DataRequest(Method.POST, url, params, new MyResponeListener(uniqId), new MyErrorListener(uniqId));
Now if you want some code of the calling class to be accessible in the ErrorListener class then do the following:
1. In calling class put the codes you want to access in methods
2. Create an interface with those method
3. The calling class will implement that interface
4. Pass the interface to constructor of the MyErrorListener or MyResponseListener
for example an activity calls the volley request, on error you want to show a message.
put that show error codes in a method:
public void showMessage(int errorCode){
//message according to code
}
now create an interface
public interface errorMessageInterface{
void showMessage(int errorCode);
}
the activity will implement errorMessageInterface and pass this to the constructor of MyErrorListener and save it in a field.
Inside onErrorResponse, you will call
field.showMessage()
You can parse error response in the same way as you parse success response. I use similar solution in my projects.
public class VolleyErrorParser {
private VolleyError mError;
private String mBody;
private int mUniqueId = -1;
public VolleyErrorParser(VolleyError e){
mError = e;
parseAnswer();
parseBody();
}
private void parseBody() {
if (mBody==null)
return;
try{
JSONObject response = new JSONObject(mBody);
mUniqueId = response.getOptInt("unique_id");
}catch (JSONException e){
e.printStackTrace();
}
}
private void parseAnswer() {
if (mError!=null&&mError.networkResponse!=null&&mError.networkResponse.data!=null){
mBody = new String(mError.networkResponse.data);
}
}
public String getBody(){
return mBody;
}
public int getUniqueId(){
return mUniqueId;
}
}
Use:
...
, new ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
int id = new VolleyErrorParse(error).getUniqueId();
switch (id) {
case -1:
//unique id not found in the answer
break;
case 1:
//task 1
break;
case 2:
//task 2
break;
default:
//nothing
}
}
}
...
Just add this code to identify which type of error you are facing.Add this in your onError() method :
if (error instanceof TimeoutError) {
Log.e(TAG, "TimeoutError");
} else if (error instanceof NoConnectionError) {
Log.e(TAG,"tNoConnectionError");
} else if (error instanceof AuthFailureError) {
Log.e(TAG,"AuthFailureError");
} else if (error instanceof ServerError) {
Log.e(TAG,"ServerError");
} else if (error instanceof NetworkError) {
Log.e(TAG,"NetworkError");
} else if (error instanceof ParseError) {
Log.e(TAG,"ParseError");
}
Log the unique_id before making a request i.e; after params.put("unique_id", unique_id);//1,2,3,4,5. And also once you get the response in onResponse() method. And cross verify what exactly is happening.
most of the solutions here will "work" but they are too complex .. for me :)
here is the simplest option with least code change I can think of:
...
final Map<String, String> params = new HashMap<String, String>();
params.put("user_id", SharedPreferenceUtil.getString(Constants.PrefKeys.PREF_USER_ID, "1"));
params.put("unique_id", unique_id);//1,2,3,4,5
DataRequest loginRequest = new DataRequest(Method.POST, url, params, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
switch (params.get("unique_id")) {
case 1:
//task 1
break;
case 2:
//task 2
break;
default:
//nothing
}
}
...
All the above answers seem to be correct.But i recommend you to do this in an optimized way. If you will add error handling code in all onErrorResponse() then it will create duplication. So create a seperate method in Utils or some other class and just call that method by passing error object to the method. Also you can inflate some dialog or toast to display an error message.
public static void handleError(final Context context, String alertTitle,
Exception exception, String logTag) {
if (context != null) {
if (exception instanceof TimeoutError)
message = context.getString(R.string.TimeoutError);
else if (exception instanceof NoConnectionError)
message = context.getString(R.string.NoConnectionError);
else if (exception instanceof AuthFailureError)
message = context.getString(R.string.AuthFailureError);
else if (exception instanceof ServerError)
message = context.getString(R.string.ServerError);
else if (exception instanceof NetworkError)
message = context.getString(R.string.NetworkError);
else if (exception instanceof ParseError)
message = context.getString(R.string.ParseError);
message = exception.getMessage();
DialogHelper.showCustomAlertDialog(context, null,
alertTitle, message, "ok",
new OnClickListener() {
#Override
public void onClick(DialogInterface dialog,
int which) {
}
}, null, null);
}
}
I think you have to make one conman method on Base class. As given bellow which I used in my code for calling php web api
/**
* <h1> Use for calling volley webService </h1>
*
* #param cContext Context of activity from where you call the webService
* #param mMethodType Should be POST or GET
* #param mMethodname Name of the method you want to call
* #param URL Url of your webService
* #param mMap Key Values pairs
* #param initialTimeoutMs Timeout of webService in milliseconds
* #param shouldCache Web Api response are stored in catch(true) or not(false)
* #param maxNumRetries maximum number in integer for retries to execute webService
* #param isCancelable set true if you set cancel progressDialog by user event
* #param aActivity pass your activity object
*/
public void callVolley(final Context cContext, String mMethodType, final String mMethodname, String URL,
final HashMap<String, String> mMap, int initialTimeoutMs, boolean shouldCache, int maxNumRetries,
Boolean isProgressDailogEnable, Boolean isCancelable, final Activity aActivity) {
mMap.put("version_key_android",BuildConfig.VERSION_NAME+"");
if (!isOnline(cContext)) {
//showErrorDailog(aActivity, Constant.PleaseCheckInternetConnection, R.drawable.icon);
} else {
StringRequest jsObjRequest;
int reqType = 0;
String RequestURL = URL.trim();
queue = Volley.newRequestQueue(cContext);
if (isProgressDailogEnable) {
customLoaderDialog = new CustomLoaderDialog(cContext);
customLoaderDialog.show(isCancelable);
customLoaderDialog.dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
// finish();
}
});
}
if (mMethodType.trim().equalsIgnoreCase("GET"))
reqType = com.android.volley.Request.Method.GET;
else if (mMethodType.trim().equalsIgnoreCase("POST"))
reqType = com.android.volley.Request.Method.POST;
if (RequestURL.equals(""))
RequestURL = Constant.BASE_URL;
else
RequestURL = URL;
if (Constant.d) Log.d("reqType", reqType + "");
jsObjRequest = new StringRequest(reqType, RequestURL, new com.android.volley.Response.Listener<String>() {
#Override
public void onResponse(String response) {
if (Constant.d) Log.d("response==>" + mMethodname, "" + response);
if (customLoaderDialog != null) {
try {
customLoaderDialog.hide();
} catch (Exception e) {
e.printStackTrace();
}
}
if (response == null || response.length() == 0) {
IVolleyRespose iVolleyRespose = (IVolleyRespose) aActivity;
iVolleyRespose.onVolleyResponse(404, response, mMethodname);
} else {
JSONObject json_str;
try {
json_str = new JSONObject(response);
int status = json_str.getInt("status");
if (status == 100) {
AlertDialog alertDialog = new AlertDialog.Builder(aActivity).create();
alertDialog.setTitle(getResources().getString(R.string.app_name));
alertDialog.setMessage(json_str.getString("message") + "");
alertDialog.setCancelable(false);
alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
try {
Intent viewIntent =
new Intent("android.intent.action.VIEW",
Uri.parse(Constant.playStoreUrl));
startActivity(viewIntent);
}catch(Exception e) {
Toast.makeText(getApplicationContext(),"Unable to Connect Try Again...",
Toast.LENGTH_LONG).show();
e.printStackTrace();
}
dialog.dismiss();
// return;
}
});
alertDialog.show();
} else {
IVolleyRespose iVolleyRespose = (IVolleyRespose) aActivity;
iVolleyRespose.onVolleyResponse(RESPONSE_OK, response, mMethodname);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}, new com.android.volley.Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError arg0) {
// TODO Auto-generated method stub
IVolleyRespose iVolleyError = (IVolleyRespose) aActivity;
iVolleyError.onVolleyError(404, "Error", mMethodname);
if (customLoaderDialog != null) {
customLoaderDialog.hide();
}
}
}) {
#Override
protected Map<String, String> getParams() {
String strRequest = "";
try {
strRequest = getWebservicejsObjRequestforvolley(mMethodname, mMap);
if (Constant.d) Log.d("Request==>", strRequest + "");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Map<String, String> params = new HashMap<>();
params.put("json", strRequest);
return params;
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("Content-Type", "application/x-www-form-urlencoded");
return params;
}
};
//if(Constant.d) Log.d("Request==>", jsObjRequest+"");
jsObjRequest.setTag(mMethodname);
jsObjRequest.setShouldCache(shouldCache);
jsObjRequest.setRetryPolicy(new DefaultRetryPolicy(initialTimeoutMs, maxNumRetries, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
queue.add(jsObjRequest);
}
}
Please observe that here we make one interface for getting response and error.
Using Interface you can get method name on both response and error so you can identify which web api is successfully called and which give error. You should extend base class to Activity and also implement Interface which you made for getting volley response. Here in above code I show how to bind interface to activity. when you call api by passing activity context.