Library / SDK
facebookincubator/Battery-Metrics avatar
facebookincubator/Battery-Metrics

Battery Metrics, instrumenting Android power use from inside the app

Library that helps in instrumenting battery related system metrics.

771 stars80 forksJavaMIT

At a glance

What is it?
facebookincubator/Battery-Metrics is a small Android library that collects hardware utilization metrics such as CPU time from procfiles so a developer can see what their own code is costing in power, rather than guessing from the coarse battery level the operating system reports. The install instructions still point at jcenter, which is the main thing to check before you try it.
Who is it for?
Adopt Battery Metrics if you maintain an Android app and need to attribute battery drain to your own code, especially during a development cycle where you are changing how much work the app does. Skip it if you are looking for field telemetry about what users experience, since the library instruments the device it runs on rather than reporting from users devices.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly Java, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The measurement problem the library is built around

Battery Metrics is a lightweight Android library for quickly instrumenting several metrics that help you understand battery consumption.

The README opens with the reason this exists, and it is a good reason. It says it is surprisingly hard to understand how your application affects battery life on Android, and it gives two reasons why the obvious approach does not work. Relying on the operating system's reported battery level tends to be inaccurate, because the reported levels are fairly coarse, are affected by every app running on the device, and are smoothed out. And while it is possible to get really good measurements locally, you do not really know what sort of experience users are having in the wild.

That second point is the boundary of the library. It is a local instrumentation tool, not a field telemetry system. It tells you what your process did on the device it ran on, which is what you need during development when you are asking whether a change doubled the CPU work. It does not tell you what your users experience, which requires a different category of tooling entirely.

The library's approach is to instrument hardware utilization rather than to measure power directly. As the README puts it, most of the underlying hardware metrics are either exposed by the operating system or not directly accessible, and the project has written several metrics collectors that read from procfiles or provide a consistent way to call into the application to instrument it.

The procfile route is the interesting one. Reading the per-process files in /proc gives you the raw counters the kernel maintains, and the library's job is to turn those into something stable you can diff between two points in time.

The API shape: snapshot, diff, log

The quick start in the README instruments a sample activity to check CPU time while it is in the foreground. The pattern has three parts: create a collector, take a snapshot at the start and another at the end, and diff them.

java
class SampleActivity extends Activity {

  private static final CpuMetricsCollector sCollector = new CpuMetricsCollector();
  private final CpuMetrics mInitialMetrics = sCollector.createMetrics();
  private final CpuMetrics mFinalMetrics = sCollector.createMetrics();

  @Override
  protected void onResume() {
    super.onResume();
    sCollector.getSnapshot(mInitialMetrics);
  }

  @Override
  protected void onPause() {
    super.onPause();
    sCollector.getSnapshot(mFinalMetrics);

    Log.d("BatteryMetrics", mFinalMetrics.diff(mInitialMetrics).toString());
  }
}

The output shows what a diff looks like:

java
CpuMetrics{userTimeS=0.06, systemTimeS=0.04, childUserTimeS=0.0, childSystemTimeS=0.0}

Two details are worth noticing. The collector is a static field, so the same collector instance serves every activity instance and the counters are continuous rather than reset per activity. And the metrics objects are created once with createMetrics and then filled in by getSnapshot, so a snapshot writes into an existing object instead of allocating a new one.

That design is deliberate for a library that reads /proc files. The snapshot call does the file reading and parsing, and the diff call does the arithmetic that turns two absolute counters into a delta over an interval. Because the underlying counters are cumulative, diffing is the only meaningful operation, and a metric object without a baseline is not very useful.

The child user time and child system time fields are the kernel's counters for work the process did on behalf of its children, which is why they are separated from the parent's own time.

Adding the library to a build, and the jcenter question

The installation section of the README tells you to add jcenter to your repositories:

groovy
repositories {
  jcenter()
}

and then to add the dependencies in build.gradle:

groovy
dependencies {
    implementation 'com.facebook.battery:metrics:1.0.0'
    implementation 'com.facebook.battery:reporters:1.0.0'   // optional
    implementation 'com.facebook.battery:serializers:1.0.0' // optional
}

There is one module you need and two you may want. The metrics module holds the collectors, the reporters module is optional and covers reporting the collected values somewhere, and the serializers module is optional and covers turning the metrics into a form that can be shipped or logged.

The jcenter instruction is the thing to verify before you start. JCenter was a Bintray-hosted repository that went read only and then shut down, and a repository block that points at it either fails or resolves nothing depending on how the build is configured. If the artifact is not on Maven Central, the practical approach is to check what the current build files in your own project resolve and, failing that, to build the library from source, since it is a Gradle project with the wrapper included.

