1
\$\begingroup\$

For school I had to do a real simple login and authentication system on an Android app, and I'm wondering how my code can be optimised to reduce code duplication and how it can be made more object oriented?

All the app does is make an API call to my SLIM restful web service using AsyncHttpClient library and stores the AUTHkey, name, and surname of the logged in user to shared preferences.

loginScreen.java:

public class LoginScreen extends ActionBarActivity {
    private String username;
    private String password;
    private ProgressDialog prgDialog;
    private String localhostURL = "http://10.0.3.2/diploma/cloud_computing/tutorials/tutorial2/";
    private String vKey;
//    private String localhostURL = "http://10.0.2.2/diploma/cloud_computing/tutorials/tutorial2/";

    StringEntity entity = null;
    StringEntity authVkeyEntity = null;

    //Will store our post data
    JSONObject params = new JSONObject();
    JSONObject paramsAuth = new JSONObject();

    //Shared Pref vars
    public static final String MyPREFERENCES = "MyPrefs";
    public static final String SURNAME = "surname";
    public static final String FIRSTNAME = "firstname";
    public static final String VKEY = "vkey";
    public static SharedPreferences sharedpreferences;



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



        //Register assets
        Button btnLogin = (Button) findViewById(R.id.btnLogin);
        final EditText txtUsername = (EditText) findViewById(R.id.txtUsername);
        final EditText txtPassword = (EditText) findViewById(R.id.txtPassword);

        //Progress dialog initiation
        prgDialog = new ProgressDialog(this); // Instantiate Progress Dialog object
        prgDialog.setMessage("Please wait...");  // Set Progress Dialog Text
        prgDialog.setCancelable(false); // Set Cancelable as False

        btnLogin.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        //Get username & password
                        username = txtUsername.getText().toString();
                        password = txtPassword.getText().toString();

                        try {
                            //Append json object name and value  ("username", username)
                            params.put("username", username);
                            params.put("password", password);
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }

