2

I am new to android and I am currently trying to make volley post request and get a response from an API. What I did is call a callback when the response is successful. This callback works fine if I call from a single class, for instance, say MainActivity callback method but not working if I try to call from other class. I tried to make the callback parameter in volleyAPIService as generic but can't succeed in it. Any kind of help would be appreciable.

VolleyAPIService.java

public class VolleyAPIService {

    public void volleyPost(final MainActivity.VolleyCallback callback, String URL, Map<String, String> param, Context context) {
        RequestQueue requestQueue = Volley.newRequestQueue(context);
        final Map<String, String> params = param;

        StringRequest stringRequest = new StringRequest(Request.Method.POST, URL,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        callback.onSuccess(response);
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                    }
                }) {
            @Override
            protected Map<String, String> getParams() {;
                return params;
            }
        };
        requestQueue.add(stringRequest);
    }
}

As I stated before I tried to make the first parameter of volleyPost() more generic to call this particular method from any class but couldn't succeed.

MainActivity.java

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        companyLogin("abc", "123");
    }

    public interface VolleyCallback {
        void onSuccess(String result);
    }

    public void companyLogin(String companyname, String password) {
        RequestQueue requestQueue = Volley.newRequestQueue(this);
        String URL = "http://...";
        final Map<String, String> params = new HashMap<String, String>();
        params.put("name", companyname);
        params.put("pwd", password);

        Intent volley_service = new Intent(MainActivity.this, VolleyAPIService.class);
        MainActivity.this.startService(volley_service);

        VolleyAPIService volleyAPIService = new VolleyAPIService();
        volleyAPIService.volleyPost(new VolleyCallback() {
            @Override
            public void onSuccess(String result) {
                //do stuff here
                Log.d("VOLLEY", "onSuccess: " + result);
                if (!result.isEmpty()) {
                    Intent userLoginActivity = new Intent(MainActivity.this, UserLogin.class);
                    startActivity(userLoginActivity);
                } else {
                    AlertDialog.Builder login_failed = new AlertDialog.Builder(MainActivity.this);
                    login_failed.setMessage("Login Failed, invalid credentials")
                            .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {

                                }
                            });
                    AlertDialog alert = login_failed.create();
                    alert.show();
                }
            }
        }, URL, params, MainActivity.this);
    }
}

I call volleyPost() with callback in MainActivity.java

UserLogin.java

public class UserLogin extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_user_login);

        userLogin("xyz", "456", "1")
    }

    public interface VolleyCallback {
        void onSuccess(String result);
    }

    public void userLogin(String username, String password, String id) {
        RequestQueue requestQueue = Volley.newRequestQueue(this);
        String URL = "http://...";
        final Map<String, String> params = new HashMap<String, String>();
        params.put("username", username);
        params.put("password", password);
        params.put("compId", id);

        Intent volley_service = new Intent(UserLogin.this, VolleyAPIService.class);
        UserLogin.this.startService(volley_service);

        VolleyAPIService volleyAPIService = new VolleyAPIService();
        volleyAPIService.volleyPost(new VolleyCallback() {
            @Override
            public void onSuccess(String result) {
                //do stuff here
                Log.d("VOLLEY", "onSuccess: " + result);
                if (!result.isEmpty()) {
                    Intent userLoginActivity = new Intent(UserLogin.this, HomePage.class);
                    startActivity(userLoginActivity);
                } else {
                    AlertDialog.Builder login_failed = new AlertDialog.Builder(UserLogin.this);
                    login_failed.setMessage("Login Failed, invalid credentials")
                            .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                }
                            });
                    AlertDialog alert = login_failed.create();
                    alert.show();
                }
            }
        }, URL, params, UserLogin.this);
    }
}

I try to call volleyPost() from this class too. I know that the type of parameter callback mismatches and tried to make the callback parameter generic for both the classes, I can't figure out a way to do that.

Any kind of help is appreciable and thanks in advance.

Reaz Murshed
  • 23,691
  • 13
  • 78
  • 98
Ram Keerthy
  • 227
  • 4
  • 16

1 Answers1

1

I would like to recommend to have a separate interface class without keeping it inside of a Class or Activity.

So declare an interface like this. Create a separate file.

public interface VolleyCallback {
    void onSuccess(String result);
}

Then create a public instance of the VolleyCallback interface in your VolleyAPIService class like the following. Remove the parameter from the volleyPost method for cleaner implementation.

public class VolleyAPIService {

    public VolleyCallback callback; 

    public void volleyPost(String URL, Map<String, String> param, Context context) {
        RequestQueue requestQueue = Volley.newRequestQueue(context);
        final Map<String, String> params = param;

        StringRequest stringRequest = new StringRequest(Request.Method.POST, URL,
                new Response.Listener<String>() {
                    @Override
                    public void onResponse(String response) {
                        callback.onSuccess(response);
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                    }
                }) {
            @Override
            protected Map<String, String> getParams() {;
                return params;
            }
        };
        requestQueue.add(stringRequest);
    }
}

Now from your MainActivity, implement the interface that you have created and override the callback function like the following.

public class MainActivity extends AppCompatActivity implements VolleyCallback {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        companyLogin("abc", "123");
    }
    public interface VolleyCallback {
        void onSuccess(String result);
    }

    public void companyLogin(String companyname, String password) {
        RequestQueue requestQueue = Volley.newRequestQueue(this);
        String URL = "http://...";
        final Map<String, String> params = new HashMap<String, String>();
        params.put("name", companyname);
        params.put("pwd", password);

        Intent volley_service = new Intent(MainActivity.this, VolleyAPIService.class);
        MainActivity.this.startService(volley_service);

        VolleyAPIService volleyAPIService = new VolleyAPIService();

        // Assign the callback here to listen the response from the API service.
        volleyAPIService.callback = this; 
        volleyAPIService.volleyPost(URL, params, MainActivity.this);
    }

    @Override
    public void onSuccess(String result) {
        // Handle the success or failure here
        if (!result.isEmpty()) {
            Intent userLoginActivity = new Intent(MainActivity.this, UserLogin.class);
            startActivity(userLoginActivity);
        } else {
            AlertDialog.Builder login_failed = new AlertDialog.Builder(MainActivity.this);
            login_failed.setMessage("Login Failed, invalid credentials")
                 .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                     @Override
                     public void onClick(DialogInterface dialog, int which) {

                     }
                 });

             AlertDialog alert = login_failed.create();
             alert.show();
        }
    }
}

Do the same for your UserLogin class.

In case of having multiple API calls in a single Activity or Fragment, you might want to keep a flag in the VolleyAPIService class and passing that to the callback function you can detect which API response you are getting in your onSuccess callback.

Hope that is clear. Please feel free to ask any questions.

Reaz Murshed
  • 23,691
  • 13
  • 78
  • 98