Getting to know the behaviors of your SDK dependencies

Fred Chung
Android Developers
Published in
4 min readMar 30, 2021


You likely are using third-party SDKs or libraries in your app. After all, why build functionality from scratch if the building blocks are readily available and can save you time? As an app developer, you are responsible for the overall user experience and code shipped in your app, including those provided by any third-party SDKs.

When you’re considering SDKs and libraries, it’s important to learn about their handling and usage of data, so you can better protect your users’ privacy.

In this post, I’ll share several tools you can use during the different development stages of your app — including development time and post-launch. (Of course, this is complementary to SDK documentation, which you’re encouraged to read very carefully, line-by-line).

Merged manifest view

To offer flexibility, Gradle allows you to provide separate manifest declarations for your app’s build variants, app modules, and library dependencies. These manifest files could include different default XML elements and attributes based on your project’s needs. When building your app, Gradle merges this hierarchy of manifests into a single manifest for your app. You can specify “merge rules” to control how values are merged. Let’s check out how you could use this facility to gain insights into your SDKs.

Android Studio offers an easy way to inspect the final merged manifest. You can simply click on the “Merged Manifest” tab of your manifest’s editor window. Through the colored bands in the UI, you are able to identify the sources of different manifest elements. These sources include various library dependencies. For example, the view below shows that the dependency named “transport-backend” has included a couple of permissions in the app.

A sample merged manifest view.

In particular, this increased visibility could help you spot any unexpected runtime permissions introduced by your app’s dependencies. This insight is useful not only because runtime permission dialogs could alter your app’s UX, but also because it makes you more aware of the data usage within your app’s dependencies. If appropriate, you should explain to your users when and why the access is necessary.

If you see any unexpected permissions in your merged manifest, carefully review the documentation (or contact the developer) of the libraries in question and make sure you understand why they’re needed.

It’s possible that such permissions are optional for the services that you’re actually using. In the interest of data minimization, you could use a “remove” node marker in your app module’s manifest to prevent the libraries’ permissions from merging into your app.

Module dependency view

Another useful facility in the development toolchain is Gradle’s module dependency support. One common use for dependency graphs is to troubleshoot build issues. The dependency graphs also include transitive dependency information, which can be helpful in identifying additional dependencies your libraries bring in. Learn more about viewing module dependencies.

Let’s have a look at another tool that you can use to better understand data access in your app.

Data access auditing

As your app’s complexity (and your team size!) increases over time, it isn’t always straightforward to diagnose SDK-related private data access during the development phase of your app.

Android 11 introduces Data Access Auditing, which helps identify which code performs data access operations as the app is used. This feature allows you to associate private data access with specific business use cases in your app, such as “order coffee” or “share with friends”. This could be useful to pinpoint any unexpected data access operations and identify which module or use case performs the access operation.

To implement, create a context object and associate it with an “attribution tag”, which corresponds with a business use case, say “order coffee”. You could do this inside OrderCoffeeActivity.onCreate().

You could use this attribution context as the Context parameter for subsequent framework API invocations.

Next, set up a callback, which will be triggered when private data access occurs. Inside the callback, you could refer to the attribution tag, retrieve the stack trace, or integrate with your app’s analytics solution for reporting purposes.

Data Access Auditing includes support for both synchronous and asynchronous API calls and is available on Android 11 or newer devices. Learn more.

Wrap up

The merged manifest tool, Gradle’s module dependency support, as well as the data access auditing APIs introduced in Android 11, are designed to give you additional insights into data access and behaviors in your app and SDK dependencies. This in turns allows you to provide better transparency for your users. You’re encouraged to integrate these tools into your existing workflows.

Additionally, if you’re distributing through the Google Play Store, be sure to check out related user data policy and verify that your SDK usage is compliant.