您的位置:首页 > 移动开发 > Android开发

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

2017-10-29 15:45 573 查看
前文概要

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

本文开始进入下一个篇章,主要是和 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;


对小球增加拖动事件,主要是在 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!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: