Android 使用 WindowManager 实现悬浮窗监控 cpu 温度

前文概要
连续四篇介绍了车载设置,主要都是和源码相关,还未看过的,可以参考借鉴学习一下源码知识。车载设置–按键提示音

本文开始进入下一个篇章,主要是和 camera 相关,例如倒车,TV ,360 全景等,其主要实现原理是基于 WindowManager 来显示全屏窗口,在窗口中加载 camera 传递的数据。基于此,有必要先介绍一下 WindowManager 和 camera 相关的知识点,本文先从 WindowManager 开始。

WindowManager 类结构

public interface WindowManager implements ViewManager

WindowManager 是窗口管理器,所有显示窗口都可以通过它来控制。通常我们调用的是 WindowManager 继承自基类的 addView 方法和 removeView 方法来显示和隐藏窗口:

  • addView(View view, ViewGroup.LayoutParams params)
    Assign the passed LayoutParams to the passed View and add the view to the window. 用于添加一个窗口
  • removeView(View view) 移除一个窗口
  • updateViewLayout(View view, ViewGroup.LayoutParams params) 更新窗口的参数

WindowManager 主要是通过 Context.getSystemService(Context.WINDOW_SERVICE) 来获取。

WindowManager.LayoutParams 参数介绍
WindowManager.LayoutParams 这个类用于提供悬浮窗所需的参数,其中有几个经常会用到的变量:

  • x 值用于确定悬浮窗的位置,如果要横向移动悬浮窗,就需要改变这个值。
  • y 值用于确定悬浮窗的位置,如果要纵向移动悬浮窗,就需要改变这个值。
  • gravity 值用于确定悬浮窗的对齐方式及设置 x 和 y 值的参考系。
  • format 值用于确定窗口背景遮罩位图格式,默认为黑色,一般设置为半透明 (PixelFormat.TRANSLUCENT)
  • alpha 值用于确定这个窗口的透明值,1.0表示不透明,0.0表示全透明
  • width 值用于指定悬浮窗的宽度。
  • height 值用于指定悬浮窗的高度。
  • type 值用于确定窗口在屏幕上的显示层次,值越高,显示层次越高。一般设为 TYPE_PHONE,表示在所有应用程序之上,但在状态栏之下。
  • flags 值用于确定悬浮窗的行为,比如说不可聚焦,非模态对话框等等。

permission denied 解决办法

1.创建悬浮窗这种窗体需要向用户申请权限才可以的,因此还需要在 AndroidManifest.xml中加入 。

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

2.手机端设置允许调试应用在其他应用显示悬浮窗。例如有以下提示:

android.view.WindowManager$BadTokenException: Unable to add window android.view.ViewRootImpl$W@e604098 -- permission denied for window type 2038
                                                                                        at android.view.ViewRootImpl.setView(ViewRootImpl.java:806)
                                                                                        at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:373)
                                                                                        at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:114)

那么 将 type 改为TYPE_PHONE ,并且在手机端打开 权限管理–>悬浮窗管理–>调试应用勾选。
这样调试应用就能显示在其他应用之上。

悬浮窗示例
1. 对 WindowManager.LayoutParams 参数进行设置:

   mWindo wManager = (WindowManager) getApplication().getSystemService(Context.WINDOW_SERVICE);
        mLayoutParams = new WindowManager.LayoutParams();
        // 设置悬浮窗显示层次,在应用层之上,状态栏之下
        mLayoutParams.type = WindowManager.LayoutParams.TYPE_PHONE;
        //悬浮窗遮罩背景  半透明
        mLayoutParams.format = PixelFormat.TRANSLUCENT;
        // 悬浮窗曲奇方式,以屏幕左上角对齐
        mLayoutParams.gravity = Gravity.LEFT | Gravity.TOP;
        mLayoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
        mLayoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
       //FLAG_NOT_TOUCH_MODAL不阻塞事件传递到后面的窗口
        mLayoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
  1. 对小球增加拖动事件,主要是在 onTouch 方法中根据手指移动距离更新 WindowManager.LayoutParams 参数:
 mLlRoot.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent event) {
                switch (event.getAction()){
                    case MotionEvent.ACTION_DOWN:
                        mStartX = (int) event.getRawX();
                        mStartY = (int) event.getRawY();
                        break;
                    case MotionEvent.ACTION_MOVE:
                        mEndX = (int) event.getRawX();
                        mEndY = (int) event.getRawY();
                        //getRawX是触摸位置相对于屏幕的坐标,getX是相对于按钮的坐标
                        mLayoutParams.x = (int) event.getRawX() - mLlRoot.getMeasuredWidth() / 2;
                        mLayoutParams.y = (int) event.getRawY() - mLlRoot.getMeasuredHeight() / 2;
                        mWindowManager.updateViewLayout(mWindowView, mLayoutParams);
                        return true;


                }
                return false;
            }
        });

3.通过定时任务去获取 CPU 温度并显示出来:

 private String getCputemp(){
        String path = "/sys/class/thermal/thermal_zone0/temp";
        StringBuffer sb = new StringBuffer();
        BufferedReader br = null;
        try {
            br = new BufferedReader(new FileReader(path));
            String readline = "";

            while ((readline = br.readLine()) != null) {
                System.out.println("readline:" + readline);
                sb.append(readline);
            }
            br.close();
            Log.d("Bradley", "onCreate: "+sb.toString());

        } catch (Exception e) {
            e.printStackTrace();
        }
        return sb.toString();
    }

总结
通过本文大致了解悬浮效果背后是通过 WindowManager 来添加 view 实现的,同时对 WindowManager.LayoutParams 参数有个大致了解,后续还会继续讲解 WindowManager 相关的文章,敬请期待!


happy a nice day!

猜你喜欢

转载自blog.csdn.net/liqianwei1230/article/details/78385842