WindowManager使用——实现悬浮窗

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Mr_theSun/article/details/87912605

WindowManager是Android中一个重要的Service,是全局且唯一的。在Activity和Service中都可以直接使用这个方法来获得WindowManager。其getSystemService返回的是一个WindowManagerImpl对象,这是一个存在于本地进程中的一个对象。而事实是WindowManagerImpl继承了WindowManager,而WindowManger继承了ViewManager。

一、WindowManager

1.获取

wManager = (WindowManager) getApplicationContext().getSystemService(
                Context.WINDOW_SERVICE);


2.WindowManager基本方法


(1)窗口添加
public void addView(View view, ViewGroup.LayoutParams params);
(2)窗口更新
public void updateViewLayout(View view, ViewGroup.LayoutParams params);
(3)窗口删除
public void removeView(View view);


3.悬浮窗口需添加权限

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

4.允许显示在其他应用上方

光有悬浮窗权限还不够,在6.0以上手机还需要在设置里打开一个开关才可使用。

4.1使用反射判断该开关是否打开

 /**
  * 只适用于大多数手机
  * @param context
  * @return
  */
public boolean hasPermission(Context context) {
        try {
            try {
                Class clazz = Settings.class;
                Method canDrawOverlays = clazz.getDeclaredMethod("canDrawOverlays", Context.class);
                return (Boolean) canDrawOverlays.invoke(null, context);
            } catch (Exception e) {

            }
        } catch (Exception e) {

        }
        return false;
}

4.2 如果是未打开转态,我们需要使用代码引导用户到跳转打开

/**
     * 只适用于大多数手机
     * @param context
     * @return
     */
    public void openOverlayPermission(Context context) {
        try {
            Class clazz = Settings.class;
            Field field = clazz.getDeclaredField("ACTION_MANAGE_OVERLAY_PERMISSION");

            Intent intent = new Intent(field.get(null).toString());
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.setData(Uri.parse("package:" + context.getPackageName()));
            context.startActivity(intent);
        } catch (Exception e) {

        }
    }

 二.使用windowmanger实现实时悬浮窗

其中悬浮的view具体自己可以随便定义,主要是 WindowManager.LayoutParams的使用配合,尤其是WindowManager.LayoutParams的type在不同版本手机上是不同的,下面给出核心代码

 核心方法: 

private void showFloatMenuView(final Context context) {
        WindowManager.LayoutParams  params = new WindowManager.LayoutParams();
        params.width = getScreenWidth();
        params.height = getScreenHeight() - getStatusHeight(context);
        params.gravity = Gravity.BOTTOM | Gravity.LEFT;
        params.x = 0;
        params.y = 0;
        int versionCode = 24;
        if (Build.VERSION.SDK_INT >= versionCode) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                /*android8.0用*/
                params.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
            } else {
                /*android7.0不能用TYPE_TOAST*/
                params.type = WindowManager.LayoutParams.TYPE_PHONE;
            }
        } else {
            /*以下代码块使得android6.0之后的用户不必再去手动开启悬浮窗权限*/
            String packname = context.getPackageName();
            PackageManager pm = context.getPackageManager();
            boolean permission = (PackageManager.PERMISSION_GRANTED ==
                    pm.checkPermission("android.permission.SYSTEM_ALERT_WINDOW", packname));
            if (permission) {
                params.type = WindowManager.LayoutParams.TYPE_PHONE;
            } else {
                params.type = WindowManager.LayoutParams.TYPE_TOAST;
            }
        }
        params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
        params.format = PixelFormat.RGBA_8888;

        mWindowManager.addView(mFloastMenuView, params);
    }

猜你喜欢

转载自blog.csdn.net/Mr_theSun/article/details/87912605