Android學習--強制下線功能
來自專欄 python
一.功能介紹
現在用這個強制下線功能的小項目來實踐一下Android的廣播機制。
這個功能也是比較常見的,就比如QQ號在別處登錄,就會被強制擠下線,這時會彈出一個對話框,這時不能進行其他操作了,只能確定然後返回登錄界面。
二.明確需求,了解效果
要想實現這個功能,得先看看實現的界面以及效果,明確要求是必要的。
首先得有一個登錄界面,賬號,密碼,登錄按鈕,這裡要有個賬號密碼匹配的功能,賬號密碼不正確,發送一個警告,正確 則進入發送廣播的主界面。
然後 主界面就一個按鈕 發送廣播
最後 彈出對話框,點擊ok後返回登錄界面。
三.步驟實現
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(); } } }}
2.創建所有活動的父類BaseActivity
該活動繼承自AppCompatActivity類,創建活動時把該活動添加入活動管理類,銷毀活動時把這個活動從活動管理類移除。
/所有活動的父類public class BaseActivity extends AppCompatActivity { private ForeOffLineReceiver receiver; @Override protected void onCreate( Bundle savedInstanceState) { super.onCreate(savedInstanceState); //添加這個活動 ActivityCollector.addActivity(this); } @Override protected void onDestroy() { super.onDestroy(); //消除這個活動 ActivityCollector.RemoveActivity(this); }}
3.接下來開始創建登錄界面啦。新建一個空活動,命名為LoginActivity。這個會同時生成一個LoginActivity的類以及 activity_login.xml的布局
activity_login布局
賬號的文本輸入框,密碼的文本輸入框,登錄按鈕。
<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="18sp" 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>
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(); //匹配判斷 if(account.equals("admin")&&password.equals("123456")){ //活動交互 賬戶密碼正確則跳轉到MainActivity Intent intent=new Intent(LoginActivity.this,MainActivity.class); startActivity(intent); finish(); }else {//否則提示密碼錯誤 Toast.makeText(LoginActivity.this,"account or password is invalid",Toast.LENGTH_SHORT).show(); } } }); }}
4.MainActivity和 activity_main.xml
主活動界面不搞花里胡哨的,只要一個發送廣播的按鈕
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" 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" /></LinearLayout>
MainActivity
這裡MainActivity 是繼承自Baseactivity ,主活動也是在活動管理類的範圍內
按鈕點擊事件發送一條廣播,值為com.example.broadcastpractice.FORCE_OFFLINE
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.example.broadcastpractice.FORCE_OFFLINE"); sendBroadcast(intent); } }); }}
5.添加廣播接收器
既然在主活動界面發送了廣播,那肯定要有一個接收廣播器來接收廣播。
這裡有個問題:
應該在哪註冊這個廣播接收器? 我們想想:我們的目的是這個廣播接收器接到廣播後彈出一個對話框,那應該是不管用戶在哪個界面 這個對話框在接收到廣播後都能彈出來,對吧?
那問題就來了,我們要所有的活動都放一個廣播接收器中嗎? 可是,這並不現實。
那該怎麼辦呢? 其實,我們只需要把廣播接收器放到BaseActivity中。因為這個是所有類的父類,子類繼承父類,那麼父類有的東西,子類當然也有。
所以,添加廣播接收器,我們就修改BaseActivity。
創建一個廣播接收器的內部類oreOffLineReceiver 繼承自BroadcastReceiver
調用其中的OnReceive方法,這裡要彈出一個對話框AlertDialog.Builder,要注意的是這個對話框不能被用戶關閉,只能通過按鈕的「OK」點擊響應。
點擊完"OK"按鈕,重啟登錄界面就行了。
/所有活動的父類public class BaseActivity extends AppCompatActivity { private ForeOffLineReceiver receiver; @Override protected void onCreate( Bundle savedInstanceState) { super.onCreate(savedInstanceState); //添加這個活動 ActivityCollector.addActivity(this); } //在OnResume 和 OnPause中註冊和取消註冊, // 目的是 讓一個棧頂活動 註冊廣播接收器 當該活動失去棧頂位置時 取消註冊 //因為 非棧頂的活動 也不需要註冊這個強制下線廣播 //註冊廣播接收器 protected void onResume(){ super.onResume(); IntentFilter intentFilter=new IntentFilter(); intentFilter.addAction("com.example.broadcastpractice.FORCE_OFFLINE"); receiver=new ForeOffLineReceiver(); 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); } //廣播接收器,在BaseActivity類中動態註冊,則 在所有活動界面都能接收到廣播 class ForeOffLineReceiver 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 forced to be offline. Please try to login again"); //無法關閉的對話框 builder.setCancelable(false); //只能點擊其中的按鈕「ok」,銷毀所有活動,並重啟LoginActivity活動 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(); } }}
四,總結
到此,一個強制系統下線的功能就已經實現了,有沒對廣播有更深一步的了解?從中,對Android的前端後台是不是有個更深的體會了呢? 學習的路還長,還得繼續走下去。
推薦閱讀:
※搭建Qt5.1.0 Beta的Android開發環境
※Android開發筆記(五)— 更改手機窗口底色
※Android開發