开发者

How to get geolocation working on appcelerator's titanium mobile application with android webview

I'm just playing with Appcelerator's Titanium platform for developing mobile apps.

My test application just opens a webview pointing to an online web page. This page uses the W3C Geolocation API to get user's location.

This are my tiapp.xml specific android permissions:

<android xmlns:android="http://schemas.android.com/apk/res/android">
    <manifest>
        <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
        <uses-permission android:name="android.permission.INTERNET"/>
        <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
        <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
        <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>
    </manifest>
</android>

This is my javascript code for getting coords:

if (navigator.geolocation) {

    navigator.geolocation.getCurrentPosition(function(position){

        $("#results").append('Longitude: ' + position.coords.longitude + '<br/>');
        $("#results").append('Latitude: ' + position.coords.latitude + '<br/>');

    }, function(error){

        $("#results").append('An error ocurred ' + error.message);
    });

} else {

    $("#results").append('Geolocation not supported');
}

It seems that navigator.geolocation and navigator.geolocation.getCurrentPosition are defined but delegate's are not executed anyway.

The question is: how to get this working? :-)

Thanks in advance.

Update: I found that the problem seems that Android 2.x webview has it's own implementation of navigator.geolocation. According to this commit on phonegap's source code.

Update 2: I wrote a very small full-native android application that opens a webclient to same webpage and works fine:

package com.sourcerebels;

import android.app.Activity;
import android.os.Bundle;
import android.webkit.GeolocationPermissions.Callback;
import android.webkit.WebChromeClient;
import android.webkit.WebView;

class MyClient extends WebChromeClient {

    @Override
    public void onGeolocationPermissionsShowPrompt(String origin,
            Callback callback) {
        callback.invoke(origin, true, false);
    }
}

public class TestWebClient extends Activity {

    WebView webView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        webView = (WebView) findViewById(R.id.webView1);
        webView.getSettings().setJavaScriptEnabled(true);
        webView.getSettings().setGeolocationDatabasePath("/data/data/testWebClient");
    开发者_如何学C    webView.loadUrl("http://www.sourcerebels.com/index2.html");

        webView.setWebChromeClient(new MyClient());
    }
}

Update 3: I found this source from appcelerator's github site: https://github.com/appcelerator/titanium_mobile/blob/master/android/modules/ui/src/ti/modules/titanium/ui/widget/webview/TiWebChromeClient.java


Titanium's strongest aspect is that it is Native Code on each platform. By using the webview you are greatly avoiding the Native Code advantage.

http://wiki.appcelerator.org/display/guides/Using+Location+services

http://wiki.appcelerator.org/display/guides/HTML5+vs+Native+UI

In the section titled When To Use HTML it states the following:

"HTML should be avoided as much as possible.Almost everything you need it can be done using native code. The app will load faster and will react faster to the user's actions leading to a better user experience."

Going by those standards I would advise you to get the location and then create or update a webview. As for why the javascript isn't working I don't have an answer because a full DOM is loaded when you create a webview?


Finally I solved this "issue" by modifying TiWebChromeClient.java from Titanium mobile SDK sources, and generating a new titanium-ui.jar file.

Added this code and now I can use geolocation on Android webView:

import android.webkit.GeolocationPermissions.Callback;

...

    @Override
    public void onGeolocationPermissionsShowPrompt(String origin,
            Callback callback) {
        callback.invoke(origin, true, false);
    }


Our solution is as follows:

import android.webkit.GeolocationPermissions;

    // enable navigator.geolocation 
    mWebView.getSettings().setGeolocationEnabled(true);
    mWebView.getSettings().setGeolocationDatabasePath("/data/data/databases/");


    // START Allow Geolocation prompt
    public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
        callback.invoke(origin, true, false);
    }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