博主在一次开发过程中因为需要用到全局弹窗,最开始考虑到在Application类中使用自定义数组管理Activity实例,来实现,但是这种方式仅能在activity处于前台时弹出弹窗,与业务不符,这种方式就不做赘述了。下面谈谈我自己使用的实现方式,及过程。
1.dialog设置(只设置重要代码)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){//6.0
dialog.window.setType(WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY)
}else {
dialog.window.setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT)
}
dialog.show()
2、权限清单
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW"/>
3、针对6.0以上动态申请权限
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (!Settings.canDrawOverlays(this)) {
AskDialog(this,this)
.setRadius(10)
.setWinTitle("系统提示")
.setMessage("为了正常接收其他用户消息,请先去允许应用在上层显示")
.setCloseListener("不用了"){
NToast.show("您拒绝了权限申请,可能无法正常接收用户信息")
}
.setSubmitListener("好的"){
this?.startActivityForResult(Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:" + this?.packageName)), 10001)
}
.show()
}
}
4、权限申请回调
@TargetApi(Build.VERSION_CODES.M)
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == 10001) {
if (!Settings.canDrawOverlays(this)) {
NToast.show("权限获取失败,可能无法正常接收用户信息")
} else {
NToast.show("权限获取成功")
}
}
}
5、最后在Application中正常show()就行了,但是还是遇到了一个问题,就是如果当前应用处于后台之后,弹窗中如果要实现Intent跳转页面功能的话,就会失效,无法正常跳转页面。所以还需要加入以下代码:
1).Applications实现ActivityLifecycleCallbacks的接口,然后全局监听activity的活动状态,标识应用是否处于前台。
class App : Application(), BusReceive,Application.ActivityLifecycleCallbacks {
override fun onActivityPaused(activity: Activity?) {
}
override fun onActivityResumed(activity: Activity?) {
}
override fun onActivityStarted(activity: Activity?) {
activityCount++
}
override fun onActivityDestroyed(activity: Activity?) {
}
override fun onActivitySaveInstanceState(activity: Activity?, outState: Bundle?) {
}
override fun onActivityStopped(activity: Activity?) {
activityCount--
}
override fun onActivityCreated(activity: Activity?, savedInstanceState: Bundle?) {
}
private var activityCount=0
}
if(activityCount<=0){
//应用处于后台
}
2).在dialog执行跳转之前,判断一下当前应用书否处于后台状态,若是处于该状态,则将应用切换到前台运行:
private fun toFront(){
/**获取ActivityManager*/
var activityManager = this.getSystemService(ACTIVITY_SERVICE) as ActivityManager
/**获得当前运行的task(任务)*/
var taskInfoList = activityManager.getRunningTasks(100)
for ( taskInfo in taskInfoList) {
/**找到本应用的 task,并将它切换到前台*/
if (taskInfo.topActivity.packageName == this.packageName) {
activityManager.moveTaskToFront(taskInfo.id, 0)
break
}
}
}
就可以正常全局弹窗和执行跳转业务了,切换应用到前台需要权限哟,各位别忘了,如果使用的开发工具是AS的话系统会提示你添加的。
以上就是我本次处理的过程,希望对各位有帮助!