0

I am trying to call this method from another class; it should return true or false after checking user ID and password on the server.

It always returns false even if the login process is successful because it returns the default value false before i got the request response!

I made a lot of search before posting this question but there is no clear answer on how to solve this problem.

MyHelper myHelper = new MyHelper();
myHelper.setVolleyResponseListener(new MyHelper.OnVolleyResponse()
{
    @Override
    public void onResponse(JSONObject jsonObject)
    {
        // do watever you want here with response.
    }
});

if (myHelper.doBackgroundLogin(getApplicationContext())) {
    uploadImageToServer();
}else{
    finish();
    startActivity(new Intent(AccountProfileImageActivity.this, AccountLoginActivity.class));
}

package com.company.testApp;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.Toast;

import com.android.volley.AuthFailureError;
import com.android.volley.DefaultRetryPolicy;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

/**
 * Created by Aly on 1/11/2017.
 */

public class MyHelper {

    private static AlertDialog.Builder builder;
    public static Context ctx;
    public static ValuesManager vm;

    public static boolean status = false;


    public static boolean doBackgroundLogin(final Context context) {
        vm = new ValuesManager( context, context.getString(R.string.saved_values_file_name) );
        String user_email = vm.retrieveSharedPreferences("user_email");
        String user_password = vm.retrieveSharedPreferences("user_password");

        Toast.makeText(context, user_email + " - " + user_password, Toast.LENGTH_SHORT).show();
        //------------------------------------------------------------------------------------------
//        final MyProgressDialog progressDialog;
//        progressDialog = MyProgressDialog.show(context, "title", "message");
//        //------------------------------------------------------------------------------------------
        String url =  context.getString(R.string.server_path);
        Log.d("URL : ", url);
        StringRequest stringRequest = new StringRequest(Request.Method.POST,
                url,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        Log.i("response : ", response); // log the error to trace it and print message to user
//                        progressDialog.dismiss();
                        try {
                            JSONObject jsonObject = new JSONObject(response);
                            JSONArray jsonArray = jsonObject.getJSONArray("server_response");
                            JSONObject JO = jsonArray.getJSONObject(0);
                            String code = JO.getString("code");
                            if( code.equals("login_true") ) {
                                status = true;
                                vm.saveSharedPreferences( "user_token", JO.getString("user_token") );
                                Log.d("trace","code = " + code);
                                Log.d("trace","statusUpdated = " + status);
                            }
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        Log.d("vERROR : ", error.toString()); // log the error to trace it and print message to user
//                        progressDialog.dismiss();
                    }
                }
        )
        {
            @Override
            protected Map<String, String> getParams() throws AuthFailureError {
                Map<String, String> params = new HashMap<>();
                params.put("action","account_login");
                params.put("email_address",vm.retrieveSharedPreferences("user_email"));
                params.put("password",vm.retrieveSharedPreferences("user_password"));
                return params;
            }
        };

        stringRequest.setRetryPolicy(new DefaultRetryPolicy(
                100000,
                DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
                DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
        MySingleton.getInstance(context).addToRequestQueue(stringRequest);
        //------------------------------------------------------------------------------------------
        Log.d("trace","status = " + status);
        return status;
   } 

    public interface OnVolleyResponse
    {
        void onResponse(JSONObject jsonObject);
    }

    public void setVolleyResponseListener(OnVolleyResponse responseListener)
    {
        this.volleyResponse = volleyResponse;
    }

}
Adham
  • 87
  • 1
  • 8
  • there's something called `AsyncTask` and `onPostExecute`? – Belladonna Dec 20 '17 at 09:25
  • You can not return value by an Asynchronous method, use `interface` for this. – Maddy Dec 20 '17 at 09:25
  • Make interface and use as callback for your network request and pass the result of request in callback's method. move your task in callback method. – Bhavesh Desai Dec 20 '17 at 09:26
  • 1
    Possible duplicate of [How to get the result of OnPostExecute() to main activity because AsyncTask is a separate class?](https://stackoverflow.com/questions/12575068/how-to-get-the-result-of-onpostexecute-to-main-activity-because-asynctask-is-a) – Belladonna Dec 20 '17 at 09:28
  • Thanks for all but i am Beginner and i don't know how to make interface and call back ...any example or code block please ? – Adham Dec 20 '17 at 09:30
  • Use ProgressDialog to wait until the data is received – Aqua 4 Dec 20 '17 at 09:42
  • See My answer it would definitely solve your problem. @Adham – Abhishek Dubey Dec 20 '17 at 09:46
  • Make a java class in any package and just paste ------>>>>> public interface NameOfClass{ public void onSuccess(boolean data); } – Abhishek Dubey Dec 20 '17 at 09:53

3 Answers3

3

You have to use interface callback for this.

Why?

Because this is asynchronous call, and work on different thread. so your Main Thread will not wait for result of it.

Solution

  1. Create interface in your MyHelper class

Edit

    OnVolleyResponse  onVolleyResponse;
    public interface OnVolleyResponse
    {
        void onResponse(JSONObject jsonObject);
    }
  1. Create setter method for callback

    public void setVolleyResponseListener(OnVolleyResponse responseListener)
    {
        this.volleyResponse = volleyResponse;
    }
    

Now call this method from your Activity

MyHelper myHelper = new MyHelper();
myHelper.setVolleyResponseListener(new OnVolleyResponse()
{
    @Override
    public void onResponse(JSONObject jsonObject)
    {
       // do watever you want here with response. 
    }
});
if (myHelper.doBackgroundLogin(getApplicationContext())) {
                            uploadImageToServer();
                        }else{
                            finish();
                            startActivity(new Intent(AccountProfileImageActivity.this, AccountLoginActivity.class));
                        }

Note

Remove static from doBackgroundLogin method, and call it with instance of MyHelper.

Vishal Chhodwani
  • 2,567
  • 5
  • 27
  • 40
  • if i put setVolleyResponseListener method in MyHelper class i get error that volleyResponse is not resolved !! – Adham Dec 20 '17 at 09:43
  • Have you follow all the steps I mention above? I edited something there – Vishal Chhodwani Dec 20 '17 at 09:44
  • You have to create interface in MyHelper class. named OnVolleyResponse, if you still facing issue paste your code in your question. it will help me to find out better solution for you – Vishal Chhodwani Dec 20 '17 at 09:46
  • code updated ... the problem in the last line in my helper calss ... this one ... this.volleyResponse = volleyResponse; – Adham Dec 20 '17 at 10:16
  • I have updated my code please check. below Edit TAG. You just need to create instance of `OnVolleyResponse` above interface. – Vishal Chhodwani Dec 20 '17 at 11:53
  • on setter method for callback ... this.volleyResponse not declared and it is = volleyResponse ... where volleyResponse comt from ?!! – Adham Dec 20 '17 at 13:17
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/161675/discussion-between-vishal-chhodwani-and-adham). – Vishal Chhodwani Dec 21 '17 at 05:44
  • @Adham make Global Variable `OnVolleyResponse onVolleyResponse;` in your `MyHelper` class. That's it. – Vishal Chhodwani Dec 21 '17 at 05:45
1

Make an interface

public interface VolleyCallback{

public void onSuccess(boolean status);}

After this when you get a response you should change your doBackgroundLogin() method like this.

