How to return string in java methods? - java

I have a problem where i am unable to return a string from this method. I was unsuccessful when I tried creating a new variable outside the Response.Listener. This is probably very simple but how do I go about returning a string from this method. The string I want to return is the 'featured_img_url' string.
public String secondServiceCall(String featuredmedia){
JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.GET,
"http://www.gadgetsinnepal.com/wp-json/wp/v2/media/"+featuredmedia, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject nested_response) {
try {
JSONObject guilld = nested_response.getJSONObject("guid");
String featured_img_url = guilld.getString("rendered");
Toast.makeText(getApplicationContext(),"IMAGE :" + featured_img_url,Toast.LENGTH_LONG).show();
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),
"Error: " + e.getMessage(),
Toast.LENGTH_LONG).show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(),
"ERROR "+error.getMessage(), Toast.LENGTH_LONG).show();
}
});
MySingleton.getInstance(getApplicationContext()).addToRequestQueue(jsonObjReq);
return featured_img_url;
}

update your code to:
String featured_img_url = null;
public String secondServiceCall(String featuredmedia){
JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.GET,
"http://www.gadgetsinnepal.com/wp-json/wp/v2/media/"+featuredmedia, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject nested_response) {
try {
JSONObject guilld = nested_response.getJSONObject("guid");
featured_img_url = guilld.getString("rendered");
Toast.makeText(getApplicationContext(),"IMAGE :" + featured_img_url,Toast.LENGTH_LONG).show();
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),
"Error: " + e.getMessage(),
Toast.LENGTH_LONG).show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(),
"ERROR "+error.getMessage(), Toast.LENGTH_LONG).show();
}
});
MySingleton.getInstance(getApplicationContext()).addToRequestQueue(jsonObjReq);
return featured_img_url;
}

Here, you should simply pass the instance that call this methods to execute the methods from the response.
So change the methods to :
public void secondServiceCall(String featuredmedia, final MyClass caller){
Note that this will return nothing. And the caller instance need to be final to be used in the inner class JsonObjectRequest.
and in the response, you need to pass the value to the instance of MyClass. So add a method in MyClass
public void setFeatureImgUrl(String featuredImgUrl){ ... }
and you just need to call this in the response.
public void onResponse(JSONObject nested_response) {
...
caller.setFeatureImgUrl(feature_img_url);
...
}
Note : This could be done with an Observer pattern but I know that some people doesn't like it. I could add an example of it if needed.

Related

Waiting for multiple volley calls

I'm trying to do something similar to the answer of this question
I'm using Volley rather than Retrofit, and have adapted my code accordingly. For me the callback handlers never actually fire, although the counDownLatch does timeout after the specified number of seconds. I suspect the handlers never fire because the countDownLatch.awaiting is using all the processing on the current thread. Or am I missing something else?
public void queryUmbrellaServer() {
ArrayList<String> identifiers = getHardwareIdentifiers(context);
VolleyLog.DEBUG = true;
CountDownLatch countDownLatch = new CountDownLatch(identifiers.size());
// creating a new variable for our request queue
final RequestQueue[] queue = {Volley.newRequestQueue(context)};
queue[0].start();
for (int i = 0; i < identifiers.size(); i++) {
String url = umbrellaServerUrl + identifiers.get(i) + "/";
Log.i(LOG_TAG, "Inside Loop " + url);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
countDownLatch.countDown();
String serverName = response.getString("mdm_server_url");
String registrationUrl = response.getString("registration_url");
String isDeviceOwner = response.getString("device_owner");
Toast.makeText(context, "Retrieved server name from umbrella server: " + serverName, Toast.LENGTH_LONG).show();
setMdmInfo(serverName, registrationUrl, isDeviceOwner);
Log.i(LOG_TAG, "Successful response");
//queue[0].stop();
results.add(isDeviceOwner.toString());
} catch (JSONException e) {
e.printStackTrace();
Log.d(LOG_TAG, "Error in parsing response");
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
countDownLatch.countDown();
if(error.networkResponse.data!=null) {
String jsonString = new String(error.networkResponse.data);
//Log.d(LOG_TAG, jsonString);
try {
JSONObject jsonObject = new JSONObject(jsonString);
String msg = jsonObject.getString("message");
if (!msg.equals("Device not found")) {
Log.d(LOG_TAG, "Error in retrieving response from server");
//queue[0].stop();
results.add("false");
}
else {
Log.d(LOG_TAG, "No device found");
results.add("false");
}
} catch (JSONException e) {
e.printStackTrace();
Log.d(LOG_TAG, "Error in retrieving response from server");
//queue[0].stop();
results.add("UNSET");
}
}
else {
Log.d(LOG_TAG, "Error in retrieving response from server");
//queue[0].stop();
results.add("UNSET");
}
}
});
// Add the request to the RequestQueue.
queue[0].add(jsonObjectRequest);
}
try {
countDownLatch.await(1L * identifiers.size(), TimeUnit.SECONDS); // join thread with timeout of second for each item
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d(LOG_TAG,"outside loop" + results);
}
I expected the results arrayList should get populated before the countDownLatch countdown completes, but I haven't been able to get any results.

