Usando o Navigator.geolocation.getCurrentPosition no WebView no Android 2.0+ (Relacionado pelo PhoneGap)

StackOverflow https://stackoverflow.com/questions/2267513

Pergunta

Eu tenho trabalhado com o PhoneGap e tem sido ótimo, mas encontrei um problema em obter a localização em um Droid Verizon com 2.0.1 (funciona conforme o esperado em um G1 W/ 1.6).

O suporte da API de geolocalização foi adicionado ao Android no 2.0 (Eclair) e funciona no navegador padrão em um Droid Verizon (em 2.0.1). Ou seja, se eu visitar um site que chama o Navigator.geolocation.GetCurrentPosition (SUCCEST_CALLBACK, ERROR_CALLBACK), o dispositivo solicita que o domínio atual "deseja saber sua localização" em uma caixa de diálogo com opções para "compartilhar localização" ou "declínio". Se eu selecionar "compartilhar localização", o sucesso_callback acabará sendo chamado com dados de localização.

Se eu visitar o mesmo site em um WebView, a chamada para o Navigator.geolocation.GetCurrentPosition não gera um erro de JavaScript, mas a caixa de diálogo "Compartilhe sua localização" não é exibida e nenhum retorno de chamada é chamado. No Logcat, vejo o que parece ser um erro relacionado: "02-15 10: 37: 00.413: Erro/Geolocationservice (16871): Exceção de segurança pegada Registro-se para atualizações de localização do sistema. Isso só deve acontecer no Dumprendertree."

Parece -me que o WebView não está se registrando para atualizações de localização, porque não possui a permissão necessária, o que, por sua vez, é resultado de não solicitar o usuário para a permissão. Embora houvesse vários métodos e objetos adicionados ao pacote Webkit no Android 2.0 relacionados às missões generalizadas, não consegui usar nenhum deles para fazer com que a WebView exiba a caixa de diálogo de geopermissão.

A seguir, é baseada no exemplo do Hello, WebView do guia do desenvolvedor do Android, mas adiciona algumas das chamadas e objetos que foram adicionados em 2.0 relacionados a geopermissões. *Atualizado com um URL apropriado (com permissão de o autor - obrigado Oliver!).

Alguém conseguiu fazer isso funcionar? Qualquer feedback seria ótimo, obrigado!

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

}

}
Foi útil?

Solução

Acabei de experimentar seu código em um Nexus One com o Android 2.1 e funciona bem. Lembre -se de que você precisará adicionar as permissões necessárias ao seu manifesto:

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

Outras dicas

Nós (a equipe do PhoneGap) lançamos recentemente uma correção para isso. Basicamente, o problema era que, no Android 2.0, o WebView nativo agora tem sua própria implementação do Navigator.geolocation e, portanto, a ponte do PhoneGap para essa função não estava sendo definida corretamente no JavaScript.

Desde então, um comprometimento específico criou uma solução alternativa para isso: nós 'proxy' o objeto de navegador nativo.geolocation para nossa própria definição desse objeto. Este objeto funciona bem com a estrutura do PhoneGAP.

Para esta correção, consulte a seguinte confirmação: http://github.com/phonegap/phonegap-android/commit/5255f632377c36beb0b4d2620940f33b6d02b2c7

Este link tem a chavehttp://cordova.apache.org/docs/en/2.5.0/cordova_device_device.md.html

Estou desenvolvendo com Android - PhoneGap

Eu adicionei

app/res/xml/config.xml

<plugin name="Device" value="org.apache.cordova.Device" />

app/androidmanifest.xml

<uses-permission android:name="android.permission.READ_PHONE_STATE" />
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top