Volley Request Tracking - java

I am using volley library for uploading images using Restful API
I made multiple image uploading request and add all these into RequestQueue.
when the request is completed I want to perform local db operation based on Request but
now the Question is how can I track the progress of each request
How can I know that which request is finished ?
How can I TAG the request ?
Any Way ?
Code :
StringRequest stringRequest = new StringRequest (Request.Method.POST, Constants.IMAGE_UPLOAD_URL,
new Response.Listener<String> ( ) {
#Override
public void onResponse(String s) {
Log.e (TAG, s.toString ( ));
}
},
new Response.ErrorListener ( ) {
#Override
public void onErrorResponse(VolleyError volleyError) {
}
}) {
#Override
protected Map<String, String> getParams() throws AuthFailureError {
//Creating parameters
Map<String, String> params = new Hashtable<String, String> ( );
//Adding parameters
params.put ("file_contents", imageString);// image string
params.put ("file_name", filenameString);//profile image in name
return params;
}
};
stringRequest.setRetryPolicy (new DefaultRetryPolicy (DefaultRetryPolicy.DEFAULT_TIMEOUT_MS * 2, DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
//Adding request to the queue
if (requestQueue==null)
requestQueue= Volley.newRequestQueue (this);
requestQueue.add (stringRequest);
}

Volley according to the documentation, is not good for long operations and this means that it's not suited for your need
you can extend the request type you're using and add a custom field and then write a RequestFilter that will find the next item according to the returned value of the response
Volley is not suitable for large download or streaming operations,
since Volley holds all responses in memory during parsing. For large
download operations, consider using an alternative like
DownloadManager.

Related

How to utilize AsyncTask for handling asynchronous RestRequests

I want to access an online API through an android application. For this purpose I have written easy to access functions to send requests via the android Volley package. However the app immediately displays 0s when I try to assign a value, that I have recieved through sending a request, to a TextView. I realize that this probably is because the function handles the Object as "null" because the response has not yet arrived and that I need to use AsyncTasks to handle this properly but the Developer Guide from Android Studio didn't really help me too much because, to be absolutely 100% honest with you, I'm not a software engineer and I'm absolutely lost at this point.
Here's some code on how I access the API:
org.json.JSONObject makeRequest(String URL, String method, String[] headers){
int reqType;
switch(method.toUpperCase()){
case "GET":
reqType = Request.Method.GET;
break;
case "DELETE":
reqType = Request.Method.DELETE;
break;
default:
return null;
}
Response.Listener<JSONObject> listener = new Response.Listener<JSONObject>(){
#Override
public void onResponse(JSONObject Response){
result = Response;
}
};
Response.ErrorListener err = new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
result = null;
}
};
JsonObjectRequest req = new JsonObjectRequest(reqType, URL, null, listener, err){
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
params.put(headers[0], headers[1]);
return params;
}
};
;
rQ_volley.add(req);
return result;
}
And additionally some code on where I access the method above
JSONArray koordTargetArr = rBuild.makeRequestArr("https://nominatim.openstreetmap.org/search?q="+target+"&format=json&polygon=1&addressdetails=1", "get",headersLonLat);
if(koordTargetArr != null) {
JSONObject koordTargetOBJ = koordTargetArr.getJSONObject(0);
koordTarget = koordTargetOBJ.getString("lon").concat(",").concat(koordTargetOBJ.getString("lat"));
}
else return 0;
I would appreciate any help you could give me on things like where I implement the AsyncTask and how I build one. I have experience in the async library in Node.js if that helps at all.
EDIT:
This is NOT a duplicate of How to use java.net.URLConnection to fire and handle HTTP requests I already know how to send HTTP Requests, I don't know how to use android AsyncTask, HTTP Requests are NOT the topic of this question.
Have you considered using Retrofit?
It will handle, construction and deserialization of all your network needs without needing to use AsyncTask + custom utilities functions.

How to call List Item in SharePoint Using REST API in Android?