java, andriod studio , volley

My API is returning integer in JSON format I tried using jasonobject request , Jason array, and Jason string through volley but was still unable to receive an integer in response.
Note: I am getting the correct response in postman
String url = static_ip.ip+"/api/Notification/GetDayWiseNotification";
Log.d("url",url);
try {
RequestQueue requestQueue= Volley.newRequestQueue(Collector_screen.this);
JsonObjectRequest request= new JsonObjectRequest(
Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.d("Onresponse","hello");
try{
int numb= Integer.parseInt(String.valueOf(response));
Log.d("lala", String.valueOf(numb));
donerequest.setText(String.valueOf(numb));
}
catch (Exception e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}
);
request.setRetryPolicy(new DefaultRetryPolicy(5000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
requestQueue.add(request);
}`enter code here`
catch(Exception ea){
String err = ea.getMessage().toString();
}

Android Volley Why does JsonObjectRequest does not call onResponse

I am trying to get my volley JsonObjectRequest working. When calling the getById() meth, onResponse() does not get called. I already have a working post request. So the connection parameters are correct. I do not get any error response or helpfull responses in LogCat.
I created a test class in order to isolate the getById() method.
public class Test {
Customer customer;
public Customer getById(int id) {
Log.i("CustomerDAO getById", "getById called");
String urlJsonObj = "http://192.168.0.39:3000/Customers/" + id;
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, urlJsonObj, null, new Response.Listener < JSONObject > () {
#Override
public void onResponse(JSONObject response) {
try {
// Parsing json object response
// response will be a json object
customer = new Customer(response.getInt("customernumber"), response.getString("name"),
response.getString("lastname"), response.getString("phonenumber"),
response.getInt("addressid"), response.getString("password"));
} catch (JSONException e) {
Log.e("JSON Exception:", e.toString());
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("GetByIdErrorResponse", error.toString());
}
});
AppController.getInstance().addToRequestQueue(request);
return customer;
}
}
This is the singleton RequestQueue class.
public class AppController extends Application {
public static final String TAG = AppController.class
.getSimpleName();
private RequestQueue mRequestQueue;
private static AppController mInstance;
#Override
public void onCreate() {
super.onCreate();
mInstance = this;
}
public static synchronized AppController getInstance() {
return mInstance;
}
public RequestQueue getRequestQueue() {
if (mRequestQueue == null) {
mRequestQueue = Volley.newRequestQueue(getApplicationContext());
Log.i("RequestQueue= ", mRequestQueue.toString());
}
return mRequestQueue;
}
}
This is how I call the getById() method
Test test = new Test();
Entities.Customer check = test.getById(1);
There are a few mistakes in your code. Since volley is an asynchronous networking library, you can't return the result from the network as you have done. You are initializing your Customer model class inside OnResponse and returning it from outside of it.
So what will be happening when you perform this operation is
Creates Request -> Adds to Request Queue -> getById() method returns null
The return statement, at last, won't wait till the response arrives. You'll be getting null every time. So what you have to do is to implement a custom callback when the API returns a result or error.
Create an interface for inside Test class for handling API response.
interface APICallback {
void onSuccess(Customer customer);
void onError(String error);
}
Pass these interface implementation to the getById() method along with id
public void getById(int id,APICallback callback) {
....
}
call methods on result
#Override
public void onResponse(JSONObject response) {
try {
// Parsing json object response
// response will be a json object
Customer customer = new Customer(response.getInt("customernumber"), response.getString("name"),
response.getString("lastname"), response.getString("phonenumber"),
response.getInt("addressid"), response.getString("password"));
callback.onSuccess(customer);
} catch (JSONException e) {
Log.e("JSON Exception:", e.toString());
}
}
#Override
public void onErrorResponse(VolleyError error) {
Log.e("GetByIdErrorResponse", error.toString());
callback.onError(error.toString());
}
and now you can call getById() as follows
Test test = new Test();
test.getById(1, new Test.APICallback() {
#Override
public void onSuccess(Customer customer) {
}
#Override
public void onError(String error) {
}
});

Nested volley request with Singleton class returns null

I am getting a error in my code. The outer request returns a data but the inner loop returns null.
What I am doing here is: I am requesting some data and again using the id that I get from the first request, i use it to send another request. Although I am receiving the first response, I am getting ERRORNull message in the second nested request.
I am sure that the url is correct. I have not been able to find the solution to this problem.
private ArrayList<Item> fetchApiData(){
String url="http://www.gadgetsinnepal.com.np/wp-json/wp/v2/posts/";
JsonArrayRequest jsArrayRequest = new JsonArrayRequest
(Request.Method.GET, url, null, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
try {
// Parsing json array response
// loop through each json object
for (int i = 0; i < response.length(); i++) {
JSONObject item = (JSONObject) response
.get(i);
String id = item.getString("id");
String date = item.getString("date");
JSONObject titleobj = item
.getJSONObject("title");
String title= titleobj.getString("rendered");
String featuredMedia= item.getString("featured_media");
Toast.makeText(getApplicationContext(), "ID :" + id +" Date: "+ date+ " Title "+ title + featuredMedia,
Toast.LENGTH_SHORT).show();
JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.GET,
"http://www.gadgetsinnepal.com/wp-json/wp/v2/media/"+featuredMedia, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject nested_response) {
try {
// Parsing json object response
// response will be a json object
JSONObject guilld = nested_response.getJSONObject("guid");
String featured_img_url = guilld.getString("rendered");
String nestid=nested_response.getString("id");
Toast.makeText(getApplicationContext(),nested_response.toString()+"IMAGE" + nestid,Toast.LENGTH_LONG).show();
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),
"Error: " + e.getMessage(),
Toast.LENGTH_LONG).show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(),
"ERROR"+error.getMessage(), Toast.LENGTH_LONG).show();
}
});
MySingleton.getInstance(getApplicationContext()).addToRequestQueue(jsonObjReq);
}
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),
"Error: " + e.getMessage(),
Toast.LENGTH_LONG).show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// TODO Auto-generated method stub
}
});
MySingleton.getInstance(this).addToRequestQueue(jsArrayRequest);
}
This problem was solved by carefully examining where the error log was giving.
Having unique logs in your methods will make finding the place where the problem occurs easier to find.
In this case we found that something was happening in:
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(),
"ERROR"+error.getMessage(), Toast.LENGTH_LONG).show();
}
Further investigation showed we got a response code 503 message there.
Reasons for this to happen: lifewire.com/503-service-unavailable-explained-2622940
Increasing the time out of the request seems to prevent this from occurring again.

