Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 403
sourcerebels Avatar asked Feb 24 '23 06:02

sourcerebels


2 Answers

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?

like image 119
rivenate247 Avatar answered Feb 26 '23 22:02

rivenate247


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);
    }
like image 34
sourcerebels Avatar answered Feb 26 '23 21:02

sourcerebels