0

I am trying to create a Login function so i can verify the users. I pass the Username , Password variables to AsyncTask class but i don't know hot to get results in order to use them. Any help? (I am posting part of the source code due to website restrictions)

btnLogin.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {

            if(txtUsername.getText().toString().trim().length() > 0 && txtPassword.getText().toString().trim().length() > 0)
            {
                // Retrieve the text entered from the EditText
                String Username = txtUsername.getText().toString();
                String Password = txtPassword.getText().toString();
                /*Toast.makeText(MainActivity.this,
                        Username +" + " + Password+" \n Ready for step to post data", Toast.LENGTH_LONG).show();*/

                String[] params = {Username, Password};
                // we are going to use asynctask to prevent network on main thread exception
                new PostDataAsyncTask().execute(params);

                // Redirect to dashboard / home screen.
                login.dismiss();
            }
            else
            {
                Toast.makeText(MainActivity.this,
                "Please enter Username and Password", Toast.LENGTH_LONG).show();

            }
        }
    });

Then i use the AsynkTask to do the check but do not know how to get the results and store them in a variable. Any help?

public class PostDataAsyncTask extends AsyncTask<String, String, String> {

    protected void onPreExecute() {
        super.onPreExecute();
        // do stuff before posting data
    }

    @Override
    protected String doInBackground(String... params) {
        try {
            // url where the data will be posted
            String postReceiverUrl = "http://server.com/Json/login.php";
            Log.v(TAG, "postURL: " + postReceiverUrl);
            String line = null;
            String fail = "notok";

            // HttpClient
            HttpClient httpClient = new DefaultHttpClient();

            // post header
            HttpPost httpPost = new HttpPost(postReceiverUrl);

            // add your data
            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
            nameValuePairs.add(new BasicNameValuePair("UserName", params[0]));
            nameValuePairs.add(new BasicNameValuePair("Password", params[1]));

            httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

            // execute HTTP post request
            HttpResponse response = httpClient.execute(httpPost);
            HttpEntity resEntity = response.getEntity();
            line = resEntity.toString();
            Log.v(TAG, "Testing response: " +  line);

            if (resEntity != null) {

                String responseStr = EntityUtils.toString(resEntity).trim();
                Log.v(TAG, "Response: " +  responseStr);
                Intent Hotels_btn_pressed =  new Intent(MainActivity.this, Hotels.class);
                startActivity(Hotels_btn_pressed);
                // you can add an if statement here and do other actions based on the response
                Toast.makeText(MainActivity.this,
                        "Error! User does not exist", Toast.LENGTH_LONG).show();
            }else{
                finish();
            }

        } catch (NullPointerException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(String lenghtOfFile) {
        // do stuff after posting data
    }
}
Ilias S.
  • 31
  • 6

1 Answers1

0

Not the best code refactoring, but just to give you a hint.

I would create an interface (lets call it 'LogInListener'):

public interface LoginListener {
    void onSuccessfulLogin(String response);
    void onFailedLogin(String response);
}

The 'MainActivity' class would implement that interface and set itself as a listener the 'PostDataAsyncTask'. So, creating the async task from the main activity would look like this:

String[] params = {Username, Password};
// we are going to use asynctask to prevent network on main thread exception
PostDataAsyncTask postTask = new PostDataAsyncTask(this);
postTask.execute(params);

I would move 'PostDataAsyncTask' class into a new file:

public class PostDataAsyncTask extends AsyncTask<String, String, String> {
    private static final String ERROR_RESPONSE = "notok";

    private LoginListener listener = null;

    public PostDataAsyncTask(LoginListener listener) {
        this.listener = listener;
    }

    @Override
    protected String doInBackground(String... params) {
        String postResponse = "";
        try {
            // url where the data will be posted
            String postReceiverUrl = "http://server.com/Json/login.php";

            // HttpClient
            HttpClient httpClient = new DefaultHttpClient();

            // post header
            HttpPost httpPost = new HttpPost(postReceiverUrl);

            // add your data
            List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
            nameValuePairs.add(new BasicNameValuePair("UserName", params[0]));
            nameValuePairs.add(new BasicNameValuePair("Password", params[1]));

            httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));

            // execute HTTP post request
            HttpResponse response = httpClient.execute(httpPost);
            HttpEntity resEntity = response.getEntity();

            postResponse = EntityUtils.toString(resEntity).trim();
        } catch (NullPointerException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return postResponse;
    }

    @Override
    protected void onPostExecute(String postResponse) {
        if (postResponse.isEmpty() || postResponse.equals(ERROR_RESPONSE) ) {
            listener.onFailedLogin(postResponse);
        } else {
            listener.onSuccessfulLogin(postResponse);
        }
    }
}

So, 'doInBackground' returns the response to 'onPostExecute' (which runs on the UI thread), and 'onPostExecute' routes the result (success or failure) to the MainActivity, which implements the 'LogInListener' methods:

@Override
public void onSuccessfulLogin(String response) {
    // you have access to the ui thread here - do whatever you want on suscess
    // I'm just assuming that you'd like to start that activity
    Intent Hotels_btn_pressed =  new Intent(this, Hotels.class);
    startActivity(Hotels_btn_pressed);
}

@Override
public void onFailedLogin(String response) {
    Toast.makeText(MainActivity.this,
            "Error! User does not exist", Toast.LENGTH_LONG).show();
}

I just assumed that that's what you wanted to do on success: start a new activity, and show a toast on fail.

Spiri
  • 1,283
  • 11
  • 24
  • Thanks for your advice!! One thing, after it posts back the respone the application fails... It seems that it freezes when it tries to execute the "LogInListener" methods. – Ilias S. Jan 28 '15 at 21:28
  • Could you describe what exception is thrown or what seems to happen? – Spiri Jan 29 '15 at 08:48
  • Although i didn't move the PostDataAsyncTask to e new file (only to save some time), i managed to get the result and move on. Thank you very very much for your help! Have a good day!! – Ilias S. Jan 29 '15 at 09:05