views:

3346

answers:

3

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

}

}
+2  A: 

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

fil maj
Thanks fil maj - I knew that the addition of the native object had broken phonegap. I ended up doing something similar to your workaround, but I was hoping we could find a way to make use of the native geolocation object from within a WebView. My code was meant to demonstrate that this simply doesn't work from a WebView (phonegap or no).
ajh158
A: 

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:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
Roman Nurik
Thanks for the response and the additional information, Roman. I'm glad to hear that this is resolved in 2.1. I'm surprised the code that I posted worked - I just threw all the GeoPermissions stuff in there to illustrate what I was trying to do in case someone could tell me the right way to do it. Any idea if there is a way to make it work in a WebView on 2.0.1? Currently I am working around navigator.geolocation because it does not seem to be usable in a 2.0.1 WebView. Thanks again!
ajh158
A: 

Hi, I make a website using asp using local database. In there I check the Id and Passward to login that page. Now how can I check the Id and Passward using android code and store data to website/make connection with web(by emulator/device)? Please anyone know, help me....My assignment submit date in knocking the door. Asma

Asma-ull-Hosna