Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ContentProvider in android library project

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.
like image 608
LR89 Avatar asked Mar 13 '17 07:03

LR89


People also ask

What is the purpose of ContentProvider in Android?

A content provider manages access to a central repository of data. A provider is part of an Android application, which often provides its own UI for working with the data. However, content providers are primarily intended to be used by other applications, which access the provider using a provider client object.

How many ContentProvider Can an app have?

You can implement as many as you want, as you can see from the documentation here. To register a content provider, you need to add its corresponding <provider> tag in the Android Manifest. In most cases, however, you won't need multiple content providers. One is usually enough, as it can handle multiple tables.


1 Answers

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;
}
like image 60
LR89 Avatar answered Oct 05 '22 07:10

LR89