 public static boolean doBackgroundLogin(final Context context,VolleyCallback callback) {
    vm = new ValuesManager( context, context.getString(R.string.saved_values_file_name) );
    String user_email = vm.retrieveSharedPreferences("user_email");
    String user_password = vm.retrieveSharedPreferences("user_password");

    Toast.makeText(context, user_email + " - " + user_password, Toast.LENGTH_SHORT).show();

    String url =  context.getString(R.string.server_path);
    Log.d("URL : ", url);
    StringRequest stringRequest = new StringRequest(Request.Method.POST, url,
            new Response.Listener<String>() {
                @Override
                public void onResponse(String response) {
                    Log.i("response : ", response); // log the error to trace it and print message to user

                    try {
                        JSONObject jsonObject = new JSONObject(response);
                        JSONArray jsonArray = jsonObject.getJSONArray("server_response");
                        JSONObject JO = jsonArray.getJSONObject(0);
                        String code = JO.getString("code");
                        if( code.equals("login_true") ) {
                            status = true;
                            vm.saveSharedPreferences( "user_token", JO.getString("user_token") );
                            Log.d("trace","code = " + code);
                            Log.d("trace","statusUpdated = " + status);

                            callback.onSuccess(status);
                        }
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            },
            new Response.ErrorListener() {
                @Override
                public void onErrorResponse(VolleyError error) {
                    Log.d("vERROR : ", error.toString()); // log the error to trace it and print message to user

                }
            }
    )
    {
        @Override
        protected Map<String, String> getParams() throws AuthFailureError {
            Map<String, String> params = new HashMap<>();
            params.put("action","account_login");
            params.put("email_address",vm.retrieveSharedPreferences("user_email"));
            params.put("password",vm.retrieveSharedPreferences("user_password"));
            return params;
        }
    };
    stringRequest.setRetryPolicy(new DefaultRetryPolicy(
            100000,
            DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
            DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
    MySingleton.getInstance(context).addToRequestQueue(stringRequest);

    Log.d("trace","status = " + status);
    return status; } 

Just see this callback.onSuccess(status);

This would send the response as soon as the login is successful.

Vishal Chhodwani
  • 2,567
  • 5
  • 27
  • 40
Abhishek Dubey
  • 937
  • 8
  • 11
  • iam trying to test it but i am getting error in the Main Activity ... how i call background method after we updated the code ? it need one more parameter – Adham Dec 20 '17 at 10:32
0

onResponse method is for you volley handle this waiting for you and call onResponse method after fetching data or response from specific url.

  final TextView mTextView = (TextView) findViewById(R.id.text);
    ...

    // Instantiate the RequestQueue.
    RequestQueue queue = Volley.newRequestQueue(this);
    String url ="http://www.google.com";

    // Request a string response from the provided URL.
    StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
                new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {
            // Display the first 500 characters of the response string.
            mTextView.setText("Response is: "+ response.substring(0,500));
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            mTextView.setText("That didn't work!");
        }
    });
    // Add the request to the RequestQueue.
    queue.add(stringRequest);
Nouman Ch
  • 4,023
  • 4
  • 29
  • 42