Cannot call runOnUiThread() - android

I have a fragment called MyRequestFragment, that contains a RecyclerView and binding the data to the RecyclerView using onBindViewHolder() using my adapter class.
Now every ViewHolder I have a button. and for every click on the button a POST request fired to the server and update a value. My problem is, if a success response comes, I need to hide the button on the particular ViewHolder.
The actual problem is the runOnUiThread() is not accept on the onBindViewHolder()
runOnUiThread(new Runnable() {
public void run() {
}
});
How do I call this inside the ViewHolder create / bind method.
My onBindViewHolder() full code is as bellow for reference.
#Override
public void onBindViewHolder(MyServiceViewHolder holder, int position) {
final MyServiceBean myServiceBean = serviceList.get(position);
holder.service_name.setText(myServiceBean.getService_name());
holder.last_updated.setText("Job Updated Date : " +myServiceBean.getDate(myServiceBean.getUpdated_at()));
holder.created_date.setText("Job Created Date : " + myServiceBean.getDate(myServiceBean.getCreated_at()));
holder.status.setText(myServiceBean.getStatus());
holder.service_note.setText("Service Note : " + myServiceBean.getService_note());
if (myServiceBean.getService_note().toString().isEmpty())
holder.service_note.setVisibility(View.GONE);
switch (myServiceBean.getStatus().toString().toLowerCase()) {
case "completed":
holder.status.setBackgroundColor(Color.GREEN);
break;
case "on progress":
holder.status.setBackgroundColor(Color.YELLOW);
break;
case "canceled":
holder.status.setBackgroundColor(Color.RED);
break;
case "rejected":
holder.status.setBackgroundColor(Color.RED);
break;
case "accept":
holder.status.setBackgroundColor(Color.BLUE);
break;
default:
holder.status.setBackgroundColor(Color.GRAY);
break;
}
if(myServiceBean.getEst_amount() != null) {
holder.estimation_region.setVisibility(View.VISIBLE);
holder.est_status.setText("Estimation is Available");
holder.btn_approve.setVisibility(View.VISIBLE);
holder.est_amount.setText("Estimation Amount: " + myServiceBean.getEst_amount());
if(myServiceBean.getEst_note() != null)
holder.est_note.setText("Estimation Note: " + myServiceBean.getEst_note());
if(myServiceBean.getEst_presented_by() != null)
holder.est_presented_by.setText("Estimation Prepared By: " + myServiceBean.getEst_presented_by());
if(myServiceBean.getEst_approved_by_customer() == "true"){
holder.btn_approve.setVisibility(View.GONE);
holder.est_status.setText("Estimation Approved on : " + myServiceBean.getEst_approved_date());
}else{
holder.btn_approve.setVisibility(View.VISIBLE);
}
}else{
holder.estimation_region.setVisibility(View.GONE);
holder.est_status.setText("Estimation on Process");
holder.btn_approve.setVisibility(View.GONE);
}
holder.btn_approve.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
updateRequest();
}
});
}
private void updateRequest() {
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("est_approved_by_customer", true);
jsonObject.put("est_approved_date", "2017-10-30");
} catch (JSONException e) {
e.printStackTrace();
}
//progress_dialog.show();
OkHttpClient client = new OkHttpClient();
MediaType JSON = MediaType.parse("application/json; charset=utf-8");
okhttp3.RequestBody body = RequestBody.create(JSON, jsonObject.toString());
okhttp3.Request request = new Request.Builder()
.url(ApplicationContants.BASE_URL + ApplicationContants.MY_SERVICE_APPROVE_URL)
.post(body)
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, final IOException e) {
}
#Override
public void onResponse(Call call, Response response) throws IOException {
try {
String responseString = response.body().string();
JSONObject jsonObject = new JSONObject(responseString);
Gson gson = new Gson();
final MyServiceBean myServiceBean = gson.fromJson(jsonObject.toString(), MyServiceBean.class);
runOnUiThread(new Runnable() {
public void run() {
}
});
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}

runOnUiThread() is a method of Activity.
Either call it on an Activity instance (if you have access to one), or use a Handler to post your Runnable to the message queue of the main thread:
new Handler(Looper.getMainLooper()).post(new Runnable() {
public void run() {
// do something
}
});

You should get your activity before calling runOnUiThread:
getActivity.runOnUiThread(new Runnable(){
#Override
public void run(){
/*your code*/
}
});

Related

android janus webrtc ondatachannel not triggered

i have made Janus videoroom work normally, now i want to implement DataChannel to send message to each other between devices
i have set data:true when publisher send configure and subscriber join
void sendLocalDescription(BigInteger handleId, JSONObject sdpObj) {
try {
JSONObject msg = new JSONObject();
JSONObject body = new JSONObject();
body.put(REQUEST, BodyRequestMessageType.CONFIGURE.getType());
body.put(AUDIO, options.audio);
body.put(VIDEO, options.video);
body.put(DATA, true);
msg.put(JANUS, SendMessageType.MESSAGE.getType());
msg.put(TRANSACTION, RandomUtil.randomString());
msg.put(SESSION_ID, sessionId);
msg.put(HANDLE_ID, handleId);
msg.put(BODY, body);
msg.put(JESP, sdpObj);
connection.sendMessage(msg.toString());
Log.e(SERVER_TAG, "publisher sendLocalDescription: " + body.toString());
} catch (JSONException e) {
e.printStackTrace();
}
}
and here is for subscriber
private void sendSubscribeMessage() {
try {
JSONObject object = new JSONObject();
object.put(JANUS, SendMessageType.MESSAGE.getType());
object.put(PLUGIN, PLUGIN_VALUE);
object.put(TRANSACTION, RandomUtil.randomString());
object.put(SESSION_ID, sessionId);
object.put(HANDLE_ID, handleId);
JSONObject body = new JSONObject();
body.put(REQUEST, BodyRequestMessageType.JOIN.getType());
body.put(PTYPE, PType.SUBSCRIBER.getType());
body.put(ROOM, options.meetNum);
body.put(PIN, options.pin);
body.put(PRIVATE_ID, privateId);
body.put(FEED, publisherBean.getId());
body.put(DATA, true);
body.put(OFFER_DATA, true);
object.put(BODY, body);
connection.sendMessage(object.toString());
if(publisherBean.isSumulcast()){
sendConfigureSimulcastMessage();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
after create peerconnection for publisher, i have create datachannel:
peerConnection = PCFactoryProxy.instance().createPeerConnection(configuration, this);
dataChannel = peerConnection.createDataChannel("1", new DataChannel.Init());
dataChannel.registerObserver(new DataChannel.Observer() {
#Override
public void onBufferedAmountChange(long l) {
}
#Override
public void onStateChange() {
Log.e(SERVER_TAG, "dataChannel state: " + dataChannel.state().toString());
}
#Override
public void onMessage(DataChannel.Buffer buffer) {
}
});
but i never see onDataChannel triggered, can someone help?
#Override
public void onDataChannel(DataChannel dataChannel) {
LogUtil.e(SERVER_TAG, "PeerConnectionChannelV3 -> onDataChannel: " + dataChannel.label());
this.dataChannel = dataChannel;
// this.dataChannel.registerObserver(this);
// sendDataChannelMessage("test");
}
as i know about DataChannel, when Peer A already has datachannel object, Peer B would receive the datachannel when onDataChannel would be triggered

Retrofit - how do I make a synchronous request within an asynchronous request

I'm implementing a two-level nested recyclerView and both recycler views make an API call using retrofit. This is the method that makes the synchronous request:
public void loadSectionStories(String sessionKey, CuratedSection section) {
Call<JsonArray> subCall;
subCall = TravelersApi.endpoint().getCuratedSectionTopics(sessionKey, section.id);
try {
Response<JsonArray> response = subCall.execute();
if(response.code() != 200) {
Toast.makeText(getApplicationContext(), "Cannot load page as of the moment.", Toast.LENGTH_SHORT).show();
return;
}
JsonArray rawStories = response.body();
if(rawStories.size() == 0) {
//TODO: show placeholder
return;
}
ArrayList<CuratedSectionItem> stories = new ArrayList<>();
for(int i = 0; i < rawStories.size(); i++) {
JsonObject jStories = rawStories.get(i).getAsJsonObject();
JSONObject temp = new JSONObject(jStories.toString());
JsonObject author = jStories.get("author").getAsJsonObject();
CuratedSectionItem story = new CuratedSectionItem();
story.title = jStories.get("title").getAsString();
story.avatar = author.get("profile_photo").getAsString();
story.displayPhoto = temp.getString("primary_photo");
story.username = author.get("username").getAsString();
story.description = jStories.get("content").getAsString();
story.topicId = jStories.get("id").getAsString();
story.postId = jStories.get("first_post_id").getAsString();
story.hasReacted = false;
story.upvotes = jStories.get("stats").getAsJsonObject().get("upvotes").getAsInt();
stories.add(story);
}
section.stories = stories;
} catch (IOException e) {
Log.d("ERROR!", e.toString());
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
This is the method that makes the asynchronous request and also calls loadSectionStories in a thread:
public void loadCuratedSections(final int start, final int limit) {
SharedPreferences prefs = getSharedPreferences("user_session", MODE_PRIVATE);
final String sessionKey = prefs.getString("session_key", null);
Call<JsonArray> call;
call = TravelersApi.endpoint().getCuratedSections(sessionKey);
call.enqueue(new Callback<JsonArray>() {
#Override
public void onResponse(Call<JsonArray> call, Response<JsonArray> response) {
if(response.code() != 200) {
Toast.makeText(getApplicationContext(), "Cannot load page as of the moment.", Toast.LENGTH_SHORT).show();
return;
}
JsonArray rawSections = response.body();
if(rawSections.size() == 0) {
return;
}
for (int i = start; i < limit; i++) {
JsonObject jSection = rawSections.get(i).getAsJsonObject();
final CuratedSection section = new CuratedSection();
section.id = jSection.get("id").getAsString();
section.header = jSection.get("section_header").getAsString();
section.isShown = jSection.get("is_shown").getAsBoolean();
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
loadSectionStories(sessionKey, section);
}
});
thread.start();
curatedSections.add(section);
}
}
#Override
public void onFailure(Call<JsonArray> call, Throwable t) {
Log.d("ERROR!", t.toString());
t.printStackTrace();
}
});
}
Everything is working fine except the fact that section.stories returns null. It doesn't make sense to me because of this statement section.stories = stories inside loadSectionStories.
If you are using section.stories before your synchronous request is completed (which is running in new threads) then it will return null which is currently happening.
so either you have to remove new thread flow if you want to use it after your first asynchronous request is completed,
or you have to reload your recycler view when you stories is updated.
Also why are you executing your synchronous request(loadSectionStories) in new thread, is it not similar to asynchronous request?
Retrofit asyncRetrofit = new Retrofit.Builder()
.baseUrl(URLS.MAIN_SERVER_URL)
// below line create thread for syncrouns request
.callbackExecutor(Executors.newSingleThreadExecutor())
.addConverterFactory(GsonConverterFactory.create())
.client(httpClient.build())
.build();
this will run your request in asyncronous

Json load dynamic to the Run handler Duration

I have request json from server and handle with Handler duration 50000.
sometime it loaded all json sometime it not yet loaded.
What i want is Run Handler dynamic to the Json load. if All json loaded I want the run duration equal to 0.
public void onLoadMore() {
Log.d("MainActivity_","onLoadMore");
mAdapter.setProgressMore(true);
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
itemList.clear();
mAdapter.setProgressMore(false);
int start = mAdapter.getItemCount();
final int end = start + 5;
RequestQueue queue = Volley.newRequestQueue(context);
HttpsTrustManager.allowAllSSL();
final String url = "https://www.iknow.com.kh/api/business/get_business_home_latest.php";
StringRequest stringRequest = new StringRequest(context, Request.Method.GET,url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d("JsonBusiness ", response);
JSONObject business;
JSONObject data;
JSONArray operator;
try {
data = new JSONObject(response);
business = data.getJSONObject("business");
operator = business.getJSONArray("content");
for (int i = 0; i < operator.length(); i++) {
JSONObject each_report = new JSONObject(operator.get(i).toString());
Log.d("cat _ ID:", each_report.getString("business_name"));
String desc, phone, subaddress, category, businessname;
if(each_report.getString("business_name").length()>25){
businessname=each_report.getString("business_name").substring(0,25)+"...";
}else {
businessname=each_report.getString("business_name");
}
if(each_report.getString("description").length()>35){
desc=each_report.getString("description").substring(0,35)+"...";
}else
{
desc=each_report.getString("description")+"...";
}
if(each_report.getString("phone").length()>35){
phone=each_report.getString("phone").substring(0, 35)+"...";
}else {
phone=each_report.getString("phone");
}
String address=each_report.getString("house") + ", " + each_report.getString("street") + ", " + each_report.getString("pro");
if(address.length()>35){
subaddress=address.substring(0,35)+"...";
}else {
subaddress=address;
}
category="Category: " + each_report.getString("cate_name");
itemList.add(new BusinessEntity(each_report.getString("first_letter"), businessname, desc ,phone,subaddress,category,each_report.getString("bussID"),each_report.getString("CID"),each_report.getString("PID")));
// bcontractor.add(b_list);
}
mAdapter.addAll(itemList);
} catch (JSONException e) {
e.printStackTrace();
}
mAdapter.notifyDataSetChanged();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
Toast.makeText(context, "Login Error", Toast.LENGTH_SHORT).show();
}
}){
#Override
public String getUrl() {
Map<String, String> params = new HashMap<>();
params.put("api_key", "iknow#ApIKeY");
params.put("search_letter", "");
params.put("offset", ""+end);
params.put("limit", "15");
Log.d("Url with Param___", SetUrl(url, params));
return SetUrl(url, params);
}
};
queue.add(stringRequest);
// for (int i = start + 1; i <= end; i++) {
// itemList.add(new BusinessEntity("F","Item " + i,"","","","","","",""));
// }
mAdapter.addItemMore(itemList);
mAdapter.setMoreLoading(false);
}
},50000);
}
Try this,
// Create handler
Handler mHandler = new Handler();
// Create Runnable task
Runnable runnable = new Runnable() {
#Override
public void run() {
...
StringRequest stringRequest = new StringRequest(context, Request.Method.GET,url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
...
mAdapter.notifyDataSetChanged();
// data has been loaded, call onLoadMore again
onLoadMore();
}
});
queue.add(stringRequest);
...
}
};
public void onLoadMore() {
Log.d("MainActivity_","onLoadMore");
mAdapter.setProgressMore(true);
// Reducing the time to 2 seconds. Just an arbitrary value
mHandler.postDelayed(runnable, 2000);
}
For first time you can run your task immidiately, and after loading data you can set another appropriate delay to run it after some time. See the code below
// Create handler
Handler mHandler = new Handler();
// Create Runnable task
Runnable runnable = new Runnable() {
#Override
public void run() {
...
}
});
queue.add(stringRequest);
mAdapter.addItemMore(itemList);
mAdapter.setMoreLoading(false);
mHandler.postDelayed(runnable, 4000); // now register to run after 4 secs
}
};
public void onLoadMore() {
Log.d("MainActivity_","onLoadMore");
mAdapter.setProgressMore(true);
// Run immediately at the start
mHandler.post(runnable);
}

Volley second request return null

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);

Android Volley Request Identity onErrorResponse Section

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.

Categories

Resources