Android懸浮窗實現(xiàn)中需要注意的兩點是
1、Android 6.0之后的懸浮窗動態(tài)申請
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 ,根據(jù)android系統(tǒng)版本選擇不同的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;
? ? ? ? //設置浮動窗口不可聚焦(實現(xiàn)操作除浮動窗口外的其他可見窗口的操作) FLAG_ALT_FOCUSABLE_IM
// wmParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;? //彈出的View收不到Back鍵的事件
//? wmParams.flags = WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
// 設置一下flag可以讓window內(nèi)部與外部事件互不干擾,不設置,可能會出現(xiàn)window內(nèi)部接收不到點擊事件或者外部接收不到事件
? ? ? ? wmParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
? ? ? ? ? ? ? ? | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
? ? ? ? ? ? ? ? | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
? ? ? ? //調(diào)整懸浮窗顯示的??课恢脼樽髠戎庙?/p>
? ? ? ? wmParams.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
? ? ? ? // 以屏幕左上角為原點,設置x、y初始值,相對于gravity偏移
? ? ? ? wmParams.x =0;
? ? ? ? wmParams.y = AutoUtils.getPercentHeightSize(56);
? ? ? ? // 設置懸浮窗口長寬數(shù)據(jù)
? ? ? ? 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
? ? ? ? }
}
}