安卓重复提供者权限问题

7
我们正在尝试发布一款休闲应用的付费无广告版本,目前该应用是免费带广告发布的。我们将所有包名重构为com.mycompanyname.appname.pro,市场上的免费版本没有结尾的".pro"。我们还进入内容提供程序并将权限更改为与包名相同。所以“免费版本”有
AUTHORITY = "com.mycompanyname.appname" 

“无广告付费版”意味着:

AUTHORITY = "com.mycompanyname.appname.pro" 

但是我们仍然无法在同一设备上安装免费版和“专业版”。不管怎样,提供程序的类名在两个应用程序中都相同。

我们无法直接从apk安装,如果尝试从Android市场下载,则会收到“重复提供程序权限”的错误消息。

我们错过了什么?还有其他地方需要查找问题,或者我们在这里基本上出了什么问题?

4个回答

2
假设您的库包为com.android.app.library,免费包为com.android.app.free,付费包为com.android.app.paid
在您的免费项目和付费项目中,创建一个相同的文件,放在任何包中,但必须相同。
例如:
  1. Create a new package in your free version with com.android.app.data

  2. Create a file called Authority.java and inside (Authority.java) put:

    public class Authority {

    `public static final String CONTENT_AUTHORITY = "YOUR PROVIDER";`
    

    }

  3. Repeat this for the paid version, remember to keep the package name the same and class name.

现在,在您的合同文件中,使用以下内容的库:
public static String AUTHORITY = initAuthority();

    private static String initAuthority() {
        String authority = "something.went.wrong.if.this.is.used";

        try {

            ClassLoader loader = Contract.class.getClassLoader();

            Class<?> clz = loader.loadClass("com.android.app.data.Authority");
            Field declaredField = clz.getDeclaredField("CONTENT_AUTHORITY");

            authority = declaredField.get(null).toString();
        } catch (ClassNotFoundException e) {} 
        catch (NoSuchFieldException e) {} 
        catch (IllegalArgumentException e) {
        } catch (IllegalAccessException e) {
        }

        return authority;
    }

    public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY);

现在你应该能够使用两个权限。
来源:Ian Warick Android - 在应用程序项目中具有提供程序权限

@Jerryl15 我也遇到了同样的问题,我应该在清单文件中声明哪个权限呢?是 "com.android.app.data.Authority" 还是 authority = "something.went.wrong.if.this.is.used"? - Manoj

2

我所做的基本上就是为每个ContentProvider创建一个抽象基类,并从中继承到我要制作的每个应用程序,覆盖授权路径。因此,在我的AbstractContentProvider中,我有:

public AbstractContentProvider() {
    sURIMatcher.addURI(getAuthority(), BASE_PATH, ITEMS);
    sURIMatcher.addURI(getAuthority(), BASE_PATH + "/#", ITEM_ID);
}

protected abstract String getAuthority();

然后在每个子类中我有:

private static final String AUTHORITY = "my.package.app1.ContentProvider";

@Override
protected String getAuthority() {
    return AUTHORITY;
}

在 AndroidManifest 中,我使用以下方式进行注册:
    <provider
          android:name="my.package.app1.ContentProvider"
          android:authorities="my.package.app1.ContentProvider">
    </provider>

现在的问题是,我希望在通用(库)代码中访问这些内容提供程序,而不知道应用程序特定的类。为此,我在我的strings.xml中定义一个字符串,并为每个应用程序覆盖它。然后我可以使用:

Uri.parse(getString(R.string.contentProviderUri))

每个应用程序都使用正确的ContentProvider而没有任何冲突。因此基本上是使用依赖注入的配置机制。


2

谷歌默认在您的APP中添加了应用程序测量提供程序,因此在build.gradle文件中,您需要在android标签下定义applicationID,示例如下:

defaultConfig {
        applicationId "com.example.my.app"
        minSdkVersion 15
        targetSdkVersion 19
        versionCode 1
        versionName "1.0"
    }

这也解决了我的问题。人们在安装我们的应用程序时,在Google Play商店上遇到了505错误。 - Jeenyus

0

我遇到了同样的问题,错误信息提示提供程序名称已经注册。我认为诀窍可能是同时使用不同的授权和不同的名称 - 因此,在免费和专业版本中从库项目中扩展我的基本提供程序,在我的情况下。如果您仍然遇到问题,则可以解决此问题(我注意到这是一篇旧文章,但没有答案,所以我决定发布我解决它的方式)。

我很好奇是否还有人遇到同样的问题,结果似乎在Android平台上出现了一个错误。请参见此处的问题详细信息或类似的SO帖子此处


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接