ContentProvider in android library project
Asked Answered
C

2

9

Is it possible to have private (exported=false) ContentProvider for a library project that's used by many different apps?

The issue is that even when the CP is not exported, it has to have unique authority. When it's not unique then you can't install multiple apps with the same library on the same phone (INSTALL_FAILED_CONFLICTING_PROVIDER).

I know that I can use application ID to define the provider in AndroidManifest like this:

<provider
    android:authorities="${applicationId}.provider.test"
    android:name=".storage.db.MyContentProvider"
    android:exported="false" />

but I can't find a solution to generate the authority in code during runtime to properly initialize a UriMatcher.

BuildConfig.APPLICATION_ID returns an ID of the library project, not the app. I could try to fetch packageId from app's context but then it's not best solution if the app uses flavors with different appIds.

So my ideas to solve this are:

  • finding a proper appplicationId in my library code in runtime (also when flavors with different application IDs are used)
  • find a way to properly match URIs in my UriMatcher without a knowledge of the authority.
Calamite answered 13/3, 2017 at 7:43 Comment(2)
you might be looking for something called protectionLevel=signature if all of your apps are signed with the same key, look here #6120525 and here #23282360, i did not use or read in details, but the main idea is to allow only apps signed with the same key to access the providerDownes
I don't own the apps that use my library, so the solution should be transparent for the app developer.Calamite
C
6

I was able to get the authority in runtime based on an answer found here. The solution looks as follows (API 9+)

private static String getAuthority(final Context appContext) throws PackageManager.NameNotFoundException {
  final ComponentName componentName = new ComponentName(appContext, MyContentProvider.class.getName());
  final ProviderInfo providerInfo = appContext.getPackageManager().getProviderInfo(componentName, 0);
  return providerInfo.authority;
}
Calamite answered 13/3, 2017 at 10:14 Comment(1)
when to call this method?Fulcher
L
-1

Unfortunately the only way is to request developers of applications who used your library to add tag to their AndroidManifest.xml with their unique authority.

Leifleifer answered 13/3, 2017 at 8:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.