广播的最佳实践——实现强制下线功能
ActivityCollector类
package com.jackie.broadcastbestpractice;
import android.app.Activity;
import java.util.ArrayList;
import java.util.List;
/**
* 用于管理所有的活动的类
* Created by Law on 2015/11/12.
*/
public class ActivityCollector {
public static List<Activity> activities = new ArrayList<Activity>();
public static void addActivity(Activity activity) {
activities.add(activity);
}
public static void removeActivity(Activity activity) {
activities.remove(activity);
}
/**
* 结束所有活动
*/
public static void finishAll() {
for (Activity activity : activities) {
if (!activity.isFinishing()) {
activity.finish();
}
}
}
}
LoginActivity
package com.jackie.broadcastbestpractice;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class LoginActivity extends AppCompatActivity {
private EditText editUsrname;
private EditText editPassword;
private Button btnLogin;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActivityCollector.addActivity(this);
editUsrname = (EditText) findViewById(R.id.editUsrname);
editPassword = (EditText) findViewById(R.id.editPassword);
btnLogin = (Button) findViewById(R.id.btnLLogin);
btnLogin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
String usrname = editUsrname.getText().toString();
String password = editPassword.getText().toString();
if (usrname.equals("admin") && password.equals("admin")) {
Intent intent = new Intent(LoginActivity.this, UserActivity.class);
startActivity(intent);
finish();
} else {
Toast.makeText(LoginActivity.this, "用户名或密码错误", Toast.LENGTH_SHORT).show();
}
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
ActivityCollector.removeActivity(this);
}
}
OfflineReceiver
强制下线,弹出窗口等逻辑写在广播接收器里面,这里要注意:
1、在Activity外部启动activity,要设置一个FLAG_ACTIVITY_NEW_TASK
2、在广播接收器里弹出对话框要设置对话框类型为TYPE_SYSTEM_ALERT
3、由于弹出的是系统级别的对话框,必须要添加权限SYSTEM_ALERT_WINDOW
package com.jackie.broadcastbestpractice;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.view.WindowManager;
/**
* 用于强制下线的广播接收器
*/
public class OfflineReceiver extends BroadcastReceiver {
public OfflineReceiver() {
}
@Override
public void onReceive(final Context context, Intent intent) {
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(context);
dialogBuilder.setTitle("注意");
dialogBuilder.setMessage("您已被强制下线,请重新登陆");
dialogBuilder.setPositiveButton("好的", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
ActivityCollector.finishAll();
Intent intent = new Intent(context, LoginActivity.class);
//在Activity外部启动activity需要设置下面这个Flag
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
});
dialogBuilder.setCancelable(false);
AlertDialog alertDialog = dialogBuilder.create();
//全局的对话框
alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
alertDialog.show();
}
}
UserActivity
package com.jackie.broadcastbestpractice;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class UserActivity extends AppCompatActivity {
private Button btnOffline;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user);
btnOffline = (Button) findViewById(R.id.btnOffline);
btnOffline.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.jackie.broadcastbestpractice.OFFLINE");
sendBroadcast(intent);
}
});
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:stretchColumns="1"
tools:context=".MainActivity">
<TableRow>
<TextView
android:layout_height="wrap_content"
android:text="用户名:" />
<EditText
android:id="@+id/editUsrname"
android:layout_height="wrap_content"
android:hint="请输入用户名" />
</TableRow>
<TableRow>
<TextView
android:layout_height="wrap_content"
android:text="密码:" />
<EditText
android:id="@+id/editPassword"
android:layout_height="wrap_content"
android:hint="请输入密码" />
</TableRow>
<TableRow>
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/btnLLogin"
android:layout_height="wrap_content"
android:layout_span="2"
android:text="登陆" />
</TableRow>
</TableLayout>
activity_user.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.jackie.broadcastbestpractice.UserActivity">
<Button
android:id="@+id/btnOffline"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="强制下线" />
</LinearLayout>
AndroidManyfest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.jackie.broadcastbestpractice">
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".LoginActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".UserActivity"></activity>
<receiver
android:name=".OfflineReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.jackie.broadcastbestpractice.OFFLINE" />
</intent-filter>
</receiver>
</application>
</manifest>