2010-02-15 21 views
12

He estado trabajando con PhoneGap y ha sido genial, pero me he encontrado con un problema para obtener la ubicación en un Verizon Droid con 2.0. 1 (funciona como se esperaba en un G1 w/1.6).Usando navigator.geolocation.getCurrentPosition en WebView en Android 2.0+ (relacionado con PhoneGap)

GeoLocation API Support se agregó a Android en 2.0 (Eclair) y funciona en el navegador predeterminado en un Verizon Droid (en 2.0.1). Es decir, si visito un sitio web que llame a navigator.geolocation.getCurrentPosition (success_callback, error_callback), el dispositivo indica que el dominio actual "quiere saber su ubicación" en un cuadro de diálogo con opciones para "Compartir ubicación" o "declinar". Si selecciono "Compartir ubicación", eventualmente se llamará a success_callback con los datos de ubicación.

Si visito el mismo sitio web en un WebView, la llamada a navigator.geolocation.getCurrentPosition no genera un error de javascript, pero el cuadro de diálogo "compartir su ubicación" no se muestra y nunca se llama a ninguna devolución de llamada. En logcat, veo lo que parece ser un error relacionado: "02-15 10: 37: 00.413: ERROR/geolocationService (16871): excepción de seguridad interceptada al registrarse para actualizaciones de ubicación del sistema. Esto solo debería ocurrir en DumpRenderTree".

Me parece que WebView no se registra para las actualizaciones de ubicación porque no tiene el permiso requerido, que a su vez es el resultado de no solicitar permiso al usuario. Aunque se agregaron varios métodos y objetos al paquete Webkit en Android 2.0 relacionado con GeoPermissions, no he podido utilizar ninguno de ellos para hacer que WebView muestre el diálogo GeoPermission.

Lo siguiente se basa en el ejemplo Hello, WebView de la Guía del desarrollador de Android pero agrega algunas de las llamadas y objetos que se agregaron en 2.0 relacionados con GeoPermissions. * Actualizado con una url apropiada (con permiso de the author - thanks Oliver!).

¿Alguien ha podido hacer que esto funcione? Cualquier comentario sería genial, gracias!

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); 
} 

} 

} 

Respuesta

22

simplemente he intentado su código en un Nexus One con Android 2.1, y funciona bien. Recuerde que usted tendrá que añadir los permisos necesarios para su manifiesta:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> 
+0

Gracias por la respuesta y la información adicional, Roman. Me complace escuchar que esto se resuelve en 2.1. Me sorprende que el código que publiqué funcionó, simplemente lancé todas las cosas de GeoPermissions para ilustrar lo que estaba tratando de hacer en caso de que alguien pudiera decirme la forma correcta de hacerlo. ¿Alguna idea de si hay una forma de hacerlo funcionar en WebView en 2.0.1? Actualmente estoy trabajando en navigator.geolocation porque no parece ser utilizable en una WebView 2.0.1. ¡Gracias de nuevo! – ajh158

3

Nosotros (el equipo de PhoneGap) hemos lanzado recientemente una solución para esto. Básicamente, el problema era que a partir de Android 2.0, el WebView nativo ahora tiene su propia implementación de navigator.geolocation, y por lo tanto, el puente PhoneGap para esta función no se estaba configurando correctamente en JavaScript.

Desde entonces, una confirmación en particular ha creado una solución para esto: 'proxy' el objeto navigator.geolocation nativo a nuestra propia definición de este objeto. Este objeto funciona bien con el marco PhoneGap.

Para esta revisión, ver el siguiente compromiso: http://github.com/phonegap/phonegap-android/commit/5255f632377c36beb0b4d2620940f33b6d02b2c7

+0

Gracias fil maj - Yo sabía que la adición del objeto nativo había roto PhoneGap. Terminé haciendo algo similar a su solución, pero esperaba poder encontrar una forma de utilizar el objeto de geolocalización nativo desde un WebView. Mi código estaba destinado a demostrar que esto simplemente no funciona desde un WebView (phonegap o no). – ajh158

+0

fil, soy nuevo en la brecha del teléfono, ¿su compromiso se incorporará en la próxima versión? cuando? No quiero cortar mi propia construcción, pero si das instrucciones, con mucho gusto te cortaré de tu sucursal. –

+1

@fil, su URL es 404. Por favor, actualice. –

Cuestiones relacionadas