电池详情获取应用运行时间

1. 电池用量时间一直为0

电池

2. 源码跟踪

2.1 字符串位置
    <string name="battery_detail_foreground" msgid="3350401514602032183">"在前台运行时"</string>
    <string name="battery_detail_background" msgid="1929644393553768999">"在后台运行时"</string>
2.2 布局文件

power_usage_detail.xml

    <PreferenceCategory
        android:title="@string/battery_detail_info_title">

        <Preference
            // 前台进程运行
            android:key="app_usage_foreground"
            android:title="@string/battery_detail_foreground"
            android:selectable="false"/>

        <Preference
            // 后台进程运行
            android:key="app_usage_background"
            android:title="@string/battery_detail_background"
            android:selectable="false"/>

        <Preference
            // 电池耗电量
            android:key="app_power_usage"
            android:title="@string/battery_detail_power_usage"
            android:selectable="false"/>

    </PreferenceCategory>
2.3 控件定义
package com.android.settings.fuelgauge;

/**
 * Power usage detail fragment for each app, this fragment contains
 *
 * 1. Detail battery usage information for app(i.e. usage time, usage amount)
 * 2. Battery related controls for app(i.e uninstall, force stop)
 */
public class AdvancedPowerUsageDetail extends DashboardFragment implements
        ButtonActionDialogFragment.AppButtonsDialogListener,
        AnomalyDialogFragment.AnomalyDialogListener,
        LoaderManager.LoaderCallbacks<List<Anomaly>> {
        
    private static final String KEY_PREF_FOREGROUND = "app_usage_foreground";
    private static final String KEY_PREF_BACKGROUND = "app_usage_background";
    private static final String KEY_PREF_POWER_USAGE = "app_power_usage";
    
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        mForegroundPreference = findPreference(KEY_PREF_FOREGROUND);
        mBackgroundPreference = findPreference(KEY_PREF_BACKGROUND);
        mPowerUsagePreference = findPreference(KEY_PREF_POWER_USAGE);
2.4 控件赋值
    @VisibleForTesting
    void initPreference() {
        final Bundle bundle = getArguments();
        final Context context = getContext();

        final long foregroundTimeMs = bundle.getLong(EXTRA_FOREGROUND_TIME);
        final long backgroundTimeMs = bundle.getLong(EXTRA_BACKGROUND_TIME);
        final String usagePercent = bundle.getString(EXTRA_POWER_USAGE_PERCENT);
        final int powerMah = bundle.getInt(EXTRA_POWER_USAGE_AMOUNT);
        mForegroundPreference.setSummary(
                TextUtils.expandTemplate(getText(R.string.battery_used_for),
                        Utils.formatElapsedTime(context, foregroundTimeMs, false)));
        mBackgroundPreference.setSummary(
                TextUtils.expandTemplate(getText(R.string.battery_active_for),
                        Utils.formatElapsedTime(context, backgroundTimeMs, false)));
        mPowerUsagePreference.setSummary(
                getString(R.string.battery_detail_power_percentage, usagePercent, powerMah));
    }
2.5 运行时间获取 startBatteryDetailPage.args.putLong
package com.android.settings.fuelgauge;

/**
 * Power usage detail fragment for each app, this fragment contains
 *
 * 1. Detail battery usage information for app(i.e. usage time, usage amount)
 * 2. Battery related controls for app(i.e uninstall, force stop)
 */
public class AdvancedPowerUsageDetail extends DashboardFragment implements
        ButtonActionDialogFragment.AppButtonsDialogListener,
        AnomalyDialogFragment.AnomalyDialogListener,
        LoaderManager.LoaderCallbacks<List<Anomaly>> {
        
    @VisibleForTesting
    static void startBatteryDetailPage(SettingsActivity caller, BatteryUtils batteryUtils,
            PreferenceFragment fragment, BatteryStatsHelper helper, int which, BatteryEntry entry,
            String usagePercent, List<Anomaly> anomalies) {
        
        ......
        final Bundle args = new Bundle();
        final BatterySipper sipper = entry.sipper;
        final BatteryStats.Uid uid = sipper.uidObj;
        final boolean isTypeApp = sipper.drainType == BatterySipper.DrainType.APP;

        final long foregroundTimeMs = isTypeApp ? batteryUtils.getProcessTimeMs(
                BatteryUtils.StatusType.FOREGROUND, uid, which) : sipper.usageTimeMs;
        final long backgroundTimeMs = isTypeApp ? batteryUtils.getProcessTimeMs(
                BatteryUtils.StatusType.BACKGROUND, uid, which) : 0;
        ......
        
        args.putInt(EXTRA_UID, sipper.getUid());
        args.putLong(EXTRA_BACKGROUND_TIME, backgroundTimeMs);
        args.putLong(EXTRA_FOREGROUND_TIME, foregroundTimeMs);
        args.putString(EXTRA_POWER_USAGE_PERCENT, usagePercent);
        args.putInt(EXTRA_POWER_USAGE_AMOUNT, (int) sipper.totalPowerMah);
        args.putParcelableList(EXTRA_ANOMALY_LIST, anomalies);
2.6 运行时间获取 batteryUtils.getProcessTimeMs
package com.android.settings.fuelgauge;

/**
 * Utils for battery operation
 */
public class BatteryUtils {

    public long getProcessTimeMs(@StatusType int type, @Nullable BatteryStats.Uid uid,
            int which) {
        if (uid == null) {
            return 0;
        }

        switch (type) {
            case StatusType.SCREEN_USAGE:
                return getScreenUsageTimeMs(uid, which);
            case StatusType.FOREGROUND:
                return getProcessForegroundTimeMs(uid, which);
            case StatusType.BACKGROUND:
                return getProcessBackgroundTimeMs(uid, which);
            case StatusType.ALL:
                return getProcessForegroundTimeMs(uid, which)
                        + getProcessBackgroundTimeMs(uid, which);
        }
        return 0;
    }
2.6 运行时间获取 BatteryUtils.getProcessForegroundTimeMs

adb shell logcat -s “BatteryUtils”


    private static final String TAG = "BatteryUtils";

    private long getProcessForegroundTimeMs(BatteryStats.Uid uid, int which) {
        final long rawRealTimeUs = convertMsToUs(SystemClock.elapsedRealtime());
        return getScreenUsageTimeMs(uid, which, rawRealTimeUs)
                + convertUsToMs(getForegroundServiceTotalTimeUs(uid, rawRealTimeUs));
    }
    
    // 屏幕使用时间
    private long getScreenUsageTimeMs(BatteryStats.Uid uid, int which, long rawRealTimeUs) {
        final int foregroundTypes[] = {BatteryStats.Uid.PROCESS_STATE_TOP};
        Log.v(TAG, "package: " + mPackageManager.getNameForUid(uid.getUid()));

        long timeUs = 0;
        for (int type : foregroundTypes) {
            final long localTime = uid.getProcessStateTime(type, rawRealTimeUs, which);
            Log.v(TAG, "type: " + type + " time(us): " + localTime);
            timeUs += localTime;
        }
        Log.v(TAG, "foreground time(us): " + timeUs);

        // Return the min value of STATE_TOP time and foreground activity time, since both of these
        // time have some errors
        return convertUsToMs(
                Math.min(timeUs, getForegroundActivityTotalTimeUs(uid, rawRealTimeUs)));
    }
    
    
    // 进程前台运行时间
    @VisibleForTesting
    long getForegroundServiceTotalTimeUs(BatteryStats.Uid uid, long rawRealtimeUs) {
        final BatteryStats.Timer timer = uid.getForegroundServiceTimer();
        if (timer != null) {
            return timer.getTotalTimeLocked(rawRealtimeUs, BatteryStats.STATS_SINCE_CHARGED);
        }

        return 0;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

法迪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值