The repository root confirms the Gradle layout: build.gradle, settings.gradle, gradle.properties, a gradlew wrapper script with the Windows variant, and release.gradle for publishing. The three modules are metrics/, reporters/ and serializers/, alongside sample/ and docs/.

The sample application is the better starting point than the README snippet, since the README points at it for a deeper dive into the API.

Running the sample app and the documentation set

The sample app builds and installs with a single Gradle command:

bash
./gradlew :sample:installDebug

That task name gives away the structure, since it installs the debug variant of the sample module onto a connected device. The README describes the sample app as building on the quick start with many more metrics to collect and some utility classes to reduce boilerplate, and it points at the BatteryApplication.java file in the sample source as the place to read.

The documentation is unusually well organised for a library of this size, and each document has a specific job.

The JavaDocs are described as a reasonably comprehensive reference to all the exposed APIs. The API description document gives a brief description of the terms used throughout the project, which is the one to read first since it explains what the metric names mean. The getting started document is the core of the sample app described, and again points at the sample source.

Two documents are about the reasoning rather than the API. The one on mistrusting battery level explains why the project does not rely on the OS reported battery level, and it is the argument behind the library's whole premise. The references document collects sources the maintainers found useful, and the roadmap is described as planned but unprioritised, with feedback invited.

The licence is MIT. The repository also has a CODE_OF_CONDUCT.md and a CONTRIBUTING.md, and the community channels are a Facebook group and a Slack workspace with an invite link.

Where this fits against other Android power tooling

The alternatives for understanding Android battery use come in two shapes, and Battery Metrics belongs to neither of the usual ones.

The first is the Android platform's own facilities for battery inspection, oriented at whole-device attribution. The difference in approach is that Battery Metrics is scoped to your own process and reads the raw kernel counters for it, which is a much finer instrument for a narrower question. If you want to know whether the CPU time of one activity doubled since your last change, this library answers it directly.

The second is field telemetry, the kind of thing that reports real battery drain from real users. The README is clear that this is not it, that good local measurements do not tell you what users experience. A library that instruments locally cannot answer that question.

There is also the simpler alternative of doing nothing special and watching the system's battery level, which the README's own documentation exists to argue against, since the level is coarse, shared with every other app and smoothed.

The practical niche is therefore narrow but real: during development, on a device you control, when you want a number for your own code's resource usage that you can diff between two runs. The library is small, MIT licensed, and the sample app gives you a working reference within a few minutes of getting the build to resolve.

Editorial conclusion

Adopt Battery Metrics if you maintain an Android app and need to attribute battery drain to your own code, especially during a development cycle where you are changing how much work the app does. Skip it if you are looking for field telemetry about what users experience, since the library instruments the device it runs on rather than reporting from users devices. Verify first by running ./gradlew :sample:installDebug on a device, then check that the CPU metrics snapshot in the sample logs the expected foreground time, and confirm that your own build resolves the artifacts since the documented repository is jcenter.

Frequently asked questions

What does the Battery Metrics library do?

It is a lightweight Android library for instrumenting metrics that show how an application affects battery consumption. It provides metrics collectors that read from procfiles or call into the application, so you can attribute hardware utilisation to your own code.

How do I use the CpuMetricsCollector in an Android activity?

Create one collector, create two metrics objects with createMetrics, call getSnapshot on each at the start and end of the interval you care about, then log the result of diffing the final metrics against the initial ones. The README's quick start does this between onResume and onPause.

How do I add Battery Metrics to my Gradle build?

The README shows adding the jcenter repository and then depending on com.facebook.battery:metrics:1.0.0, with the reporters and serializers modules optional. Because jcenter is no longer a live repository, verify that the artifacts resolve from your current repository configuration before you rely on the documented instructions.

Can I run the Battery Metrics sample app?

Yes. With a device connected, run ./gradlew :sample:installDebug. The sample app demonstrates the full set of collectors and is the reference the README points to for a deeper look at the API.

Why does Battery Metrics not use the OS reported battery level?

The README argues that the reported level is inaccurate because it is coarse, affected by every app on the device and smoothed out, and its documentation includes a document devoted to that reasoning. The library therefore measures hardware utilisation of your own process instead.

Official sources

  1. facebookincubator/Battery-Metrics on GitHub
  2. Issues
  3. License: MIT
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/facebookincubator-battery-metrics.svg)](https://hysenlabs.com/projects/facebookincubator-battery-metrics)

Was this useful?