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!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于 Android 悬浮实现,可以使用 WindowManager实现。但是在实现过程中,可能会遇到 WindowManager 无法传递事件的问题。 这个问题的原因可能是因为 WindowManager 的类型不正确。在创建 WindowManager 的时候,需要指定正确的类型,例如 TYPE_APPLICATION_OVERLAY 类型。 下面是一个基本的悬浮实现示例: ```java public class FloatingWindowService extends Service { private WindowManager mWindowManager; private View mFloatingView; public FloatingWindowService() { } @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); // 创建一个 WindowManager mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE); // 创建一个悬浮 View mFloatingView = LayoutInflater.from(this).inflate(R.layout.floating_window, null); // 设置悬浮的类型为 TYPE_APPLICATION_OVERLAY WindowManager.LayoutParams params = new WindowManager.LayoutParams( WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT, Build.VERSION.SDK_INT >= Build.VERSION_CODES.O ? WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY : WindowManager.LayoutParams.TYPE_PHONE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT); // 将悬浮添加到 WindowManager 中 mWindowManager.addView(mFloatingView, params); } @Override public void onDestroy() { super.onDestroy(); if (mFloatingView != null) { // 从 WindowManager 中移除悬浮 mWindowManager.removeView(mFloatingView); } } } ``` 在这个示例中,我们通过创建一个 WindowManager,并将悬浮 View 添加到 WindowManager 中来实现悬浮。同时,我们还需要设置悬浮的类型为 TYPE_APPLICATION_OVERLAY 类型,以确保能够正常接收事件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值