在练习内容提供器(ContentProvider)时,遇到问题报错信息:
03-31 23:59:55.637 2273-2273/com.zhengguo.test.providertest E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.SecurityException: Permission Denial: opening provider com.zhengguo.test.databasetest.DatabaseProvider from ProcessRecord{5372b968 2273:com.zhengguo.test.providertest/u0a10058} (pid=2273, uid=10058) that is not exported from uid 10056
at android.os.Parcel.readException(Parcel.java:1425)
at android.os.Parcel.readException(Parcel.java:1379)
at android.app.ActivityManagerProxy.getContentProvider(ActivityManagerNative.java:2545)
at android.app.ActivityThread.acquireProvider(ActivityThread.java:4462)
at android.app.ContextImpl$ApplicationContentResolver.acquireProvider(ContextImpl.java:1995)
at android.content.ContentResolver.acquireProvider(ContentResolver.java:1054)
at android.content.ContentResolver.insert(ContentResolver.java:860)
at com.zhengguo.test.providertest.MainActivity.onClick(MainActivity.java:72)
at android.view.View.performClick(View.java:4204)
at android.view.View$PerformClick.run(View.java:17355)
at android.os.Handler.handleCallback(Handler.java:725)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5041)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)
**
解决方案:
**
在provider中添加如下属性值 android:exported=”true”
<provider>
android:authorities="com.zhengguo.test.databasetest.provider"
android:name="com.zhengguo.test.databasetest.DatabaseProvider"
android:exported="true">
</provider>
查询provider的API说明,官方说明如下:
android:exported
Whether the content provider is available for other applications to use:
true: The provider is available to other applications. Any application can use the provider's content URI to access it, subject to the permissions specified for the provider.
false: The provider is not available to other applications. Set android:exported="false" to limit access to the provider to your applications. Only applications that have the same user ID (UID) as the provider will have access to it.
The default value is "true" for applications that set either android:minSdkVersion orandroid:targetSdkVersion to "16" or lower. For applications that set either of these attributes to"17" or higher, the default is "false".
You can set android:exported="false" and still limit access to your provider by setting permissions with the permission attribute.
在API 16 或者更低的版本中,该属性默认值为true,在17及更高的版本中默认值是false。我的练习中使用的API是21版本,因此如果不指定该属性的值,则默认false,其他应用程序则无法使用该内容提供器,只要在内容提供应用中,指定android:exported=“true”,就可以解决问题。