Android – 在应用程序项目中拥有提供者权限

一个Android库项目包含一些供应商,其权限在合同类中定义如下:

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

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

Solutions Collecting From Web of "Android – 在应用程序项目中拥有提供者权限"

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

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

  • 那些静态数据成员(现在转移到托pipe应用程序)
  • UriMatcher (滚动你自己的东西,不检查权威,但侧重于其余的Uri

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

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

  • 如果您仅支持API Level 11+,请让自定义Application类在ContentResolver上使用call()将权限提供给ContentProvider

  • 假设唯一的真正的调用(例如, query()insert() )是有效的,只是惰性初始化您的权限根据你看到的第一个Uri

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

我想出的解决scheme是添加一个静态初始化到我们生成的合约,使用reflection查找类,并使用静态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"; } 

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