很长时间没有写文章,最近在学习Android开发,今天实现一下模拟强制下线的功能共涉及到以下几个阶段:
-
编写Activity管理类
-
布局登录界面,并实现逻辑代码
-
MainActivity实现点击按钮发出一条自定义广播
-
自定义广播接收器的相关动作
-
AndroidManifest.xml清单文件的配置
-
自定义的Activity类
首先来看一下效果:
(一)Activity管理类ActivityCollector
public class ActivityCollector {
public static List<Activity> activities = new ArrayList<>();
//向集合添加Activity
public static void addActivity(Activity activity){
activities.add(activity);
}
//从集合删除Activity
public static void removeActivity(Activity activity){
activities.remove(activity);
}
//集合中全部Activity移出栈
public static void finishAll(){
for (Activity activity : activities){
if (!activity.isFinishing()){
activity.finish();
}
}
}
}
(二)登录界面XML布局and逻辑代码实现登录跳转
login.xml布局:
使用约束布局:
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="44dp"
android:layout_marginTop="36dp"
android:text="账号:"
android:textColor="#000000"
android:textSize="24sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="60dp"
android:text="密码:"
android:textColor="#000000"
android:textSize="24sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="@+id/textView"
app:layout_constraintTop_toBottomOf="@+id/textView" />
<EditText --账号输入框
android:id="@+id/et_login_account"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="text"
android:textColor="#000000"
android:textStyle="bold"
app:layout_constraintStart_toEndOf="@+id/textView"
app:layout_constraintTop_toTopOf="@+id/textView" />
<EditText --密码输入框
android:id="@+id/et_login_password"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textPassword"
android:textColor="#000000"
android:textStyle="bold"
app:layout_constraintStart_toEndOf="@+id/textView2"
app:layout_constraintTop_toTopOf="@+id/textView2" />
<Button --登录按钮
android:id="@+id/btn_login"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="116dp"
android:text="登录"
android:textColor="#3F51B5"
android:textSize="18sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/et_login_password" />
</androidx.constraintlayout.widget.ConstraintLayout>
LoginActivity逻辑代码:
public class LoginActivity extends Activity {
//定义控件成员变量
private EditText mEtAccount,mEtPassword;
private Button mBtnLogin;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login);
//初始化控件获得控件对象引用
mEtAccount = findViewById(R.id.et_login_account);
mEtPassword = findViewById(R.id.et_login_password);
mBtnLogin = findViewById(R.id.btn_login);
//登录按钮的单击事件
mBtnLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//获得用户输入的账号密码
String account = mEtAccount.getText().toString();
String password = mEtPassword.getText().toString();
//判断账号密码书否正确
if (account.equals("admin") && password.equals("123456")) {
//账号密码正确跳转至MainActivity页面
Intent intent = new Intent(LoginActivity.this,MainActivity.class);
startActivity(intent);
} else {
//账号密码不正确清空账号密码输入框,并Toast提示
mEtAccount.setText("");
mEtPassword.setText("");
Toast.makeText(LoginActivity.this, "请输入正确的信息!!", Toast.LENGTH_SHORT).show();
}
}
});
}
}
(三)MainActivity实现点击按钮发送广播
布局中只有一个按钮,XML省略
MainActivity代码:
//继承自定义BaseActivity类自动加入Activity管理类中
public class MainActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button forceOffline = findViewById(R.id.btn_force_offline);
//按钮点击事件发送一条自定义广播
forceOffline.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.example.broadcastpractice.FORCE_OFFLINE");
sendBroadcast(intent);
}
});
}
}
(四)广播接收者类ForceOfflineReceiver
public class ForceOfflineReceiver extends BroadcastReceiver {
@Override
public void onReceive(final Context context, final Intent intent) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle("Warning警告");
//对话框设置提示
builder.setMessage("You are forced to be offline. Please try to login again," +
"您被迫下线。请再次尝试登录!!");
//对话框设置成不可取消,否者用户点击Back则回到界面没有实现强制下线功能
builder.setCancelable(false);
//设置OK按钮
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//调用活动管理类的全部出栈方法将MainActivity出栈,回退到登录界面
ActivityCollector.finishAll();
Toast.makeText(context, "请重新登录!!", Toast.LENGTH_SHORT).show();
}
});
AlertDialog dialog = builder.create();
//设置对话框类型为TYPE_SYSTEM_ALERT,保证在广播接收器中弹出
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
dialog.show();
}
}
(五)AndroidManifest清单文件
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.broadcastpractice">
<!--SDK的配置-->
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="19"/>
<!--广播接收其中弹出体统级对话框需要声明此权限-->
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<!--LoginActivity设置为主活动-->
<activity android:name=".LoginActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!--MainActivity活动-->
<activity android:name=".MainActivity"/>
<!--静态注册接收的广播-->
<receiver android:name=".ForceOfflineReceiver">
<intent-filter>
<action android:name="com.example.broadcastpractice.FORCE_OFFLINE"/>
</intent-filter>
</receiver>
</application>
</manifest>
(六)自定义的Activity类BaseActivity
public class BaseActivity extends Activity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityCollector.addActivity(this);
}
}
源码地址:
https://github.com/Chenghui666/BroadcastPractice
文章到此结束,如果您在实现的过程中有任何问题,请后台提问,或者添加博主微信交流!!
*参考Android第一行代码(第一版)
*程序运行在android5.1,API22,高版本会有差异