Android - Wait for volley response for continue - java

I build an app, that it load markers in a map, the markers I get it for volley JSON file, but I need that first to load volley, and after continue executing the code, because the other way show me error with latLng null, this parameter is not loaded fast, and another method execute first and show me null.
My volley code for load markers
public void getMarkers(){
requestQueue = Volley.newRequestQueue(getApplicationContext());
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, url, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray saagTracker = response.getJSONArray("saagMRK");
for (int i = 0; i < saagTracker.length(); i++) {
JSONObject object = saagTracker.getJSONObject(i);
title = object.getString(TITLE);
snnipet = object.getString(SNNIP);
latLng = new LatLng(Double.parseDouble(object.getString(LAT)), Double.parseDouble(object.getString(LNG)));
coor = coor + "|" + object.getString(LAT) + "," + object.getString(LNG); // Menambah data marker untuk di tampilkan ke google map
addMarker(latLng, title, snnipet);
}
} catch (JSONException e) {
e.printStackTrace();
}
//JSONArray array = new JSONArray(response.body().string());
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(MainActivity.this, "Ocurrio un error", Toast.LENGTH_LONG).show();
}
});
requestQueue.add(jsonObjectRequest);
}
onCreate it need latLng first for it to can load my geofire parameter
geoQuery = geofire.queryAtLocation(new GeoLocation(latLng.latitude, latLng.longitude),0.1f); // latLng it coming null

