Android全局性的Dialog

来源:互联网 发布:无间道音响知乎 编辑:程序博客网 时间:2024/05/09 08:25

有时候,一个APP要求同时只能登陆一在一台设备,就如同QQ一样,当有其他人登你的qq时,你自己的app就会弹出一个对话,并提示你重新登录,就如下图所示:



因为在弹出这个对话框时,用户所在的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;@Overridepublic IBinder onBind(Intent intent) {return null;}@Overridepublic 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() {@Overridepublic void onClick(DialogInterface dialog, int which) {}}); handler = new Handler(); runnable = new Runnable() {@Overridepublic 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;@Overrideprotected 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{@Overridepublic void onReceive(Context context, Intent intent) {if(!remindDialog.isShowing()){remindDialog.show();}}}@Overrideprotected void onResume() {IntentFilter filter = new IntentFilter("com.fooww.soft.android.Presentation.LoginCheck");registerReceiver(dialogReceiver, filter);super.onResume();}@Overrideprotected void onPause() {unregisterReceiver(dialogReceiver);super.onStop();}}
其实这个方法的关键便在于,在onResume中注册广播,在onPause中便解绑。一开始我并没有这么做,发现,每启动一个Activity便注册一个新的广播,而每个广播的名字又是一样的,这样广播便产生了冲突,导致APP报错。于是,我便这么写了。每次进入一个Activity在onResume中注册广播,当进入另一个Activity的时候,将后台的Activity解绑,也就是onPause中解绑,新的前台Activity中注册了新的广播,这样广播便会一直保存,并且有且只有一个,满足了我们需求。因此,一旦接收到要弹出dialog的广播信息,前台总有一个广播在接受,并弹出dialog。

如果还有其他方法,欢迎大家分享!


1 0
原创粉丝点击