《第一行程式碼Android》學習總結第四章 廣播機制實踐——強制下線功能
阿新 • • 發佈:2018-11-16
強制下線功能需要在任何一個介面上彈出一個對話方塊,讓使用者必須點選對話方塊中的確定按鈕,關閉所有活動,然後回到登入介面即可。
1、建立ActivityCollector類用於管理活動。
public class ActivityCollector { public static List<Activity> activities = new ArrayList<>(); 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(); } } activities.clear(); } }
2、建立BaseActivity類作為所有活動的父類。
public class BaseActivity extends AppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); ActivityCollector.addActivity(this); } @Override protected void onDestroy() { super.onDestroy(); ActivityCollector.removeActivity(this); } }
3、建立一個登入介面的Activity,並編輯修改生成的activity_login.xml。
該佈局外層為一個垂直LinearLayout,包含三個子元素,第一行與第二行為一個橫向LinearLayout,分別用於輸入賬戶資訊與密碼,第三行為一個登入按鈕。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="60dp"> <TextView android:layout_width="90dp" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:textSize="18sp" android:text="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="90dp" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:textSize="18dp" android:text="Password:"/> <EditText android:id="@+id/password" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:layout_gravity="center_vertical" android:inputType="textPassword"/> </LinearLayout> <Button android:id="@+id/login" android:layout_width="match_parent" android:layout_height="60dp" android:text="Login"/> </LinearLayout>
4、修改LoginActivity中程式碼。
public class LoginActivity extends BaseActivity {
private EditText accountEdit;
private EditText passwordEdit;
private Button login;
//模擬登入功能
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
accountEdit = (EditText) findViewById(R.id.account);
passwordEdit = (EditText) findViewById(R.id.password);
login = (Button) findViewById(R.id.login);
login.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String account = accountEdit.getText().toString();
String password = passwordEdit.getText().toString();
//當賬號為admin,密碼為123456時登入成功,進入主介面
if(account.equals("admin") && password.equals("123456")){
Intent intent = new Intent(LoginActivity.this,MainActivity.class);
startActivity(intent);
finish();
}else{
Toast.makeText(LoginActivity.this,"invalid",Toast.LENGTH_SHORT).show();
}
}
});
}
}
5、修改activity_main.xml,新增一個按鈕,用於觸發強制下線功能。
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/force_offline"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Send force offline broadcast"/>
</LinearLayout>
6、修改MainActivity中程式碼,設定Button的監聽,傳送廣播通知使用者強制下線。
public class MainActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button forceoffline = (Button) findViewById(R.id.force_offline);
forceoffline.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent intent = new
Intent("com.launcher.broadcastbestpractice.FORCE_OFFLINE");
sendBroadcast(intent);
}
});
}
}
7、在BaseActivity中註冊廣播接收器來接受強制下線的廣播,因為所有Activity都繼承自BaseActivity,所以該操作可以完成在所有Activity中都實現該廣播的註冊。
public class BaseActivity extends AppCompatActivity {
private ForceOfflineReceiver receiver;
@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.launcher.broadcastbestpractice.FORCE_OFFLINE");
receiver = new ForceOfflineReceiver();
registerReceiver(receiver,intentFilter);
}
@Override
protected void onPause() {
super.onPause();
//登出廣播
if(receiver != null){
unregisterReceiver(receiver);
receiver = null;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
ActivityCollector.removeActivity(this);
}
//強制下線廣播
class ForceOfflineReceiver extends BroadcastReceiver{
@Override
public void onReceive(final Context context, Intent intent) {
//建立AlertDialog對話方塊
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle("Warning");
builder.setMessage("you are forced to be offline");
builder.setCancelable(false);
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
ActivityCollector.finishAll();
Intent intent=new Intent(context,LoginActivity.class);
context.startActivity(intent);
}
});
builder.show();
}
}
}
注意:因為要始終保持只有處在棧頂的Activity才能接受到強制下線的廣播,非棧頂的Activity不應該也沒必要接收到此條廣播,所以此次將註冊廣播與登出廣播寫在了onResume() 與onPause()方法中(見activity的生命週期),當一個活動失去棧頂位置會自動失去廣播接收器的註冊。
8、修改AndroidManifest.xml,將主活動設定為LoginActivity而不是MainActivity。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.launcher.broadcastbestpractice">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
</activity>
<activity android:name=".LoginActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>