I'm using volley library for sending requests and I have a memory leak. I traced it with leak canary and it seems to be from my requests mListeners. after some searching I cancel all my requests in my current activity but still I have a leak I could use some help thanks here is my download code:
(note: I use singleton pattern for getting volley request queue)
private void startImageDownloadService(final NEWS selectedNews) {
if (selectedNews.getIMG_URL() != null && !selectedNews.getIMG_URL().equals("null")) {
ImageRequest imageRequest = new ImageRequest(selectedNews.getIMG_URL(),
new Response.Listener<Bitmap>() {
#Override
public void onResponse(Bitmap bitmap) {
newsImage_imageView.setVisibility(View.VISIBLE);
newsImage_imageView.setImageBitmap(bitmap);
saveImageToFileStarter(bitmap, selectedNews);
}
}, 200, 200, null, null, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
Toast.makeText(getApplicationContext(), "Failed to download image", Toast.LENGTH_SHORT).show();
}
});
imageRequest.setShouldCache(false);
MyVolleySingleton.getInstance(getApplicationContext()).addToRequestQueue(imageRequest, "newsActivityImage");
//
}
}
private void requestLike(final ImageButton likeButton, final long id) {
try {
StringRequest jsonRequest = new StringRequest(Request.Method.POST, G.likeURL + id + "/like",
new Response.Listener<String>() {
#Override
public void onResponse(String s) {
try {
Log.e("requestLikeJson", s);
JSONObject likeObject = new JSONObject(s);
int likeNumbers = likeObject.getInt("likes");
// Toast.makeText(NewsActivity.this, likeNumbers + "", Toast.LENGTH_LONG)
// .show();
if (likeButton.getTag().equals("notliked")) {
setLikeChangeInDatabase(false, id, likeNumbers);
}
else{
setLikeChangeInDatabase(true, id, likeNumbers);
}
// viewsCount_textView.setText("" + likeNumbers);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
Toast.makeText(NewsActivity.this, "No Internet connection", Toast.LENGTH_LONG).show();
try {
volleyError.printStackTrace();
Log.e("network error", new String(volleyError.networkResponse.data));
} catch (Exception e) {
e.printStackTrace();
}
if (likeButton.getTag().equals("notliked")) {
likeButton.setTag("liked");
likeButtonImageSetter();
} else {
likeButton.setTag("notliked");
likeButtonImageSetter();
}
Animation shake = AnimationUtils.loadAnimation(NewsActivity.this, R.anim.actionfeedback);
likeButton.startAnimation(shake);
}
}) {
#Override
public Priority getPriority() {
return Priority.HIGH;
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
Log.e("sent token", "Token " + G.token);
params.put("Authorization", "Token " + G.token);
params.put("Accept-Language", "en-US,en;q=0.8,fa;q=0.6,pt;q=0.4,ar;q=0.2,gl;q=0.2");
return params;
}
#Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
String utf8String = null;
try {
utf8String = new String(response.data, "UTF-8");
return Response.success(utf8String, HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
}
}
};
jsonRequest.setRetryPolicy(new DefaultRetryPolicy(
G.socketTimeout,
0,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
MyVolleySingleton.getInstance(getApplicationContext()).addToRequestQueue(jsonRequest, "like");
} catch (Exception e) {
}
}
private void requestView(long id) {
try {
StringRequest jsonRequest = new StringRequest(Request.Method.GET, G.viewURL + id + "/view", new Response.Listener<String>() {
#Override
public void onResponse(String s) {
try {
JSONObject viewObject = new JSONObject(s);
Log.e("requestViewJson", s);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
try {
volleyError.printStackTrace();
Log.e("network error", new String(volleyError.networkResponse.data));
} catch (Exception e) {
e.printStackTrace();
}
}
}) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
Log.e("sent token", "Token " + G.token);
params.put("Authorization", "Token " + G.token);
params.put("Accept-Language", "en-US,en;q=0.8,fa;q=0.6,pt;q=0.4,ar;q=0.2,gl;q=0.2");
return params;
}
#Override
public Priority getPriority() {
return Priority.HIGH;
}
#Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
String utf8String = null;
try {
utf8String = new String(response.data, "UTF-8");
return Response.success(utf8String, HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
}
}
};
jsonRequest.setRetryPolicy(new DefaultRetryPolicy(
G.socketTimeout,
0,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
MyVolleySingleton.getInstance(getApplicationContext()).addToRequestQueue(jsonRequest,"view");
} catch (Exception e) {
}
}
and in my onStop() I have :
#Override
protected void onStop() {
try {//new change
MyVolleySingleton.getInstance(getApplicationContext()).cancelPendingRequests("newsActivityImage");
MyVolleySingleton.getInstance(getApplicationContext()).cancelPendingRequests("view");
MyVolleySingleton.getInstance(getApplicationContext()).cancelPendingRequests("like");
loadImageFromFile.cancel(true);
loadImageFromFile=null;
}catch (Exception e){}
super.onStop();
}
After some researching I found that the volley listeners cause the activity leak because they are instantiated as anonymous classes and therefore hold an implicit reference to their outer class (in this example news activity) so I made a separate class for VolleyRequest (just to make them customizable not really related to the leak) and made a listener interface which I implement as an innerclass and use a weak reference to have access to the activity
request code :
public class MyVolleyStringRequest extends com.android.volley.toolbox.StringRequest {
StringResponseListener mListener;
public MyVolleyStringRequest(int method, String url, final StringResponseListener mListener) {
super(method, url, new Response.Listener<String>() {
#Override
public void onResponse(String s) {
mListener.onSuccess(s);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
mListener.onFailure(volleyError);
}
});
this.mListener = mListener;
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
Log.e("sent token", "Token " + G.token);
params.put("Authorization", "Token " + G.token);
params.put("Accept-Language", "en-US,en;q=0.8,fa;q=0.6,pt;q=0.4,ar;q=0.2,gl;q=0.2");
return params;
}
#Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
try {
String utf8String = new String(response.data, "UTF-8");
return Response.success(utf8String, HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
}
}
}
requestLike and requestView Code:
private void requestLike(final ImageButton likeButton, final long id) {
MyVolleyStringRequest likeRequest = new MyVolleyStringRequest(Request.Method.POST, G.likeURL + id + "/like",
new RequestLikeStringListener(this));
MyVolleySingleton.getInstance(getApplicationContext()).addToRequestQueue(likeRequest, "like");
}
private void requestView(long id) {
MyVolleyStringRequest viewRequest = new MyVolleyStringRequest(Request.Method.GET, G.viewURL + id + "/view",
new RequestViewStringListener());
MyVolleySingleton.getInstance(getApplicationContext()).addToRequestQueue(viewRequest, "view");
}
listener interface code :
public interface StringResponseListener {
void onSuccess(String response);
void onFailure(VolleyError error);
}
innerclasses code:
public static class RequestLikeStringListener implements StringResponseListener{
WeakReference<NewsActivity> contextWeakReference;
RequestLikeStringListener(NewsActivity context){
contextWeakReference = new WeakReference<>(context);
}
public void onSuccess(String response) {
try {
NewsActivity context = contextWeakReference.get();
if(context != null) {
ImageButton likeButton = (ImageButton) context.findViewById(R.id.likeButton);
Log.e("requestLikeJson", response);
JSONObject likeObject = new JSONObject(response);
int likeNumbers = likeObject.getInt("likes");
if (likeButton.getTag().equals("notliked")) {
context.setLikeChangeInDatabase(false, contextWeakReference.get().id, likeNumbers);
} else {
context.setLikeChangeInDatabase(true, contextWeakReference.get().id, likeNumbers);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
public void onFailure(VolleyError error) {
NewsActivity context = contextWeakReference.get();
if(context != null) {
ImageButton likeButton = (ImageButton) context.findViewById(R.id.likeButton);
Toast.makeText(context, "No Internet connection", Toast.LENGTH_LONG).show();
try {
error.printStackTrace();
Log.e("network error", new String(error.networkResponse.data));
} catch (Exception e) {
e.printStackTrace();
}
if (likeButton.getTag().equals("notliked")) {
likeButton.setTag("liked");
context.likeButtonImageSetter();
} else {
likeButton.setTag("notliked");
context.likeButtonImageSetter();
}
Animation shake = AnimationUtils.loadAnimation(context, R.anim.actionfeedback);
likeButton.startAnimation(shake);
}
}
hope it helps someone!
Related
I am trying to upload a file to Amazon s3 using a PUT request from my android application. I have got a link from server with private key exposed in the same.
When trying to upload the file from POSTMAN its working when uploaded using binary option and content type application/octet-stream or application/x-www-form-urlencoded (Tried with both) in header but if uploading same image using form data its not working.
In my android application i have tried JsonObject request using volley in which i am getting.
Json Org exception
Please find my request below
JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.PUT,
url, new JSONObject(parameters),
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
if (listener != null) {
Log.e("Response", response + "");
listener.onResult(response + "", responseCode);
if (showDialog == true) {
try {
mOverlayDialog.dismiss();
} catch (Exception e) {
// Crashlytics.logException(e);
}
try {
materialDialog.dismiss(); // To hide the progress bar
} catch (Exception e) {
// Crashlytics.logException(e);
}
}
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
if (listener != null) {
try {
if(error.networkResponse!=null && error.networkResponse.data!=null) {
String responseBody = new String(error.networkResponse.data, "utf-8");
if (!responseBody.equalsIgnoreCase("")) {
JSONObject data = new JSONObject(responseBody);
listener.onResult(data + "", responseCode);
//listener.onResult(error.toString(), WebAPIConstants.VOLLEY_ERROR);
Log.e("ERROR", error.toString() + "");
} else {
listener.onResult("", responseCode);
}
}
else
listener.onResult("", responseCode);
} catch (JSONException e) {
} catch (UnsupportedEncodingException errorr) {
} catch (Exception e) {
Crashlytics.logException(e);
}
}
if (showDialog == true) {
try {
mOverlayDialog.dismiss();
} catch (Exception e) {
// Crashlytics.logException(e);
}
try {
materialDialog.dismiss(); // To hide the progress bar
} catch (Exception e) {
// Crashlytics.logException(e);
}
}
try {
if (error instanceof TimeoutError) {
AlertDialogManager.showAlertDialog(mContext, mContext.getResources().getString(R.string.timeout_error_title), mContext.getResources().getString(R.string.timeout_error_string), new MaterialDialog.SingleButtonCallback() {
#Override
public void onClick(#NonNull MaterialDialog dialog, #NonNull DialogAction which) {
}
});
} else if (error instanceof NoConnectionError) {
if (CheckInternetConnection.haveNetworkConnection(mContext)) {
AlertDialogManager.showAlertDialog(mContext, mContext.getResources().getString(R.string.timeout_error_title), mContext.getResources().getString(R.string.timeout_error_string), new MaterialDialog.SingleButtonCallback() {
#Override
public void onClick(#NonNull MaterialDialog dialog, #NonNull DialogAction which) {
}
});
} else {
AlertDialogManager.showAlertDialog(mContext, mContext.getResources().getString(R.string.no_internet_title), mContext.getResources().getString(R.string.no_internet_message), new MaterialDialog.SingleButtonCallback() {
#Override
public void onClick(#NonNull MaterialDialog dialog, #NonNull DialogAction which) {
}
});
}
}
} catch (Exception e) {
Crashlytics.logException(e);
}
}
(Have sent image in bytecode), On using String request the image is being uploaded but with size 1kB but dosent open on server (Have sent image in bytecode).
String request
StringRequest stringRequest=new StringRequest(Request.Method.PUT, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
if (listener != null) {
Log.e("Response", response + "");
if (showDialog == true) {
try {
mOverlayDialog.dismiss();
} catch (Exception e) {
// Crashlytics.logException(e);
}
try {
materialDialog.dismiss(); // To hide the progress bar
} catch (Exception e) {
// Crashlytics.logException(e);
}
}
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
if (listener != null) {
try {
if(error.networkResponse!=null && error.networkResponse.data!=null) {
String responseBody = new String(error.networkResponse.data, "utf-8");
if (!responseBody.equalsIgnoreCase("")) {
JSONObject data = new JSONObject(responseBody);
listener.onResult(data + "", responseCode);
//listener.onResult(error.toString(), WebAPIConstants.VOLLEY_ERROR);
Log.e("ERROR", error.toString() + "");
} else {
listener.onResult("", responseCode);
}
}
else
listener.onResult("", responseCode);
} catch (JSONException e) {
} catch (UnsupportedEncodingException errorr) {
} catch (Exception e) {
Crashlytics.logException(e);
}
}
if (showDialog == true) {
try {
mOverlayDialog.dismiss();
} catch (Exception e) {
// Crashlytics.logException(e);
}
try {
materialDialog.dismiss(); // To hide the progress bar
} catch (Exception e) {
// Crashlytics.logException(e);
}
}
try {
if (error instanceof TimeoutError) {
AlertDialogManager.showAlertDialog(mContext, mContext.getResources().getString(R.string.timeout_error_title), mContext.getResources().getString(R.string.timeout_error_string), new MaterialDialog.SingleButtonCallback() {
#Override
public void onClick(#NonNull MaterialDialog dialog, #NonNull DialogAction which) {
}
});
} else if (error instanceof NoConnectionError) {
if (CheckInternetConnection.haveNetworkConnection(mContext)) {
AlertDialogManager.showAlertDialog(mContext, mContext.getResources().getString(R.string.timeout_error_title), mContext.getResources().getString(R.string.timeout_error_string), new MaterialDialog.SingleButtonCallback() {
#Override
public void onClick(#NonNull MaterialDialog dialog, #NonNull DialogAction which) {
}
});
} else {
AlertDialogManager.showAlertDialog(mContext, mContext.getResources().getString(R.string.no_internet_title), mContext.getResources().getString(R.string.no_internet_message), new MaterialDialog.SingleButtonCallback() {
#Override
public void onClick(#NonNull MaterialDialog dialog, #NonNull DialogAction which) {
}
});
}
}
} catch (Exception e) {
Crashlytics.logException(e);
}
}
})
{
#Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
if (listener!=null) {
listener.onResult(mStatusCode + "", responseCode);
}
mStatusCode = response.statusCode;
return super.parseNetworkResponse(response);
}
#Override
protected Map<String, String> getParams() throws AuthFailureError {
return parameters;
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<String, String>();
headers.put("Content-Type", "application/octet-stream");
return headers;
}
};
stringRequest.setRetryPolicy(new DefaultRetryPolicy(120000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
try {
stringRequest.setShouldCache(false);
queue.getCache().clear();
queue.add(stringRequest);
} catch (Exception e) {
Crashlytics.logException(e);
}
Have also tried Multipart request but getting errors like auth error etc.
Multi part request where docUrl is same url as in postman
Dependency added for below request:
compile group: 'org.apache.httpcomponents' , name: 'httpclient-android' , version: '4.3.5.1'
compile('org.apache.httpcomponents:httpmime:4.3') {
exclude module: "httpclient"
}
MultipartRequestAWS class
package spice.mudra.csp_cred;
import com.android.volley.AuthFailureError;
import com.android.volley.NetworkResponse;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyLog;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
public class MultipartRequestAWS extends Request<String> {
private MultipartEntity entity = new MultipartEntity();
private static final String FILE_PART_NAME = "file";
private static final String STRING_PART_NAME = "text";
private final Response.Listener<String> mListener;
private final File mFilePart;
private final String mStringPart;
public MultipartRequestAWS(String url, Response.Listener<String> listener, Response.ErrorListener errorListener,File file, String stringPart) {
super(Method.POST, url, errorListener);
mListener = listener;
mFilePart = file;
mStringPart = stringPart;
buildMultipartEntity();
}
private void buildMultipartEntity()
{
entity.addPart(FILE_PART_NAME, new FileBody(mFilePart));
try
{
entity.addPart(STRING_PART_NAME, new StringBody(mStringPart));
}
catch (UnsupportedEncodingException e)
{
VolleyLog.e("UnsupportedEncodingException");
}
}
#Override
public String getBodyContentType()
{
return "application/octet-stream";
}
#Override
public byte[] getBody() throws AuthFailureError
{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try
{
entity.writeTo(bos);
}
catch (IOException e)
{
VolleyLog.e("IOException writing to ByteArrayOutputStream");
}
return bos.toByteArray();
}
#Override
protected Response<String> parseNetworkResponse(NetworkResponse response)
{
return Response.success("Uploaded", getCacheEntry());
}
#Override
protected void deliverResponse(String response)
{
mListener.onResponse(response);
}
}
****Multipart request****
MultipartRequestAWS request = new MultipartRequestAWS(docUrl, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.e("Responce", "" + response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("Responce", "" + error);
}
}, outputFile, imageArray.toString()
);
request.setRetryPolicy(new DefaultRetryPolicy(300000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
//adding request to request queue
// if(!Constants.IS_PRODUCTION) {
Volley.newRequestQueue(this).add(request);
// }else{
// Volley.newRequestQueue(getActivity(), new OKHttpStack(new URL(request.getUrl()).getHost())).add(request);
//
// // Volley.newRequestQueue(getActivity(), new HurlStack(null, newSslSocketFactory())).add(request);
// }
Other Multipart request tried
private final String boundary = "apiclient-" + System.currentTimeMillis();
private final String mimeType = "multipart/form-data;boundary=" + boundary;
//multipartBody is byte code of image to be uploaded
MultipartRequest request = new MultipartRequest(url, null, mimeType, multipartBody, new Response.Listener<NetworkResponse>() {
#Override
public void onResponse(NetworkResponse response) {
try {
mOverlayDialogAsync.dismiss();
} catch (Exception e) {
Crashlytics.logException(e);
}
try {
materialDialogAsync.dismiss(); // To hide the progress bar
} catch (Exception e) {
Crashlytics.logException(e);
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
try {
mOverlayDialogAsync.dismiss();
} catch (Exception e) {
Crashlytics.logException(e);
}
try {
materialDialogAsync.dismiss(); // To hide the progress bar
} catch (Exception e) {
Crashlytics.logException(e);
}
try {
// getting json string form the response obtained from server
String jsonString = new String(error.toString());
Log.e("response multipart", jsonString);
} catch (Exception e) {
Crashlytics.logException(e);
}
try {
//Network errors handling
if (error instanceof TimeoutError) {
AlertDialogManager.showAlertDialog(CustomDialogNetworkRequest.this, getResources().getString(R.string.timeout_error_title), getResources().getString(R.string.timeout_error_string), new MaterialDialog.SingleButtonCallback() {
#Override
public void onClick(#NonNull MaterialDialog dialog, #NonNull DialogAction which) {
}
});
} else if (error instanceof NoConnectionError) {
if (spice.mudra.utils.CheckInternetConnection.haveNetworkConnection(AddYourProffDetails.this)) {
AlertDialogManager.showAlertDialog(AddYourProffDetails.this, getResources().getString(R.string.timeout_error_title), getResources().getString(R.string.timeout_error_string), new MaterialDialog.SingleButtonCallback() {
#Override
public void onClick(#NonNull MaterialDialog dialog, #NonNull DialogAction which) {
}
});
} else {
AlertDialogManager.showAlertDialog(AddYourProffDetails.this, getResources().getString(R.string.no_internet_title), getResources().getString(R.string.no_internet_message), new MaterialDialog.SingleButtonCallback() {
#Override
public void onClick(#NonNull MaterialDialog dialog, #NonNull DialogAction which) {
}
});
}
} else {
AlertDialogManager.showAlertDialog(AddYourProffDetails.this, "", "Something went wrong. Please try again.", new MaterialDialog.SingleButtonCallback() {
#Override
public void onClick(#NonNull MaterialDialog dialog, #NonNull DialogAction which) {
}
});
}
} catch (Exception e) {
Crashlytics.logException(e);
}
}
});
//setting timeout to multipart request
request.setRetryPolicy(new DefaultRetryPolicy(300000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
//adding request to request queue
Log.i("++++++++++", "Request body: " + new String(request.getBody()));
Volley.newRequestQueue(CustomDialogNetworkRequest.this).add(request);
} catch (Exception e) {
Crashlytics.logException(e);
}
}
Please help with the same.
Please find POSTMAN screenshot for reference. This also has URL type that i am using.
For uploading image file add the following functions to your StringRequest object. Here outputFileUri is the Uri of the file which you want to upload. s3Url is the s3 bucket url where you want to place the image file.
StringRequest putRequest = new StringRequest(Request.Method.PUT, s3Url,
new Response.Listener<String>()
{
#Override
public void onResponse(String response) {
// response
}
},
new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error) {
// error
}
}){
#Override
public String getBodyContentType() {
return "image/jpeg";
}
#Override
public byte[] getBody() throws AuthFailureError {
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
InputStream inputStream = mContext.getContentResolver().openInputStream(outputFileUri);
byte[] b = new byte[8192];
for (int readNum; (readNum = inputStream.read(b)) != -1; ) {
bos.write(b, 0, readNum);
}
inputStream.close();
return bos.toByteArray();
} catch (Exception e) {
Log.d(TAG, e.toString());
}
return null;
}
};
Volley.newRequestQueue(this).add(putRequest);
I want to integrate youtube like button in my android app. By refering through this tutorial Videos: rate
I found this api link https://www.googleapis.com/youtube/v3/videos/rate can be used to do that. Can anybody tell me how can I pass a particular video Id along with this api link
Used this code for like youtube Videos....
//getPostLikeBtn (Create this Method.)
private void getPostLikeBtn(final String rating) {
String tag_json_obj = "recipeLike";
final SpotsDialog spotsDialog = new SpotsDialog(context);
spotsDialog.show();
spotsDialog.setMessage("Loading...");
StringRequest jsonObjectRequest = new StringRequest(Request.Method.POST,
"https://www.googleapis.com/youtube/v3/videos/rate",
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
spotsDialog.dismiss();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
try {
spotsDialog.dismiss();
try {
if (error.networkResponse.data != null) {
try {
String body = new String(error.networkResponse.data, "UTF-8");
Log.e("errorLike", body);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
spotsDialog.dismiss();
Toast.makeText(context, getResources().getString(R.string.try_again), Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
Toast.makeText(context, getResources().getString(R.string.try_again), Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
// hide the progress dialog
}
}) {
#Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
int mStatusCode = response.statusCode;
Log.e("mStatusCode", "" + mStatusCode);
if (mStatusCode == 204) {
Toast.makeText(context, "Successfully updated", Toast.LENGTH_SHORT).show();
getLikeShare();
} else {
Toast.makeText(context, getResources().getString(R.string.try_again), Toast.LENGTH_SHORT).show();
}
return super.parseNetworkResponse(response);
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
SharedPreferences prefs = getSharedPreferences("GOOGLE_TOKEN", MODE_PRIVATE);
String token = prefs.getString("token", null);
params.put("Authorization", "Bearer " + token);
return params;
}
#Override
protected Map<String, String> getParams() {
Map<String, String> jsonObject = new HashMap<>();
try {
jsonObject.put("id", "Video id");
jsonObject.put("rating", rating);
} catch (Exception e) {
e.printStackTrace();
}
Log.e("jsonObject", "" + jsonObject);
return jsonObject;
}
};
AppController.getInstance().addToRequestQueue(jsonObjectRequest, tag_json_obj);
}
I hope this is usefull for you..
In my android app there is a portion which shows list of pictures. Each picture is associated with a video id.On Clicking that picture corresponding video id will be passed to youtube player and that video will be played in youtube player. Below each picture there is a like button and a comment button. I want to integrate them with youtube like and comment.So that on clicking like or commenting a video in my app is same as clicking like or commenting on youtube. How can I impliment that?
Used this code for like youtube Videos....
//getPostLikeBtn (Create this Method.)
private void getPostLikeBtn(final String rating) {
String tag_json_obj = "recipeLike";
final SpotsDialog spotsDialog = new SpotsDialog(context);
spotsDialog.show();
spotsDialog.setMessage("Loading...");
StringRequest jsonObjectRequest = new StringRequest(Request.Method.POST,
"https://www.googleapis.com/youtube/v3/videos/rate",
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
spotsDialog.dismiss();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
try {
spotsDialog.dismiss();
try {
if (error.networkResponse.data != null) {
try {
String body = new String(error.networkResponse.data, "UTF-8");
Log.e("errorLike", body);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
spotsDialog.dismiss();
Toast.makeText(context, getResources().getString(R.string.try_again), Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
Toast.makeText(context, getResources().getString(R.string.try_again), Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
// hide the progress dialog
}
}) {
#Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
int mStatusCode = response.statusCode;
Log.e("mStatusCode", "" + mStatusCode);
if (mStatusCode == 204) {
Toast.makeText(context, "Successfully updated", Toast.LENGTH_SHORT).show();
getLikeShare();
} else {
Toast.makeText(context, getResources().getString(R.string.try_again), Toast.LENGTH_SHORT).show();
}
return super.parseNetworkResponse(response);
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
SharedPreferences prefs = getSharedPreferences("GOOGLE_TOKEN", MODE_PRIVATE);
String token = prefs.getString("token", null);
params.put("Authorization", "Bearer " + token);
return params;
}
#Override
protected Map<String, String> getParams() {
Map<String, String> jsonObject = new HashMap<>();
try {
jsonObject.put("id", "Video id");
jsonObject.put("rating", rating);
} catch (Exception e) {
e.printStackTrace();
}
Log.e("jsonObject", "" + jsonObject);
return jsonObject;
}
};
AppController.getInstance().addToRequestQueue(jsonObjectRequest, tag_json_obj);
}
I hope this is usefull for you..
I have an API call with below details
URL: http://pankajservers.in/api/v1/AuthenticateUser with Input params
below
EmailAddress and Password
if I type wrong credentials, I get below JSON response with Status Code : 403
{"Status":false,"Message":"Invalid Credentials. 5 attempts left.","Data":null}
Below is the Error Response Code.
new Response.ErrorListener()
{
#Override
public void onErrorResponse(VolleyError error)
{
if (null != error.networkResponse)
{
Log.d(TAG + ": ", "Error Response code: " + error.networkResponse.statusCode);
}
}
});
Is there any way to get JSON response in this code block?
I tried this post: Volley handle onErrorResponse
But it seems it never execute parseNetworkError
To print the Error on that block you just need to obtain the Response bytes:
NetworkResponse networkResponse = error.networkResponse;
if (networkResponse != null && networkResponse.data != null) {
String jsonError = new String(networkResponse.data);
// Print Error!
}
You can create custom request like this:
public class BaseRequest extends Request {
private static final String TAG = BaseRequest.class.getSimpleName();
private final Gson gson = new Gson();
private final Response.Listener listener;
public BaseRequest(String url, Response.Listener responseListener, Response.ErrorListener listener) {
super(Request.Method.GET, url, listener);
Log.e(TAG, "Requesting url : " + url);
this.listener = responseListener;
}
public BaseRequest(int method, String url, Response.Listener responseListener, Response.ErrorListener listener) {
super(method, url, listener);
Log.e(TAG, "Requesting url : " + url);
this.listener = responseListener;
}
#Override
public Response parseNetworkResponse(NetworkResponse response) {
try {
String json = null;
json = new String(
response.data,
HttpHeaderParser.parseCharset(response.headers));
JSONObject result = new JSONObject(json);
if (!result.getBoolean("Status"))
return Response.success(
result.get("Data"),
HttpHeaderParser.parseCacheHeaders(response));
else
return Response.error(new VolleyError(result.getString("Message")));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JsonSyntaxException e) {
return Response.error(new ParseError(e));
} catch (JSONException e) {
return Response.error(new ParseError(e));
}
}
#Override
protected VolleyError parseNetworkError(VolleyError volleyError) {
return volleyError;
}
#Override
protected void deliverResponse(Object response) {
listener.onResponse(response);
}
}
and make request:
BaseRequest baseRequest = new BaseRequest(Request.Method.POST, url, new Response.Listener() {
#Override
public void onResponse(Object response) {
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "Error : " + error.getMessage());
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
//Your parameters
return params;
}
};
queue.add(baseRequest);
You can cast an error response to a Json Object
JSONObject jsonObject = new JSONObject();
JsonObjectRequest JO = new JsonObjectRequest(Request.Method.POST,"URL String Here",jsonObject, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
//Your Logic
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
try {
JSONObject JO = new JSONObject(error.toString());
}catch (JSONException e){
e.printStackTrace();
}
}
});
Hi I am relatively new to android, I have used multipart request to upload an image to server using volley. The image is being uploaded correctly but I am getting the response as null. I checked on postman, I am strangely getting the correct response there.
MultipartRequest.java
public class MultipartRequest extends Request<JSONObject> {
private static final String FILE_PART_NAME = "user[avatar]";
private long cacheTimeToLive = 0;
private MultipartEntityBuilder mBuilder = MultipartEntityBuilder.create();
private final Response.Listener<JSONObject> mListener;
private final File mImageFile;
protected Map<String, String> headers;
public MultipartRequest(String url, File imageFile, Listener<JSONObject> listener, ErrorListener errorListener){
super(Method.PUT, url,errorListener);
mListener = listener;
mImageFile = imageFile;
buildMultipartEntity();
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = super.getHeaders();
if (headers == null
|| headers.equals(Collections.emptyMap())) {
headers = new HashMap<String, String>();
}
headers.put("Accept", "application/json");
return headers;
}
private void buildMultipartEntity(){
mBuilder.addBinaryBody(FILE_PART_NAME, mImageFile, ContentType.create("image/jpeg"), mImageFile.getName());
mBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
mBuilder.setLaxMode().setBoundary("xx").setCharset(Charset.forName("UTF-8"));
}
#Override
public String getBodyContentType(){
String contentTypeHeader = mBuilder.build().getContentType().getValue();
return contentTypeHeader;
}
#Override
public byte[] getBody() throws AuthFailureError{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
mBuilder.build().writeTo(bos);
} catch (IOException e) {
VolleyLog.e("IOException writing to ByteArrayOutputStream bos, building the multipart request.");
}
return bos.toByteArray();
}
#Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
JSONObject result = null;
return Response.success(result, HttpHeaderParser.parseCacheHeaders(response));
}
#Override
protected void deliverResponse(JSONObject response) {
mListener.onResponse(response);
}
}
uploadImage method :-
private void uploadImage(final Bitmap bitmap){
String name = "DP_"+ userName +".jpeg";
try {
file=bitmapToFile(name,bitmap);
} catch (IOException e) {
e.printStackTrace();
}
MultipartRequest jsonRequest = new MultipartRequest( UPLOAD_URL,
file,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.d(TAG,response.toString());
try {
// parseUserPhotoResponse(response);
Picasso.with(getApplicationContext())
.load(destination)
.placeholder(R.mipmap.placeholder)
.resize(avatarSize, avatarSize)
.centerCrop()
.transform(new CircleTransformation())
.into(ivUserProfilePhoto);
} catch (Exception e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
Log.d(TAG, "Error: " + volleyError.getMessage());
if(volleyError!=null)
{
try {
NetworkResponse networkResponse = volleyError.networkResponse;
if (networkResponse != null) {
String responseBody = new String(volleyError.networkResponse.data, "utf-8");
JSONObject jsonObject = new JSONObject(responseBody);
Log.d(TAG, "Response body" + responseBody.toString());
Log.d(TAG, jsonObject.toString());
if (jsonObject.getBoolean("error") == false) {
} else {
Toast.makeText(getApplicationContext(), "" + jsonObject.getString("message"), Toast.LENGTH_LONG).show();
}
}
} catch (JSONException e) {
//Handle a malformed json response
} catch (UnsupportedEncodingException error) {
}
}
}
})
;
//Creating a Request Queue
jsonRequest.setShouldCache(false);
MyApplication.getInstance().addToRequestQueue(jsonRequest, "UPLOAD_IMAGE");
}