详细的电池使用情况 - iOS

7

我的当前项目是一个常驻应用程序(类似Tinder或Foursquare),电池消耗量非常大。我们认为对电源的主要吸引力是GPS和WiFi天线。我们希望能够在几种不同的配置下测量我们应用程序的能量使用情况。

但是如何做到这一点呢?我们想要一个过程:

  • 可以在手机未连接到计算机的情况下使用(这样我们就知道我们正在使用电池而不是通过USB绘制电源)
  • 具有足够粒度,使我们能够将能量峰值与应用程序事件相关联(启动应用程序、更新位置、向Mixpanel发送分析信息等)
  • 可以在没有看守时夜间运行
  • 可以导出为CSV或其他格式进行统计分析

我知道这是一份相当长的清单。

这些是要求,这里是我所知道的选项:

1. 在iOS设备上开启无线能量诊断日志记录,并导出到Instruments

这是显而易见的答案,但它有一个巨大的缺陷。

优点:

  • 需要使用电池而不是USB电源。
  • 优秀的粒度(1秒时间序列数据,20个离散的能源使用级别),
  • 与其他设备事件相关,如GPS天线使用等。

缺点:

2. 通过Instruments监视插入手机

优点:

  • 相同的优秀粒度和与其他设备事件的关联性。
  • 电池不会耗尽。

缺点:

  • 不使用电池,因此能耗与实际使用无法比较。
  • 仪器甚至不能可靠地显示能源使用情况。有时它只是空白的。
  • 无法导出到CSV。

3. 使用公共Cocoa API在我们的应用程序中记录能源使用情况 - [UIDevice.currentDevice batteryLevel]

这是SO上最常见的答案。我看了 iOS上估计的电池寿命, iphone: 计算电池寿命和其他大约十几个网站。

优点:

  • 可以测量时间间隔任意小。
  • 即使电池死亡也可以通过某种方式写入磁盘(CoreData、默认值、网络等)来保留数据。
  • 可以选择任意格式的数据,如CSV。

缺点:

  • 比其他方法需要更多的工作。
  • 公共API仅提供电池电量精度为5%。这本质上是我们从方法1和2获得的瞬时功耗数据的时间积分。不足以与其他设备事件相关(但可能足以粗略估计设备电池寿命)。

4. 使用私有Cocoa API记录能源使用情况

由于我们只会在开发过程中执行此操作,因此如果苹果拒绝使用私有API的应用程序也无关紧要。假定存在某些私有API可用于此,因为苹果可以在打开Untethered Energy Diagnostics时记录数据。

优点:

  • 任意粒度,任意文件格式,任意持久性。

缺点:

  • 需要更多的工作来弄清如何使用它。甚至可能不可能。

5. 组合方法

我们可以使用无线诊断来量化每个操作的边际能耗。 "好的,启动GPS天线需要150mW·H。计算位置需要50mW·H。发送Mixpanel事件需要25mW·H,除非我们在前30秒内进行了另一次网络调用,在这种情况下,它需要15mW·H。"(所有数字都是现场虚构的)。然后,我们可以使用有线监测记录每个操作发生的时间,输入线性方程,估计它应该消耗的能量。

优点:

  • 灵活。任意内容。

缺点:

  • 数学。
  • 很容易错过非线性贡献。得到类似E = k0 / (gps轮询间隔) + k1 *(分析调用编号)这样的结果很容易,但如果同时启动两个天线的成本低于单独启动它们,则怎么办?
  • 忽略了苹果可能在位置服务中 internally 进行的任何缓存策略。
  • 与实际利用远不相符。

总之,我已经说得够多了。有人以前做过吗?如何做到的?


太宽泛了吗?您认为他需要添加更多详细信息吗? - Jesse Rusak
是的,如果说什么的话,我认为这个问题太过具体了。我只是想预先防范一些明显但不足够的解决方案,这些方案我已经尝试过了。 - Michael Chinigo
你说的“电池消耗量飙升”是什么意思?电池能持续多少小时? - AlexWien
你是怎么解决这个问题的? - William Grand
3个回答

3

不确定是否适用于这个确切的应用场景,但我开发了一个名为 UIDeviceListener 的库,可以轻松地(基本上只需要一行代码)从操作系统中检索有关电源消耗和许多其他与电池/充电相关的数据点的数据:https://github.com/eldoogy/PowerData

下面是一个示例字典,让您了解可以获取的信息类型。请注意InstantAmperage键。这显示了整个设备实时功率消耗(设备未插入电源时)的mA数。这可能有助于实现您在此寻找的内容。

