Android悬浮窗实现中需要注意的两点是
1、Android 6.0之后的悬浮窗动态申请
2、Window 的type属性在Android8.0前后的适配
public abstract class AudioFloatWindow {
private WindowManager.LayoutParamswmParams =null;
private WindowManagermWindowManager =null;
private ViewmRootView =null;
private boolean isShown =false;
public AudioFloatWindow(Context activity) {
init(activity);
}
public void init(Context context) {
wmParams =new WindowManager.LayoutParams();
//获取的是WindowManagerImpl.CompatModeWrapper
mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Log.i("test", "mWindowManager--->" +mWindowManager);
//设置window type ,根据android系统版本选择不同的type
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
wmParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
}else {
wmParams.type = WindowManager.LayoutParams.TYPE_PHONE;
}
//设置图片格式,效果为背景透明
wmParams.format = PixelFormat.RGBA_8888;
//设置浮动窗口不可聚焦(实现操作除浮动窗口外的其他可见窗口的操作) FLAG_ALT_FOCUSABLE_IM
// wmParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; //弹出的View收不到Back键的事件
// wmParams.flags = WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
// 设置一下flag可以让window内部与外部事件互不干扰,不设置,可能会出现window内部接收不到点击事件或者外部接收不到事件
wmParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
//调整悬浮窗显示的停靠位置为左侧置顶
wmParams.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
// 以屏幕左上角为原点,设置x、y初始值,相对于gravity偏移
wmParams.x =0;
wmParams.y = AutoUtils.getPercentHeightSize(56);
// 设置悬浮窗口长宽数据
wmParams.width = WindowManager.LayoutParams.MATCH_PARENT;
wmParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
LayoutInflater inflater = LayoutInflater.from(context);
mRootView = initView(inflater);
}
public abstract ViewinitView(LayoutInflater inflater);
private void change() {
if (isShown) {
hide();
}else {
show();
}
}
public void show() {
if (!isShown &&null !=mRootView) {
//添加mFloatLayout
mWindowManager.addView(mRootView, wmParams);
isShown =true;
}
}
public void hide() {
if (isShown &&null !=mRootView) {
mWindowManager.removeView(mRootView);
isShown =false;
}
}
public ViewgetRootView(){
return mRootView;
}
/**
* 申请 悬浮窗权限
*/
public void requestWindowPismisstion(Activity activity){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Settings.canDrawOverlays(activity)) {
Intent intent =new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
Uri.parse("package:" + getRootView().getContext().getPackageName()));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activity.startActivityForResult(intent, WINDOW_PERMISSION);
}else {
// Todo 弹出Window
}
}
}