如何使用 android webview 在 appcelerator 的钛移动应用程序上进行地理定位

发布于 2024-11-05 13:06:20 字数 3327 浏览 1 评论 0原文

我只是在使用 Appcelerator 的 Titanium 平台来开发移动应用程序。

我的测试应用程序只是打开一个指向在线网页的网络视图。此页面使用 W3C 地理定位 API 来获取用户的位置。

这是我的 tiapp.xml 特定的 android 权限:

<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>

这是我用于获取坐标的 javascript 代码:

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

似乎 navigator.geolocation 和 navigator.geolocation.getCurrentPosition 已定义,但委托无论如何都不会执行。

问题是:如何让它发挥作用? :-)

提前致谢。

更新:我发现问题似乎是Android 2.x webview有它自己的navigator.geolocation实现。根据phonegap源代码上的此提交

更新 2: 我编写了一个非常小的完整原生 Android 应用程序,它可以将 Web 客户端打开到同一网页并且工作正常:

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

更新 3:我从 appcelerator 的 github 站点找到了此源代码: https://github.com/appcelerator/titanium_mobile/blob/master/android/modules/ui/src/ti/modules/titanium/ui/widget/webview/TiWebChromeClient.java

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

冰魂雪魄 2024-11-12 13:06:21

Titanium 的最强之处在于它是每个平台上的本机代码。通过使用 webview,您可以极大地避免本机代码的优势。

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

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

在标题为“何时使用 HTML”的部分中,它指出以下内容:

“应尽可能避免使用 HTML。几乎您需要的所有内容都可以使用本机代码完成。应用程序将加载速度更快,对用户操作的反应更快,从而带来更好的用户体验。”

按照这些标准,我建议您获取位置,然后创建或更新网络视图。至于为什么 javascript 不起作用我没有答案,因为创建 webview 时会加载完整的 DOM?

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?

懷念過去 2024-11-12 13:06:21

最后我通过修改 TiWebChromeClient.java,并生成新的 titan-ui.jar 文件。

添加了此代码,现在我可以在 Android webView 上使用地理定位:

import android.webkit.GeolocationPermissions.Callback;

...

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

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);
    }
梦幻之岛 2024-11-12 13:06:21

我们的解决方案如下:

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

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);
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文