You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
liyuxuan_gitProject/LoginActivity.java

515 lines
20 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.annotation.TargetApi;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.CursorLoader;
import android.content.Loader;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.inputmethod.EditorInfo;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static android.Manifest.permission.READ_CONTACTS;
/**
* A login screen that offers login via name/password.
* 通过账号/密码提供登录的登录屏幕。
*/
public class LoginActivity extends AppCompatActivity implements LoaderCallbacks<Cursor> {
/**
* Id to identity READ_CONTACTS permission request.
* ID来标识READ_CONTACTS权限请求。
*/
private static final int REQUEST_READ_CONTACTS = 0;
/**
* 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",
//DUMMY_CREDENTTALS用于模拟已存在的账户冒号前为账户冒号后为密码
};
/**
* Keep track of the login task to ensure we can cancel it if requested.
* 跟踪登录任务以确保我们可以根据请求取消它。
*/
private UserLoginTask mAuthTask = null;
// UI references.
private AutoCompleteTextView mUserNameView;
private EditText mPasswordView;
private View mProgressView;
private View mLoginFormView;
private SharedPreferences preferences;
private SharedPreferences.Editor editor;
//记住密码
private CheckBox rememberPass;
//自动登录
private CheckBox autoLogin;
@Override
protected void onCreate(Bundle savedInstanceState) {
if (Build.VERSION.SDK_INT >= 21) {
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE);
getWindow().setStatusBarColor(Color.TRANSPARENT);
}
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
preferences = PreferenceManager.getDefaultSharedPreferences(this);
// Set up the login form. 设置登录表单
rememberPass = (CheckBox) findViewById(R.id.remember_pass);
autoLogin = (CheckBox) findViewById(R.id.auto_login);
//账号输入
mUserNameView = (AutoCompleteTextView) findViewById(R.id.UserName);
populateAutoComplete();
//密码输入
mPasswordView = (EditText) findViewById(R.id.password);
mPasswordView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView textView, int id, KeyEvent keyEvent) {
if (id == EditorInfo.IME_ACTION_DONE || id == EditorInfo.IME_NULL) {
attemptLogin();
return true;
}
return false;
}
});
//记住密码
boolean isRemember = preferences.getBoolean("remember_password",false);
boolean isAutoLogin = preferences.getBoolean("auto_Login",false);
if(isRemember ) {
//将账户和密码都设置到文本框中
String account = preferences.getString("UserName", "");
String password = preferences.getString("password", "");
mUserNameView.setText(account);
mPasswordView.setText(password);
rememberPass.setChecked(true);
//自动登录
if (isAutoLogin) {
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
LoginActivity.this.startActivity(intent);
Toast.makeText(getApplicationContext(), "自动登录", Toast.LENGTH_SHORT).show();
}
}
//登录按钮
Button mUserNameSignInButton = (Button) findViewById(R.id.UserName_sign_in_button);
mUserNameSignInButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
attemptLogin();
}
});
//注册按钮
Button register = (Button) findViewById(R.id.register);
register.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new Intent(LoginActivity.this,registerActivity.class);
startActivity(intent);
}
});
//方法最后两个mLoginFormView和mProgressView是用于获取显示的View
//在登陆的时候可以进行登陆窗口goneProgressBar visible的操作。
mLoginFormView = findViewById(R.id.login_form);
mProgressView = findViewById(R.id.login_progress);
}
//先是通过mayRequestContacts判断是否继续执行若通过判断则初始化Loaders通过Loaders后台异步读取用户的账户信息。
private void populateAutoComplete() {
if (!mayRequestContacts()) {
return;
}
getLoaderManager().initLoader(0, null, this);
}
//这个方法是用于请求用户以获取读取账户的权限主要是为了适配6.0新的权限机制
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(mUserNameView, 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 UserName, missing fields, etc.), the
* 如果有表单错误(无效的电子邮件,缺少字段等)
* errors are presented and no actual login attempt is made.
* 出现错误并且没有进行实际的登录尝试。
*/
private void attemptLogin() {
if (mAuthTask != null) {
return;
}
// Reset errors.重置错误。
mUserNameView.setError(null);
mPasswordView.setError(null);
// Store values at the time of the login attempt.在登录尝试时存储值。
String UserName = mUserNameView.getText().toString();
String password = mPasswordView.getText().toString();
editor = preferences.edit();
if(autoLogin.isChecked()){
editor.putBoolean("auto_Login",true);
}
if (rememberPass.isChecked()) {
editor.putBoolean("remember_password", true);
editor.putString("UserName", UserName);
editor.putString("password", password);
} else {
editor.clear();
}
editor.apply();
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
if (TextUtils.isEmpty(UserName)) {
mUserNameView.setError(getString(R.string.error_field_required));
focusView = mUserNameView;
cancel = true;
} else if (!isUserNameValid(UserName)) {
mUserNameView.setError(getString(R.string.error_invalid_UserName));
focusView = mUserNameView;
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(UserName, password);
mAuthTask.execute((Void) null);
}
}
private boolean isUserNameValid(String UserName) {
//TODO: Replace this with your own logic 用你自己的逻辑代替这个
return UserName.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.
* 显示进度UI并隐藏登录表单。
*/
@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.
//ViewPropertyAnimator API不可用因此只需显示和隐藏相关的UI组件。
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,
ContactsContract.Contacts.Data.MIMETYPE +
" = ?", new String[]{ContactsContract.CommonDataKinds.UserName
.CONTENT_ITEM_TYPE},
ContactsContract.Contacts.Data.IS_PRIMARY + " DESC");
}
@Override
public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
List<String> UserNames = new ArrayList<>();
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
UserNames.add(cursor.getString(ProfileQuery.ADDRESS));
cursor.moveToNext();
}
addUserNamesToAutoComplete(UserNames);
}
@Override
public void onLoaderReset(Loader<Cursor> cursorLoader) {
}
private void addUserNamesToAutoComplete(List<String> UserNameAddressCollection) {
//Create adapter to tell the AutoCompleteTextView what to show in its dropdown list.
//创建适配器以告诉AutoCompleteTextView在其下拉列表中显示什么。
ArrayAdapter<String> adapter =
new ArrayAdapter<>(LoginActivity.this,
android.R.layout.simple_dropdown_item_1line, UserNameAddressCollection);
mUserNameView.setAdapter(adapter);
}
private interface ProfileQuery {
String[] PROJECTION = {
ContactsContract.CommonDataKinds.UserName.ADDRESS,
ContactsContract.CommonDataKinds.UserName.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 mUserName;
private final String mPassword;
UserLoginTask(String UserName, String password) {
mUserName = UserName;
mPassword = password;
}
@Override
protected Boolean doInBackground(Void... params) {
// TODO: attempt authentication against a network service.
//尝试对网络服务进行身份验证。
try {
LoginRequest(mUserName,mPassword);
// Simulate network access.模拟网络访问。
Thread.sleep(3000);
} catch (InterruptedException e) {
return false;
}
for (String credential : DUMMY_CREDENTIALS) {
String[] pieces = credential.split(":");
if (pieces[0].equals(mUserName)) {
// Account exists, return true if the password matches.
//帐户存在如果密码匹配则返回true。
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) {
/*
Intent intent = new Intent(LoginActivity.this,MainActivity.class);
startActivity(intent);
finish();
*/
} else {
mPasswordView.setError(getString(R.string.error_incorrect_password));
mPasswordView.requestFocus();
}
}
@Override
protected void onCancelled() {
mAuthTask = null;
showProgress(false);
}
}
public void LoginRequest(final String account, final String password) {
//请求地址
String url = "http://8.130.38.15:8080/Whoere/LoginServlet?account="+account+"&password="+password;
String tag = "Login";
//取得请求队列
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
//防止重复请求所以先取消tag标识的请求队列
requestQueue.cancelAll(tag);
//创建StringRequest定义字符串请求的请求方式为POST(省略第一个参数会默认为GET方式)
final StringRequest request = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>() {
//@Override
public void onResponse(String response) {
try {
JSONObject jsonObject = (JSONObject) new JSONObject(response).get("params");
String result = jsonObject.getString("Result");
if (result.equals("success")) {
//做自己的登录成功操作,如页面跳转
Intent intent = new Intent(LoginActivity.this,MainActivity.class);
startActivity(intent);
Toast.makeText(LoginActivity.this,"欢迎!",Toast.LENGTH_LONG).show();
} else {
if (result.equals("failed"))
Toast.makeText(LoginActivity.this,"账户或密码错误!",Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
//做自己的请求异常操作如Toast提示“无网络连接”等
Log.e("TAG", e.getMessage(), e);
}
}
}, new Response.ErrorListener() {
//@Override
public void onErrorResponse(VolleyError error) {
//做自己的响应错误操作如Toast提示“请稍后重试”等
Log.e("TAG", error.getMessage(), error);
}
}) {
@Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<>();
params.put("Account", account);
params.put("Password", password);
return params;
}
};
//设置Tag标签
request.setTag(tag);
//将请求添加到队列中
requestQueue.add(request);
}
}