The following way can be used to package a ContentProvider within a library and set the ContentProvider's authority at runtime, so that it can be included into multiple projects without ContentProvider Authority conflict. This works because the real 'authority' comes from the AndroidManifest...not the ContentProvider class.
Start with the basic ContentProvider implementation..AUTHORITY, CONTENT_URI and UriMatcher are static, but not 'final'....
public class MyContentProvider extends ContentProvider {
public static String AUTHORITY = "com.foo.bar.content";
public static Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY);
protected static UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
Then, override the 'attachInfo' method, so that when the ContentProvider is first initialized, your ContentProvider will be called with the ProviderInfo that's gleaned from the AndroidManifest. This will occur BEFORE any possible queries are made, most likely during the initial Application class setup. Use this opportunity to reset the AUTHORITY, CONTENT_URI and UriMatcher to their 'real' values, as provided by the Application that's using the ContentProvider library.
@Override
public void attachInfo(Context context, ProviderInfo info) {
super.attachInfo(context, info);
AUTHORITY = info.authority;
CONTENT_URI = Uri.parse("content://" + AUTHORITY);
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(AUTHORITY, AlarmTable.TABLENAME, ALARMS);
uriMatcher.addURI(AUTHORITY, AttributeTable.TABLENAME, ATTRIBUTES);
uriMatcher.addURI(AUTHORITY, DeepLinkTable.TABLENAME, DEEPLINKS);
uriMatcher.addURI(AUTHORITY, NotificationTable.TABLENAME, NOTIFICATIONS);
uriMatcher.addURI(AUTHORITY, MetaDataTable.TABLENAME, RESOURCE_METADATA);
uriMatcher.addURI(AUTHORITY, ResourceTable.TABLENAME, RESOURCES);
uriMatcher.addURI(AUTHORITY, ResourceAttributeTable.TABLENAME, RESOURCES_ATTRIBUTES);
uriMatcher.addURI(AUTHORITY, ResourceTagTable.TABLENAME, RESOURCES_TAGS);
uriMatcher.addURI(AUTHORITY, TagTable.TABLENAME, TAGS);
uriMatcher.addURI(AUTHORITY, UserTagTable.TABLENAME, USER_TAGS);
uriMatcher.addURI(AUTHORITY, UserTable.TABLENAME, USERS);
uriMatcher.addURI(AUTHORITY, CUSTOM, RAW);
}
When the Application is started, the ContentProvider is actually instantiated along with the Application class, so it will have access to all the required package info. the ProviderInfo object will contain the information provided in the AndroidManifest... The listing that's included in the final Application.
<provider android:authorities="com.foo.barapp.content"
android:name="com.foo.bar.MyContentProvider"/>
The Authority will now be rewritten with "com.foo.barapp.content" instead of the default value, and the UriMatcher will be updated to the application's value instead of the default. Classes that rely on the "AUTHORITY" will now access the updated value, and the UriMatcher will properly distinguish the incoming queries for the 'com.foo.barapp.content'.
I've tested this with both both a sample application and an androidTest package simultaneously and found it to work correctly.