动态设置ContentProvider的权限

时间:2013-04-28 21:30:13

标签: java android android-contentprovider

也许标题有点误导。我的问题是我有一个Android库项目,它在两个标准的Android项目之间共享:一个用于免费版本的应用程序,另一个用于付费版本。该库目前具有ContentProvider的代码,包括具有多个静态String变量的契约类,例如URI和列名称。现在我希望URI的“权限”根据使用该库的应用程序而改变。想到的一个解决方案是将权限存储为字符串资源,并在运行时将该字符串加载到静态最终String变量中。但是,我不知道如何做到这一点,因为契约类有一个私有构造函数而没有Context对象来加载字符串资源。还有哪些其他选择可以解决我的问题?

3 个答案:

答案 0 :(得分:22)

对于那些使用较新版本的构建工具的人来说,这是一个更好的解决方案:相对于您的软件包名称设置权限。您可以使用${applicationId}自动执行此操作,该<provider android:name=".MyContentProvider" android:authorities="${applicationId}.provider"/> 会在构建过程中扩展为您应用的程序包名称。

com.example.app.paid

我们假设您的软件包名称为com.example.app.freecom.example.app.paid.provider。在构建应用时,权限将相应地变为com.example.app.free.providerBuildConfig.APPLICATION_ID + ".provider"

要在代码中引用提供程序权限,请使用PrintWriter

答案 1 :(得分:6)

在用户尝试安装这两个版本的情况下,使用免费和付费版本的不同权限是有意义的。 我正在为清单中的两个版本定义不同的权限,如下所示:

<provider
    android:name="MyApp.MyProvider"
    android:authorities="MyApp.MyProvider.free"
    android:grantUriPermissions="true"/>

然后我在xml文件中配置提供程序(我使用一个特殊的config.xml文件,因为我有更多的配置数据,如提供程序权限,但你当然可以使用strings.xml):

<string name="my_provider_authority">MyApp.MyProvider.free</string>

代码以任何其他字符串资源的形式检索提供者权限。要在没有上下文的情况下访问字符串资源,请使用应我正在使用应用程序类从我的应用程序中的任何位置访问应用程序上下文(但有两个例外):

public class MyApplication extends Application {
    private static Context sContext;

    @Override
    public void onCreate() {
        super.onCreate();
        sContext = this;
    }

    public static Context getContext() {
        return sContext;
    }
}

当然,您需要在清单中定义MyApplication。 这允许您从应用程序的任何位置访问字符串和其他资源。 但有两个例外:

  1. ContentProviders。 ContentProviders可以在Application启动之前启动,因此您将无法使用Application上下文。这不是问题,因为ContentProviders通过getContext()获得自己的上下文。
  2. 静态代码:在Android组件的生命周期(活动,片段,BroadcastReceivers,服务等)之外,上下文可能不可用。因此,依赖于应用程序上下文的静态初始化程序并不是一个好主意。但这也不是一个真正的问题,因为无论如何都不允许在Android组件的生命周期之外使用上下文,并且始终会在该生命周期内调用访问上下文的静态方法。例如。如果一个Activity需要知道一个ContentProvider的权限,它会在你的契约类中调用一个静态方法,并且该调用将来自onCreate()或onStart()之类的activity的onXYZ()方法之一,这将确保上下文被初始化。所以你需要做的就是延迟初始化你的契约类中的变量,并确保调用者只有在清楚之前已经调用过Application.onCreate()时才会检索变量。当然,从活动中您可以直接检索字符串资源。当您需要其他类/对象中的资源时,我的方法的真正优势将变得明显。这些对象仍将与某些Android组件的生命周期相关联,但您不必将上下文传递给所有这些对象,这非常麻烦且2)在泄漏上下文时非常容易出错。可能导致内存使用问题(Android应用程序最常见的问题之一)。

答案 2 :(得分:0)

为什么要改变权威呢?您不需要导出提供程序,这意味着除了解构应用程序之外,没有人甚至可以看到权限名称。即便如此,他们也无法访问提供商。

如果是为了您自己的内部便利,那么我将使用相同的权限,但在URI上使用不同的安全性。

简而言之,你的想法很有趣,但我不这样做。太乱了。