You would need to implement a call back for the volley response. A very simple way to do this would be the following.
Step 1: Create this interface
public interface VolleyCallBack {
void onSuccess();
}
Step 2: change your getMarkers() method to this:
public void getMarkers(final VolleyCallBack callBack){
requestQueue = Volley.newRequestQueue(getApplicationContext());
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST, url, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray saagTracker = response.getJSONArray("saagMRK");
for (int i = 0; i < saagTracker.length(); i++) {
JSONObject object = saagTracker.getJSONObject(i);
title = object.getString(TITLE);
snnipet = object.getString(SNNIP);
latLng = new LatLng(Double.parseDouble(object.getString(LAT)), Double.parseDouble(object.getString(LNG)));
coor = coor + "|" + object.getString(LAT) + "," + object.getString(LNG); // Menambah data marker untuk di tampilkan ke google map
addMarker(latLng, title, snnipet);
callback.onSuccess();
}
} catch (JSONException e) {
e.printStackTrace();
}
//JSONArray array = new JSONArray(response.body().string());
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(MainActivity.this, "Ocurrio un error", Toast.LENGTH_LONG).show();
}
});
requestQueue.add(jsonObjectRequest);
}
Step 3: Call your getMarkers() method like this:
getMarkers(new VolleyCallBack() {
#Override
public void onSuccess() {
// this is where you will call the geofire, here you have the response from the volley.
geoQuery = geofire.queryAtLocation(new GeoLocation(latLng.latitude, latLng.longitude),0.1f);
});

Related

Return of a function into onResponse Method volley android studio

I got a function where Im making an arrayrequest with the purpose to get the quantity of the registers from de callback; but, Im trying to return that number for the function.
I´m declaring a variable that gets the lenght or size of the temporal ArrayList, which it´s filled whith the response of the api request using the volley library.
public int Contar(int position){
final int[] Cant = new int[1];
ArrayList<Entidad_Decision> listaO = new ArrayList<>();
if (position == 0){
RequestQueue requestQueue = Volley.newRequestQueue(mContext.getApplicationContext());
JsonArrayRequest arrayRequest = new JsonArrayRequest(Request.Method.GET, "http:My Api IP", null,
new Response.Listener<JSONArray>() {
#SuppressLint("SetTextI18n")
#Override
public void onResponse(JSONArray jsonArray) {
try {
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
String numero_de_decision = jsonObject.getString("NUMERO_DE_DECISION");
listaO.add(new Entidad_Decision(numero_de_decision,"","responsables","fecha" + " - " + "plazo", "observaciones", "procede", "status"));
}
//buscar.setText(listaO.size() + "");
Cant[0] = listaO.size();
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
arrayRequest.setRetryPolicy(new DefaultRetryPolicy(MY_DEFAULT_TIMEOUT4,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
requestQueue.add(arrayRequest);
}else if (position == 1){
RequestQueue requestQueue = Volley.newRequestQueue(mContext.getApplicationContext());
JsonArrayRequest arrayRequest = new JsonArrayRequest(Request.Method.GET, "http:My API IP", null,
new Response.Listener<JSONArray>() {
#SuppressLint("SetTextI18n")
#Override
public void onResponse(JSONArray jsonArray) {
try {
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject = jsonArray.getJSONObject(i);
String numero_de_decision = jsonObject.getString("NUMERO_DE_DECISION");
listaO.add(new Entidad_Decision(numero_de_decision,"","responsables","fecha" + " - " + "plazo", "observaciones", "procede", "status"));
}
//buscar.setText(listaO.size() + "");
Cant[0] = listaO.size();
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
arrayRequest.setRetryPolicy(new DefaultRetryPolicy(MY_DEFAULT_TIMEOUT,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
requestQueue.add(arrayRequest);
}
return Cant[0];
}
When I´m calling that variable, the value is 0.
How can I solve this??

How to add JSONArrayRequest without the use of for loop?

I am using volley library and I want to pass data from a JSON API url with the GET method. What exactly I need is to get the user ID == CurrentUserId. Here is my full code:
RequestQueue queue = Volley.newRequestQueue(getContext());
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.GET, JSON_URL, null, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
for (int i = 0; i < response.length(); i++) {
try {
JSONObject usersObject = response.getJSONObject(i);
Toast.makeText(getContext(), "Name: "+usersObject, Toast.LENGTH_LONG).show();
String ID = usersObject.getString("ID");
if (ID.equalsIgnoreCase(CurrentUser)) {
String fullName = usersObject.getString("fullName");
String userName = usersObject.getString("username");
fullname.setText(fullName);
username.setText(userName);
} else {
fullname.setText("No Name");
}
Toast.makeText(getContext(), "Name: "+CurrentUser, Toast.LENGTH_SHORT).show();
Toast.makeText(getContext(), "Name: "+ID, Toast.LENGTH_SHORT).show();
} catch (JSONException e) {
e.printStackTrace();
Log.d("CATCH", e.getMessage());
}
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
queue.add(jsonArrayRequest);
The downside is that when I use the for loop the code continues to read every item of the JSON. On the other hand when I don't use the for loop I have to set an array index here JSONObject usersObject = response.getJSONObject(i);. So, what index should I set in order to make the code read every item and stop to what is ID == CurrentUserId?

Second fuction executes before the first fuction is completely executed

I have two functions fetchData() and setDataUI(), in fetchData() i'm sending a request and saving the response. In setDataUI() function i'm setting adapter to bind the data's.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_image_gallery);
recyclerView = (RecyclerView) findViewById(R.id.image_recycler_view);
data_list = new ArrayList<>();
fetchData2(1);
}
fetchData2() to fetch data from server.
public void fetchData2(final int next){
String url = Constants.URL+"image/gallery?page="+next;
Log.d(TAG,"Data2 Url-->"+url);
StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
Log.d(TAG, "Response-->" + response);
JSONObject jsonObject = new JSONObject(response);
JSONArray jsonArray = jsonObject.getJSONArray("media");
Log.d(TAG, "Media Array-->" + jsonArray);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject1 = jsonArray.getJSONObject(i);
ImageGallery imageGallery = new ImageGallery(
jsonObject1.getString("file"),
jsonObject1.getString("description"),
jsonObject.getInt("next"));
data_list.add(imageGallery);
Log.d(TAG, "Data List in AsyncTask-->" + data_list);
setDataUI();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(ActivityImageGallery.this, "Server Error!!!!", Toast.LENGTH_SHORT).show();
}
});
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
requestQueue.add(stringRequest);
}
then in setDataUI()
private void setDataToUI() {
gridLayoutManager = new GridLayoutManager(this,1);
recyclerView.setLayoutManager(gridLayoutManager);
Log.d(TAG,"Data_List-->"+data_list);
adapter = new AdapterImageGallery(this, data_list);
recyclerView.setAdapter(adapter);
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrolled(#NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (gridLayoutManager.findLastCompletelyVisibleItemPosition() == data_list.size()-1){
fetchData2(data_list.get(data_list.size()-1).getNext());
}
}
});
}
Expected Result:
function setDataUI() must only start when fetchData2() finishes execution completely. So, data_list in setDataUI() will have the values that are initialized in fetchData2().
Actual Result :
currently setDataUI() starts execution before fetchData2() completes its execution, resulting in data_list to be empty in setDataUI().
I do get the correct response from the server but after the setDataUI() is executed.
What you need to do is just change like below in your response method,
#Override
public void onResponse(String response) {
try {
if(response.isSuccessful){
Log.d(TAG, "Response-->" + response);
JSONObject jsonObject = new JSONObject(response);
JSONArray jsonArray = jsonObject.getJSONArray("media");
Log.d(TAG, "Media Array-->" + jsonArray);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject1 = jsonArray.getJSONObject(i);
ImageGallery imageGallery = new ImageGallery(
jsonObject1.getString("file"),
jsonObject1.getString("description"),
jsonObject.getInt("next"));
data_list.add(imageGallery);
Log.d(TAG, "Data List in AsyncTask-->" + data_list);
}
setDataToUI();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
-Put setDataToUI(); method call after completion of your for loop in onresponse.
-Also, your second method gets executed before your first method because, your first method is asynchronous (i.e., working on another thread. It's not executing in the Main Thread or UI thread).
Volleys' requests are aynchronous. So, you should call your setDataToUI from callback:
StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
// all your code
runOnUiThread(new Runnable() {
#Override
public void run() {
setDataToUI();
}
}
}
This is because in your fetchData() Async Task is running in background which you cannot predict how much time it will take. So rather than calling setDataToUI() after fetchData2() function you can just call it inside the response of the fetchData2() function. You can edit this in fetchData2 Function
data_list.add(imageGallery);
Log.d(TAG, "Data List in AsyncTask-->" + data_list);
setDataToUI()

JSON Array request cannot be applied error listener

I am newbie at Android programming, I have used Google Volley library for calling API and now I have some problem in my Android code. There is JSON error occurred
here
HERE MY CODE :
private void loadJson()
{
pd.setMessage("Mengambil Data");
pd.setCancelable(false);
pd.show();
JsonArrayRequest reqData = new JsonArrayRequest(Request.Method.POST, ServerAPI.URL_DATA,null,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
pd.cancel();
Log.d("volley","response : " + response.toString());
for(int i = 0 ; i < response.length(); i++)
{
try {
JSONObject data = response.getJSONObject(i);
ModelData md = new ModelData();
md.setNpm(data.getString("npm"));
md.setNama(data.getString("nama"));
md.setProdi(data.getString("prodi"));
md.setFakultas(data.getString("fakultas"));
mItems.add(md);
} catch (JSONException e) {
e.printStackTrace();
}
}
mAdapter.notifyDataSetChanged();
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
pd.cancel();
Log.d("volley", "error : " + error.getMessage());
}
});
AppController.getInstance().addToRequestQueue(reqData);
}
You have passed wrong parameter in your JSONArryRequest, You need to pass URL (String) and your response listeners.
JsonArrayRequest request = new JsonArrayRequest(Request.Method.POST,"http://example.com/feed.json",
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray jsonArray) {
//Your code
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
Toast.makeText(MainActivity.this, "Unable to fetch data: " + volleyError.getMessage(), Toast.LENGTH_SHORT).show();
}
});
The arguments are wrong in your JsonArrayRequest (you have to pass a String for the URL).
Try something like this :
private void loadJson()
{
pd.setMessage("Mengambil Data");
pd.setCancelable(false);
pd.show();
JsonArrayRequest reqData = new JsonArrayRequest(ServerAPI.URL_DATA,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
pd.cancel();
Log.d("volley","response : " + response.toString());
for(int i = 0 ; i < response.length(); i++)
{
try {
JSONObject data = response.getJSONObject(i);
ModelData md = new ModelData();
md.setNpm(data.getString("npm"));
md.setNama(data.getString("nama"));
md.setProdi(data.getString("prodi"));
md.setFakultas(data.getString("fakultas"));
mItems.add(md);
} catch (JSONException e) {
e.printStackTrace();
}
}
mAdapter.notifyDataSetChanged();
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
pd.cancel();
Log.d("volley", "error : " + error.getMessage());
}
});
AppController.getInstance().addToRequestQueue(reqData);
}
Remove the first parameter of Request.Method.POST . JsonArrayRequest object takes three parameter in constructor. URL, Listener , ErrorListener .
JsonArrayRequest req = new JsonArrayRequest(url,
new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
It seems like you're passing wrong arguments to JsonArrayRequest().
According to the documentation found here, the method signature is public JsonArrayRequest(String url, Response.Listener<JSONArray> listener, Response.ErrorListener errorListener) and you're passing (int, String, null, Response.Listener<JSONArray>, Response.ErrorListener).
Remove the Request.Method.POST and the null and you should be good to go.

public List<Model> loadInBackground() method in android does not get data from jSon Array

I am developing an application using android and i'm trying to get the jSon Array displayed in Listfragment using the loadInBackground() method below in my DataListLoader class:
class DataListLoader extends AsyncTaskLoader<List<Model>> {
List<Model> mModels;
String jsonString;
String name = "Daniel Nyerere", phone = "0652400670";
public DataListLoader(Context context) {
super(context);
loadInBackground();
}
public List<Model> loadInBackground() {
// You should perform the heavy task of getting data from
// Internet or database or other source
// Here, we are generating some Sample data
// Create corresponding array of entries and load with data.
final List<Model> entries = new ArrayList<Model>(50);
StringRequest stringRequest = new StringRequest(
Request.Method.GET, "http://10.0.2.2/webapp/json_get_data.php", new Response.Listener<String>() {
#Override
public void onResponse(String response) {
if (response.trim().contains("server_response")) {
jsonString = response.toString();
try {
JSONObject jsonObject = new JSONObject(jsonString);
JSONArray jsonArray = jsonObject.getJSONArray("server_response");
int count = 0;
while (count < jsonArray.length()) {
JSONObject jo = jsonArray.getJSONObject(count);
name = jo.getString("name");
phone = jo.getString("user_phone");
entries.add(new Model(name, phone));
System.out.println("DATA FROM JSON ARRAY: " + name + " " + phone);
count++;
return;
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
RequestQueue requestQueue = VolleySingleton.getInstance().getRequestQueue();
requestQueue.add(stringRequest);
entries.add(new Model(name, phone));
return entries;
}
But when i try to run it the data from System.out.println("DATA ENTRIES: "+entries); comes as null list ,so no data get displayed in the fragment activity . Anyone who can help me to fix it so that i get data from json because it consume me a lot of time
//You can call it in UI thread
final List<Model> entries = new ArrayList<Model>(5);
StringRequest stringRequest = new StringRequest(
Request.Method.GET, "http://10.0.2.2/webapp/json_get_data.php", new Response.Listener<String>() {
#Override
public void onResponse(String response) {
//you need to update the `ListView` content here
//If you need you can create new thread here too e.g. using AsyncTask
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
RequestQueue requestQueue = VolleySingleton.getInstance().getRequestQueue();
requestQueue.add(stringRequest);

Categories