`

Android中的BatteryService及相关组件

阅读更多

原创   Android中的BatteryService及相关组件 

<script type="text/javascript"> document.body.oncopy = function() { if (window.clipboardData) { setTimeout(function() { var text = clipboardData.getData(&quot;text&quot;); if (text &amp;&amp; text.length &gt; 300) { text = text + &quot;\r\n\n本文来自CSDN博客,转载请标明出处:&quot; + location.href; clipboardData.setData(&quot;text&quot;, text); } }, 100); } } </script><script type="text/javascript"> function StorePage() { d = document; t = d.selection ? (d.selection.type != 'None' ? d.selection.createRange().text : '') : (d.getSelection ? d.getSelection() : ''); void (keyit = window.open('http://www.365key.com/storeit.aspx?t=' + escape(d.title) + '&amp;u=' + escape(d.location.href) + '&amp;c=' + escape(t), 'keyit', 'scrollbars=no,width=475,height=575,left=75,top=20,status=no,resizable=yes')); keyit.focus(); }</script>

转载时请注明出处和作者联系方式
文章出处:http://www.limodev.cn/blog


BatteryService作为电池及充电相关的服务,它的实现非常简单:

o 监听UEvent,读取sysfs里中的状态。

实现了一个UEvent的观察者。uevent是Linux内核用来向用户空间主动上报事件的机制,对于JAVA程序来说,只实现UEventObserver的虚函数onUEvent,然后注册即可。

    private UEventObserver mUEventObserver = new UEventObserver() {
        @Override
        public void onUEvent(UEventObserver.UEvent event) {
            update();
        }
    };

这里只关注power_supply的事件:

mUEventObserver.startObserving("SUBSYSTEM=power_supply");

当有power_supply相关的事件上报时,就会调用update函数。

update先调用native_update从sysfs中读取相关状态(com_android_server_BatteryService.cpp):

Linux驱动提供了下列文件,供应用程序获取电源相关状态:

#define AC_ONLINE_PATH "/sys/class/power_supply/ac/online"
#define USB_ONLINE_PATH "/sys/class/power_supply/usb/online"
#define BATTERY_STATUS_PATH "/sys/class/power_supply/battery/status"
#define BATTERY_HEALTH_PATH "/sys/class/power_supply/battery/health"
#define BATTERY_PRESENT_PATH "/sys/class/power_supply/battery/present"
#define BATTERY_CAPACITY_PATH "/sys/class/power_supply/battery/capacity"
#define BATTERY_VOLTAGE_PATH "/sys/class/power_supply/battery/batt_vol"
#define BATTERY_TEMPERATURE_PATH "/sys/class/power_supply/battery/batt_temp"
#define BATTERY_TECHNOLOGY_PATH "/sys/class/power_supply/battery/technology"

在<DA9034驱动程序阅读笔记(6)>一文中,我已经提到drivers/power/micco_power.c里注册了充电器(ac)、 usb和电池(battery)三个power_supply。各个power_supply提供的属性和上述文件是对应的,从这些文件中可以读到充电器 (ac)、usb和电池(battery)三个power_supply的相应状态。

update然后根据读到的状态更新BatteryService的成员变量,并广播一个Intent来通知其它关注电源状态的组件。

    private final void sendIntent() {
        //  Pack up the values and broadcast them to everyone
        Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED);
        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
        try {
            mBatteryStats.setOnBattery(mPlugType == BATTERY_PLUGGED_NONE, mBatteryLevel);
        } catch (RemoteException e) {
            // Should never happen.
        }
 
        int icon = getIcon(mBatteryLevel);
 
        intent.putExtra("status", mBatteryStatus);
        intent.putExtra("health", mBatteryHealth);
        intent.putExtra("present", mBatteryPresent);
        intent.putExtra("level", mBatteryLevel);
        intent.putExtra("scale", BATTERY_SCALE);
        intent.putExtra("icon-small", icon);
        intent.putExtra("plugged", mPlugType);
        intent.putExtra("voltage", mBatteryVoltage);
        intent.putExtra("temperature", mBatteryTemperature);
        intent.putExtra("technology", mBatteryTechnology);
 
        ActivityManagerNative.broadcastStickyIntent(intent, null);
    }

关注ACTION_BATTERY_CHANGED的地方有好几个:

o KeyguardUpdateMonitor 这里主要是用来更新锁屏界面下的电池状态。还有低电警告和关机也是在这里做的。

    private void handleBatteryUpdate(int pluggedInStatus, int batteryLevel) {
        if (DEBUG) Log.d(TAG, "handleBatteryUpdate");
        final boolean pluggedIn = isPluggedIn(pluggedInStatus);
 
        if (isBatteryUpdateInteresting(pluggedIn, batteryLevel)) {
            mBatteryLevel = batteryLevel;
            mDevicePluggedIn = pluggedIn;
            for (int i = 0; i < mInfoCallbacks.size(); i++) {
                mInfoCallbacks.get(i).onRefreshBatteryInfo(
                        shouldShowBatteryInfo(), pluggedIn, batteryLevel);
            }
        }
 
        // shut down gracefully if our battery is critically low and we are not powered
        if (batteryLevel == 0 &&
                pluggedInStatus != BATTERY_STATUS_CHARGING &&
                pluggedInStatus != BATTERY_STATUS_UNKNOWN) {
 
            ShutdownThread.shutdownAfterDisablingRadio(mContext, false);
 
        }
    }

o NotificationManagerService 用来更新充电状态(LED)

            if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
                boolean batteryCharging = (intent.getIntExtra("plugged", 0) != 0);
                int level = intent.getIntExtra("level", -1);
                boolean batteryLow = (level >= 0 && level <= Power.LOW_BATTERY_THRESHOLD);
                int status = intent.getIntExtra("status", BatteryManager.BATTERY_STATUS_UNKNOWN);
                boolean batteryFull = (status == BatteryManager.BATTERY_STATUS_FULL || level >= 90);
 
                if (batteryCharging != mBatteryCharging ||
                        batteryLow != mBatteryLow ||
                        batteryFull != mBatteryFull) {
                    mBatteryCharging = batteryCharging;
                    mBatteryLow = batteryLow;
                    mBatteryFull = batteryFull;
                    updateLights();
                }
            }

o PowerManagerService 这里主要是做两件事件,先是检查是否在充电时不允许睡眠,并采用相应的行动,其次是触发一个用户行为(会影响下一次睡眠的时间)。

    private final class BatteryReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            synchronized (mLocks) {
                boolean wasPowered = mIsPowered;
                mIsPowered = mBatteryService.isPowered();
 
                if (mIsPowered != wasPowered) {
                    // update mStayOnWhilePluggedIn wake lock
                    updateWakeLockLocked();
 
                    // treat plugging and unplugging the devices as a user activity.
                    // users find it disconcerting when they unplug the device
                    // and it shuts off right away.
                    // temporarily set mUserActivityAllowed to true so this will work
                    // even when the keyguard is on.
                    synchronized (mLocks) {
                        boolean savedActivityAllowed = mUserActivityAllowed;
                        mUserActivityAllowed = true;
                        userActivity(SystemClock.uptimeMillis(), false);
                        mUserActivityAllowed = savedActivityAllowed;
                    }
                }
            }
        }
    }

o LocationManagerService 这里似乎没有什么用处,我没找到mCollector赋值的地方。

             if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
                log("PowerStateBroadcastReceiver: Battery changed");
                synchronized (mLocationListeners) {
                    int scale = intent.getIntExtra(BATTERY_EXTRA_SCALE, 100);
                    int level = intent.getIntExtra(BATTERY_EXTRA_LEVEL, 0);
                    boolean plugged = intent.getIntExtra(BATTERY_EXTRA_PLUGGED, 0) != 0;
 
                    // Notify collector battery state
                    if (mCollector != null) {
                        mCollector.updateBatteryState(scale, level, plugged);
                    }
                }
            }

o WifiService 根据电源状态来决定是否需要定时唤醒(没搞得太明白,看Wifi服务时再研究)。

if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
                /*
                 * Set a timer to put Wi-Fi to sleep, but only if the screen is off
                 * AND we are transitioning from a state in which the device was supposed
                 * to stay awake to a state in which it is not supposed to stay awake.
                 * If "stay awake" state is not changing, we do nothing, to avoid resetting
                 * the already-set timer.
                 */
                int pluggedType = intent.getIntExtra("plugged", 0);
                if (mScreenOff && shouldWifiStayAwake(stayAwakeConditions, mPluggedType) &&
                        !shouldWifiStayAwake(stayAwakeConditions, pluggedType)) {
                    long triggerTime = System.currentTimeMillis() + idleMillis;
                    mAlarmManager.set(AlarmManager.RTC_WAKEUP, triggerTime, mIdleIntent);
                    mPluggedType = pluggedType;
                    return;
                }
                mPluggedType = pluggedType;
            }

o StatusBarPolicy用来更新状态栏上的充电图标。

if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
                updateBattery(intent);
            }

分享到:
评论

相关推荐

    android手机电量显示源代码

    要理解整个电量显示的实现,需要阅读`BatteryService`、`BatteryStatsService`、`BatteryController`以及SystemUI相关组件的源代码。这些源代码可以在Android开源项目(AOSP)的Git仓库中找到。 以上就是Android...

    基于Android的battery(电池)监控程序.zip

    在Android Studio或IntelliJ IDEA中,开发者可以创建一个新的Android项目,并在项目中引入BatteryManager服务。通过调用`Context.getSystemService(BATTERY_SERVICE)`方法获取BatteryManager实例,然后通过对应的...

    android 电池管理

    Android电池管理的关键组件是BatteryService,它通过Java代码、JNI代码以及内核驱动协同工作,确保系统能够实时监控和报告电池状态。关键文件包括: - **Java代码**:`BatteryService.java`位于`frameworks/base/...

    android BatteryDog源码.rar

    通过对BatteryDog的源码进行研究,我们可以深入了解Android系统中电池管理的机制以及应用能耗分析的原理。 首先,我们打开`readme.md`文件,这是项目的基本介绍和指南。在readme中,通常会包含项目的目标、功能特性...

    Android广播组件

    在Android开发中,广播(Broadcast)是一种用于在应用程序之间或者应用程序内部的不同组件之间传递消息的一种机制。它主要用于通知其他组件发生了某些特定的事件,比如设备开机完成、电池电量变化等。与事件处理机制...

    Battery-Indicator-Pro,Android电池指示灯.zip

    在这个讨论中,我们将详细探讨Battery-Indicator-Pro的实现细节,以及如何从源代码中学习到关于Android电池管理的知识。 首先,我们来看“Battery-Indicator-Pro-master”这个文件夹,它是整个项目的主分支,包含了...

    Android底层开发实战_Android底层开发实战_android_android开发实战_

    4. **Android系统服务**:分析系统服务如Activity Manager、Power Manager、Battery Service等,它们是如何管理设备状态和用户交互的。 5. **JNI(Java Native Interface)**:学习如何使用JNI在Java代码和C/C++...

    Android-提高android服务进程的优先级

    在Android系统中,服务(Service)是一种用于在后台执行长时间操作的应用组件,它不提供用户界面,但可以与其他组件交互。在某些情况下,开发者可能希望确保服务能够保持运行,即使设备资源紧张,也不会轻易被系统杀...

    Android中文文档

    这篇文档集合了开发者在实际工作中可能遇到的各种问题及解决方案,旨在为Android开发者提供一个全面的学习和参考资料。 1. **Android基础知识**: - Android系统架构:包括Linux内核、运行时环境(如Dalvik/ART)...

    Android自定义显示电池电量

    在Android系统中,电池电量的显示通常是系统默认的,但有时候开发者或用户可能希望自定义电池电量的展示方式,以实现独特的UI效果或者更个性化的交互体验。本篇将深入探讨如何在Android应用中实现自定义电池电量的...

    安卓Android源码——battery(电池)监控程序.rar

    这份“安卓Android源码——battery(电池)监控程序.rar”压缩包包含了实现这一功能的相关源代码,对于开发者来说,深入研究这些源码可以提升对Android系统电池管理机制的理解。 1. **电池状态API**: Android提供了...

    Android中文API

    总之,Android中文API是一个全面的资源,覆盖了Android开发中的各种关键元素,包括组件、权限、服务和接口的详细解释,对开发者来说是非常宝贵的参考资料。通过这个资源,开发者可以更轻松地理解Android系统的工作...

    Android学习之Broadcast练习_dlc

    在实践过程中,你可能还会接触到PendingIntent,它可以与BroadcastReceiver一起使用,使得发送广播的组件能够执行更复杂的操作,如启动一个Service或Activity。PendingIntent提供了权限控制,确保只有特定的应用才能...

    android 类型电池电量进度条

    在本文中,我们将深入探讨如何在Android应用中实现一个自定义的"android类型电池电量进度条",以及相关的设计和实现细节。 首先,我们需要理解Android中的进度条(ProgressBar)组件。进度条是Android UI工具包中的...

    android电源管理

    Android电源管理的具体实现涉及到许多库和服务,如`PowerManagerService`、`BatteryService`和`WakefulnessService`等。这些服务监控系统事件,执行电源管理决策,并与内核进行通信以执行相应的操作。 ### 结论 ...

    安卓Android源码——手机电量测试.zip

    2. **BatteryService**:这是Android系统中的一个关键组件,它负责与硬件交互获取电池状态,并更新`BatteryStats`数据。`BatteryService`会监听电池状态的变化,并在状态变化时发送广播。 3. **电源管理接口...

    深入理解android 卷II 目录

    - **BatteryService及BatteryStatsServic分析**: - **BatteryService分析**:介绍BatteryService的功能及其如何监控电池状态。 - **BatteryStatsService分析**:解析BatteryStatsService如何收集和报告关于电池...

Global site tag (gtag.js) - Google Analytics