在 Android 2.0 上的 WebView 中使用 navigator.geolocation.getCurrentPosition+ (PhoneGap相关)
我一直在使用 PhoneGap,它非常棒,但我在 Verizon Droid w/ 2.0.1 上获取位置时遇到了问题(在 G1 w/ 1.6 上按预期工作)。
GeoLocation API 支持已在 2.0 (Eclair) 中添加到 Android 中,并且可以在 Verizon Droid(2.0.1 上)的默认浏览器中运行。也就是说,如果我访问一个调用 navigator.geolocation.getCurrentPosition(success_callback, error_callback) 的网站,设备会在对话框中提示当前域“想要知道您的位置”,并提供“共享位置”或“拒绝”选项。如果我选择“共享位置”,则 success_callback 最终会使用位置数据进行调用。
如果我在 WebView 中访问同一网站,对 navigator.geolocation.getCurrentPosition 的调用不会生成 javascript 错误,但不会显示“共享您的位置”对话框,并且不会调用任何回调。在 logcat 中,我看到似乎是相关的错误:“02-15 10:37:00.413: ERROR/geolocationService(16871): Caught security exception Registrationing for location update from system. This should only indicates in DumpRenderTree.”
在我看来,WebView 无法注册位置更新,因为它没有所需的权限,而这又是由于未提示用户授予权限而导致的。虽然Android 2.0中的Webkit包中添加了一些与GeoPermissions相关的方法和对象,但我无法使用它们中的任何一个来使WebView显示GeoPermission对话框。
以下内容基于 Android 开发人员指南中的 Hello, WebView 示例,但添加了 2.0 中添加的一些与 GeoPermissions 相关的调用和对象。 *使用适当的网址进行更新(经 许可作者 - 感谢奥利弗!)。
有人能让这个工作吗?任何反馈都会很棒,谢谢!
package com.example.android.helloactivity;
import android.app.Activity;
import android.os.Bundle;
import android.webkit.GeolocationPermissions;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.GeolocationPermissions.Callback;
public class HelloActivity extends Activity implements GeolocationPermissions.Callback{
WebView webview;
String geoWebsiteURL = "http://maxheapsize.com/static/html5geolocationdemo.html";
public HelloActivity() {
}
/**
* Called with the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.hello_activity);
webview = (WebView) findViewById(R.id.webview);
webview.getSettings().setJavaScriptEnabled(true);
webview.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
webview.getSettings().setGeolocationEnabled(true); //seems like if i set this, the webview should prompt when I call navigator.geolocation.getCurrentPosition
GeolocationPermissions geoPerm = new GeolocationPermissions(); //added in API Level 5 but no methods exposed until API level 7
GeoClient geo = new GeoClient();
webview.setWebChromeClient(geo);
String origin = ""; //how to get origin in correct format?
geo.onGeolocationPermissionsShowPrompt(origin, this); //obviously not how this is meant to be used but expected usage not documented
webview.loadUrl(geoWebsiteURL);
}
public void invoke(String origin, boolean allow, boolean remember) {
}
final class GeoClient extends WebChromeClient {
@Override
public void onGeolocationPermissionsShowPrompt(String origin,
Callback callback) {
// TODO Auto-generated method stub
super.onGeolocationPermissionsShowPrompt(origin, callback);
callback.invoke(origin, true, false);
}
}
}
I've been working with PhoneGap and it's been great, but I've run into a problem with getting location on a Verizon Droid w/ 2.0.1 (works as expected on a G1 w/ 1.6).
GeoLocation API Support was added to Android in 2.0 (Eclair) and it works in the default browser on a Verizon Droid (on 2.0.1). That is, if I visit a website that calls navigator.geolocation.getCurrentPosition(success_callback, error_callback), the device prompts that the current domain "wants to know your location" in a dialog with options to "Share location" or "decline". If I select "Share location", success_callback eventually gets called with location data.
If I visit the same website in a WebView, the call to navigator.geolocation.getCurrentPosition does not generate a javascript error, but the "share your location" dialog is not displayed and neither callback ever gets called. In logcat, I see what seems to be a related error: "02-15 10:37:00.413: ERROR/geolocationService(16871): Caught security exception registering for location updates from system. This should only happen in DumpRenderTree."
It seems to me that the WebView is failing to register for location updates because it does not have the required permission, which in turn is a result of not prompting the user for the permission. Although there were several methods and objects added to the Webkit package in Android 2.0 related to GeoPermissions, I haven't been able to use any of them to cause WebView to display the GeoPermission dialog.
The following is based on the Hello, WebView example from the Android Developer's Guide but it adds some of the calls and objects that were added in 2.0 related to GeoPermissions. *Updated with an appropriate url (with permission from the author - thanks Oliver!).
Has anyone been able to get this working? Any feedback would be great, thanks!
package com.example.android.helloactivity;
import android.app.Activity;
import android.os.Bundle;
import android.webkit.GeolocationPermissions;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.GeolocationPermissions.Callback;
public class HelloActivity extends Activity implements GeolocationPermissions.Callback{
WebView webview;
String geoWebsiteURL = "http://maxheapsize.com/static/html5geolocationdemo.html";
public HelloActivity() {
}
/**
* Called with the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.hello_activity);
webview = (WebView) findViewById(R.id.webview);
webview.getSettings().setJavaScriptEnabled(true);
webview.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
webview.getSettings().setGeolocationEnabled(true); //seems like if i set this, the webview should prompt when I call navigator.geolocation.getCurrentPosition
GeolocationPermissions geoPerm = new GeolocationPermissions(); //added in API Level 5 but no methods exposed until API level 7
GeoClient geo = new GeoClient();
webview.setWebChromeClient(geo);
String origin = ""; //how to get origin in correct format?
geo.onGeolocationPermissionsShowPrompt(origin, this); //obviously not how this is meant to be used but expected usage not documented
webview.loadUrl(geoWebsiteURL);
}
public void invoke(String origin, boolean allow, boolean remember) {
}
final class GeoClient extends WebChromeClient {
@Override
public void onGeolocationPermissionsShowPrompt(String origin,
Callback callback) {
// TODO Auto-generated method stub
super.onGeolocationPermissionsShowPrompt(origin, callback);
callback.invoke(origin, true, false);
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我刚刚在 Android 2.1 的 Nexus One 上尝试了你的代码,效果很好。请记住,您需要将必要的权限添加到清单中:
I just tried your code on a Nexus One with Android 2.1, and it works fine. Remember that you'll need to add the necessary permissions to your manifest:
我们(PhoneGap 团队)最近发布了针对此问题的修复程序。基本上,问题是从 Android 2.0 开始,原生 WebView 现在有自己的 navigator.geolocation 实现,因此该函数的 PhoneGap 桥没有在 JavaScript 中正确设置。
从那时起,一个特定的提交为此创建了一个解决方法:我们将本机 navigator.geolocation 对象“代理”到我们自己对此对象的定义。该对象与 PhoneGap 框架配合良好。
对于此修复,请参阅以下提交: http://github.com/phonegap/phonegap -android/commit/5255f632377c36beb0b4d2620940f33b6d02b2c7
We (the PhoneGap team) have recently released a fix for this. Basically, the problem was that as of Android 2.0, the native WebView now has its own implementation of navigator.geolocation, and thus the PhoneGap bridge for this function was not getting set properly in JavaScript.
Since then, a particular commit has created a workaround for this: we 'proxy' the native navigator.geolocation object to our own definition of this object. This object works well with the PhoneGap framework.
For this fix, see the following commit: http://github.com/phonegap/phonegap-android/commit/5255f632377c36beb0b4d2620940f33b6d02b2c7
这个链接有关键
http://cordova.apache.org/docs/en/ 2.5.0/cordova_device_device.md.html
我正在使用 Android 进行开发 - Phonegap
我添加了
app/res/xml/config.xml
app/AndroidManifest.xml
This link has the key
http://cordova.apache.org/docs/en/2.5.0/cordova_device_device.md.html
I am developing with Android - Phonegap
I added
app/res/xml/config.xml
app/AndroidManifest.xml