{
AdapterDetails =     {
    Amperage = 1000;
    Description = "usb host";
    FamilyCode = "-536854528";
    PMUConfiguration = 1000;
    Watts = 5;
};
AdapterInfo = 16384;
Amperage = 1000;
AppleRawCurrentCapacity = 1279;
AppleRawMaxCapacity = 1275;
AtCriticalLevel = 0;
AtWarnLevel = 0;
BatteryData =     {
    BatterySerialNumber = REDACTED;
    ChemID = 355;
    CycleCount = 524;
    DesignCapacity = 1420;
    Flags = 640;
    FullAvailableCapacity = 1325;
    ManufactureDate = REDACTED;
    MaxCapacity = 1273;
    MfgData = REDACTED;
    QmaxCell0 = 1350;
    StateOfCharge = 100;
    Voltage = 4194;
};
BatteryInstalled = 1;
BatteryKey = "0003-default";
BootBBCapacity = 52;
BootCapacityEstimate = 2;
BootVoltage = 3518;
CFBundleIdentifier = "com.apple.driver.AppleD1815PMU";
ChargerConfiguration = 990;
CurrentCapacity = 1275;
CycleCount = 524;
DesignCapacity = 1420;
ExternalChargeCapable = 1;
ExternalConnected = 1;
FullyCharged = 1;
IOClass = AppleD1815PMUPowerSource;
IOFunctionParent64000000 = <>;
IOGeneralInterest = "IOCommand is not serializable";
IOInterruptControllers =     (
    IOInterruptController34000000,
    IOInterruptController34000000,
    IOInterruptController34000000,
    IOInterruptController34000000
);
IOInterruptSpecifiers =     (
    <03000000>,
    <26000000>,
    <04000000>,
    <24000000>
);
IOMatchCategory = AppleD1815PMUPowerSource;
IOPowerManagement =     {
    CurrentPowerState = 2;
    DevicePowerState = 2;
    MaxPowerState = 2;
};
IOProbeScore = 0;
IOProviderClass = AppleD1815PMU;
InstantAmperage = 0;
IsCharging = 0;
Location = 0;
Manufacturer = A;
MaxCapacity = 1275;
Model = "0003-A";
Serial = REDACTED;
Temperature = 2590;
TimeRemaining = 0;
UpdateTime = 1461830702;
Voltage = 4182;
"battery-data" =     {
    "0003-default" = <...>;
    "0004-default" = <...>;
    "0005-default" = <...};
"built-in" = 1;
}

UIDeviceListener支持常规的非越狱iOS设备,并且不调用任何私有API。


1
GPS每小时需要10%的电量,因此每秒记录高精度位置将持续约10小时。位置轮询间隔与电池消耗无关。GPS芯片要么启用,要么禁用。没有低功耗GPS模式!如果您知道用户不需要GPS,则可以禁用它。
对于位置数据的永久记录,只有选择低精度(1000米基站或WLAN定位)而不是高精度(3-6米= GPS),才能节省电池电量。
当然,在测量过程中,您将关闭所有第三方应用程序,特别是最著名的通讯应用程序之一,它每秒连接到互联网!!

1
我无法提供有关在iOS上进行功率测量的建议,但可以指出可能导致能耗过高的一些来源,并在进行测量时指出需要考虑的一些问题。
过高能耗的常见来源:
- 轮询而非使用中断。这会阻止处理器进入较低的功率状态。较低的功率状态可以将处理器的功耗降低一个数量级以上。 - 使用间隔太小的中断。常见错误是认为较小的轮询间隔(如10ms)可以获得更快的响应时间。如果您的应用程序/用户的响应能力为500ms,则10ms只会使处理器保持清醒并消耗能量。 - 任何传输都很能耗,接收则稍微好一些(如WiFi、GPS、蓝牙等)。尽量减少它们的使用。 - 外围设备也有低功耗状态。请适度使用它们,以使它们保持在较低的功耗状态。
有关测量功耗的注释:
  • 监控本身可能会导致过度的功耗。监控电力非常棘手。监控使用中断或轮询,使处理器/设备保持唤醒状态和高功耗状态。

  • 大多数监控来自操作系统,可能是“真正”的硬件测量还是软件“猜测”。

  • 试图真正地精确意味着更频繁的测量,这会让处理器和设备保持唤醒状态。

我建议你仔细看一下你真正需要的采样间隔,并设计你的应用程序尽可能地让处理器和设备休息。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接