i have an entry level question:
if there is external java class let's say 'Class1' inside this class there is a method called 'method1' inside this method there is Override method 'onResponse' inside this method two variables is being set 'a' and 'b'.
in the android mainActivity i called the method from the class like this:
Class1.method1();
after calling the method how i can retrieve these variables to be used in mainActivity...
thanks..
public abstract class Class1 extends Context {
final Context mcontext;
public static void method1(final Context mcontext, final String x){
StringRequest stringRequest = new StringRequest(Request.Method.POST, constants.URL, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject parentObject = new JSONObject(response);
JSONObject userDetails = parentObject.getJSONObject("data");
//read attributes
String a = userDetails.getString("a");
String b = userDetails.getString("b");
} catch (JSONException e) {
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(mcontext, error.getMessage() ,Toast.LENGTH_LONG).show();
}
}){
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String,String> params = new HashMap<>();
params.put("x", x);
return params;
}
};
requestHandler.getInstance(mcontext).addToRequestQueue(stringRequest);
}
Why not create a wrapper class for a and b
public class Details {
public string a;
public string b;
}
and then read/return it in the method1
public abstract class Class1 extends Context {
final Context mcontext;
public static Details method1(final Context mcontext, final String x){
Details data = new Details;
StringRequest stringRequest = new StringRequest(Request.Method.POST, constants.URL, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject parentObject = new JSONObject(response);
JSONObject userDetails = parentObject.getJSONObject("data");
//read attributes
data.a = userDetails.getString("a");
data.b = userDetails.getString("b");
} catch (JSONException e) {
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(mcontext, error.getMessage() ,Toast.LENGTH_LONG).show();
}
}){
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String,String> params = new HashMap<>();
params.put("x", x);
return params;
}
};
requestHandler.getInstance(mcontext).addToRequestQueue(stringRequest);
return data;
}
if you want to return more than one value you should use Android ways called Intent
but if you insist
you can use Array or ArrayList return type for the inner inner method
class Class1{
public static ArrayList<Object> method1(){
return onResponse();
}
public static ArrayList<Object> onResponse(){
return arrayList<Object>;
}
}
but still i see no reason to not use Intent
Related
I have a variable inside an interface method and I want it outside the interface:
String responseString;
StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
// i want this value out!
responseString = response.toString();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
System.out.println(error.toString());
}
});
Of course I can't just assign responseString = response.toString() because they have different scopes. So how can I do this?
Probably this question has already been answered but I couldn't find anything similar online.
Try this once as per your JSON structure Either JSONArray or JSONObject.
//JSON Array
private JSONArray result;
//Creating a string request
StringRequest stringRequest = new StringRequest(URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
JSONObject j = null;
try {
//Parsing the fetched Json String to JSON Object
j = new JSONObject(response);
//Storing the Array of JSON String to our JSON Array
result = j.getJSONArray("your key");
//OPTIONAL function
functionName(result);//If using function
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
The new Response.Listener<String>() {...} that you're doing in that method is called "anonymous" implementation. Indeed you are implementing the interface, but you don't hold any static reference to it in the code.
What you should do, is to have a normal implementation of the interface which of course implements the method required, but also holds a field and a special getter for your field:
public class YourStringListener implements Response.Listener<String> {
private String responseString; //<-- declare a field
#Override
public void onResponse(String response) {
this.responseString = response.toString(); //<-- set the field
}
public String getResponseString() {
return this.responseString; //<-- get the field from outside
}
}
Now, you should be able to do this:
String responseString;
YourStringListener listener = new YourStringListener(); //<-- don't implement anonimously, use the concrete implementation
StringRequest stringRequest = new StringRequest(Request.Method.GET, url, listener, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
System.out.println(error.toString());
}
});
System.out.println(listener.getResponseString()); //<-- access the value of response string from the concrete implementation instance
Of course, be careful you're into a listener. The value will be null until when the method onResponse will have asynchronously been called back.
How to send multiple q input texts? As I see, the API doesn't allow q[] type arrays, instead it uses multiple q parameters.
protected Map<String,String> getParams(){
List<String> textString = new ArrayList<>();
Map<String,String> params = new HashMap<String, String>();
params.put("key", "key");
params.put("target", "DE");
params.put("q", text);
return params;
}
};
I found the following helper class:
class HttpParams extends HashMap<String, List<String>> {
private static final long serialVersionUID = 1L;
public HttpParams() {
super();
}
public HttpParams(int capacity) {
super(capacity);
}
public HttpParams(Map<String, List<String>> map) {
super(map);
}
public HttpParams(int capacity, float loadFactor) {
super(capacity, loadFactor);
}
/*
* This is the method to use for adding post parameters
*/
public void add(String key, String value) {
if (containsKey(key)) {
get(key).add(value);
}
else {
ArrayList<String> list = new ArrayList<String>();
list.add(value);
put(key, list);
}
}
/**
* Converts the Map into an application/x-www-form-urlencoded encoded string.
*/
public byte[] encodeParameters(String paramsEncoding) {
StringBuilder encodedParams = new StringBuilder();
try {
for (Map.Entry<String, List<String>> entry : entrySet()) {
String key = URLEncoder.encode(entry.getKey(), paramsEncoding);
for (String value : entry.getValue()) {
encodedParams.append(key);
encodedParams.append('=');
try {
encodedParams.append(URLEncoder.encode(value, paramsEncoding));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
encodedParams.append('&');
}
}
return encodedParams.toString().getBytes(paramsEncoding);
} catch (UnsupportedEncodingException uee) {
throw new RuntimeException("Encoding not supported: " + paramsEncoding, uee);
}
}
}
and then in Main class that extends Request overrided the getBody():
public void volleyPost(String text,OnServiceResponseListener onServiceResponseListener){
String URL = "Your Url here";
RequestQueue requestQueue = Volley.newRequestQueue(this);
HttpParams mParams = new HttpParams();
mParams.add("key", "key");
mParams.add("target", "languageCode");
String wordsArray [] = text.split(",");
for(int i = 0;i<wordsArray.length;i++) {
mParams.add("q", wordsArray[i]);
}
StringRequest stringRequest = new StringRequest(Request.Method.POST, URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
onServiceResponseListener.onSuccess(response);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
onServiceResponseListener.onFailed(error.getMessage());
}
}){
#Override
public byte[] getBody() throws AuthFailureError {
if (mParams != null && mParams.size() > 0) {
Log.d(TAG,"mParams--->"+new Gson().toJson(mParams));
return mParams.encodeParameters(getParamsEncoding());
}
return null;
}
};
requestQueue.add(stringRequest);
}
I have a Class, that get me a String of a Data Base.
I call the Class in my Activity, and then I use that string.
The stirng is returned because I get it by Log.d, but the String variable of my Activity don´t get it because the program continues without wait the Class ends.
(SORRY MY BAD ENGLISH)
Code:
Activity:
Cargar_Imagen ci = new Cargar_Imagen();
String s = ci.Cargar_Imagen(params...);
Class:
public class Cargar_Imagen {
private Map<String, String> params;
String sBitmap = "";
public String Cargar_Imagen(final String email, final String id, final String f1, final Context context, final String type, final View v){
StringRequest stringRequest = new StringRequest(Request.Method.POST, "https://feticher.webcindario.com/cargar_imagen.php",
new Response.Listener<String>() {
#Override
public void onResponse(String s) {
Log.d("Imagen", "Se cargo la foto");
try {
JSONObject jsonRespose = new JSONObject(s);
sBitmap =jsonRespose.getString("imagen");
Log.d("Imagen", "STRING: " + sBitmap);
Download_Image download_image = new Download_Image();
download_image.Download_Image(f1, type,context, v, sBitmap);
} catch (JSONException e) {
e.printStackTrace();
Log.d("Imagen", "ERROR: " + e.getMessage());
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("Imagen", "No se pudo cargar la foto");
}
}) {
#Override
protected Map<String, String> getParams(){
Log.d("Imagen", "Ejecutando MAP Cargar Imagen");
Log.d("Imagen", "DATOS: " + id + " " + email + " " + f1);
Map<String, String> params = new Hashtable<String, String>();
params.put("id", id);
params.put("email", email);
params.put("foto", f1);
Log.d("Imagen", "PASO POR AKI");
return params;
}};
RequestQueue queue = Volley.newRequestQueue(context);
queue.add(stringRequest);
return sBitmap;
}
}
sBitmap is assigned after the method gets executed since it's asynchronous. One approach is to declare an interface with a method [for example onFinish(String) ] and pass it as a parameter of Cargar_Imagen, after that you can call it inside your onResponse.Listener method.
// The interface
interface CallBack {
public void onFinish(String response);
}
// The activity (which calls Cargar_Imagen) should implement CallBack
public class MainActivity extends Activity implements CallBack
public void onFinish(String response) {
// here the method did finish, do something with the string
}
// somewhere you call to Cargar_Imagen
String s = ci.Cargar_Imagen(params..., this);
}
// the method signature should receive a CallBack
public String Cargar_Imagen(final String email, final String id, final String f1, final Context context, final String type, final View v, final CallBack callback){
/* code .... */
// ...
// in your onResponse
callback.onFinish(sBitmap);
You have written retrun sBitmap;, try with the correct return and let us know if it solved the problem.
So I am trying to parse an array of objects from json using Google's Gson library and Volley for HTTP requests. My issue is it's as if the code isn't 'hitting' the OnResponse call. I've tried adding a simple Log printout within the function just to see if it does anything.
My GsonRequest class comes straight from Google's Training Docs. I constructed these methods based on an answer to this question.
This is my code:
private void runVolleyJson() throws AuthFailureError {
GsonRequest<Meetings> getMeetings = new GsonRequest<Meetings>(AUTH_URL, Meetings.class, getHeaders(),
createMyReqSuccessListener(),
createMyReqErrorListener());
helper.add(getMeetings);
}
private Response.Listener<Meetings> createMyReqSuccessListener() {
return new Response.Listener<Meetings>() {
#Override
public void onResponse(Meetings response) {
// NOTHING HAPPENS FROM HERE!
try {
Log.d("response", response.toString());
} catch (Exception e) {
e.printStackTrace();
}
// Do whatever you want to do with response;
// Like response.tags.getListing_count(); etc. etc.
}
};
}
private Response.ErrorListener createMyReqErrorListener() {
return new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// Do whatever you want to do with error.getMessage();
}
};
}
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> map = new HashMap<>();
map.put("Content-Type", "application/json;");
map.put("Authorization", "Bearer <sometoken>");
return map;
}
There is absolutely no error. It is authorizing the request, but nothing happens in OnResponse, it just seems to ignore that function.
Now I've tried using a standard StringRequest with volley and it works flawlessly, like this:
private void runVolleyTest() {
StringRequest request = new StringRequest(Request.Method.GET, AUTH_URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONArray jsonarray = new JSONArray(response);
for(int i = 0; i < jsonarray.length(); i++) {
Gson gson = new Gson();
Meeting m = gson.fromJson(jsonarray.get(i).toString(), Meeting.class);
Log.e("Meeting", m.getMeetingId() + " " + m.getStatus());
}
} catch (JSONException e) {
e.printStackTrace();
}
;
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
txtError(error);
}
}) {
#Override
public Map<String, String> getHeaders() {
HashMap<String, String> map = new HashMap<>();
map.put("Content-Type", "application/json;");
map.put("Authorization", "Bearer <sometoken>");
return map;
}
};
//request.setPriority(Request.Priority.HIGH);
helper.add(request);
}
Try adding this line at the beginning
RequestQueue helper = Volley.newRequestQueue(mContext);
Add these line
RequestQueue requestQueue = Volley.newRequestQueue(context);
requestQueue.add(stringRequest);
if you don't want to the save response in cache memory then add this
requestQueue.add(stringRequest);
According to my personal opinion its better if you pass the application context.
i have an json object like this and i am getting this response in my Fragment.
json
{
"data":{
"categories":[
{
"id":"d5c4eedf-093e-422f-8335-6c6376ca3ccb",
"schedule_m_id":1,
"title_en":"Bakery Products",
"title_fr":"Produits de boulangerie",
"subtitle_en":"Bread, Cakes, Cookies, Crackers, Pies",
"subtitle_fr":"Pain, gateaux, biscuits, craquelins, tartes",
"created_at":"2015-03-04 15:39:44",
"updated_at":"2015-03-04 15:39:44"
},
{
"id":"6d1d4945-9910-40ae-82a8-3fe4137c24c2",
"schedule_m_id":2,
"title_en":"Beverages",
"title_fr":"Boissons",
"subtitle_en":"Soft Drinks, Coffee, Tea, Cocoa",
"subtitle_fr":"Boissons gazeuses, café, thé, cacao",
"created_at":"2015-03-04 15:39:44",
"updated_at":"2015-03-04 15:39:44"
}
]
},
"result":"success"
}
and my categories class is like this:
public class Categories {
private int id;
private String title_en;
private String title_fr;
private int schedule_m_id;
private String subtitle_en;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle_en() {
return title_en;
}
public void setTitle_en(String title_en) {
this.title_en = title_en;
}
public String getTitle_fr() {
return title_fr;
}
public void setTitle_fr(String title_fr) {
this.title_fr = title_fr;
}
public int getSchedule_m_id() {
return schedule_m_id;
}
public void setSchedule_m_id(int schedule_m_id) {
this.schedule_m_id = schedule_m_id;
}
public String getSubtitle_en() {
return subtitle_en;
}
public void setSubtitle_en(String subtitle_en) {
this.subtitle_en = subtitle_en;
}
}
In my fragment how can i parse this json object. i need to make an ArrayList which type is "Categories". i need this Categories object List to make an custom adapter. Can anybode help me.
JSONObject jsonObject = (JSONObject) response;
JSONObject dataProject = jsonObject.getJSONObject("data");
JSONArray products = dataProject.getJSONArray("categories");
Gson gson = new Gson();
Categories categories = new Categories();
ArrayList<Categories> items = new ArrayList<Categories>();
int productCount = products.length();
for (int i = 0; i < productCount; i++) {
categories = gson.fromJson(products.get(i), Categories.class);
items.add(categories);
}
```
I posting a class working with gson volley May be Helpful for you....
Step1. For Parsing your json data use "www.jsonschema2pojo.org/" and generate pojo classes. copy classes in your project with same name.
Step2. Just create a GsonRequest Class as follows (taken from https://developer.android.com/training/volley/request-custom.html)
public class GsonRequest<T> extends Request<T> {
private final Gson gson = new Gson();
private final Class<T> clazz;
private final Map<String, String> headers;
private final Listener<T> listener;
/**
* Make a GET request and return a parsed object from JSON.
*
* #param url URL of the request to make
* #param clazz Relevant class object, for Gson's reflection
* #param headers Map of request headers
*/
public GsonRequest(String url, Class<T> clazz, Map<String, String> headers,
Listener<T> listener, ErrorListener errorListener) {
super(Method.GET, url, errorListener);
this.clazz = clazz;
this.headers = headers;
this.listener = listener;
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
return headers != null ? headers : super.getHeaders();
}
#Override
protected void deliverResponse(T response) {
listener.onResponse(response);
}
#Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
try {
String json = new String(
response.data,
HttpHeaderParser.parseCharset(response.headers));
return Response.success(
gson.fromJson(json, clazz),
HttpHeaderParser.parseCacheHeaders(response));
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JsonSyntaxException e) {
return Response.error(new ParseError(e));
}
}
Step3.Now in your main Activity just use this "GsonRequest" class like that:
mRequestQueue = Volley.newRequestQueue(getApplicationContext());
GsonRequest<MyPojoClass> gsonRequest = new GsonRequest<MyPojoClass>(
Request.Method.GET,
apiurl,
MyPojoClass.class,
mySuccessListener(),
myErrorListener());
//Add below these code lines for "Retry" data fetching from api
gsonRequest.setRetryPolicy(new DefaultRetryPolicy(
5000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
mRequestQueue.add(gsonRequest);
}
private Response.Listener<MyPojoClass> mySuccessListener() {
return new Response.Listener<CustomRequest>() {
#Override
public void onResponse(MyPojoClass pRequest) {
//do something
}
};
}
private Response.ErrorListener myErrorListener() {
return new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
System.out.println(volleyError.getMessage().toString());
}
};
}