动态设置ContentProvider的权限

Cod*_*ice 7 java android android-contentprovider

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

And*_*Sun 24

对于那些使用较新版本的构建工具的人来说,这是一个更好的解决方案:相对于包名称赋予权限.您可以使用自动执行此操作${applicationId},在构建过程中将其扩展到应用程序的包名称中.

<provider
    android:name=".MyContentProvider"
    android:authorities="${applicationId}.provider"/>
Run Code Online (Sandbox Code Playgroud)

假设您的包名是com.example.app.paidcom.example.app.free.当您构建应用程序时,权限将变为,com.example.app.paid.providercom.example.app.free.provider相应地.

要在代码中引用提供程序权限,请使用BuildConfig.APPLICATION_ID + ".provider".


Ema*_*lin 7

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

<provider
    android:name="MyApp.MyProvider"
    android:authorities="MyApp.MyProvider.free"
    android:grantUriPermissions="true"/>
Run Code Online (Sandbox Code Playgroud)

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

<string name="my_provider_authority">MyApp.MyProvider.free</string>
Run Code Online (Sandbox Code Playgroud)

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

public class MyApplication extends Application {
    private static Context sContext;

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

    public static Context getContext() {
        return sContext;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

  • 根据这个答案:http://stackoverflow.com/q/6461776/534471你不应该使用@string引用来定义提供者的权限,但你可以(至少在Android版本更高的2.1).但我同意那里的答案,它很危险,应该省略. (2认同)