如何使用 android webview 在 appcelerator 的钛移动应用程序上进行地理定位
我只是在使用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
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?
最后我通过修改 TiWebChromeClient.java,并生成新的 titan-ui.jar 文件。
添加了此代码,现在我可以在 Android 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:
我们的解决方案如下:
Our solution is as follows: