有時候,一個APP要求同時隻能登陸一在一台裝置,就如同QQ一樣,當有其他人登你的qq時,你自己的app就會彈出一個對話,并提示你重新登入,就如下圖所示:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIyVGduV2QvwVe0lmdhJ3ZvwFM38CXlZHbvN3cpR2Lc1TPB10QGtWUCpEMJ9CXsxWam9CXwADNvwVZ6l2c052bm9CXUJDT1wkNhVzLcRnbvZ2LcZXUYpVd1kmYr50MZV3YyI2cKJDT29GRjBjUIF2LcRHelR3LcJzLctmch1mclRXY39TN2AzMwMDM1EDNyYDM2EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
因為在彈出這個對話框時,使用者所在的Activity是不一定的,然而我們也不可能在每一個Activity都new一個新的AlertDialog,這樣操作很不現實。最近的公司項目要求實作這個功能,在網上翻了翻大都寫的不詳細,是以便自己寫了一個。同時也遇到了一個問題。
方法一:談到全局性的dialog,大家第一反應,肯定是使用service,通過service來檢測是否需要彈窗。
加入權限 <span style="color:#FF0000;"><uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/></span>
public class LoginCheckService extends Service{
Handler handler;
Runnable runnable;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
final MyAlertDialog remindDialog = new MyAlertDialog(this, R.style.MyAlertDialog, "提醒",
String.format("您的賬号%s已綁定在其他裝置上,将在此裝置上自動登出!", App.Cellphone));
remindDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
remindDialog.setTitleColor(getResources().getColor(R.color.black));
remindDialog.setSingleSelect();
remindDialog.setOKBtn(new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
handler = new Handler();
runnable = new Runnable() {
@Override
public void run() {
if(App.NeedOffLine){
if(!remindDialog.isShowing()){
remindDialog.show();
}
}
handler.postDelayed(runnable, 500);
}
};
handler.post(runnable);
}
}
上面的代碼很簡單,其實就是一個service,每隔5秒通過全局變量App.NeedOffLine來判斷一下是否需要彈出視窗。
最關鍵的部分便是:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
remindDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
這句話是為了使dialog擷取系統優先級,需要申請權限。
但是,實際使用的時候發現使用service彈出dialog的方式在小米手機和三星上并不能實作,而需要其開啟懸浮窗功能才能這些,這樣是不能滿足我們的要求的,是以我便想出了方法二:使用BroadcastReceiver實作。
方法二:使用BroadcastReceiver實作:
這個方法需要我們實作一個基類BaseActivity,以後每個新的Activity都繼承BaseActivity,這樣就不需要在每個Activity都寫一個廣播。
public class BaseActivity extends Activity{
DialogReceiver dialogReceiver;
MyAlertDialog remindDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
remindDialog = new MyAlertDialog(this, R.style.MyDialogTheme);
dialogReceiver = new DialogReceiver();
}
class DialogReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
if(!remindDialog.isShowing()){
remindDialog.show();
}
}
}
@Override
protected void onResume() {
IntentFilter filter = new IntentFilter("com.fooww.soft.android.Presentation.LoginCheck");
registerReceiver(dialogReceiver, filter);
super.onResume();
}
@Override
protected void onPause() {
unregisterReceiver(dialogReceiver);
super.onStop();
}
}
其實這個方法的關鍵便在于,在onResume中注冊廣播,在onPause中便解綁。一開始我并沒有這麼做,發現,每啟動一個Activity便注冊一個新的廣播,而每個廣播的名字又是一樣的,這樣廣播便産生了沖突,導緻APP報錯。于是,我便這麼寫了。每次進入一個Activity在onResume中注冊廣播,當進入另一個Activity的時候,将背景的Activity解綁,也就是onPause中解綁,新的前台Activity中注冊了新的廣播,這樣廣播便會一直儲存,并且有且隻有一個,滿足了我們需求。是以,一旦接收到要彈出dialog的廣播資訊,前台總有一個廣播在接受,并彈出dialog。
如果還有其他方法,歡迎大家分享!