android 库项目中的 ContentProvider
ContentProvider in android library project
是否可以为被许多不同应用程序使用的库项目提供私有 (exported=false) ContentProvider?
问题是即使不导出CP,它也必须具有唯一的权限。如果它不是唯一的,那么您不能在同一个 phone (INSTALL_FAILED_CONFLICTING_PROVIDER).
上安装具有相同库的多个应用程序
我知道我可以使用应用程序 ID 在 AndroidManifest 中定义提供者,如下所示:
<provider
android:authorities="${applicationId}.provider.test"
android:name=".storage.db.MyContentProvider"
android:exported="false" />
但我找不到在运行时在代码中生成权限以正确初始化 UriMatcher 的解决方案。
BuildConfig.APPLICATION_ID
returns 库项目的 ID,不是应用程序。
我可以尝试从应用程序的上下文中获取 packageId,但如果应用程序使用具有不同 appIds 的口味,这就不是最佳解决方案。
所以我解决这个问题的想法是:
- 运行时在我的库代码中找到合适的 appplicationId(当使用具有不同应用程序 ID 的风格时也是如此)
- 找到一种方法在我的 UriMatcher 中正确匹配 URI,而无需知道权限。
不幸的是,唯一的方法是要求使用您的库的应用程序开发人员以其独特的权限将标签添加到他们的AndroidManifest.xml。
根据找到的答案here,我能够在运行时获得权限。解决方案如下所示 (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;
}
是否可以为被许多不同应用程序使用的库项目提供私有 (exported=false) ContentProvider?
问题是即使不导出CP,它也必须具有唯一的权限。如果它不是唯一的,那么您不能在同一个 phone (INSTALL_FAILED_CONFLICTING_PROVIDER).
上安装具有相同库的多个应用程序我知道我可以使用应用程序 ID 在 AndroidManifest 中定义提供者,如下所示:
<provider
android:authorities="${applicationId}.provider.test"
android:name=".storage.db.MyContentProvider"
android:exported="false" />
但我找不到在运行时在代码中生成权限以正确初始化 UriMatcher 的解决方案。
BuildConfig.APPLICATION_ID
returns 库项目的 ID,不是应用程序。
我可以尝试从应用程序的上下文中获取 packageId,但如果应用程序使用具有不同 appIds 的口味,这就不是最佳解决方案。
所以我解决这个问题的想法是:
- 运行时在我的库代码中找到合适的 appplicationId(当使用具有不同应用程序 ID 的风格时也是如此)
- 找到一种方法在我的 UriMatcher 中正确匹配 URI,而无需知道权限。
不幸的是,唯一的方法是要求使用您的库的应用程序开发人员以其独特的权限将标签添加到他们的AndroidManifest.xml。
根据找到的答案here,我能够在运行时获得权限。解决方案如下所示 (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;
}