Android - 在应用项目中拥有提供商权限

500*_*865 17 java android authority android-contentprovider android-library

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

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

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

Ian*_*ick 23

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

我想出的解决方案是为我们生成的合同添加一个静态初始化程序,该合同使用反射来查找一个类,如果它存在则使用静态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);
// ...
Run Code Online (Sandbox Code Playgroud)

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

package com.example.app.data;

public class QuxContentProviderAuthority {
    public static final String CONTENT_AUTHORITY = "com.example.app.data.baz";
}
Run Code Online (Sandbox Code Playgroud)

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


Com*_*are 22

应用程序是唯一一个绝对需要了解权限的应用程序,因为它是<provider>在清单中使用android:authorities属性声明的权限.

因此,原则上,只要从提供者中删除所有特定于权限的逻辑,它就应该"正常工作",例如:

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

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

  • 由于a ContentProvider是一个自然的单例,将它分配给静态数据成员,然后通过自定义Application类的自定义方法向其提供权限字符串(因为提供程序首先被初始化,所以这应该工作)

  • 如果你只支持API级别11+,有自定义Application类使用call()ContentResolver提供权威的ContentProvider

  • 假设唯一的真实调用(例如,to query(),insert())是有效的,并且只是根据Uri您看到的第一个调用来初始化您的权限