I am creating an app, when you log in with user name and password, it requests the info from the server.
The server's request takes time (15-20 sec), meanwhile I want to show a spinning bar with few words.
But I tried so many variations of the AsyncTask class, and I can't get it to work. It gets the information okay, but freezes the screen until the response.
Right now I just have a new thread implementing runnable. I'm not sure from where in the code I need to call the AsyncTask .
The onClick triggers the attemptLogin() function:
public void onClick(View view) {
attemptLogin();
}
In attemptLogin() function:
// more code
showProgress(true);
new Thread(new GetServerResponseRunnable()).start();
while (wait) {}
// more code
And the Runnable is:
public class GetServerResponseRunnable implements Runnable {
#Override
public void run() {
response = getInfo.getTours(mUsername, mPassword);
wait = false;
}
}
Which as you can see call another function from a different class.
This is the function:
public String getTours(String username, String password) {
String req = "GETALLDATA";
String retStr = "";
try {
url = getURL(req, username, password);
sendOutputLine(url, "");
retStr = getReturnString();
Log.d(LoginActivity.DEBUG_TAG, "getTours() return: " + retStr);
} catch (Exception e) {
Log.d(LoginActivity.DEBUG_TAG, "programm bommed client: " + e.getMessage());
}
return retStr;
}
I need help, please. Mainly what I want to do is:
response = getInfo.getTours(mUsername, mPassword);
wait = false;
And show the spinning bar meanwhile.
Thanks
Update: 02.13.2013
I used this code, but I got a
02-13 09:07:16.142: E/AndroidRuntime(1046): java.lang.NullPointerException
in the line:
this.dialog.setMessage(getResources().getString(R.string.login_progress_signing_in));
Any idea why?
public class LoginTask extends AsyncTask<Object, Void, String> {
public Context context;
public ProgressDialog dialog;
public void BaseTask(Context context) {
this.context = context;
this.dialog = new ProgressDialog(context);
}
#Override
protected void onPreExecute() {
this.dialog.setMessage(getResources().getString(R.string.login_progress_signing_in));
this.dialog.show();
}
#Override
protected String doInBackground(Object... objects) {
String name = (String) objects[0];
String password = (String) objects[1];
String response = getInfo.getTours(name , password );
return response;
}
#Override
protected void onPostExecute(String response) {
if (dialog != null && dialog.isShowing())
dialog.dismiss();
LoginActivity.response = response;
// process response as you need
}
}
I think you need thomething like this
public class LoginTask extends AsyncTask<Object, Void, String> {
public Context context;
public ProgressDialog dialog;
public BaseTask(Context context) {
this.context = context;
this.dialog = new ProgressDialog(context);
}
#Override
protected void onPreExecute() {
this.dialog.setMessage(context.getResources().getString(R.string.loading));
this.dialog.show();
}
#Override
protected String doInBackground(Object... objects) {
String name = (String) objects[0];
String password = (String) objects[1];
String response = getInfo.getTours(name , password );
return response;
}
#Override
protected void onPostExecute(String response) {
if (dialog != null && dialog.isShowing())
dialog.dismiss();
// process response as you need
}
}
Call this taks
public void onClick(View view) {
new LoginTask(YourActivity.this).execute(name, password);
}
Try to implement android login activity.
In your ADT under create new activity pick: login activity
This will generate the following template code for you:
/**
* Activity which displays a login screen to the user, offering registration as
* well.
*/
public class LoginActivityTest extends Activity {
/**
* A dummy authentication store containing known user names and passwords.
* TODO: remove after connecting to a real authentication system.
*/
private static final String[] DUMMY_CREDENTIALS = new String[] {
"foo#example.com:hello", "bar#example.com:world" };
/**
* The default email to populate the email field with.
*/
public static final String EXTRA_EMAIL = "com.example.android.authenticatordemo.extra.EMAIL";
/**
* Keep track of the login task to ensure we can cancel it if requested.
*/
private UserLoginTask mAuthTask = null;
// Values for email and password at the time of the login attempt.
private String mEmail;
private String mPassword;
// UI references.
private EditText mEmailView;
private EditText mPasswordView;
private View mLoginFormView;
private View mLoginStatusView;
private TextView mLoginStatusMessageView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login_activity_test);
// Set up the login form.
mEmail = getIntent().getStringExtra(EXTRA_EMAIL);
mEmailView = (EditText) findViewById(R.id.email);
mEmailView.setText(mEmail);
mPasswordView = (EditText) findViewById(R.id.password);
mPasswordView
.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView textView, int id,
KeyEvent keyEvent) {
if (id == R.id.login || id == EditorInfo.IME_NULL) {
attemptLogin();
return true;
}
return false;
}
});
mLoginFormView = findViewById(R.id.login_form);
mLoginStatusView = findViewById(R.id.login_status);
mLoginStatusMessageView = (TextView) findViewById(R.id.login_status_message);
findViewById(R.id.sign_in_button).setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View view) {
attemptLogin();
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.activity_login_activity_test, menu);
return true;
}
/**
* Attempts to sign in or register the account specified by the login form.
* If there are form errors (invalid email, missing fields, etc.), the
* errors are presented and no actual login attempt is made.
*/
public void attemptLogin() {
if (mAuthTask != null) {
return;
}
// Reset errors.
mEmailView.setError(null);
mPasswordView.setError(null);
// Store values at the time of the login attempt.
mEmail = mEmailView.getText().toString();
mPassword = mPasswordView.getText().toString();
boolean cancel = false;
View focusView = null;
// Check for a valid password.
if (TextUtils.isEmpty(mPassword)) {
mPasswordView.setError(getString(R.string.error_field_required));
focusView = mPasswordView;
cancel = true;
} else if (mPassword.length() < 4) {
mPasswordView.setError(getString(R.string.error_invalid_password));
focusView = mPasswordView;
cancel = true;
}
// Check for a valid email address.
if (TextUtils.isEmpty(mEmail)) {
mEmailView.setError(getString(R.string.error_field_required));
focusView = mEmailView;
cancel = true;
} else if (!mEmail.contains("#")) {
mEmailView.setError(getString(R.string.error_invalid_email));
focusView = mEmailView;
cancel = true;
}
if (cancel) {
// There was an error; don't attempt login and focus the first
// form field with an error.
focusView.requestFocus();
} else {
// Show a progress spinner, and kick off a background task to
// perform the user login attempt.
mLoginStatusMessageView.setText(R.string.login_progress_signing_in);
showProgress(true);
mAuthTask = new UserLoginTask();
mAuthTask.execute((Void) null);
}
}
/**
* Shows the progress UI and hides the login form.
*/
#TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
private void showProgress(final boolean show) {
// On Honeycomb MR2 we have the ViewPropertyAnimator APIs, which allow
// for very easy animations. If available, use these APIs to fade-in
// the progress spinner.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
int shortAnimTime = getResources().getInteger(
android.R.integer.config_shortAnimTime);
mLoginStatusView.setVisibility(View.VISIBLE);
mLoginStatusView.animate().setDuration(shortAnimTime)
.alpha(show ? 1 : 0)
.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
mLoginStatusView.setVisibility(show ? View.VISIBLE
: View.GONE);
}
});
mLoginFormView.setVisibility(View.VISIBLE);
mLoginFormView.animate().setDuration(shortAnimTime)
.alpha(show ? 0 : 1)
.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
mLoginFormView.setVisibility(show ? View.GONE
: View.VISIBLE);
}
});
} else {
// The ViewPropertyAnimator APIs are not available, so simply show
// and hide the relevant UI components.
mLoginStatusView.setVisibility(show ? View.VISIBLE : View.GONE);
mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
}
}
/**
* Represents an asynchronous login/registration task used to authenticate
* the user.
*/
public class UserLoginTask extends AsyncTask<Void, Void, Boolean> {
#Override
protected Boolean doInBackground(Void... params) {
// TODO: attempt authentication against a network service.
try {
// Simulate network access.
Thread.sleep(2000);
} catch (InterruptedException e) {
return false;
}
for (String credential : DUMMY_CREDENTIALS) {
String[] pieces = credential.split(":");
if (pieces[0].equals(mEmail)) {
// Account exists, return true if the password matches.
return pieces[1].equals(mPassword);
}
}
// TODO: register the new account here.
return true;
}
#Override
protected void onPostExecute(final Boolean success) {
mAuthTask = null;
showProgress(false);
if (success) {
finish();
} else {
mPasswordView
.setError(getString(R.string.error_incorrect_password));
mPasswordView.requestFocus();
}
}
#Override
protected void onCancelled() {
mAuthTask = null;
showProgress(false);
}
}
}
The UserLoginTask is where you want to do your authentication. This will allow you to show a spinner while you are trying to login.
The 'onPostExecute' will be the place where you either move to your next activity upon verification, or go back to the login screen with a message for the user, for example invalid password.
Please note that the template includes dummy_credentials that you don't need if you are authenticating with a server, and that it comes with email and password textEdits, but you can change those to anything you want.
You need to implement a new class that extends AsyncTask, do all of the extensive work inside a function called doInBackground, and publish the results to the UI thread using some other common methods like onProgressUpdate. A quick web search for "android asynctask tutorial" will yield some good results for you to learn from.
Your AsyncTask might look something like this:
private class DownloadFilesTask extends AsyncTask<Login, Void, Tours> {
protected void onPreExecute(){
//show the dialog here
}
protected Long doInBackground(URL... urls) {
Tours response = getInfo.getTours(Login.mUsername, Login.mPassword);
return response;
}
protected void onPostExecute(Long result) {
//hide the dialog here
}
}
I don't know enough about your project to make it be a drop in, you'll have to customize it a bit, but the overall "way" will be similar to this.
Related
I am creating an android app chatbot using google's dialog flow (API.AI). The problem is, If I am sending text input for my intents,it is giving right response, whereas if same thing I am sending using voice input, am getting wrong response. I am not able to understand what is the problem.
Here is my code :-
public class MyChatActivity extends AppCompatActivity implements View.OnClickListener, AIListener {
public String TAG = this.getClass().getSimpleName();
private List<ChatMessageBean> chatList = new ArrayList<>();
private String CLIENT_ACCESS_TOKEN = "My dialog flow agent's client access token";
AIConfiguration config;
AIService aiService;
AIRequest aiRequest;
AIDataService aiDataService;
TextToSpeech textToSpeech;
RecyclerView chatRecyclerView,menuRecyclerView;
ChatMessageListAdapter chatMessageListAdapter;
FloatingActionButton sendMessageButton,recordMessageButton;
EditText enterMessage;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_chat_activity);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
initializeVariables();
setListeners();
}
public void initializeVariables() {
config = new AIConfiguration(CLIENT_ACCESS_TOKEN, AIConfiguration.SupportedLanguages.English, AIConfiguration.RecognitionEngine.System);
aiService = AIService.getService(getApplicationContext(), config);
aiRequest = new AIRequest();
aiDataService = new AIDataService(getApplicationContext(), config);
chatRecyclerView = (RecyclerView) findViewById(R.id.chat_list_recycler_view);
setMenuRecyclerView();
enterMessage = (EditText) findViewById(R.id.enter_text_message);
sendMessageButton = (FloatingActionButton) findViewById(R.id.send_message_button);
recordMessageButton =(FloatingActionButton) findViewById(R.id.record_message_button);
textToSpeech = new TextToSpeech(getApplicationContext(),new TextToSpeech.OnInitListener(){
#Override
public void onInit(int status) {
if(status != TextToSpeech.ERROR) {
textToSpeech.setLanguage(Locale.US);
}
}
});
}
public void setListeners() {
sendMessageButton.setOnClickListener(this);
aiService.setListener(this);
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.record_message_button:
aiService.startListening();
break;
case R.id.send_message_button:
String message = enterMessage.getText().toString().trim();
enterMessage.setText("");
sendMessage(message);//sending message with text input
break;
}
}
private boolean validateMessage(String message) {
if ((message.equals("")) || (message.isEmpty()) || (message.length() == 0))
return false;
return true;
}
public void sendMessage(String message) {
// In this method i am sending the message to dialog flow
if (validateMessage(message)) {
ChatMessageBean chatMessageBean = new ChatMessageBean(message); // this is the bean I am using for chatbot app's messages
chatList.add(chatMessageBean);
chatMessageListAdapter = new ChatMessageListAdapter(chatList);// this is the adapter for recycler view that I am using for app's messages
chatRecyclerView.setAdapter(chatMessageListAdapter);
chatRecyclerView.setLayoutManager(new LinearLayoutManager(this));
aiRequest.setQuery(message);
new AsyncTask<AIRequest, Void, AIResponse>() {
#Override
protected AIResponse doInBackground(AIRequest... aiRequests) {
final AIRequest request = aiRequests[0];
try {
final AIResponse response = aiDataService.request(aiRequest);
return response;
} catch (AIServiceException e) {
}
return null;
}
#Override
protected void onPostExecute(AIResponse response) {
if (response != null) {
Result result = response.getResult();
String reply = result.getFulfillment().getSpeech();
ChatMessageBean chatMessageBean = new ChatMessageBean(reply.trim());
chatList.add(chatMessageBean);
chatMessageListAdapter = new ChatMessageListAdapter(chatList);
chatRecyclerView.setLayoutManager(new LinearLayoutManager(PersonaAssistantChatActivity.this));
chatRecyclerView.setAdapter(chatMessageListAdapter);
textToSpeech.speak(reply,TextToSpeech.QUEUE_FLUSH,null);
if(reply.trim().equalsIgnoreCase(API_ACCESS_STRING)){ //API_ACCESS_STRING is the string after which I have to get response from my own defined intents. So I am cheking if the reply is equal to API_ACCESS_STRING
String intentName=result.getMetadata().getIntentName();
switch(intentName){
case "AvailableEmployees":
Log.d(TAG, "CallIntents: AvailableEmployees:"+intentName);
String jobName=result.getStringParameter("JobName");
String date = result.getStringParameter("Date");
Log.d(TAG,"JobName:"+jobName+"date: "+date); // When I send voice input here I get jobName="AvailableEmployees" automatically, and dialog flow doesnot ask for jobName, where as with text input I get everything right.
}
}
}
}
}.execute(aiRequest);
} else {
Toast.makeText(getApplicationContext(), "Please enter some text first or record your message", Toast.LENGTH_LONG).show();
}
}
#Override
public void onResult(AIResponse result) {
String message= result.getResult().getResolvedQuery().toString().trim();
sendMessage(message);//sending message with voice input
}
#Override
public void onError(AIError error) {
Log.i(TAG, ": onError" + error);
}
#Override
public void onAudioLevel(float level) {
Log.i(TAG, ": onAudioLevel:" + level);
}
#Override
public void onListeningStarted() {
Log.i(TAG, ": onListeningStarted");
}
#Override
public void onListeningCanceled() {
Log.i(TAG, ": onListeningCanceled");
}
#Override
public void onListeningFinished() {
Log.i(TAG, ": onListeningFinished");
}
}
You can not call sendMessage(message);//sending message with voice input in the onResult method. This method is called when aiService finishes listening and has already sent a request to Dialogflow and you get the response. When you call aiService.startListening(); the service detect what the user is saying and sends it to Dialogflow.
If you want to know the text "aiService" is sending to Dialogflow you have to use PartialResultsListener and implement it:
#Override
public void onPartialResults(final List<String> partialResults) {
if (!partialResults.isEmpty()) {
String partialResult = partialResults.get(0);
}
}
That way you will get what the user says, but be aware as the method will be called BEFORE onListeningFinished() ends.
Best of luck playing with Handler.postDelayed() :)
I am working on Login Activity in Android app. I am using template from Android Studio but with little modification.
When I am trying to sign in first time I have an error "Incorrect Password" but when I am trying sign in second time with same data everything works fine.
I think problem is here
public class UserLoginTask extends AsyncTask<Void, Void, Boolean> {
private final String mEmail;
private final String mPassword;
UserLoginTask(String email, String password) {
mEmail = email;
mPassword = password;
}
#RequiresApi(api = Build.VERSION_CODES.KITKAT)
#Override
protected Boolean doInBackground(Void... params) {
try {
Call<User> call = apiService.DataForUser(mEmail);
call.enqueue(new Callback<User>() {
#Override
public void onResponse(Call<User> call, Response<User> response) {
user=response.body();
}
#Override
public void onFailure(Call<User> call, Throwable t) {
}
});
} catch (Exception e) {
return false;
}
if(user!=null)
{
String hash_pass = Hashing.sha256()
.hashString(mPassword, StandardCharsets.UTF_8)
.toString();
if(hash_pass.equals(user.getPassword())) {
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
#Override
protected void onPostExecute(final Boolean success) {
mAuthTask = null;
showProgress(false);
if (success) {
Switch();
} else {
mPasswordView.setError(getString(R.string.error_incorrect_password));
mPasswordView.requestFocus();
}
}
#Override
protected void onCancelled() {
mAuthTask = null;
showProgress(false);
}
}
All code from the Activity class:
public class LoginActivity extends AppCompatActivity implements LoaderCallbacks<Cursor> {
/**
* Id to identity READ_CONTACTS permission request.
*/
private static final int REQUEST_READ_CONTACTS = 0;
/**
* Keep track of the login task to ensure we can cancel it if requested.
*/
private UserLoginTask mAuthTask = null;
// UI references.
private AutoCompleteTextView mEmailView;
private EditText mPasswordView;
private View mProgressView;
private View mLoginFormView;
//Retrofit
private Api api;
private ApiService apiService;
//User
User user = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
// Set up the login form.
mEmailView = (AutoCompleteTextView) findViewById(R.id.email);
populateAutoComplete();
mPasswordView = (EditText) findViewById(R.id.password);
mPasswordView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView textView, int id, KeyEvent keyEvent) {
if (id == R.id.login || id == EditorInfo.IME_NULL) {
attemptLogin();
return true;
}
return false;
}
});
Button mEmailSignInButton = (Button) findViewById(R.id.email_sign_in_button);
mEmailSignInButton.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
attemptLogin();
}
});
mLoginFormView = findViewById(R.id.login_form);
mProgressView = findViewById(R.id.login_progress);
//Retrofit
api = Api.getInstance();
apiService = api.getApiService();
}
private void populateAutoComplete() {
if (!mayRequestContacts()) {
return;
}
getLoaderManager().initLoader(0, null, this);
}
private boolean mayRequestContacts() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
return true;
}
if (checkSelfPermission(READ_CONTACTS) == PackageManager.PERMISSION_GRANTED) {
return true;
}
if (shouldShowRequestPermissionRationale(READ_CONTACTS)) {
Snackbar.make(mEmailView, R.string.permission_rationale, Snackbar.LENGTH_INDEFINITE)
.setAction(android.R.string.ok, new View.OnClickListener() {
#Override
#TargetApi(Build.VERSION_CODES.M)
public void onClick(View v) {
requestPermissions(new String[]{READ_CONTACTS}, REQUEST_READ_CONTACTS);
}
});
} else {
requestPermissions(new String[]{READ_CONTACTS}, REQUEST_READ_CONTACTS);
}
return false;
}
/**
* Callback received when a permissions request has been completed.
*/
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions,
#NonNull int[] grantResults) {
if (requestCode == REQUEST_READ_CONTACTS) {
if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
populateAutoComplete();
}
}
}
/**
* Attempts to sign in or register the account specified by the login form.
* If there are form errors (invalid email, missing fields, etc.), the
* errors are presented and no actual login attempt is made.
*/
private void attemptLogin() {
if (mAuthTask != null) {
return;
}
// Reset errors.
mEmailView.setError(null);
mPasswordView.setError(null);
// Store values at the time of the login attempt.
String email = mEmailView.getText().toString();
String password = mPasswordView.getText().toString();
boolean cancel = false;
View focusView = null;
// Check for a valid password, if the user entered one.
if (!TextUtils.isEmpty(password) && !isPasswordValid(password)) {
mPasswordView.setError(getString(R.string.error_invalid_password));
focusView = mPasswordView;
cancel = true;
}
// Check for a valid email address.
if (TextUtils.isEmpty(email)) {
mEmailView.setError(getString(R.string.error_field_required));
focusView = mEmailView;
cancel = true;
} else if (!isEmailValid(email)) {
mEmailView.setError(getString(R.string.error_invalid_email));
focusView = mEmailView;
cancel = true;
}
if (cancel) {
// There was an error; don't attempt login and focus the first
// form field with an error.
focusView.requestFocus();
} else {
// Show a progress spinner, and kick off a background task to
// perform the user login attempt.
showProgress(true);
mAuthTask = new UserLoginTask(email, password);
mAuthTask.execute((Void) null);
}
}
private boolean isEmailValid(String email) {
//TODO: Replace this with your own logic
return email.contains("#");
}
private boolean isPasswordValid(String password) {
//TODO: Replace this with your own logic
return password.length() > 4;
}
/**
* Shows the progress UI and hides the login form.
*/
#TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
private void showProgress(final boolean show) {
// On Honeycomb MR2 we have the ViewPropertyAnimator APIs, which allow
// for very easy animations. If available, use these APIs to fade-in
// the progress spinner.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
int shortAnimTime = getResources().getInteger(android.R.integer.config_shortAnimTime);
mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
mLoginFormView.animate().setDuration(shortAnimTime).alpha(
show ? 0 : 1).setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
}
});
mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
mProgressView.animate().setDuration(shortAnimTime).alpha(
show ? 1 : 0).setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
}
});
} else {
// The ViewPropertyAnimator APIs are not available, so simply show
// and hide the relevant UI components.
mProgressView.setVisibility(show ? View.VISIBLE : View.GONE);
mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
}
}
#Override
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
return new CursorLoader(this,
// Retrieve data rows for the device user's 'profile' contact.
Uri.withAppendedPath(ContactsContract.Profile.CONTENT_URI,
ContactsContract.Contacts.Data.CONTENT_DIRECTORY), ProfileQuery.PROJECTION,
// Select only email addresses.
ContactsContract.Contacts.Data.MIMETYPE +
" = ?", new String[]{ContactsContract.CommonDataKinds.Email
.CONTENT_ITEM_TYPE},
// Show primary email addresses first. Note that there won't be
// a primary email address if the user hasn't specified one.
ContactsContract.Contacts.Data.IS_PRIMARY + " DESC");
}
#Override
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
List<String> emails = new ArrayList<>();
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
emails.add(cursor.getString(ProfileQuery.ADDRESS));
cursor.moveToNext();
}
addEmailsToAutoComplete(emails);
}
#Override
public void onLoaderReset(Loader<Cursor> cursorLoader) {
}
private void addEmailsToAutoComplete(List<String> emailAddressCollection) {
//Create adapter to tell the AutoCompleteTextView what to show in its dropdown list.
ArrayAdapter<String> adapter =
new ArrayAdapter<>(LoginActivity.this,
android.R.layout.simple_dropdown_item_1line, emailAddressCollection);
mEmailView.setAdapter(adapter);
}
private interface ProfileQuery {
String[] PROJECTION = {
ContactsContract.CommonDataKinds.Email.ADDRESS,
ContactsContract.CommonDataKinds.Email.IS_PRIMARY,
};
int ADDRESS = 0;
int IS_PRIMARY = 1;
}
/**
* Represents an asynchronous login/registration task used to authenticate
* the user.
*/
public class UserLoginTask extends AsyncTask<Void, Void, Boolean> {
private final String mEmail;
private final String mPassword;
UserLoginTask(String email, String password) {
mEmail = email;
mPassword = password;
}
#RequiresApi(api = Build.VERSION_CODES.KITKAT)
#Override
protected Boolean doInBackground(Void... params) {
try {
Call<User> call = apiService.DataForUser(mEmail);
call.enqueue(new Callback<User>() {
#Override
public void onResponse(Call<User> call, Response<User> response) {
user=response.body();
}
#Override
public void onFailure(Call<User> call, Throwable t) {
}
});
} catch (Exception e) {
return false;
}
if(user!=null)
{
String hash_pass = Hashing.sha256()
.hashString(mPassword, StandardCharsets.UTF_8)
.toString();
if(hash_pass.equals(user.getPassword())) {
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
#Override
protected void onPostExecute(final Boolean success) {
mAuthTask = null;
showProgress(false);
if (success) {
Switch();
} else {
mPasswordView.setError(getString(R.string.error_incorrect_password));
mPasswordView.requestFocus();
}
}
#Override
protected void onCancelled() {
mAuthTask = null;
showProgress(false);
}
}
public void Switch (){
Toast.makeText(LoginActivity.this, "Succes!", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(this, MainActivity.class);
startActivity (intent);
}
}
Starting from the fact that it seems that you're trying to do the password match on your client, which is always wrong and dangerous if you want to match the data that you retrieve from your API call you must include your authentication logic inside the callback function onResponse. In your activity, instaed of this:
} else {
// Show a progress spinner, and kick off a background task to
// perform the user login attempt.
showProgress(true);
mAuthTask = new UserLoginTask(email, password);
mAuthTask.execute((Void) null);
}
do this because you do not need another async task since Call is already asynchronous ( see #matrix comments):
} else {
// Show a progress spinner, and kick off a background task to
// perform the user login attempt.
showProgress(true);
Call<User> call = apiService.DataForUser(email);
call.enqueue(new Callback<User>() {
#Override
public void onResponse(Call<User> call, Response<User> response) {
user=response.body();
if(user!=null){
String hash_pass = Hashing.sha256()
.hashString(password, StandardCharsets.UTF_8)
.toString();
if(hash_pass.equals(user.getPassword())) {
return true;
} else {
return false;
}
} else {
return false;
}
}
}
Please adapt your boolean returns considering this new configuration and please if this is a login form logic don't do the password matching in your client but do this on your server and then pass to the client a token or something else.
When I am trying to sign in first time I have an error "Incorrect Password" but when I am trying sign in second time with same data everything works fine.
This is because the first time the callback is not ready and then user is null, the second time user is already ready from the previous call and the logic works
I am new to android programing and I have two, one problem in the AsyncTask class named RetrieveTokenTask(), in this class I get a token for access email account on gmail, when I call the AsyncTask class create a infinite loop and the message for approbation is open and closed for the app.
The other problem is when I press the button revoke access for data, when try again login in the app not show the Layout with contains data.
I've done this following some tutorials.
Any help would helpful.
Thanks and sorry for any error in my writing but my english is not good.
This code for mi app is the next:
`protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
`
...
//Initializing google plus api client
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).addApi(Plus.API)
.addScope(Plus.SCOPE_PLUS_LOGIN).build();
}
protected void onStart(){
super.onStart();
mGoogleApiClient.connect();
}
protected void onStop(){
super.onStop();
if(mGoogleApiClient.isConnected()){
mGoogleApiClient.disconnect();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onClick(View v) {
switch(v.getId()){
case R.id.btn_sign_in:
signInWithGplus();
break;
case R.id.btn_sign_out:
signOutFromGplus();
break;
case R.id.btn_revoke_access:
revokeGplusAccess();
break;
}
}
#Override
public void onConnectionFailed(ConnectionResult result) {
if(!result.hasResolution()){
GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(), this,
0).show();
return;
}
if(!mIntentInProgress){
//Store the connection for later usage
mConnectionResult = result;
if(mSignInClicked){
// The user has already clicked 'sign-in' so we attempt to
// resolve all
// errors until the user is signed in, or they cancel.
resolveSignInError();
}
}
}
#Override
public void onConnected(Bundle arg0) {
mSignInClicked = false;
Toast.makeText(this, "User is connected", Toast.LENGTH_LONG).show();
// Get User's information
getProfileInformation();
// Update the UI after sign-in
updateUI(true);
}
#Override
public void onConnectionSuspended(int arg0) {
mGoogleApiClient.connect();
updateUI(false);
}
private void updateUI(boolean isSignedIn){
if(isSignedIn){
btnSignIn.setVisibility(View.GONE);
btnSignOut.setVisibility(View.VISIBLE);
btnRevokeAccess.setVisibility(View.VISIBLE);
llProfileLayout.setVisibility(View.VISIBLE);
}
else {
btnSignIn.setVisibility(View.VISIBLE);
btnSignOut.setVisibility(View.GONE);
btnRevokeAccess.setVisibility(View.GONE);
llProfileLayout.setVisibility(View.GONE);
}
}
/*
* Sign-in into google
*/
private void signInWithGplus(){
if(!mGoogleApiClient.isConnecting()){
mSignInClicked = true;
resolveSignInError();
}
}
/*
* Method to resolve any sign-in errors
*/
private void resolveSignInError(){
if(mConnectionResult.hasResolution()){
try{
mIntentInProgress = true;
mConnectionResult.startResolutionForResult(this, RC_SIGN_IN);
}
catch(SendIntentException e){
mIntentInProgress = false;
mGoogleApiClient.connect();
}
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == RC_SIGN_IN) {
mIntentInProgress = false;
if (resultCode == RESULT_OK) {
// Make sure the app is not already connected or attempting to connect
if (!mGoogleApiClient.isConnecting() &&
!mGoogleApiClient.isConnected()) {
mGoogleApiClient.connect();
}
}
}
}
/*
* User's information name, email, profile pic
*/
private void getProfileInformation(){
try{
if(Plus.PeopleApi.getCurrentPerson(mGoogleApiClient) != null){
Person currentPerson = Plus.PeopleApi.getCurrentPerson(mGoogleApiClient);
String personName = currentPerson.getDisplayName();
String perosnPhotoUrl = currentPerson.getImage().getUrl();
String personGooglePlusProfile = currentPerson.getUrl();
String email = Plus.AccountApi.getAccountName(mGoogleApiClient);
Log.e(TAG, "Name: " + personName + ", plusProfile: "
+ personGooglePlusProfile + ", email: " + email
+ ", Image: " + perosnPhotoUrl);
txtName.setText(personName);
txtEmail.setText(email);
perosnPhotoUrl = perosnPhotoUrl.substring(0,
perosnPhotoUrl.length() - 2)
+ PROFILE_PIC_SIZE;
new LoadProfileImage(imgProfilePic).execute(perosnPhotoUrl);
new RetrieveTokenTask(txtToken).execute(email);
}
else{
Toast.makeText(getApplicationContext(),
"Person informations is null", Toast.LENGTH_LONG).show();
}
}
catch(Exception e){
e.printStackTrace();
}
}
/*
* Background Async task to load user profile picture from url
*/
private class LoadProfileImage extends AsyncTask<String, Void, Bitmap>{
ImageView bmImage;
public LoadProfileImage(ImageView bmImage){
this.bmImage = bmImage;
}
#Override
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mIcon11 = null;
try{
InputStream in = new java.net.URL(urldisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
}
catch(Exception e){
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mIcon11;
}
protected void onPostExecute(Bitmap result){
bmImage.setImageBitmap(result);
}
}
/*
* Sign-out from google
*/
private void signOutFromGplus(){
if(mGoogleApiClient.isConnected()){
Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
mGoogleApiClient.disconnect();
mGoogleApiClient.connect();
updateUI(false);
}
}
/*
* Revoking access from google
*/
private void revokeGplusAccess(){
if(mGoogleApiClient.isConnected()){
Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
Plus.AccountApi.revokeAccessAndDisconnect(mGoogleApiClient)
.setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(Status arg0) {
Log.e(TAG, "User acces revoked!");
mGoogleApiClient.connect();
updateUI(false);
}
});
}
}
private class RetrieveTokenTask extends AsyncTask<String, Void, String> {
TextViewTkn Tkn;
private RetrieveTokenTask(TextView tkn){
this.Tkn = tkn;
}
#Override
protected String doInBackground(String... params) {
String accountName = params[0];
String scopes = "oauth2:https://www.googleapis.com/auth/gmail.compose";
String token = null;
try {
token = GoogleAuthUtil.getToken(getApplicationContext(), accountName, scopes);
} catch (IOException e) {
Log.e(TAGTKN, e.getMessage());
} catch (UserRecoverableAuthException e) {
startActivityForResult(e.getIntent(), REQ_SIGN_IN_REQUIRED);
} catch (GoogleAuthException e) {
Log.e(TAGTKN, e.getMessage());
}
return token;
}
#Override
protected void onPostExecute(String result) {
txtToken.setText(result);
}
}
To your second question, an asynctask does not run more than once. If you are trying to reexecute an instance it will not run. You must create new AsyncTask instance every time you want to execute.
You better set a break point in doBackground method and check it.
What and where should I add code to make it work?
By default It does not do anything, the button shows "sign in or register" but it doesn't shows any registration activity.
"Recover lost password" in the menu also does nothing.
I managed to open a new activity after signing by creating an intent after finish();
though it logins successfully irrespective of the email and password!
EDIT: Here's the code!
public class LoginActivity extends Activity
{
/**
* A dummy authentication store containing known user names and passwords.
* TODO: remove after connecting to a real authentication system.
*/
private static final String[] CREDENTIALS = new String[]
{
"myaccount1#gmail.com:12345", "myaccount2#gmail.com:54321"
};
/**
* The default email to populate the email field with.
*/
public static final String EXTRA_EMAIL = "myaccount1#gmail.com";
/**
* Keep track of the login task to ensure we can cancel it if requested.
*/
private UserLoginTask mAuthTask = null;
// Values for email and password at the time of the login attempt.
private String mEmail;
private String mPassword;
// UI references.
private EditText mEmailView;
private EditText mPasswordView;
private View mLoginFormView;
private View mLoginStatusView;
private TextView mLoginStatusMessageView;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
// Set up the login form.
mEmail = getIntent().getStringExtra(EXTRA_EMAIL);
mEmailView = (EditText) findViewById(R.id.email);
mEmailView.setText(mEmail);
mPasswordView = (EditText) findViewById(R.id.password);
mPasswordView
.setOnEditorActionListener(new TextView.OnEditorActionListener()
{
#Override
public boolean onEditorAction(TextView textView, int id,
KeyEvent keyEvent)
{
if (id == R.id.login || id == EditorInfo.IME_NULL)
{
attemptLogin();
return true;
}
return false;
}
});
mLoginFormView = findViewById(R.id.login_form);
mLoginStatusView = findViewById(R.id.login_status);
mLoginStatusMessageView = (TextView) findViewById(R.id.login_status_message);
findViewById(R.id.sign_in_button).setOnClickListener(
new View.OnClickListener()
{
#Override
public void onClick(View view)
{
attemptLogin();
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.activity_login, menu);
return true;
}
/**
* Attempts to sign in or register the account specified by the login form.
* If there are form errors (invalid email, missing fields, etc.), the
* errors are presented and no actual login attempt is made.
*/
public void attemptLogin()
{
if (mAuthTask != null)
{
return;
}
// Reset errors.
mEmailView.setError(null);
mPasswordView.setError(null);
// Store values at the time of the login attempt.
mEmail = mEmailView.getText().toString();
mPassword = mPasswordView.getText().toString();
boolean cancel = false;
View focusView = null;
// Check for a valid password.
if (TextUtils.isEmpty(mPassword))
{
mPasswordView.setError(getString(R.string.error_field_required));
focusView = mPasswordView;
cancel = true;
} else if (mPassword.length() < 4)
{
mPasswordView.setError(getString(R.string.error_invalid_password));
focusView = mPasswordView;
cancel = true;
}
// Check for a valid email address.
if (TextUtils.isEmpty(mEmail))
{
mEmailView.setError(getString(R.string.error_field_required));
focusView = mEmailView;
cancel = true;
} else if (!mEmail.contains("#"))
{
mEmailView.setError(getString(R.string.error_invalid_email));
focusView = mEmailView;
cancel = true;
}
if (cancel)
{
// There was an error; don't attempt login and focus the first
// form field with an error.
focusView.requestFocus();
} else
{
// Show a progress spinner, and kick off a background task to
// perform the user login attempt.
mLoginStatusMessageView.setText(R.string.login_progress_signing_in);
showProgress(true);
mAuthTask = new UserLoginTask();
mAuthTask.execute((Void) null);
}
}
/**
* Shows the progress UI and hides the login form.
*/
#TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
private void showProgress(final boolean show)
{
// On Honeycomb MR2 we have the ViewPropertyAnimator APIs, which allow
// for very easy animations. If available, use these APIs to fade-in
// the progress spinner.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2)
{
int shortAnimTime = getResources().getInteger(
android.R.integer.config_shortAnimTime);
mLoginStatusView.setVisibility(View.VISIBLE);
mLoginStatusView.animate().setDuration(shortAnimTime)
.alpha(show ? 1 : 0)
.setListener(new AnimatorListenerAdapter()
{
#Override
public void onAnimationEnd(Animator animation)
{
mLoginStatusView.setVisibility(show ? View.VISIBLE
: View.GONE);
}
});
mLoginFormView.setVisibility(View.VISIBLE);
mLoginFormView.animate().setDuration(shortAnimTime)
.alpha(show ? 0 : 1)
.setListener(new AnimatorListenerAdapter()
{
#Override
public void onAnimationEnd(Animator animation)
{
mLoginFormView.setVisibility(show ? View.GONE
: View.VISIBLE);
}
});
} else
{
// The ViewPropertyAnimator APIs are not available, so simply show
// and hide the relevant UI components.
mLoginStatusView.setVisibility(show ? View.VISIBLE : View.GONE);
mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
}
}
/**
* Represents an asynchronous login/registration task used to authenticate
* the user.
*/
public class UserLoginTask extends AsyncTask<Void, Void, Boolean>
{
#Override
protected Boolean doInBackground(Void... params)
{
// TODO: attempt authentication against a network service.
try
{
// Simulate network access.
Thread.sleep(2000);
} catch (InterruptedException e)
{
return false;
}
for (String credential : CREDENTIALS)
{
String[] pieces = credential.split(":");
if (pieces[0].equals(mEmail))
{
// Account exists, return true if the password matches.
return pieces[1].equals(mPassword);
}
}
// TODO: register the new account here.
//CREDENTIALS[2]=mEmail+":"+mPassword; tried this for regisration
return true;
}
#Override
protected void onPostExecute(final Boolean success)
{
mAuthTask = null;
showProgress(false);
if (success)
{
finish();
Intent myIntent = new Intent(LoginActivity.this,CalculatorActivity.class);
LoginActivity.this.startActivity(myIntent);
} else
{
mPasswordView
.setError(getString(R.string.error_incorrect_password));
mPasswordView.requestFocus();
}
}
#Override
protected void onCancelled()
{
mAuthTask = null;
showProgress(false);
}
}
}
This works well for the default strings in the CREDENTIALS but I don't know how to implement the registration process, how do I add those mEmail and mPassword to the CREDENTIALS string?
CREDENTIALS is just a string array defined in the first few lines of the program and you can edit it manually. for exmaple:
private static final String[] CREDENTIALS = new String[]
{
"myaccount1#gmail.com:12345", "myaccount2#gmail.com:54321", "bla#bla.com:1234"
};
But this template code is intended for login against a webservice database or something similar. If you want to login against a local database you don't need the AsyncTask mumbo jumbo, you could just write the authentication code in the attemptlogin() function, when cancel != true.
This works well for the default strings in the CREDENTIALS but I don't know how to implement the registration process, how do I add those mEmail and mPassword to the CREDENTIALS string?
The template has a TODO register the new account here prompt in the AsyncTask.
public class LoginActivity extends Activity
{
/**
* A dummy authentication store containing known user names and passwords.
* TODO: remove after connecting to a real authentication system.
*/
//
//before
//private static final String[] CREDENTIALS = new String[]
// {
// "myaccount1#gmail.com:12345", "myaccount2#gmail.com:54321"
// };
//after
ArrayList<String> CREDENTIALS = new ArrayList<String>(Arrays.asList("myaccount1#gmail.com:12345","myaccount2#gmail.com:54321"));
/**
* The default email to populate the email field with.
*/
public static final String EXTRA_EMAIL = "myaccount1#gmail.com";
/**
* Keep track of the login task to ensure we can cancel it if requested.
*/
private UserLoginTask mAuthTask = null;
// Values for email and password at the time of the login attempt.
private String mEmail;
private String mPassword;
// UI references.
private EditText mEmailView;
private EditText mPasswordView;
private View mLoginFormView;
private View mLoginStatusView;
private TextView mLoginStatusMessageView;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
// Set up the login form.
mEmail = getIntent().getStringExtra(EXTRA_EMAIL);
mEmailView = (EditText) findViewById(R.id.email);
mEmailView.setText(mEmail);
mPasswordView = (EditText) findViewById(R.id.password);
mPasswordView
.setOnEditorActionListener(new TextView.OnEditorActionListener()
{
#Override
public boolean onEditorAction(TextView textView, int id,
KeyEvent keyEvent)
{
if (id == R.id.login || id == EditorInfo.IME_NULL)
{
attemptLogin();
return true;
}
return false;
}
});
mLoginFormView = findViewById(R.id.login_form);
mLoginStatusView = findViewById(R.id.login_status);
mLoginStatusMessageView = (TextView) findViewById(R.id.login_status_message);
findViewById(R.id.sign_in_button).setOnClickListener(
new View.OnClickListener()
{
#Override
public void onClick(View view)
{
attemptLogin();
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.activity_login, menu);
return true;
}
/**
* Attempts to sign in or register the account specified by the login form.
* If there are form errors (invalid email, missing fields, etc.), the
* errors are presented and no actual login attempt is made.
*/
public void attemptLogin()
{
if (mAuthTask != null)
{
return;
}
// Reset errors.
mEmailView.setError(null);
mPasswordView.setError(null);
// Store values at the time of the login attempt.
mEmail = mEmailView.getText().toString();
mPassword = mPasswordView.getText().toString();
boolean cancel = false;
View focusView = null;
// Check for a valid password.
if (TextUtils.isEmpty(mPassword))
{
mPasswordView.setError(getString(R.string.error_field_required));
focusView = mPasswordView;
cancel = true;
} else if (mPassword.length() < 4)
{
mPasswordView.setError(getString(R.string.error_invalid_password));
focusView = mPasswordView;
cancel = true;
}
// Check for a valid email address.
if (TextUtils.isEmpty(mEmail))
{
mEmailView.setError(getString(R.string.error_field_required));
focusView = mEmailView;
cancel = true;
} else if (!mEmail.contains("#"))
{
mEmailView.setError(getString(R.string.error_invalid_email));
focusView = mEmailView;
cancel = true;
}
if (cancel)
{
// There was an error; don't attempt login and focus the first
// form field with an error.
focusView.requestFocus();
} else
{
// Show a progress spinner, and kick off a background task to
// perform the user login attempt.
mLoginStatusMessageView.setText(R.string.login_progress_signing_in);
showProgress(true);
mAuthTask = new UserLoginTask();
mAuthTask.execute((Void) null);
}
}
/**
* Shows the progress UI and hides the login form.
*/
#TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
private void showProgress(final boolean show)
{
// On Honeycomb MR2 we have the ViewPropertyAnimator APIs, which allow
// for very easy animations. If available, use these APIs to fade-in
// the progress spinner.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2)
{
int shortAnimTime = getResources().getInteger(
android.R.integer.config_shortAnimTime);
mLoginStatusView.setVisibility(View.VISIBLE);
mLoginStatusView.animate().setDuration(shortAnimTime)
.alpha(show ? 1 : 0)
.setListener(new AnimatorListenerAdapter()
{
#Override
public void onAnimationEnd(Animator animation)
{
mLoginStatusView.setVisibility(show ? View.VISIBLE
: View.GONE);
}
});
mLoginFormView.setVisibility(View.VISIBLE);
mLoginFormView.animate().setDuration(shortAnimTime)
.alpha(show ? 0 : 1)
.setListener(new AnimatorListenerAdapter()
{
#Override
public void onAnimationEnd(Animator animation)
{
mLoginFormView.setVisibility(show ? View.GONE
: View.VISIBLE);
}
});
} else
{
// The ViewPropertyAnimator APIs are not available, so simply show
// and hide the relevant UI components.
mLoginStatusView.setVisibility(show ? View.VISIBLE : View.GONE);
mLoginFormView.setVisibility(show ? View.GONE : View.VISIBLE);
}
}
/**
* Represents an asynchronous login/registration task used to authenticate
* the user.
*/
public class UserLoginTask extends AsyncTask<Void, Void, Boolean>
{
#Override
protected Boolean doInBackground(Void... params)
{
// TODO: attempt authentication against a network service.
try
{
// Simulate network access.
Thread.sleep(2000);
} catch (InterruptedException e)
{
return false;
}
for (String credential : CREDENTIALS)
{
String[] pieces = credential.split(":");
if (pieces[0].equals(mEmail))
{
// Account exists, return true if the password matches.
return pieces[1].equals(mPassword);
}
}
// TODO: register the new account here.
CREDENTIALS.add(mEmail+":"+mPassword);
return true;
}
#Override
protected void onPostExecute(final Boolean success)
{
mAuthTask = null;
showProgress(false);
if (success)
{
finish();
Intent myIntent = new Intent(LoginActivity.this,CalculatorActivity.class);
LoginActivity.this.startActivity(myIntent);
} else
{
mPasswordView
.setError(getString(R.string.error_incorrect_password));
mPasswordView.requestFocus();
}
}
#Override
protected void onCancelled()
{
mAuthTask = null;
showProgress(false);
}
}
Here, u have used String[] CREDENTIALS. Array of String is final and declared.So u need to take ArrayList of String instead of String Array.
Then U can append your Text from mEmailView & mPasswordView with ":". Now add this new String to your Arraylist CREDENTIALS.