Android 实现记住密码和强制下线功能
1.实现的界面
登录界面:
强退界面
2.实现的功能
退出程序之后重启程序,会记住之前输入正确的账号与密码,登录进去之后,点击 offLine 会要求强制下线。强制下线功能需要先关闭掉所有的活动,然后回到登录界面。
这个强制下线并不是直接 finish(); 进程,这里要用到的是广播机制,在任何一个界面只要发送下线的广播,便可实现下线功能。
3.界面代码
(1)登录界面
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_main"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="15dp">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="60dp">
<TextView
android:layout_width="110dp"
android:layout_height="wrap_content"
android:textSize="20sp"
android:layout_gravity="center_vertical"
android:text="@string/account"/>
<EditText
android:id="@+id/account"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center_vertical"/>
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="60dp">
<TextView
android:layout_width="110dp"
android:layout_height="wrap_content"
android:textSize="20sp"
android:layout_gravity="center_vertical"
android:text="@string/password"/>
<EditText
android:id="@+id/password"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:inputType="textPassword"
android:layout_gravity="center_vertical"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<CheckBox
android:id="@+id/remember_pass"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="16sp"
android:text="@string/remember"/>
</LinearLayout>
<Button
android:id="@+id/login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/login"
android:textAllCaps="false"
android:textSize="20sp"/>
</LinearLayout>
(2)下线界面
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:id="@+id/activity_login"
android:padding="15dp"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/offline"
android:text="@string/offline"
android:textSize="20sp"
android:textAllCaps="false"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
4.Activity代码
因为关系到强制下线时可能正处于任何一个界面,在每个界面都写一个强制下线弹出对话框的逻辑显然不可取。所以需要用到广播的技术。
(1)ActivityCollector 类代码
要关闭所有活动,就可以先创建一个 ActivityCollector 类用于管理所有的活动,然后在这个类关闭所有。
public class ActivityCollector {
public static List<Activity> activityList = new ArrayList<>();
public static void addActivity(Activity activity){
activityList.add(activity);
}
public static void removeActivity(Activity activity){
activityList.remove(activity);
}
public static void finishAll(){
for (Activity activity:activityList) {
if(!activity.isFinishing())
activity.finish();
}
}
}
(2)BaseActivity 类代码
然后创建 BaseActivity 类作为所有活动的父类,广播接收器就是在这个类动态创建,因为静态的接收器没有办法在 onReceive(); 方法弹出对话框之类的框架的。
public class BaseActivity extends AppCompatActivity {
private ForceOfflineReceive receive;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityCollector.addActivity(this);
}
@Override
protected void onResume() {
super.onResume();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.example.admin.offline.FORCE_OFFLINE");
receive = new ForceOfflineReceive();
registerReceiver(receive, intentFilter);
}
@Override
protected void onPause() {
super.onPause();
if(receive != null){
unregisterReceiver(receive);
receive = null;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
ActivityCollector.removeActivity(this);
}
class ForceOfflineReceive extends BroadcastReceiver{
@Override
public void onReceive(final Context context, Intent intent) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle("Warning");
builder.setMessage("You are force to be offline. Please try to login again.");
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ActivityCollector.finishAll();
Intent intent = new Intent(context, MainActivity.class);
context.startActivity(intent);
}
});
builder.show();
}
}
}
(3)MainActivity 代码(登录界面的Activity)
记住密码功能用的是数据存储的 SharedPrefreferences 存储方式。使用 SharedPrefreferences 的 put 和 get 方法保存和存取数据。
还用到了一个新控件,CheckBox。这是一个复选框控件,用户可以通过点击的方 式来进行选中和取消,使用这个控件来表示用户是否需要记住密码。
public class MainActivity extends BaseActivity {
private EditText accountEdit;
private EditText passwordEdit;
private Button login;
private SharedPreferences pref;
private SharedPreferences.Editor editor;
private CheckBox rememberPass;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pref = PreferenceManager.getDefaultSharedPreferences(this);
accountEdit = (EditText)findViewById(R.id.account);
passwordEdit = (EditText)findViewById(R.id.password);
login = (Button)findViewById(R.id.login);
rememberPass = (CheckBox)findViewById(R.id.remember_pass);
boolean isRemember = pref.getBoolean("remember_password", false);
if(isRemember){
String account = pref.getString("account","");
String password = pref.getString("password","");
accountEdit.setText(account);
passwordEdit.setText(password);
rememberPass.setChecked(true);
}
login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String account = accountEdit.getText().toString();
String password = passwordEdit.getText().toString();
if(account.equals("admin") && password.equals("123456")){
editor = pref.edit();
if(rememberPass.isChecked()){ //是否被选中
editor.putBoolean("remember_password",true);
editor.putString("account",account);
editor.putString("password",password);
}else{
editor.clear();
}
editor.apply();
Intent intent = new Intent(MainActivity.this,LoginActivity.class);
startActivity(intent);
finish();
}else{
Toast.makeText(MainActivity.this,
"acount or password is invalid", Toast.LENGTH_SHORT).show();
}
}
});
}
}
(4)LoginActivity 代码(下线界面的Activity)
这段很简单,按钮发送下线广播触发下线
public class LoginActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
Button offline = (Button)findViewById(R.id.offline);
offline.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(LoginActivity.this,"OK",Toast.LENGTH_SHORT).show();
Intent intent = new Intent("com.example.admin.offline.FORCE_OFFLINE");
sendBroadcast(intent);
}
});
}
}
然后
然后就没了啊。挺简单的。(自言自语)