Sending POST Request and Receive Json Responds using Retrofit Unable to use Responds data I need to pass it to another activity

I am using Retrofit for sending POST request.Server return's a JSON Response and i am able to parse the response in the callback method. I need to pass the data from server to another activity. But i can't use the response data outside.
api.LoginUser(
Email.getText().toString(), // passing value to interface of retrofit
Password.getText().toString(),
new Callback<Response>() {
#Override
public void success(Response result, Response response) {
BufferedReader reader = null;
String output = "";
try {
reader = new BufferedReader(new InputStreamReader(result.getBody().in()));
output = reader.readLine();
} catch (IOException e) {
e.printStackTrace();
}
//Json PArsing
try {
JSONObject mainObject = new JSONObject(output);
JSONObject dataObj = mainObject.getJSONObject("data");
String id = dataObj.getString("id");
String name = dataObj.getString("name");
n=name;
Log.d("jsontext", n); //This works
}
catch(JSONException e)
{
e.printStackTrace();
}
Toast.makeText(MainActivity.this, output, Toast.LENGTH_LONG).show();
}
#Override
public void failure(RetrofitError error) {
//If any error occured displaying the error as toast
Toast.makeText(MainActivity.this, error.toString(), Toast.LENGTH_LONG).show();
}
}
);
I can't use this when it executes App crashes.its ok now there is no value in the variable.how to get values out of the callback Responds OnSuccess method???
Log.d("outer",n);
Intent dash = new Intent(this,Dashboard.class);
dash.putExtra("Value",fi);
startActivity(dash);
}
You can create an object and implement Serializable:
class User implements Serializable {
...
}
Then put object User to bundle, add to intent:
Bundle bundle = new Bundle();
bundle.putSerializable("data", user);
Intent intent = new Intent(this, YourClass.class);
intent.putExtras(bundle);
startActivity(intent);
Hope it help you.
Hold all data in a string and using intent app another activity and parse it;
You can do it as follows
public void onSuccess(int statusCode, Header[] headers,
byte[] response) {
try {
BufferedReader br = new BufferedReader(
new InputStreamReader(new ByteArrayInputStream(
response)));
String st = "";
String st1 = "";
while ((st = br.readLine()) != null) {
st1 = st1 + st;
}
showStoreData(st1);
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onFailure(int statusCode, Header[] headers,
byte[] errorResponse, Throwable e) {
// called when response HTTP status is "4XX" (eg. 401, 403, 404)
Log.e("FAIL", "FAIl" + statusCode);
}
#Override
public void onRetry(int retryNo) {
// called when request is retried
}
});
after that
public void showStoreData(String st) {
Intent intent = new Intent(this, YourClass.class);
intent.putExtras(st);
startActivity(intent);
}
You should use an interface that you initialize from the calling method and pass as a parameter into you request class, that way you can call the requests from anywhere and get the callback response back to where you called it from, an example would be:
A general interface, separated in another file:
public interface SomeCustomListener<T>
{
public void getResult(T object);
}
In the class holding your call (complete the stuff you need):
public void someRequestReturningString(Object param1, final SomeCustomListener<String> listener)
{
//here you initialize what you need... it's your stuff
response.enqueue(new Callback<ResponseBody>()
{
#Override
public void onResponse(Call<ResponseBody> call, retrofit2.Response<ResponseBody> rawResponse)
{
try
{
String response = rawResponse.body().string();
// do what you want with it and based on that...
//return it to who called this method
listener.getResult("someResultString");
}
catch (Exception e)
{
e.printStackTrace();
listener.getResult("Error1...");
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable throwable)
{
try
{
// do something else in case of an error
listener.getResult("Error2...");
}
catch (Exception e)
{
throwable.printStackTrace();
listener.getResult("Error3...");
}
}
});
}
Then from where you're calling the request (could be anywhere, Fragments, onClicks, etc):
public class BlaBla
{
//.....
public void someMethod()
{
NetworkManager.getInstance().someRequestReturningString(someObject, new SomeCustomListener<String>()
{
#Override
public void getResult(String result)
{
if (!result.isEmpty())
{
//do what you need with the result...
}
}
});
}
}
If you need more context, you can refer to this SO thread.
Hope this helps!

Categories

Resources