ios - 详细的电池使用情况-iOS

标签 ios cocoa-touch gps instruments battery

我当前的项目是一个恒定状态的应用程序(例如Tinder或Foursquare),电池消耗是通过屋顶来实现的。我们认为主要的功耗来自GPS和WiFi天线。我们希望能够在几种不同的配置下测量应用程序的能源使用情况。

但是该怎么做呢?我们想要一个过程,该过程:

  • 可以在电话与计算机断开连接的情况下使用(因此我们知道我们使用的是电池,而不是通过USB供电),
  • 具有足够的粒度,可以使能量峰值与应用程序事件相关联(启动应用程序,更新位置,将分析信息发送到Mixpanel等),
  • 无需保姆就可以整夜运行,
  • 可以导出为CSV或其他格式以进行统计分析。

  • 我知道很多。

    这些是要求,以下是我知道的选项:

    1.在iOS设备上打开不受限制的能源诊断程序,并导出到Instruments

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

    优点:
  • 使用电池代替USB电源。
  • 卓越的粒度(1秒的时间序列数据,20个离散的能源使用水平),
  • 与其他设备事件(例如GPS天线使用情况等)相关。

  • 缺点:
  • 不能在一夜之间运行,因为“如果设备电池电量耗尽或iOS设备已关闭电源,则日志数据将丢失。”这是一个CRAZY限制,几乎使这种方法对我们的案例(https://developer.apple.com/library/ios/recipes/Instruments_help_articles/LoggingEnergyUsageinaniOSDevice/LoggingEnergyUsageinaniOSDevice.html)无用。
  • 无法导出为CSV。因为仪器。

  • 2.通过乐器监视插入的电话

    优点:
  • 同样出色的粒度和与其他设备事件的关联性。
  • 电池电量耗尽。

  • 缺点:
  • 不使用电池,因此能耗与实际使用无可比拟。
  • Instruments甚至无法可靠地显示能源使用情况。有时只是空白。
  • 无法导出为CSV。

  • 3.使用公共(public) cocoa API记录应用程序中的能源使用– [UIDevice.currentDevice batteryLevel]

    这是关于SO的最常见答案。我看过Estimated battery time on iOSiphone: Calculating battery life和其他十几个。

    优点:
  • 测量之间的时间间隔很小。
  • 即使通过某种方式写入磁盘(CoreData,默认值,网络等),即使电池没电,也可以保留数据。
  • 可以为数据选择任意格式,例如CSV。

  • 缺点:
  • 比其他方法要多得多的工作。
  • 公共(public)API仅使您的电池电量达到5%的准确度。从本质上讲,这是我们从方法1和方法2中获得的瞬时功耗数据的时间积分。不够细致,无法与其他设备事件相关联(但可能足以获得设备电池生命周期的总体估算值)。

  • 4.使用私有(private) cocoa API记录能源使用情况

    由于我们只会在开发期间进行此操作,因此Apple是否会拒绝使用私有(private)API的应用程序无关紧要。大概有一些专用API可以使用,因为Apple可以在Untethered Energy Diagnostics开启的情况下记录数据。

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

  • 缺点:
  • Waaaaay需要做更多的工作来弄清楚如何使用它。甚至不可能。

  • 5.组合方法

    我们可以使用不受限制的诊断方法来量化每个操作的边际能源成本。 “好吧,旋转GPS天线需要150mW•H。计算位置需要50mW•H。发送Mixpanel事件需要25mW•H,除非我们在前30秒内进行了另一个网络调用,在这种情况下需要15mW•H。” (所有的数字都是当场发明的。)然后,我们可以使用系留监控器来记录这些 Action 中的每一个何时发生,插入一个线性方程式,并估算应该采取的能量。

    优点:
  • 灵活。随心所欲。

  • 缺点:
  • 数学。
  • 非常容易错过非线性贡献。得到类似E = k0/(gps轮询间隔)+ k1 *(分析调用次数)的方法很容易,但是如果将两个天线拆分起来的成本小于将它们分别拆分起来的总和呢?
  • 忽略Apple内部可能在定位服务中制定的任何缓存策略。
  • 甚至与现实世界的利用率还差得很远。

  • 不管怎样,我已经足够虚张声势了。有人做过吗?如何?

    最佳答案

    不知道这是否适用于这个确切的用例,但是我已经开发了一个名为UIDeviceListener的库,该库使您可以轻松地(基本上使用一行代码)从操作系统中检索有关功耗和许多其他电池/的数据。收费相关数据点:https://github.com/eldoogy/PowerData

    这是一个示例字典,可让您大致了解可以获取的信息种类。我将把您的注意力转移到InstantAmperage键上。这显示了整个设备(拔出设备时)的实时功耗(毫安)。这可能有助于完成您在此处查找的内容。

    {
    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设备,并且不调用任何私有(private)API。

    关于ios - 详细的电池使用情况-iOS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24831813/

    相关文章:

    cocoa-touch - 哪个事件处理对象成为/失去第一响应者状态?

    objective-c - 是否有与 +initialize 对应的类拆卸?

    android - 可以通过智能手机 GPS 定位到我们所在的楼层吗?

    c - 通过 GPS 坐标测量距离

    一直运行的 iOS GPS 跟踪应用程序

    ios - AFNetworking 2 - 请求失败时没有响应正文

    ios - APNS生产证书发行

    iphone - 在模态转场之后移除最后一个 UIViewController

    iphone - 如何获取有关 UIScrollView 中页面的信息?

    ios - 适当的线程处理