                        try {
                            entity = new StringEntity(params.toString());
                        } catch (UnsupportedEncodingException e) {
                            e.printStackTrace();
                        }
                        entity.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));


                        //Make the request with the above params
                        makeApiRequest(entity);
                        System.out.println("4");
                    }
                });

    }

    public void makeApiRequest(StringEntity entity){
        // Show Progress Dialog
        prgDialog.show();

        // Make RESTful webservice call using AsyncHttpClient object
        AsyncHttpClient client = new AsyncHttpClient();
        Context context = this.getApplicationContext();

        client.post(context, localhostURL + "user", entity, "application/json", new AsyncHttpResponseHandler() {

            // When the response returned by REST has Http response code '200'
            @Override
            public void onSuccess(String response) {
                prgDialog.hide(); // Hide Progress Dialog
                try {
                    JSONObject obj = new JSONObject(response);   // Create JSON Object

                    //If the object has a string named "key" run the following code
                    if (obj.has("key")) {
                        Toast.makeText(getApplicationContext(), obj.getString("givename") + " You are successfully logged in!", Toast.LENGTH_LONG).show();

                        // Save data to shared pref and change page
                        saveSharedPreferences(obj.getString("surname"),obj.getString("givename"),
                                obj.getString("key"));
                        changeToWelcomeActivity();

                    }
                    else if (obj.has("pass-error"))
                        Toast.makeText(getApplicationContext(), "Your password is incorrect", Toast.LENGTH_LONG).show();
                    else if((obj.has("account-error")))
                        Toast.makeText(getApplicationContext(), "Your account doesn't exists", Toast.LENGTH_LONG).show();

                } catch (JSONException e) {
                    Toast.makeText(getApplicationContext(), "Error Occured [Server's JSON response might be invalid]!", Toast.LENGTH_LONG).show();
                    e.printStackTrace();

                }
            }

            // When the response returned by REST has Http response code other than '200'
            @Override
            public void onFailure(int statusCode, Throwable error,
                                  String content) {
                // Hide Progress Dialog
                prgDialog.hide();
                // When Http response code is '404'
                if (statusCode == 404) {
                    Toast.makeText(getApplicationContext(), "Requested resource not found", Toast.LENGTH_LONG).show();
                }
                // When Http response code is '500'
                else if (statusCode == 500) {
                    Toast.makeText(getApplicationContext(), "Something went wrong at server end", Toast.LENGTH_LONG).show();
                }
                // When Http response code other than 404, 500
                else {
                    Toast.makeText(getApplicationContext(), "Unexpected Error occcured! [Most common Error: Device might not be connected to Internet or remote server is not up and running]", Toast.LENGTH_LONG).show();
                }
            }
        });
    }

    public void saveSharedPreferences(String surname, String firstname, String key){
        // Set up preferences collection
        sharedpreferences = getSharedPreferences(MyPREFERENCES,
                Context.MODE_PRIVATE);

        //Save vkey, firstname, and vkey
        SharedPreferences.Editor editor = sharedpreferences.edit();
        editor.putString(SURNAME, surname );
        editor.putString(FIRSTNAME, firstname );
        editor.putString(VKEY, key );
        editor.apply();

        changeToWelcomeActivity();
    }

    public void checkIfLoggedIn(){
        // Get vKey shared pref and assign to variable
        validateSharedPreferenceAuthKeyApiRequest();
        Log.d("checkIfLoggedIn", "???");
        Log.d("vkey", vKey);

        // If vKey is NOT empty, then don't run API request
        if(vKey != "") {
            validateSharedPreferenceAuthKeyApiRequest();
            Log.d("in vKey = \"\"", "'VKEY is not empty'");
        }
        // If vKey is empty then do nothing
        else
            return;
    }

    // Get shared pref vKey and assign to vKey variable
    public void getSharedPref(){
        SharedPreferences prefs = this.getSharedPreferences(MyPREFERENCES, Context.MODE_PRIVATE);
        vKey = prefs.getString(VKEY, "");
        Log.d("in SHARED PREF = \"\"", vKey);

    }

    // Create the JSON auth params that will be sent via the POST HTTP
    public void createAuthJsonRequestParams(){

        try {
            //Append json object/string name and value  ("auth", vKey)
            paramsAuth.put("auth", vKey);
            Log.d("inCreateJsonReques", vKey);

        } catch (JSONException e) {
            e.printStackTrace();
        }

        try {
            authVkeyEntity = new StringEntity(paramsAuth.toString());
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        authVkeyEntity.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));


    }

    // Validate the auth key by sending post key of AUTH and receiving a true or false value
    public void validateSharedPreferenceAuthKeyApiRequest(){
        // Create the JSON object that is used below
        getSharedPref();
        createAuthJsonRequestParams();

        // Make RESTful webservice call using AsyncHttpClient object
        AsyncHttpClient client = new AsyncHttpClient();
        Context context = this.getApplicationContext();

        client.post(context, localhostURL + "user/auth/", authVkeyEntity, "application/json", new AsyncHttpResponseHandler() {

            // When the response returned by REST has Http response code '200'
            @Override
            public void onSuccess(String response) {
                prgDialog.hide(); // Hide Progress Dialog
                try {
                    Log.d("in AUTHENTICATED = \"\"", "HIIHIHIHI");
                    JSONObject obj = new JSONObject(response);   // Create JSON Object

                    //If the object has a string named "authenticated" run the following code
                    if (obj.has("authenticated")) {
                        Toast.makeText(getApplicationContext(), "Valid verification key!", Toast.LENGTH_LONG).show();
                        Log.d("in AUTHENTICATED = \"\"", vKey);
                        changeToWelcomeActivity();

                    }
                    // If the vKey is incorrect then post this
                    else if (obj.has("error_authenticated"))
                        Toast.makeText(getApplicationContext(), "Something has gone wrong, invalid authentication key", Toast.LENGTH_LONG).show();

                } catch (JSONException e) {
                    Toast.makeText(getApplicationContext(), "!Error Occured [Server's JSON response might be invalid]!", Toast.LENGTH_LONG).show();
                    e.printStackTrace();

                }
            }

            // When the response returned by REST has Http response code other than '200'
            @Override
            public void onFailure(int statusCode, Throwable error,
                                  String content) {
                // Hide Progress Dialog
                prgDialog.hide();
                // When Http response code is '404'
                if (statusCode == 404) {
                    Toast.makeText(getApplicationContext(), "Requested resource not found", Toast.LENGTH_LONG).show();
                }
                // When Http response code is '500'
                else if (statusCode == 500) {
                    Toast.makeText(getApplicationContext(), "Something went wrong at server end", Toast.LENGTH_LONG).show();
                }
                // When Http response code other than 404, 500
                else {
                    Toast.makeText(getApplicationContext(), "Unexpected Error occcured! [Most common Error: Device might not be connected to Internet or remote server is not up and running]", Toast.LENGTH_LONG).show();
                }
            }
        });
    }

    // Change from current activity to Welcome.class activity
    public void changeToWelcomeActivity(){
        //Change to welcome page
        Intent myIntent = new Intent(this.getApplicationContext(), Welcome.class);
        startActivity(myIntent);
    }

Welcome.java:

public class Welcome extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_welcome);
        TextView txtWelcome = (TextView) findViewById(R.id.txtWelcome);
        Log.d("in welcome", "eee");

        if(getPreferences() == 1)
            txtWelcome.setText("Welcome " + LoginScreen.sharedpreferences.getString(LoginScreen.FIRSTNAME, "") +
                    " " + LoginScreen.sharedpreferences.getString(LoginScreen.SURNAME, ""));
        else
            txtWelcome.setText("Not logged in");


    }

    // custom method to get preferences
    public static int getPreferences(){
        int returned;

        if (LoginScreen.sharedpreferences.contains(LoginScreen.SURNAME))
            returned = 1;
        else
            returned = 0;

        return returned;



    }
\$\endgroup\$
3
\$\begingroup\$

Add constructors to LoginScreen.java and Welcome.java. Place super(); in these as first line, calling constructor located within parent ActionBarActivity.

Below could be a final, constant:

private String localhostURL = "http://10.0.3.2/diploma/cloud_computing/tutorials/tutorial2/";

Preferably move the String literal out of the class, replacing with an attributes, properties configuration collection. Values such as the URL could come from an XML file outside the source.

Number of class instance variables could be reduced, merging into new objects such as Credentials or Identity.

Initialize all instance variables when declared and also within constructors to protect against NPE, perhaps with an init() initialization method.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.