Usando o Navigator.geolocation.getCurrentPosition no WebView no Android 2.0+ (Relacionado pelo PhoneGap)
-
20-09-2019 - |
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);
}
}
}
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" />