当前位置: 首页 > news >正文

Android平台如何获取CPU占用率和电池电量信息

技术背景

我们在做Android平台GB28181设备接入模块、轻量级RTSP服务模块和RTMP推流模块的时候,遇到这样的技术诉求,开发者希望把实时CPU占用、电池信息等叠加在视频界面。

获取CPU占用率

Android平台获取CPU占用情况,可以读取/proc/stat文件,解析出各个 CPU 时间参数,然后计算出 CPU 的使用率,示例代码如下:

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Process;
import android.util.Log;import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;public class MainActivity extends Activity {private Handler handler = new Handler(Looper.getMainLooper());private Runnable runnable;private long prevTotalCpuTime = 0;private long prevIdleCpuTime = 0;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);runnable = new Runnable() {@Overridepublic void run() {try {// 读取 /proc/stat 文件获取 CPU 时间信息BufferedReader reader = new BufferedReader(new FileReader("/proc/stat"));String line = reader.readLine();reader.close();String[] tokens = line.split("\\s+");long user = Long.parseLong(tokens[2]);long nice = Long.parseLong(tokens[3]);long system = Long.parseLong(tokens[4]);long idle = Long.parseLong(tokens[5]);long iowait = Long.parseLong(tokens[6]);long irq = Long.parseLong(tokens[7]);long softirq = Long.parseLong(tokens[8]);long totalCpuTime = user + nice + system + idle + iowait + irq + softirq;long idleCpuTime = idle;// 计算 CPU 使用率if (prevTotalCpuTime!= 0 && prevIdleCpuTime!= 0) {long diffTotalCpuTime = totalCpuTime - prevTotalCpuTime;long diffIdleCpuTime = idleCpuTime - prevIdleCpuTime;float cpuUsage = ((diffTotalCpuTime - diffIdleCpuTime) / (float) diffTotalCpuTime) * 100;Log.d("CPU_USAGE", "CPU Usage: " + cpuUsage + "%");}prevTotalCpuTime = totalCpuTime;prevIdleCpuTime = idleCpuTime;} catch (IOException e) {e.printStackTrace();}// 延迟一段时间后再次执行handler.postDelayed(this, 1000);}};// 启动获取 CPU 使用率的任务handler.post(runnable);}@Overrideprotected void onDestroy() {super.onDestroy();// 停止任务handler.removeCallbacks(runnable);}
}

使用BatteryManager类获取电池电量

在 Android 中,可以使用BatteryManager类来获取电池电量信息。以下是具体步骤:

一、注册广播接收器

在你的 Android 组件(如 Activity 或 Service)中注册一个广播接收器来监听电池状态变化的广播。可以在onCreate方法中进行注册。

IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
registerReceiver(batteryReceiver, filter);

这里创建了一个IntentFilter来指定要监听的广播为电池状态变化广播(Intent.ACTION_BATTERY_CHANGED),然后使用registerReceiver方法注册广播接收器。

二、创建广播接收器

创建一个广播接收器类来处理电池状态变化的广播,如下所示:

private BroadcastReceiver batteryReceiver = new BroadcastReceiver() {@Overridepublic void onReceive(Context context, Intent intent) {int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);int batteryPercentage = (level / (float)scale) * 100;// 这里可以根据获取到的电池电量信息进行相应的处理}
};

在广播接收器的onReceive方法中,可以从广播意图中获取电池电量的级别(BatteryManager.EXTRA_LEVEL)和总刻度(BatteryManager.EXTRA_SCALE),然后计算出电池电量的百分比。

三、取消注册广播接收器

在适当的时候,如组件的onDestroy方法中,取消注册广播接收器,以避免资源泄漏:

unregisterReceiver(batteryReceiver);

这样,当电池状态发生变化时,你的广播接收器将会收到通知,并可以获取到电池电量信息进行相应的处理。

需要注意的是,获取电池电量信息可能需要相应的权限。在 AndroidManifest.xml 文件中添加以下权限声明:

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

场景应用

以大牛直播SDK的GB28181设备接入模块为例,摄像头实时视频采集,可以叠加上实时CPU占用和实时电量信息,亦或实时时间信息,会对场景带来很大益处,比如CPU占用率或电量信息,简单来说可以通过bitmap把文字读取下来,投递到底层比如jni层即可,非常方便。下面就文字和图片水印做个简短的技术普及。

文字水印

文字水印不再赘述,主要注意的是文字的大小、颜色、位置。

private int postText1Layer(int index, int left, int top) {Bitmap text_bitmap = makeTextBitmap("文本水印一", getFontSize()+8,Color.argb(255, 200, 250, 0),false, 0,false);if (null == text_bitmap)return 0;ByteBuffer buffer = ByteBuffer.allocateDirect(text_bitmap.getByteCount());text_bitmap.copyPixelsToBuffer(buffer);libPublisher.PostLayerImageRGBA8888ByteBuffer(handle_, index, left, top, buffer, 0,text_bitmap.getRowBytes(), text_bitmap.getWidth(), text_bitmap.getHeight(),0, 0, 0, 0, 0,0);int ret = text_bitmap.getHeight();text_bitmap.recycle();return ret;
}

png水印

png水印,除了常规的位置需要注意之外,还涉及到logo水印的大小问题,为此,我们添加了缩放效果,可以缩放后,再贴到图层,确保以更合适的比例展示在图层期望位置。

private int postPictureLayer(int index, int left, int top) {Bitmap bitmap = getAssetsBitmap();if (null == bitmap) {Log.e(TAG, "postPitcureLayer getAssetsBitmap is null");return 0;}if (bitmap.getConfig() != Bitmap.Config.ARGB_8888) {Log.e(TAG, "postPitcureLayer config is not ARGB_8888, config:" + Bitmap.Config.ARGB_8888);return 0;}ByteBuffer buffer = ByteBuffer.allocateDirect(bitmap.getByteCount());bitmap.copyPixelsToBuffer(buffer);final int w = bitmap.getWidth();final int h = bitmap.getHeight();if ( w < 2 || h < 2 )return 0;int scale_w = 0, scale_h = 0, scale_filter_mode = 0;final float r_w = width_ - left; // 有可能负数final float r_h = height_ - top; // 有可能负数if (w > r_w || h > r_h) {float s_w = w;float s_h = h;// 0.85的10次方是0.19687, 缩放到0.2倍差不多了for ( int i = 0; i < 10; ++i)  {s_w *= 0.85f;s_h *= 0.85f;if (s_w < r_w && s_h < r_h )break;}if (s_w > r_w || s_h > r_h)return 0;// 如果小于16就算了,太小看也看不见if (s_w < 16.0f || s_h < 16.0f)return  0;scale_w = align((int)(s_w + 0.5f), 2);scale_h = align( (int)(s_h + 0.5f), 2);scale_filter_mode = 3;}/*if ( scale_w > 0 && scale_h > 0)Log.i(TAG, "postTextLayer scale_w:" + scale_w + ", scale_h:" + scale_h + " w:" + w + ", h:" + h) ; */libPublisher.PostLayerImageRGBA8888ByteBuffer(handle_, index, left, top, buffer, 0, bitmap.getRowBytes(), w, h,0, 0, scale_w, scale_h, scale_filter_mode,0);int ret = scale_h > 0 ? scale_h : bitmap.getHeight();bitmap.recycle();return ret;
}

http://www.mrgr.cn/news/38703.html

相关文章:

  • C语言课程设计题目六:学生信息管理系统设计
  • 【分布式微服务云原生】10分钟打造坚不可摧的系统:深入探索系统的鲁棒性
  • 树莓派外挂Camera(基操)(TODO)
  • 全功能运营级开源跨境电商平台源码 —— 多语言全球化商城解决方案
  • systemd-analyze命令:Linux系统启动分析
  • Python库matplotlib之二
  • 【C++篇】启航——初识C++(上篇)
  • 设计模式之组合模式
  • Tomcat安装和配置教程(图文详解,最简洁易懂)
  • AI运用在营销领域的经典案例及解析
  • 深度学习反向传播-过程举例
  • 【网络安全】公钥基础设施
  • timedatectl命令:告别时间烦恼,一键同步系统时间
  • 第三节-类与对象(中)
  • 进制转换 总结
  • 深入理解 `strncat()` 函数:安全拼接字符串
  • 数据资产新范式,URP城市焕新平台东博会首发!
  • GB28181信令交互流程及Android端设备对接探讨
  • Linux 学习笔记(十六)—— 重定向与缓冲区
  • Java 注解的使用范围ElementType