Следующим способом можно упаковать ContentProvider в библиотеке и установить полномочия ContentProvider во время выполнения, чтобы его можно было включить в несколько проектов без конфликта полномочий ContentProvider. Это работает, потому что настоящий «авторитет» исходит от AndroidManifest, а не от класса ContentProvider.
Начните с базовой реализации ContentProvider. AUTHORITY, CONTENT_URI и UriMatcher являются статическими, но не «окончательными» ....
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);
Затем переопределите метод 'attachInfo', чтобы при первой инициализации ContentProvider вызывался ваш ContentProvider с ProviderInfo, который был получен из AndroidManifest. Это будет происходить ПЕРЕД любыми возможными запросами, скорее всего, во время начальной настройки класса Application. Используйте эту возможность, чтобы сбросить AUTHORITY, CONTENT_URI и UriMatcher к их «реальным» значениям, как это предусмотрено приложением, использующим библиотеку ContentProvider.
@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);
}
Когда приложение запускается, ContentProvider фактически создается вместе с классом Application, поэтому у него будет доступ ко всей необходимой информации о пакете. объект ProviderInfo будет содержать информацию, представленную в AndroidManifest ... Список, включенный в окончательное приложение.
<provider android:authorities="com.foo.barapp.content"
android:name="com.foo.bar.MyContentProvider"/>
Орган управления теперь будет переписан с именем «com.foo.barapp.content» вместо значения по умолчанию, а UriMatcher будет обновлен до значения приложения вместо значения по умолчанию. Классы, которые полагаются на «AUTHORITY», теперь будут получать доступ к обновленному значению, и UriMatcher будет правильно распознавать входящие запросы для «com.foo.barapp.content».
Я протестировал это одновременно с образцом приложения и пакетом androidTest и обнаружил, что он работает правильно.