博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android 8.0— 02 电池的耗电详情-模拟耗电数据 getFakeStats
阅读量:4147 次
发布时间:2019-05-25

本文共 8126 字,大约阅读时间需要 27 分钟。

1.PowerUsageSummary.getFakeStats()

Google的函数调试,实际用途不大,但是适合修改UI和算法,毕竟总不能静静等耗电数据产生吧。

故这里提供了非常好的模拟数据和方法,进行调试耗电详情列表

模拟数据

1.1 开启调试开关

Z:\8.1\vendor\mediatek\proprietary\packages\apps\MtkSettings\src\com\android\settings\fuelgauge\PowerUsageSummary.java

/** * Displays a list of apps and subsystems that consume power, ordered by how much power was * consumed since the last time it was unplugged. */public class PowerUsageSummary extends PowerUsageBase implements        AnomalyDialogListener, OnLongClickListener, OnClickListener {
private static final boolean USE_FAKE_DATA = true; private static final int MAX_ITEMS_TO_LIST = USE_FAKE_DATA ? 30 : 10;

1.2 耗电详情类型

// frameworks/base/core/java/com/android/internal/os/BatterySipper.javaimport com.android.internal.os.BatterySipper;import com.android.internal.os.BatterySipper.DrainType;    public enum DrainType {        IDLE,        CELL,        PHONE,        WIFI,        BLUETOOTH,        FLASHLIGHT,        SCREEN,        APP,        USER,        UNACCOUNTED,        OVERCOUNTED,        CAMERA,        MEMORY    }

1.3 制造模拟耗电数据

PowerUsageSummary->getFakeStats() 主要进行 DrainType 中的所有类型的模拟数据填充

private static List
getFakeStats() { ArrayList
stats = new ArrayList<>(); // 耗电量 单位是 mA float use = 5; // 遍历耗电类型,除了APP类型,其他类型数据填充模拟数据 use for (DrainType type : DrainType.values()) { // 应用类型的耗电数据 if (type == DrainType.APP) { // 过滤掉 continue; } // 接口名称 BatterySipper(DrainType drainType, Uid uid, double value) /** 05-30 12:27:56.464 1295 1295 D fadi: type = IDLE, use = 5.0 mA 05-30 12:27:56.464 1295 1295 D fadi: type = CELL, use = 10.0 mA 05-30 12:27:56.464 1295 1295 D fadi: type = PHONE, use = 15.0 mA 05-30 12:27:56.464 1295 1295 D fadi: type = WIFI, use = 20.0 mA 05-30 12:27:56.464 1295 1295 D fadi: type = BLUETOOTH, use = 25.0 mA 05-30 12:27:56.464 1295 1295 D fadi: type = FLASHLIGHT, use = 30.0 mA 05-30 12:27:56.465 1295 1295 D fadi: type = SCREEN, use = 35.0 mA 05-30 12:27:56.465 1295 1295 D fadi: type = USER, use = 40.0 mA 05-30 12:27:56.465 1295 1295 D fadi: type = UNACCOUNTED, use = 45.0 mA 05-30 12:27:56.465 1295 1295 D fadi: type = OVERCOUNTED, use = 50.0 mA 05-30 12:27:56.465 1295 1295 D fadi: type = CAMERA, use = 55.0 mA 05-30 12:27:56.465 1295 1295 D fadi: type = MEMORY, use = 60.0 mA */ stats.add(new BatterySipper(type, null, use)); use += 5; } // 将 UID为 10000 ~ 10099 的应用,填写上模拟耗电数据数据 for (int i = 0; i < 100; i++) { // 具体UID 对应的应用可以使用命令导出查看 adb pull /data/system/packages.xml D:// /** * 05-30 12:48:54.623 1297 1297 D fadi : DrainType.APP UID = 10000, use = 65.0 mA 05-30 12:48:54.624 1297 1297 D fadi : DrainType.APP UID = 10001, use = 65.0 mA 05-30 12:48:54.625 1297 1297 D fadi : DrainType.APP UID = 10002, use = 65.0 mA ... ... 05-30 12:48:54.649 1297 1297 D fadi : DrainType.APP UID = 10097, use = 65.0 mA 05-30 12:48:54.649 1297 1297 D fadi : DrainType.APP UID = 10098, use = 65.0 mA 05-30 12:48:54.649 1297 1297 D fadi : DrainType.APP UID = 10099, use = 65.0 mA */ stats.add(new BatterySipper(DrainType.APP, new FakeUid(Process.FIRST_APPLICATION_UID + i), use)); } // 事实上没有 uid 为 0 的进程,可作为防错检测 // stats.add(new BatterySipper(DrainType.APP,new FakeUid(0), use)); // 模拟odex进程的耗电数据 Simulate dex2oat process. // // 模拟UID 10000 的耗电数据 // android.auto_generated_rro__ 10000 0 /data/user/0/android.auto_generated_rro__ platform:targetSdkVersion=27 none BatterySipper sipper = new BatterySipper(DrainType.APP, new FakeUid(UserHandle.getSharedAppGid(Process.FIRST_APPLICATION_UID)), 10.0f); sipper.packageWithHighestDrain = "dex2oat"; stats.add(sipper); // 模拟UID 10001 的耗电数据 // com.android.systemui.theme.dark 10001 1 /data/user/0/com.android.systemui.theme.dark platform:targetSdkVersion=27 none sipper = new BatterySipper(DrainType.APP, new FakeUid(UserHandle.getSharedAppGid(Process.FIRST_APPLICATION_UID + 1)), 10.0f); sipper.packageWithHighestDrain = "dex2oat"; stats.add(sipper); // 模拟日志进程的耗电数据 sipper = new BatterySipper(DrainType.APP, new FakeUid(UserHandle.getSharedAppGid(Process.LOG_UID)), 9.0f); stats.add(sipper); return stats; }

1.4 显示耗电数据

PowerUsageSummary->refreshAppListGroup()

具体如下

private void refreshAppListGroup() {        final Context context = getContext();        // 获取电量校准文件        final PowerProfile powerProfile = mStatsHelper.getPowerProfile();        // 电量相关数据,我们也可以使用 adb shell dumpsys batterystats > batterystats.txt 导出        final BatteryStats stats = mStatsHelper.getStats();        // 屏幕最高亮度平均电流        final double averagePower = powerProfile.getAveragePower(PowerProfile.POWER_SCREEN_FULL);        boolean addedSome = false;        // frameworks/base/core/res/res/values/attrs.xml:1095:        
// TypedArray是存储资源数组的容器 TypedArray array = context.obtainStyledAttributes( new int[]{android.R.attr.colorControlNormal}); final int colorControl = array.getColor(0, 0); Log.d("fadi", "colorControl = " + colorControl); // 使用完后释放 array.recycle(); // dichargeaAmount 相当于 usb 拔掉后这段时间的电量 final int dischargeAmount = USE_FAKE_DATA ? 5000 : stats != null ? stats.getDischargeAmount(mStatsType) : 0; cacheRemoveAllPrefs(mAppListGroup); // 被add进来的时候是否排序 mAppListGroup.setOrderingAsAdded(false); Log.d("fadi", "averagePower = " + averagePower); if (averagePower >= MIN_AVERAGE_POWER_THRESHOLD_MILLI_AMP || USE_FAKE_DATA) { final List
usageList = getCoalescedUsageList( USE_FAKE_DATA ? getFakeStats() : mStatsHelper.getUsageList()); double hiddenPowerMah = mShowAllApps ? 0 /**完整设备用电量*/: mBatteryUtils.removeHiddenBatterySippers(usageList)/**显示应用使用情况*/; // 排序,耗电量从高到低 mBatteryUtils.sortUsageList(usageList); final int numSippers = usageList.size(); for (int i = 0; i < numSippers; i++) { final BatterySipper sipper = usageList.get(i); double totalPower = USE_FAKE_DATA ? 4000 : mStatsHelper.getTotalPower(); // 耗电量百分比换算 final double percentOfTotal = mBatteryUtils.calculateBatteryPercent( sipper.totalPowerMah/**该类型耗电量大小*/, totalPower/**总负载耗电量*/, hiddenPowerMah, dischargeAmount/**usb 拔掉后这段时间的电量*/); ... 主要是应用信息获取形成 list

1.5 耗电百分百换算

package com.android.settings.fuelgauge;/** * Utils for battery operation */public class BatteryUtils {
/** * Calculate the power usage percentage for an app * * @param powerUsageMah power used by the app * @param totalPowerMah total power used in the system * @param hiddenPowerMah power used by no-actionable app that we want to hide, i.e. Screen, * Android OS. * @param dischargeAmount The discharge amount calculated by {@link BatteryStats} * @return A percentage value scaled by {@paramref dischargeAmount} * @see BatteryStats#getDischargeAmount(int) */ public double calculateBatteryPercent(double powerUsageMah, double totalPowerMah, double hiddenPowerMah, int dischargeAmount) { if (totalPowerMah == 0) { return 0; } // return (powerUsageMah / (totalPowerMah - hiddenPowerMah)) * dischargeAmount; }

1.6 结语

我们可以通过 getFakeStats() 函数进行模拟数据的修改和调试,快速看到功耗结果。

其中模拟数据 BatterySipper(DrainType drainType, Uid uid, double value),的三个参数,耗电类型,耗电应用UID,和耗电量构成了耗电列表的主要参数。

你可能感兴趣的文章
C++学习路线
查看>>
私有构造函数
查看>>
组队总结
查看>>
TitledBorder 设置JPanel边框
查看>>
DBCP——开源组件 的使用
查看>>
抓包工具
查看>>
海量数据相似度计算之simhash和海明距离
查看>>
DeepLearning tutorial(5)CNN卷积神经网络应用于人脸识别(详细流程+代码实现)
查看>>
DeepLearning tutorial(6)易用的深度学习框架Keras简介
查看>>
DeepLearning tutorial(7)深度学习框架Keras的使用-进阶
查看>>
流形学习-高维数据的降维与可视化
查看>>
Python-OpenCV人脸检测(代码)
查看>>
python+opencv之视频人脸识别
查看>>
人脸识别(OpenCV+Python)
查看>>
6个强大的AngularJS扩展应用
查看>>
网站用户登录系统设计——jsGen实现版
查看>>
第三方SDK:讯飞语音听写
查看>>
第三方SDK:JPush SDK Eclipse
查看>>
第三方开源库:imageLoader的使用
查看>>
自定义控件:飞入飞出的效果
查看>>