@@ -36,12 +36,9 @@ import cc.winboll.studio.libappbase.LogUtils;
public class BatteryReportActivity extends Activity {
public static final String TAG = " BatteryReportActivity " ;
// 目标应用包名常量(统一维护,数据计算核心标识)
private static final String TARGET_APP_PACKAGE = " cc.winboll.studio.mymessagemanager " ;
private RecyclerView rvBatteryReport ;
private BatteryReportAdapter adapter ;
// 数据列表:仅存储包名、耗电、时长(不存储名称,计算全程用包名)
private List < AppBatteryModel > dataList = new ArrayList < AppBatteryModel > ( ) ;
private List < AppBatteryModel > filteredList = new ArrayList < AppBatteryModel > ( ) ;
private BroadcastReceiver batteryReceiver ;
@@ -49,18 +46,14 @@ public class BatteryReportActivity extends Activity {
private float lastBatteryPercent = 100 . 0f ;
private long lastCheckTime = System . currentTimeMillis ( ) ;
private EditText etSearch ;
// 应用运行时长缓存( key: 包名, value: 时长ms)
private Map < String , Long > appRunTimeCache = new HashMap < String , Long > ( ) ;
// 新增:包名-应用名称映射缓存(用于搜索匹配名称,避免重复查询)
private Map < String , String > packageToAppNameCache = new HashMap < String , String > ( ) ;
// 包管理工具(全局持有,避免重复获取)
private PackageManager mPackageManager ;
@Override
protected void onCreate ( Bundle savedInstanceState ) {
super . onCreate ( savedInstanceState ) ;
setContentView ( R . layout . activity_batteryreport ) ;
// 初始化包管理工具(仅一次,供后续查询名称使用)
setContentView ( R . layout . activity_battery_ report ) ;
mPackageManager = getPackageManager ( ) ;
// 权限检查( Java7 传统条件判断)
@@ -74,36 +67,31 @@ public class BatteryReportActivity extends Activity {
rvBatteryReport = ( RecyclerView ) findViewById ( R . id . rv_battery_report ) ;
rvBatteryReport . setLayoutManager ( new LinearLayoutManager ( this ) ) ;
// 1. 加载所有应用(仅存包名,不查名称)
// 初始化流程: 新增“加载24小时累计耗电”步骤
loadAllAppPackage ( ) ;
// 2. 预缓存所有包名对应的应用名称(为搜索名称做准备)
preCacheAllAppNames ( ) ;
// 3. 强制添加目标应用(包名兜底)
//forceAddTargetPackage();
// 4. 首次获取运行时长( key: 包名)
appRunTimeCache = getAppRunTime ( ) ;
// 5. 更新时长到数据模型(用包名匹配)
updateAppRunTimeToModel ( ) ;
// 6. 初始化过滤列表和适配器(传入包管理工具+名称缓存)
calculateInitial24hTotalConsumption ( ) ; // 初始化时计算24小时累计耗电
filteredList . addAll ( dataList ) ;
adapter = new BatteryReportAdapter ( this , filteredList , mPackageManager , packageToAppNameCache ) ;
rvBatteryReport . setAdapter ( adapter ) ;
// 搜索监听:修改为“包名+应用名称”双匹配
// 搜索监听(不变)
etSearch . addTextChangedListener ( new TextWatcher ( ) {
@Override
public void beforeTextChanged ( CharSequence s , int start , int count , int after ) { }
@Override
public void onTextChanged ( CharSequence s , int start , int before , int count ) {
filterAppsByPackageAndName ( s . toString ( ) ) ; // 替换为新的双维度过滤方法
filterAppsByPackageAndName ( s . toString ( ) ) ;
}
@Override
public void afterTextChanged ( Editable s ) { }
} ) ;
// 电池广播(耗电计算全程用包名)
// 电池广播:调用修改后的“单次耗电计算+累计累加”方法
batteryReceiver = new BroadcastReceiver ( ) {
@Override
public void onReceive ( Context context , Intent intent ) {
@@ -112,17 +100,13 @@ public class BatteryReportActivity extends Activity {
float currentPercent = ( float ) level / scale * 100 ;
LogUtils . d ( TAG , " 电池百分比变化: " + lastBatteryPercent + " -> " + currentPercent ) ;
// 计算电池消耗并更新数据(全程用包名)
if ( currentPercent < lastBatteryPercent ) {
float dropPercent = lastBatteryPercent - currentPercent ;
long duration = System . currentTimeMillis ( ) - lastCheckTime ;
LogUtils . d ( TAG , " 电池消耗: " + dropPercent + " %,时长: " + duration + " ms " ) ;
// 重新获取最新运行时长( key: 包名)
appRunTimeCache = getAppRunTime ( ) ;
// 更新模型中的运行时长(包名匹配)
updateAppRunTimeToModel ( ) ;
// 分配耗电(包名计算)
distributeBatteryConsumption ( dropPercent , appRunTimeCache ) ;
calculateSingleConsumptionAndAccumulate ( dropPercent , appRunTimeCache ) ; // 单次+累计逻辑
}
lastBatteryPercent = currentPercent ;
@@ -142,92 +126,63 @@ public class BatteryReportActivity extends Activity {
}
/**
* 加载所有应用(仅获取包名,不查询应用名称,数据计算核心步骤 )
* 加载所有应用(仅获取包名,初始化模型时单次耗电、累计耗电均设为0 )
*/
private void loadAllAppPackage ( ) {
List < ApplicationInfo > appList = mPackageManager . getInstalledApplications ( PackageManager . GET_META_DATA ) ;
dataList . clear ( ) ; // 清空列表避免重复
dataList . clear ( ) ;
LogUtils . d ( TAG , " 开始加载应用包名列表,共找到 " + appList . size ( ) + " 个应用 " ) ;
// 仅遍历包名,不处理名称(避免名称获取异常影响)
for ( ApplicationInfo appInfo : appList ) {
String packageName = appInfo . packageName ;
// 模型仅存包名、初始耗电0、初始时长0( 名称显示/搜索时用缓存)
dataList . add ( new AppBatteryModel ( packageName , " 0.0 " , 0 ) ) ;
// 初始化: 单次耗电( consumption) =0, 累计耗电( totalConsumption) =0, 运行时长=0
dataList . add ( new AppBatteryModel ( packageName , 0 . 0f , 0 . 0f , 0 ) ) ;
}
LogUtils . d ( TAG , " 应用包名列表加载完成,共添加 " + dataList . size ( ) + " 个包名。 " ) ;
}
/**
* 新增:预缓存所有包名对应的应用名称(为搜索提供支持,避免重复查询 )
* 预缓存应用名称(逻辑不变 )
*/
private void preCacheAllAppNames ( ) {
packageToAppNameCache . clear ( ) ; // 清空旧缓存
packageToAppNameCache . clear ( ) ;
LogUtils . d ( TAG , " 开始预缓存包名-应用名称映射 " ) ;
for ( AppBatteryModel model : dataList ) {
String packageName = model . getPackageName ( ) ;
String appName = getAppNameByPackage ( packageName ) ; // 复用工具方法获取名称
packageToAppNameCache . put ( packageName , appName ) ; // 缓存映射关系
String appName = getAppNameByPackage ( packageName ) ;
packageToAppNameCache . put ( packageName , appName ) ;
}
LogUtils . d ( TAG , " 预缓存完成,共缓存 " + packageToAppNameCache . size ( ) + " 个应用名称 " ) ;
}
/**
* 工具方法: 通过包名获取应用名称(带异常处理,避免崩溃 )
* 通过包名获取应用名称(逻辑不变 )
*/
private String getAppNameByPackage ( String packageName ) {
try {
ApplicationInfo appInfo = mPackageManager . getApplicationInfo ( packageName , 0 ) ;
return mPackageManager . getApplicationLabel ( appInfo ) . toString ( ) ;
} catch ( PackageManager . NameNotFoundException e ) {
// 包名不存在(如应用已卸载),用包名兜底
LogUtils . e ( TAG , " 包名 " + packageName + " 对应的应用未找到: " + e . getMessage ( ) ) ;
return packageName ;
} catch ( Exception e ) {
// 其他异常(如权限问题),同样用包名兜底
LogUtils . e ( TAG , " 查询应用名称失败(包名: " + packageName + " ) : " + e . getMessage ( ) ) ;
return packageName ;
}
}
/**
* 强制添加目标包名(兜底逻辑,仅操作包名 )
*/
private void forceAddTargetPackage ( ) {
// 1. 先检查列表中是否已存在目标包名
boolean isTargetExists = false ;
for ( AppBatteryModel model : dataList ) {
if ( TARGET_APP_PACKAGE . equals ( model . getPackageName ( ) ) ) {
isTargetExists = true ;
break ;
}
}
if ( isTargetExists ) {
LogUtils . d ( TAG , " 目标包名已在列表中,无需重复添加 " ) ;
return ;
}
// 2. 仅用包名创建模型,强制添加(不依赖名称查询)
dataList . add ( 0 , new AppBatteryModel ( TARGET_APP_PACKAGE , " 0.0 " , 0 ) ) ;
// 同步更新名称缓存
packageToAppNameCache . put ( TARGET_APP_PACKAGE , getAppNameByPackage ( TARGET_APP_PACKAGE ) ) ;
LogUtils . d ( TAG , " 强制添加目标包名成功: " + TARGET_APP_PACKAGE ) ;
}
/**
* 更新运行时长到模型(用包名匹配,不涉及名称)
* 更新运行时长到模型(逻辑不变 )
*/
private void updateAppRunTimeToModel ( ) {
int nCount = 0 ;
for ( AppBatteryModel model : dataList ) {
String packageName = model . getPackageName ( ) ;
Long runTime ;
// Java7 显式判断包名是否在缓存中
if ( appRunTimeCache . containsKey ( packageName ) ) {
runTime = appRunTimeCache . get ( packageName ) ;
LogUtils . d ( TAG , String . format ( " 应用包 %s 运行时长已更新。 " , packageName ) ) ;
@@ -242,45 +197,94 @@ public class BatteryReportActivity extends Activity {
}
/**
* 新增:双维度过滤(包名+应用名称 )
* 搜索关键词同时匹配“包名(不区分大小写)”或“应用名称(不区分大小写)”
* 【 新增】初始化时计算24小时累计耗电( 赋值给totalConsumption )
* 逻辑: 基于24小时运行时长占比, 分配当前电池容量的理论24小时消耗
*/
private void calculateInitial24hTotalConsumption ( ) {
long total24hRunTime = 0 ;
// 1. 计算24小时内所有应用总运行时长
for ( Map . Entry < String , Long > entry : appRunTimeCache . entrySet ( ) ) {
total24hRunTime + = entry . getValue ( ) ;
}
LogUtils . d ( TAG , " 24小时内所有应用总运行时长: " + formatRunTime ( total24hRunTime ) ) ;
// 2. 按运行时长占比分配24小时累计耗电( 假设电池满电循环, 用总容量近似24小时总消耗)
for ( AppBatteryModel model : dataList ) {
String packageName = model . getPackageName ( ) ;
Long app24hRunTime = appRunTimeCache . getOrDefault ( packageName , 0L ) ;
// 计算占比与累计耗电
float ratio = ( total24hRunTime > 0 ) ? ( float ) app24hRunTime / total24hRunTime : 0 ;
float initialTotalConsumption = batteryCapacity * ratio ; // 用电池容量近似24小时总消耗
model . setTotalConsumption ( initialTotalConsumption ) ; // 初始化累计耗电
LogUtils . d ( TAG , String . format ( " 应用包 %s 24小时累计耗电初始化: %.1f mAh " , packageName , initialTotalConsumption ) ) ;
}
}
/**
* 【核心修改】计算单次耗电( 赋值给consumption) + 累加至累计耗电( totalConsumption = totalConsumption + consumption)
*/
private void calculateSingleConsumptionAndAccumulate ( float dropPercent , Map < String , Long > runTimeMap ) {
long totalSingleRunTime = 0 ;
// 1. 计算本次电池下降期间的总运行时长
for ( Map . Entry < String , Long > entry : runTimeMap . entrySet ( ) ) {
totalSingleRunTime + = entry . getValue ( ) ;
}
// 2. 遍历计算每个应用的“单次耗电”并“累加至累计”
for ( AppBatteryModel model : dataList ) {
String packageName = model . getPackageName ( ) ;
Long appSingleRunTime = runTimeMap . getOrDefault ( packageName , 0L ) ;
// 步骤1: 计算本次单次耗电( 赋值给consumption)
float ratio = ( totalSingleRunTime > 0 ) ? ( float ) appSingleRunTime / totalSingleRunTime : 0 ;
float singleConsumption = batteryCapacity * dropPercent / 100 * ratio ; // 单次消耗
model . setConsumption ( singleConsumption ) ; // 存储单次耗电
// 步骤2: 累加单次耗电到累计耗电( totalConsumption = 原有累计 + 本次单次)
float newTotalConsumption = model . getTotalConsumption ( ) + singleConsumption ;
model . setTotalConsumption ( newTotalConsumption ) ; // 更新累计耗电
// 同步运行时长
model . setRunTime ( appSingleRunTime ) ;
LogUtils . d ( TAG , String . format ( " 应用包 %s: 单次耗电%.1f mAh, 累计耗电%.1f mAh " ,
packageName , singleConsumption , newTotalConsumption ) ) ;
}
// 3. 按累计耗电排序(从高到低)
Collections . sort ( dataList , new Comparator < AppBatteryModel > ( ) {
@Override
public int compare ( AppBatteryModel m1 , AppBatteryModel m2 ) {
return Float . compare ( m2 . getTotalConsumption ( ) , m1 . getTotalConsumption ( ) ) ;
}
} ) ;
// 4. 重新应用过滤并刷新列表
filterAppsByPackageAndName ( etSearch . getText ( ) . toString ( ) ) ;
}
/**
* 双维度过滤(逻辑不变)
*/
private void filterAppsByPackageAndName ( String keyword ) {
filteredList . clear ( ) ;
if ( keyword = = null | | keyword . isEmpty ( ) ) {
filteredList . addAll ( dataList ) ;
} else {
String lowerKeyword = keyword . toLowerCase ( ) ; // 统一转为小写,实现不区分大小写搜索
boolean isTargetMatched = false ;
String lowerKeyword = keyword . toLowerCase ( ) ;
for ( AppBatteryModel model : dataList ) {
String packageName = model . getPackageName ( ) ;
String packageNameLower = packageName . toLowerCase ( ) ;
// 从缓存中获取应用名称( 避免重复查询PackageManager)
String appName = packageToAppNameCache . get ( packageName ) ;
String appNameLower = appName . toLowerCase ( ) ;
// 匹配规则:包名包含关键词 OR 应用名称包含关键词
boolean isMatched = packageNameLower . contains ( lowerKeyword )
| | appNameLower . contains ( lowerKeyword ) ;
if ( isMatched ) {
filteredList . add ( model ) ;
// 检查是否是目标包名
if ( TARGET_APP_PACKAGE . equals ( packageName ) ) {
isTargetMatched = true ;
}
}
}
// 兜底:目标包名未匹配时强制添加
if ( ! isTargetMatched ) {
for ( AppBatteryModel model : dataList ) {
if ( TARGET_APP_PACKAGE . equals ( model . getPackageName ( ) ) ) {
filteredList . add ( 0 , model ) ;
LogUtils . d ( TAG , " 搜索兜底:强制添加目标包名到结果列表 " ) ;
break ;
}
}
}
}
@@ -288,7 +292,7 @@ public class BatteryReportActivity extends Activity {
}
/**
* 获取应用运行时长(返回包名-时长映射,不处理名称 )
* 获取应用运行时长(逻辑不变, 返回24小时运行时长 )
*/
private Map < String , Long > getAppRunTime ( ) {
Map < String , Long > runTimeMap = new HashMap < String , Long > ( ) ;
@@ -301,11 +305,10 @@ public class BatteryReportActivity extends Activity {
List < android . app . usage . UsageStats > statsList = manager . queryUsageStats (
android . app . usage . UsageStatsManager . INTERVAL_DAILY , startTime , endTime ) ;
// 仅存储包名和时长(不查名称)
for ( android . app . usage . UsageStats stats : statsList ) {
long runTimeMs = stats . getTotalTimeInForeground ( ) ;
String packageName = stats . getPackageName ( ) ;
LogUtils . d ( TAG , " 包名 " + packageName + " 运行时长: " + formatRunTime ( runTimeMs ) ) ;
LogUtils . d ( TAG , " 包名 " + packageName + " 24小时 运行时长:" + formatRunTime ( runTimeMs ) ) ;
runTimeMap . put ( packageName , runTimeMs ) ;
if ( packageName . equals ( " aidepro.top " ) ) {
LogUtils . d ( TAG , String . format ( " runTimeMap.put(packageName, runTimeMs) 特殊查询 %s 查询有结果。 " , packageName ) ) ;
@@ -321,7 +324,7 @@ public class BatteryReportActivity extends Activity {
}
/**
* 格式化运行时长(工具方法,与包名无关 )
* 格式化运行时长(逻辑不变 )
*/
private String formatRunTime ( long runTimeMs ) {
if ( runTimeMs < = 0 ) {
@@ -342,48 +345,7 @@ public class BatteryReportActivity extends Activity {
}
/**
* 分配电池消耗(全程用包名计算,不涉及名称 )
*/
private void distributeBatteryConsumption ( float totalDropPercent , Map < String , Long > runTimeMap ) {
long totalRunTime = 0 ;
// 遍历包名计算总时长
for ( Map . Entry < String , Long > entry : runTimeMap . entrySet ( ) ) {
totalRunTime + = entry . getValue ( ) ;
}
// 按包名匹配计算各应用耗电
for ( AppBatteryModel model : dataList ) {
String packageName = model . getPackageName ( ) ;
Long appRunTime ;
// Java7 显式判断包名是否存在
if ( runTimeMap . containsKey ( packageName ) ) {
appRunTime = runTimeMap . get ( packageName ) ;
} else {
appRunTime = 0L ;
}
float ratio = ( totalRunTime > 0 ) ? ( float ) appRunTime / totalRunTime : 0 ;
float consumption = batteryCapacity * totalDropPercent / 100 * ratio ;
model . setConsumption ( String . format ( " %.1f " , consumption ) ) ;
model . setRunTime ( appRunTime ) ; // 同步更新时长
}
// 按耗电排序(用包名对应的耗电值排序)
Collections . sort ( dataList , new Comparator < AppBatteryModel > ( ) {
@Override
public int compare ( AppBatteryModel m1 , AppBatteryModel m2 ) {
float c1 = Float . parseFloat ( m1 . getConsumption ( ) ) ;
float c2 = Float . parseFloat ( m2 . getConsumption ( ) ) ;
return Float . compare ( c2 , c1 ) ; // 逆序(耗电从高到低)
}
} ) ;
// 重新应用“包名+名称”双维度过滤
filterAppsByPackageAndName ( etSearch . getText ( ) . toString ( ) ) ;
}
/**
* 权限检查(仅操作系统服务,与包名无关)
* 权限检查(逻辑不变 )
*/
private boolean hasUsageStatsPermission ( Context context ) {
if ( Build . VERSION . SDK_INT < Build . VERSION_CODES . LOLLIPOP ) {
@@ -405,31 +367,43 @@ public class BatteryReportActivity extends Activity {
}
/**
* 数据模型(仅存储包名、耗电、时长,不存名称)
* 【核心修改】数据模型:明确字段含义
* - consumption: 单次耗电( 两次电池广播间的消耗, float类型便于计算)
* - totalConsumption: 累计耗电( 24小时初始化值+后续单次累加,显示用)
*/
public static class AppBatteryModel {
private String packageName ; // 核心标识: 应用包名
private String consumption ; // 电量消耗( mAh )
private String packageName ; // 应用包名(核心标识)
private float consumption ; // 单次耗电( mAh, float类型 )
private float totalConsumption ; // 累计耗电( mAh, 显示+排序用)
private long runTime ; // 运行时长( ms)
// Java7 显式构造(仅传入包名、初始耗电、初始时长)
public AppBatteryModel ( String packageName , String c onsumption, long runTime ) {
// Java7 显式构造: 初始化单次耗电、累计耗电为0
public AppBatteryModel ( String packageName , float consumption , float totalC onsumption, long runTime ) {
this . packageName = packageName ;
this . consumption = consumption ;
this . consumption = consumption ; // 单次耗电初始为0
this . totalConsumption = totalConsumption ; // 累计耗电初始为0( 后续初始化时赋值)
this . runTime = runTime ;
}
// Getter/Setter(仅操作包名、耗电、时长)
// Getter/Setter:覆盖所有字段,确保数据操作正常
public String getPackageName ( ) {
return packageName ;
}
public String getConsumption ( ) {
return consumption ;
public float getConsumption ( ) {
return consumption ; // 获取单次耗电
}
public void setConsumption ( String consumption ) {
this . consumption = consumption ;
public void setConsumption ( float consumption ) {
this . consumption = consumption ; // 设置单次耗电
}
public float getTotalConsumption ( ) {
return totalConsumption ; // 获取累计耗电(显示用)
}
public void setTotalConsumption ( float totalConsumption ) {
this . totalConsumption = totalConsumption ; // 设置累计耗电(初始化/累加用)
}
public long getRunTime ( ) {
@@ -442,37 +416,37 @@ public class BatteryReportActivity extends Activity {
}
/**
* RecyclerView 适配器(支持从缓存获取名称,避免重复查询)
* RecyclerView 适配器: 仅显示累计耗电( totalConsumption) , 逻辑适配模型修改
*/
public static class BatteryReportAdapter extends RecyclerView . Adapter < BatteryReportAdapter . ViewHolder > {
private Context mContext ;
private List < AppBatteryModel > mDataList ;
private PackageManager mPm ; // 兜底用:缓存无名称时查询
private Map < String , String > mPackageToNameCache ; // 新增:名称缓存映射
private PackageManager mPm ;
private Map < String , String > mPackageToNameCache ;
// Java7 显式构造(新增 名称缓存参数)
// Java7 显式构造:接收 名称缓存,确保显示时高效获取应用名
public BatteryReportAdapter ( Context context , List < AppBatteryModel > dataList ,
PackageManager pm , Map < String , String > packageToNameCache ) {
this . mContext = context ;
this . mDataList = dataList ;
this . mPm = pm ;
this . mPackageToNameCache = packageToNameCache ; // 接收名称缓存
this . mPackageToNameCache = packageToNameCache ;
}
@Override
public ViewHolder onCreateViewHolder ( ViewGroup parent , int viewType ) {
// 加载系统列表项布局( text1显示应用名, text2显示累计耗电+时长)
View itemView = LayoutInflater . from ( mContext )
. inflate ( android . R . layout . simple_list_item_2 , parent , false ) ;
return new ViewHolder ( itemView ) ;
}
// 绑定数据:优先从缓存取名称,无缓存时兜底查询
@Override
public void onBindViewHolder ( ViewHolder holder , int position ) {
// Java7 显式非空判断( 避免空指针)
// Java7 显式非空判断: 避免空指针异常
if ( mDataList = = null | | mDataList . isEmpty ( ) | | position > = mDataList . size ( ) ) {
holder . tvAppName . setText ( " 未知应用 " ) ;
holder . tvConsumption . setText ( " 耗电: 0.0 mAh | 运行时长: 0秒 " ) ;
holder . tvConsumption . setText ( " 累计 耗电: 0.0 mAh | 运行时长: 0秒" ) ;
return ;
}
@@ -480,66 +454,59 @@ public class BatteryReportActivity extends Activity {
String packageName = model . getPackageName ( ) ;
String appName = " " ;
// 优先从缓存获取名称(避免重复调用 PackageManager, 提升性能)
// 优先从缓存获取应用名:减少 PackageManager调用 ,提升性能
if ( mPackageToNameCache ! = null & & mPackageToNameCache . containsKey ( packageName ) ) {
appName = mPackageToNameCache . get ( packageName ) ;
} else {
// 缓存无数据时, 兜底查询名称(兼容异常场景)
// 缓存无数据时兜底查询,并同步更新缓存
try {
ApplicationInfo appInfo = mPm . getApplicationInfo ( packageName , 0 ) ;
appName = mPm . getApplicationLabel ( appInfo ) . toString ( ) ;
// 同步更新到缓存,后续复用
if ( mPackageToNameCache ! = null ) {
mPackageToNameCache . put ( packageName , appName ) ;
}
} catch ( PackageManager . NameNotFoundException e ) {
appName = packageName ;
appName = packageName ; // 包名不存在时用包名兜底
LogUtils . e ( " Adapter " , " 包名 " + packageName + " 对应的应用未找到: " + e . getMessage ( ) ) ;
} catch ( Exception e ) {
appName = packageName ;
appName = packageName ; // 其他异常时用包名兜底
LogUtils . e ( " Adapter " , " 查询应用名称失败(包名: " + packageName + " ) : " + e . getMessage ( ) ) ;
}
}
// 显示应用名称(缓存/兜底结果)
// 显示逻辑: 仅展示累计耗电( totalConsumption) , 隐藏单次耗电
holder . tvAppName . setText ( appName ) ;
// 格式化运行时长(调用 Activity 的工具方法)
// 格式化运行时长 + 累计耗电( 保留1位小数, 提升可读性)
String runTimeStr = ( ( BatteryReportActivity ) mContext ) . formatRunTime ( model . getRunTime ( ) ) ;
// 显示耗电+运行时长(基于包名计算的结果)
String consumptionText = String . format ( " 耗电:%s mAh | 运行时长:%s " ,
mo del . ge tConsumption( ) , runTimeStr ) ;
holder . tvConsumption . setText ( consumptionText ) ;
String totalConsumptionText = String . format ( " 累计耗电:%.1f mAh | 运行时长:%s " ,
model . getTotalConsumption ( ) , runTimeStr ) ;
hol der . tv Consumption . setText ( totalConsumptionText ) ;
// 优化显示:目标应用文字标蓝(通过包名匹配 )
if ( BatteryReportActivity . TARGET_APP_PACKAGE . equals ( packageName ) ) {
holder . tvAppName . setTextColor ( mContext . getResources ( ) . getColor ( android . R . color . holo_blue_dark ) ) ;
holder . tvConsumption . setTextColor ( mContext . getResources ( ) . getColor ( android . R . color . holo_blue_dark ) ) ;
} else {
// 显示优化:文字颜色区分(避免所有应用均标蓝,仅示例可按需修改 )
holder . tvAppName . setTextColor ( mContext . getResources ( ) . getColor ( android . R . color . black ) ) ;
holder . tvConsumption . setTextColor ( mContext . getResources ( ) . getColor ( android . R . color . darker_gray ) ) ;
}
// 调整文字大小( 提升可读性)
// 调整文字大小:适配手机屏幕, 提升可读性
holder . tvAppName . setTextSize ( 16 ) ;
holder . tvConsumption . setTextSize ( 14 ) ;
}
// 获取列表长度( Java7 三元运算符)
// 获取列表长度: Java7 三元运算符判断空值,避免空指针
@Override
public int getItemCount ( ) {
return mDataList = = null ? 0 : mDataList . size ( ) ;
}
// ViewHolder( 绑定系统布局的两个 TextView)
/**
* ViewHolder: 绑定系统布局控件, 与显示逻辑对应
*/
public static class ViewHolder extends RecyclerView . ViewHolder {
TextView tvAppName ; // 显示应用名称(缓存/兜底获取)
TextView tvConsumption ; // 显示耗电+运行时长(包名计算结果)
TextView tvAppName ; // 显示应用名称
TextView tvConsumption ; // 显示累计耗电 + 运行时长
// Java7 显式构造
// Java7 显式构造: 绑定控件ID( 系统布局固定ID: text1、text2)
public ViewHolder ( View itemView ) {
super ( itemView ) ;
// 强制类型转换(系统布局控件 ID: text1 和 text2)
tvAppName = ( TextView ) itemView . findViewById ( android . R . id . text1 ) ;
tvConsumption = ( TextView ) itemView . findViewById ( android . R . id . text2 ) ;
}