I'm want to consume share point rest API service to call from Android previously i use to call share point web service through the graph API but while generating token from graph API its not support in below URL, does any one have any solution about this problem.
https://mysharepoint.sharepoint.com/sites/MySite/_api/web/lists/getbytitle('Announcements')/Items
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, MSGRAPH_URL,
parameters,new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
/* Successfully called graph, process data and send to UI */
Log.d(TAG, "Response: " + response.toString());
updateGraphUI(response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d(TAG, "Error: " + error.toString());
}
}) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<>();
headers.put("Authorization", "Bearer " + authResult.getAccessToken());
return headers;
}
};
Log.d(TAG, "Adding HTTP GET to Queue, Request: " + request.toString());
request.setRetryPolicy(new DefaultRetryPolicy(
3000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
queue.add(request);
I already tried with MSAL library but its does not work with this token.
Update: i used to call graph api for janrating token but i got 401 error with this above mention URL.
You are calling a SharePoint API, so you will need a SharePoint token instead of a Graph token. These are two separate APIs with different authentications.
To get a SharePoint token you will need to register an App in SharePoint itself or use the users username + password if available in your app.
Also see:
https://spshell.blogspot.com/2015/03/sharepoint-online-o365-oauth.html
https://shareyourpoint.net/2017/01/25/operations-using-rest-in-sharepoint-online-authorization/
For Graph, use an URL like this to get your list items:
https://graph.microsoft.com/v1.0/sites/{site-id}/lists/{list-id}/items?expand=fields(select=Column1,Column2)
You will probably need to do several calls to get your site ID and list ID first.
https://learn.microsoft.com/en-us/graph/api/listitem-list?view=graph-rest-1.0

send json to Laravel using postman and android

i am trying to send json using postman to Lavavel but i facing this error.
enter image description here
this is my json code:
{
"email":"test#test.com",
"password":"testtest"
}
and this is Laravel codes :
Route::get('/r','test#store');
and
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use DB;
use Log;
class test extends Controller
{
public function store(Request $request)
{
$email = $request->input('email');
$password = $request->input('password');
Log::info('test');
Log::info($email);
Log::info($password);
DB::table('login')->insert([
['email' => $email],
['password' => $password]
]);
}
}
also i trying using android for send data using volley and so checked Laravel logs :
Column 'email' cannot be null (this is Laravel logs)
and on android Logs:
E/Volley: [299] BasicNetwork.performRequest: Unexpected response code 500 for http://192.168.1.4:8000/r
D/error: com.android.volley.ServerErro
my android code is :
public class ApiService {
private final Context context;
public ApiService(Context context){
this.context=context;
}
public void loginUser(String email, String password, final OnLoginResponse onLoginResponse){
JSONObject requestJsonObject=new JSONObject();
try {
requestJsonObject.put("email",email);
requestJsonObject.put("password",password);
JsonObjectRequest request=new JsonObjectRequest(Request.Method.GET, "http://192.168.1.4:8000/r",requestJsonObject , new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.d("response",response.toString());
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("error",error.toString());
}
}) {
#Override
public Map getHeaders() throws AuthFailureError {
HashMap headers = new HashMap();
headers.put("Content-Type", "application/json");
return headers;
}
};
request.setRetryPolicy(new DefaultRetryPolicy(18000,DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
Volley.newRequestQueue(context).add(request);
} catch (JSONException e) {
Log.e(TAG, "loginUser: "+e.toString());
}
}
public interface OnLoginResponse{
void onResponse(boolean success);
}
}
I hope this helps people trying to search on how to send JSON data to laravel not only specific to android applications but to all. The goal of this solution is to identify whether you can send a JSON data to laravel or not.
First of all you have to download postman from https://www.getpostman.com/ to test if your API is really working or not.
Create a post request using postman. Be sure that you follow the example data below
Be sure that you set your Routes that would associate to the controller
This is the controller part that will show the JSON data you sent if it was successfully accepted or not.
And also, if ever you are trying to send POST data to laravel, by default they provided a CSRF Token which is applicable for the forms if you are going to use the MVC of laravel. For the meantime, we are going to take this down and comment it out. Just go to app/http/kernel.php
and now you'll get the following result from the code earlier
$json = json_decode($request['json']);
echo $json->{'email'};
echo "\n";
echo $json->{'password'};
We tested that we were able to send data to laravel. I hope this truly helps.
Wen you want to send data, you will want to use POST or PUT method on your postman, specially if you are sending a body, that means that you are sending data. Get method is used to retrieve data from a service.
Take a look into CRUD functions for more information.
Your postman should look something like this
Last in your android code try to change this line
JsonObjectRequest request=new JsonObjectRequest(Request.Method.GET, "http://192.168.1.4:8000/r",requestJsonObject , new Response.Listener<JSONObject>() {
to use Request.Method.POST

Send Images as Multipart with Other Params in Volley Request

I was sending a request to the server with two parameters using volley request and it was working fine. Now the requirement has changed and I need to send at least one image or maximum 3 images to the server along with the other two parameters. The image must be sent as multi-part. I have following code for Getting image from gallery and storing their file paths in the list.
List<String> imagePathList = imageFilePaths;
List<MultipartBody.Part> partMap = new ArrayList<>();
for (int i = 0; i < imagePathList.size(); i++) {
Uri fileUri = Uri.parse(imagePathList.get(i));
RequestBody requestFile = RequestBody.create(
MediaType.parse(getMimeTypee(FileUtils.getFile(getContext(), fileUri).getAbsolutePath())),
FileUtils.getFile(getContext(), fileUri)
);
MultipartBody.Part body = MultipartBody.Part.createFormData("court_image[" + i + "]", FileUtils.getFile(getContext(), fileUri).getName(), requestFile);
partMap.add(body);
}
Where imageFilePaths is an ArrayList. The server will receive images like court_image[0], court_image[1] and so on, depends on how many image paths I have in ArrayList.
The volley request is here:
RequestQueue queue = Volley.newRequestQueue(getContext());
StringRequest postRequest = new StringRequest(Request.Method.POST, url1,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Toast.makeText(mBaseAppCompatActivity, "Success", Toast.LENGTH_SHORT).show();
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}
) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<String, String>();
String token = getToken();
params.put("Authorization", "Bearer " + token);
params.put("Content-Type", "multipart/form-data");
return params;
}
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("terms", "true");
params.put("phone", "phoneNo");
return params;
}
};
queue.add(postRequest);
Now the thing is as I am new to the multi-part thing, with the help I am able to get the image from gallery and storing their path in ArrayList but I don't know how to pass the multi-part data in this volley request. Please help.
For uploading the image along with some other parameters, I used volley. However, I found a wrapper of the original volley library which is easier to integrate for multi-part requests. Hence I added the following library in the build.gradle file.
dependencies {
compile 'dev.dworks.libs:volleyplus:+'
}
I removed the original volley library from my build.gradle and used the above library instead which can handle both multi-part and normal requests having similar integration technique.
Then I just had to write the following class which handles the POST request operation.
public class POSTMediasTask {
public void uploadMedia(final Context context, String filePath) {
String url = getUrlForPOSTMedia(); // This is a dummy function which returns the POST url for you
SimpleMultiPartRequest multiPartRequestWithParams = new SimpleMultiPartRequest(Request.Method.POST, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d("Response", response);
// TODO: Do something on success
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// TODO: Handle your error here
}
});
// Add the file here
multiPartRequestWithParams.addFile("file", filePath);
// Add the params here
multiPartRequestWithParams.addStringParam("terms", "SomeTerms");
multiPartRequestWithParams.addStringParam("phone", "85050055055");
RequestQueue queue = Volley.newRequestQueue(context);
queue.add(multiPartRequestWithParams);
}
}
Now execute the task like the following.
new POSTMediasTask().uploadMedia(context, mediaPath);
You can upload one file at a time using this library. However, I could manage to upload multiple files, just by initiating multiple tasks.

