【问题标题】:ContentProvider in android library projectandroid库项目中的ContentProvider
【发布时间】:2017-03-13 07:43:13
【问题描述】:

是否可以为许多不同应用程序使用的库项目提供私有 (exported=false) ContentProvider?

问题是即使 CP 没有被导出,它也必须具有唯一的权限。如果它不是唯一的,则您无法在同一部手机上安装具有相同库的多个应用程序 (INSTALL_FAILED_CONFLICTING_PROVIDER)。

我知道我可以使用应用程序 ID 在 AndroidManifest 中定义提供程序,如下所示:

<provider
    android:authorities="${applicationId}.provider.test"
    android:name=".storage.db.MyContentProvider"
    android:exported="false" />

但我找不到在运行时在代码中生成权限以正确初始化 UriMatcher 的解决方案。

BuildConfig.APPLICATION_ID 返回库项目的 ID,而不是应用程序的 ID。 我可以尝试从应用程序的上下文中获取 packageId,但如果应用程序使用具有不同 appIds 的风味,这不是最佳解决方案。

所以我解决这个问题的想法是:

  • 在运行时在我的库代码中找到合适的 appplicationId(在使用具有不同应用程序 ID 的风味时也是如此)
  • 在我的 UriMatcher 中找到一种在不了解权限的情况下正确匹配 URI 的方法。

【问题讨论】:

  • 如果您的所有应用程序都使用相同的密钥签名,您可能正在寻找名为 protectionLevel=signature 的东西,请看这里 stackoverflow.com/questions/6120025/… 和这里 stackoverflow.com/questions/23281860/…,我没有使用或阅读详细信息,但主要思想是只允许使用相同密钥签名的应用程序访问提供程序
  • 我不拥有使用我的库的应用程序,因此解决方案应该对应用程序开发人员透明。

标签: android android-contentprovider


【解决方案1】:

我能够根据找到的答案 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;
}

【讨论】:

  • 什么时候调用这个方法?
【解决方案2】:

不幸的是,唯一的方法是请求使用您的库的应用程序开发人员以他们的唯一权限将标签添加到他们的 AndroidManifest.xml。

【讨论】:

    猜你喜欢
    • 2011-02-16
    • 1970-01-01
    • 1970-01-01
    • 2012-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多