Использование navigator.geolocation.getCurrentPosition в WebView на Android 2.0+ (связано с PhoneGap)

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

Вопрос

Я работал с PhoneGap, и это было здорово, но я столкнулся с проблемой получения местоположения на Verizon Droid с поддержкой 2.0.1 (работает, как и ожидалось, на G1 с поддержкой 1.6).

Поддержка GeoLocation API была добавлена в Android в версии 2.0 (Eclair), и она работает в браузере по умолчанию на 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:ОШИБКА /geolocationService(16871):Поймано исключение безопасности, регистрирующееся для получения обновлений местоположения из системы.Это должно происходить только в DumpRenderTree."

Мне кажется, что WebView не удается зарегистрироваться для обновления местоположения, потому что у него нет требуемого разрешения, что, в свою очередь, является результатом того, что пользователь не запрашивает разрешение.Хотя в пакет Webkit в Android 2.0 было добавлено несколько методов и объектов, связанных с GeoPermissions, я не смог использовать ни один из них, чтобы вызвать WebView для отображения диалогового окна GeoPermission.

Следующее основано на примере Hello, WebView из Руководства разработчика Android, но в нем добавлены некоторые вызовы и объекты, которые были добавлены в версии 2.0, связанные с геопереходами.* Обновлено с помощью соответствующего URL-адреса (с разрешения автор - спасибо Оливеру!).

Кто-нибудь смог заставить это работать?Любой отзыв был бы замечательным, спасибо!

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

}

}
Это было полезно?

Решение

Я только что попробовал ваш код на Nexus One с Android 2.1, и он работает нормально.Помните, что вам нужно будет добавить необходимые разрешения в свой манифест:

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

Другие советы

Мы (команда PhoneGap) недавно выпустили исправление для этого.По сути, проблема заключалась в том, что начиная с Android 2.0, собственный WebView теперь имеет свою собственную реализацию navigator.geolocation, и, следовательно, мост PhoneGap для этой функции не был настроен должным образом в JavaScript.

С тех пор конкретный коммит создал обходной путь для этого:мы "прокси" собственный объект navigator.geolocation привязываем к нашему собственному определению этого объекта.Этот объект хорошо работает с фреймворком PhoneGap.

Для этого исправления смотрите следующую фиксацию: 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

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

app/AndroidManifest.xml

<uses-permission android:name="android.permission.READ_PHONE_STATE" />
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top