JMR*_*ies 13 android android-widget android-contentprovider android-permissions
我有一个小部件,我试图用它来显示我的应用程序的本地数据库里面的listview信息.
我正在使用RemoteViewsService.RemoteViewsFactory接口来加载我的列表的内容.如果我运行在onDataSetChanged方法中重新加载列表的代码块.该应用程序崩溃时出现以下消息:
11-01 16:40:39.540: E/ACRA(27175): DataDisplay fatal error : Permission Denial: reading com.datadisplay.content.ContentProviderAdapter uri content://com.datadisplay.provider.internalDB/events from pid=573, uid=10029 requires the provider be exported, or grantUriPermission()
但是,在类的构造函数中运行的相同代码工作得很好.当然,我需要在onDataSetChanged方法中使用它来进行更新和填充.
这是我的提供者在清单中的条目:
<provider android:name="com.datadisplay.content.ContentProviderAdapter"
android:authorities="com.datadisplay.provider.internalDB"
android:exported="true"
android:enabled="true"
android:grantUriPermissions="true">
<grant-uri-permission android:pathPattern="/events/"/>
</provider>
Run Code Online (Sandbox Code Playgroud)
我正在导出它并授予Uri权限,如错误消息请求,但它仍然失败.我发现了这个问题,这个人有问题,但最终删除了他的自定义权限,并且它有效.我没有这样的自定义权限,但仍然没有运气:
内容提供商的小部件; 不可能使用ReadPermission?
如果有人有洞察力,我会非常感激,这令人非常沮丧,哈哈.
Jef*_*key 29
发生这种情况是因为正在从远程进程调用RemoteViewsFactory,并且该上下文正用于权限实施.(远程调用者没有使用您的提供者的权限,因此它会抛出SecurityException.)
要解决此问题,您可以清除远程进程的标识,以便针对您的应用而不是针对远程调用方检查权限强制执行.这是您在整个平台上可以找到的常见模式:
final long token = Binder.clearCallingIdentity();
try {
[perform your query, etc]
} finally {
Binder.restoreCallingIdentity(token);
}
Run Code Online (Sandbox Code Playgroud)
把它放在你的onDataSetChanged()方法中:
Thread thread = new Thread() {
public void run() {
query();
}
};
thread.start();
try {
thread.join();
} catch (InterruptedException e) {
}
Run Code Online (Sandbox Code Playgroud)
从query()方法内部的数据库中获取数据.我不知道为什么在单独的线程中获取数据有助于解决这个问题,但它的工作原理!我从一个Android示例中得到了这个.
如果这只发生在4.2而不是其余部分,则需要设置android:exported ="true",因为默认值已更改:http: //developer.android.com/about/versions/android-4.2.html
默认情况下不再导出内容提供程序.也就是说,android:exported属性的默认值现在是"false".如果其他应用程序能够访问您的内容提供者很重要,您现在必须显式设置android:exported ="true".
| 归档时间: |
|
| 查看次数: |
6342 次 |
| 最近记录: |