多个应用使用相同的内容提供商

dou*_*zor 38 android android-contentprovider

我正在开发一组仅在某些品牌中有所区别的应用程序(想想不同的运动队); 但是,我遇到了一个问题,我正在为所有特定品牌的应用程序使用一个Library项目,并希望为所有这些应用程序使用相同的ContentProvider.当我创建ContentProvider时,我将AUTHORITY声明为类中的常量(根据dev示例代码),并且我在清单文件中的每个特定应用程序中使用相同的权限.看起来我不能在每个应用程序中使用相同的权限,因为我在尝试安装第二个应用程序时遇到此错误(我安装一个品牌的应用程序,但第二个安装):

WARN/PackageManager(66): Can't install because provider name com.xxx.Provider (in package com.xxx) is already used by com.zzz
Run Code Online (Sandbox Code Playgroud)

我尝试了几种方法,但似乎没有一种方法可行.我还没有完成的一个想法是创建一个库jar,只省略我拥有的Provider类,并在每个特定的应用程序中自定义它.关于如何解决这个问题而不诉诸于此的任何想法?

Gau*_*pta 26

这是一个老问题,但我最近正在考虑做类似的事情.使用Build flavors,它现在非常直接.

在gradle文件中指定BuildConfigField:

    productFlavors {
    free {
        applicationId "com.example.free"
        buildConfigField 'String', 'AUTHORITY', '"com.example.free.contentprovider"'
    }

    paid {
        applicationId "com.example.paid"
        buildConfigField 'String', 'AUTHORITY', '"com.example.paid.contentprovider"'
    }
Run Code Online (Sandbox Code Playgroud)

在清单中指定提供程序权限:

    <provider
        android:name=".ContentProvider"
        android:authorities="${applicationId}.contentprovider" />
Run Code Online (Sandbox Code Playgroud)

使用BuildConfigField变量在提供程序中设置权限:

    public static final String AUTHORITY = BuildConfig.AUTHORITY
Run Code Online (Sandbox Code Playgroud)

  • 这应该是新接受的答案.虽然你可以避免在运行时使用`getApplicationContext().getPackageName()`来创建`buildConfigField`. (2认同)

小智 21

ContentProviders由权威机构识别,因此它必须是唯一的.我不认为有任何伎俩.

此外,Android平台中存在一个错误,该错误还会阻止对两个不同的ContentProviders使用相同的类名,即使它们具有不同的权限并且包含在单独的APK中.看到这里的错误.

我建议您使用的解决方案是在库项目中创建抽象提供程序类,然后在每个单独的应用程序中使用唯一名称对其进行扩展.为了实现这一点,您可能需要创建一个脚本来生成/修改单个清单和contentprovider类.

希望这可以帮助.

  • 对于较新版本的Android,此答案已不再适用,因为Google已按照[此处] [https://code.google.com/p/android/issues/detail?id=7716#c12]的说明在2014年解决了该问题 (3认同)

Yai*_*pro 5

您可以!

就像在这篇文章中所说(它解释了Firebase如何在不给Application#onCreate()方法提供上下文的情况下初始化其库),您可以在清单中使用一个占位符,如下所示:

    <provider
         android:authorities="${applicationId}.yourcontentprovider"
         android:name=".YourContentProvider" />
Run Code Online (Sandbox Code Playgroud)