【问题标题】:Android - Having Provider authority in the app projectAndroid - 在应用项目中拥有 Provider 权限
【发布时间】:2013-01-30 04:56:33
【问题描述】:

一个 android 库项目包含一些提供者,其权限在合约类中定义如下:

public static final String CONTENT_AUTHORITY = "my.com.library.providers.tester";
private static final Uri BASE_CONTENT_URI = Uri.parse("content://" + CONTENT_AUTHORITY);

现在有很多应用程序项目使用这个库项目。我目前遇到的问题是,对于每个应用程序项目,我需要在每个应用程序的库项目中都有一个单独的分支,只是为了拥有唯一的内容权限。这会产生一些版本管理问题(例如将功能/错误修复从一个分支传播到每个其他分支等)。相反,我想将定义内容权限的责任委托给应用程序项目。有没有办法做到这一点?

【问题讨论】:

标签: java android android-contentprovider android-library authority


【解决方案1】:

我知道这是一个老话题,但今天遇到了这个问题,我们已经开发了很长一段时间,所以还没有准备好检查我们的内容提供者合同中的所有静态并更改它们,也是因为我们的内容提供者和数据库由Mechanoid Plugin for Eclipse生成(没错,我也是作者!:))

我想出的解决方案是在我们生成的合约中添加一个静态初始化程序,它使用反射来查找一个类,并在其存在时使用静态 CONTENT_AUTHORITY 字段,如果不回退到默认值:

public class QuxContract  {
    public static final String CONTENT_AUTHORITY = initAuthority();

    private static String initAuthority() {
        String authority = "com.example.app.data.qux";

        try {

            ClassLoader loader = QuxContract.class.getClassLoader();

            Class<?> clz = loader.loadClass("com.example.app.data.QuxContentProviderAuthority");
            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;
    }

    private static final Uri BASE_CONTENT_URI = Uri.parse("content://" + CONTENT_AUTHORITY);
// ...

现在在每个链接到库项目的项目中都可以提供自己的权限:

package com.example.app.data;

public class QuxContentProviderAuthority {
    public static final String CONTENT_AUTHORITY = "com.example.app.data.baz";
}

另外,不要忘记更改清单中的权限

【讨论】:

  • 接近我实施的解决方案。谢谢分享!!
  • 谢谢,我今天可以发布了!
  • @ Ian Warwick 实际上我是 Android 新手,我使用 Android Studio 为我工作,同样的权威问题你能帮我一些样本吗
  • 这个解决方案简直太棒了!非常感谢! :D
【解决方案2】:

应用程序是唯一绝对需要了解权限的应用程序,因为它是在清单中使用 android:authorities 属性声明 &lt;provider&gt; 的应用程序。

因此,原则上,它应该“正常工作”,只要您从提供程序中删除所有权限特定的逻辑,例如:

  • 那些静态数据成员(现在移动到托管应用程序)
  • UriMatcher(自己滚动一些不检查权限的东西,但专注于Uri 的其余部分)

如果出于某种原因,您绝对确定您的提供者需要知道其权限,那么应用程序必须在提供者用于实际工作之前将其提供给提供者。可能的方法包括:

    1234563所以这应该有效)
  • 如果您只支持 API 级别 11+,请让自定义 Application 类在 ContentResolver 上使用 call()ContentProvider 提供权限

  • 假设只有真正的调用(例如,到 query()insert())是有效的,然后根据你看到的第一个 Uri 的内容懒惰地初始化你的权限

【讨论】:

  • 我几乎回答完了这个问题……然后我看到弹出“1 个新答案”,当然是 CommonsWare,它的答案涵盖了我提到的所有内容等等。只是我的运气......:P
  • @AlexLockwood:很抱歉。如果它让你感觉更好,它也会发生在我身上。另外,当这种事情发生时,不要害怕继续发布你的答案。您的措辞或其他内容可能比现有答案更能引起提问者的共鸣。此外,如果您不厌其烦地输入(大部分)答案,您也可以发布它。
  • 我明白了。我在考虑编译期间的代码修改。这不是一种可能吗?如果可能的话,它会比这种方法容易而且可能简单。
  • @500865:“这不可能吗?” -- 嗯,不容易,除非你要推出自己的 Ant 任务或制作库副本、调整源、调整托管应用程序的 project.properties 以指向副本等的东西。”如果可能的话,它会比这种方法容易而且可能简单。” - 我认为编译期间的代码修改会复杂几个数量级。毕竟,根据第一个 query() 等调用来懒惰地查找您的 Uri 应该在 10 行代码以下。
  • 上述解决方案均不适合我: 1. 更正 ContentProvider 是单例的,但是如果在具有小部件的库中使用 ContentProvider 怎么办,现在用户将无法打开应用程序将小部件放在屏幕上,所以ContentProvider 权限如何不会使用公共静态常量进行初始化。 2. ContentResolver 的调用方法我不能按照@DraškoKokić 的建议使用:3. 如果我从库本身而不是应用程序进行 query() 调用,那么在这种情况下,第三种解决方案也将不起作用
猜你喜欢
  • 2019-09-03
  • 2011-08-08
  • 1970-01-01
  • 1970-01-01
  • 2014-06-25
  • 1970-01-01
  • 1970-01-01
  • 2013-01-29
  • 1970-01-01
相关资源
最近更新 更多