Java 动态设置ContentProvider的权限
也许这个标题有点误导。我的问题是,我有一个Android库项目,由两个标准的Android项目共享:一个是免费版本的应用程序,另一个是付费版本的应用程序。该库当前具有ContentProvider的代码,包括一个包含多个静态字符串变量的契约类,这些变量用于URI和列名等。现在,我希望URI的“权限”根据使用库的应用程序而改变。想到的一个解决方案是将权限存储为字符串资源,并在运行时将该字符串加载到静态final string变量中。但是,我不确定如何执行此操作,因为契约类有一个私有构造函数,并且没有上下文对象来加载字符串资源。还有什么其他选择可以解决我的问题?为什么要更改权限?你不需要导出提供者,这意味着除了解构应用程序,没有人能看到授权名称。即使这样,他们也无法访问提供商 如果是为了您自己的内部便利,那么我会使用相同的权限,但在URI上设置不同的安全性Java 动态设置ContentProvider的权限,java,android,android-contentprovider,Java,Android,Android Contentprovider,也许这个标题有点误导。我的问题是,我有一个Android库项目,由两个标准的Android项目共享:一个是免费版本的应用程序,另一个是付费版本的应用程序。该库当前具有ContentProvider的代码,包括一个包含多个静态字符串变量的契约类,这些变量用于URI和列名等。现在,我希望URI的“权限”根据使用库的应用程序而改变。想到的一个解决方案是将权限存储为字符串资源,并在运行时将该字符串加载到静态final string变量中。但是,我不确定如何执行此操作,因为契约类有一个私有构造函数,并且没
简言之,你的想法很有趣,但我不会那样做。太乱了。如果用户试图安装两个版本,免费和付费版本使用不同的权限是有意义的。 我为清单中的两个版本定义了不同的权限,如下所示:
<provider
android:name="MyApp.MyProvider"
android:authorities="MyApp.MyProvider.free"
android:grantUriPermissions="true"/>
当然,您需要在清单中定义MyApplication。
这允许您从应用程序中的任何位置访问字符串和其他资源。
但有两个例外:
对于使用较新版本的构建工具的用户,这里有一个更好的解决方案:使权限相对于您的应用程序ID。您可以使用
${applicationId}
自动执行此操作,它在构建过程中被扩展到您的应用程序ID中
<provider
android:name=".MyContentProvider"
android:authorities="${applicationId}.provider"/>
假设您的应用程序ID是com.example.app.paid
和com.example.app.free
。当您构建应用程序时,权限将相应地变成com.example.app.paid.provider
和com.example.app.free.provider
要在代码中引用提供者权限,请使用
BuildConfig.APPLICATION\u ID+“.provider”
如果用户同时安装了两个版本,会发生什么情况?免费版本还公开只读提供者,以允许付费版本导入现有数据。最终,免费和付费版本中的提供者都将由游标加载程序在内部使用。如果我理解正确,我不需要为以后的用例添加标签,因为它是每个应用程序的内部标签。我的测试表明,即使提供商没有导出,权限也必须是全球唯一的(在电话上)。感谢您的建议。我认为创建一个应用程序子类听起来是一个不错的选择。当我从“contract”类中的静态初始值设定项调用MyApplication.getContext()
时,需要注意哪些问题?另外,您能否在android:authorities
属性中使用@string/my\u provider\u authority
,以减少重复?我修改了我的答案,以解决您对在静态初始值设定项中使用应用程序上下文的担忧。答案基本上是延迟初始化从字符串资源读取的变量,并确保您不会从应用程序生命周期之外调用getter方法。根据这个答案:您不应该使用@string引用来定义提供者的权限,但您可以(至少在安卓版本2.1以上)。但我同意那里的答案,即这是危险的,可能应该忽略。你介意检查我的答案,让我知道它是否回答了你的问题,或者是否有什么问题吗?@EmanuelMoecklin我培养了你的A,但自从我问了这个问题后,就没有时间玩我的应用。这是一个爱好应用程序,工作一直在妨碍我;-(一旦我有机会找出哪一个最有用,我会接受答案。感谢Android Studio和gradle构建链提供的功能更新。此外,我如何从
public class MyApplication extends Application {
private static Context sContext;
@Override
public void onCreate() {
super.onCreate();
sContext = this;
}
public static Context getContext() {
return sContext;
}
}
<provider
android:name=".MyContentProvider"
android:authorities="${applicationId}.provider"/>