Return a result to same level as the call Volley android

I know there are a few very question that are almost identical, however they are just different enough that I can't get my code to work.
I'm using volley to check if a token is valid and want to be able to store the result at the same level as the call i.e. so as if to simulate Boolean isValid = validToken().
This is what I have so far...
Callback interface
interface VolleyCallback {
void onSuccess(boolean result);
}
Volley function to check token
private void validToken(final String token, final VolleyCallback callback){
String url = "http://example/api/validate_token";
JsonObjectRequest jsObjRequest = new JsonObjectRequest
(Request.Method.POST, url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
callback.onSuccess(true);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
callback.onSuccess(false);
}
}){
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String,String> headers = new HashMap<String, String>();
headers.put("Authorization", token);
return headers;
}
};
//Access the RequestQueue through the singleton class.
MySingleton.getInstance(this).addToRequestQueue(jsObjRequest);
}
The function call
Boolean tokenIsValid;
validToken("Bearer eyJhbGciOiJ", new VolleyCallback() {
#Override
public void onSuccess(boolean result) {
}
});
All I want to be able to do is store the result of the validToken call in the tokenIsValid variable.
Thanks
In my question I was using a asynchronous volley request and wanting a return value right away. This is wrong, I should have used a synchronous request with a timeout. See this post (Look at the answer about not locking the thread. Asynchronous requests should no be used for things like I was trying to use it for.

Categories