可以通过以下方式将一个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 时,将使用从 AndroidManifest 收集的 ProviderInfo 调用您的 ContentProvider。这将在进行任何可能的查询之前发生,最有可能在初始应用程序类设置期间发生。利用这个机会将 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 实际上是与应用程序类一起实例化的,因此它可以访问所有必需的包信息。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 包对此进行了测试,发现它可以正常工作。