找回密码
 注册
搜索
查看: 1195|回复: 1

[讨论] Rexsee API介绍:GPS定位与原生源码

[复制链接]
发表于 2011-12-22 15:24:39 | 显示全部楼层 |阅读模式
GPS是相对较为熟悉的功能,网上也有大量的相关应用源码分享。作为Rexsee API中很重要的一部分功能,这里重点分享一下应该如何启动这项服务。以及结合Rexsee与高德地图的合作,如何实现在地图中的定位。最后会把整个源码分享出来。内容有点多,收藏了吧~~

在Rexsee实现的应用中,GPS不能通过程序直接启动,而需要按一定顺序执行:首先你需要打开GPS,GPS在一个终端上,你首先需要判断GPS是否就绪,通过下面这个函数来判断。
【函数】 boolean isReady()
【说明】 GPS是否就绪。
【返回】 true或false。
【参数】 无
【示例】 alert(rexseeGps.isReady());运行示例  

如果GPS没有就绪,这是你需要先打开GPS,通过下面这个函数来判断
【函数】 void openSettings()
【说明】 打开GPS配置页面,成功打开GPS会触发事件onGpsSettingSuccessed,否则会触发事件onGpsSettingFailed。
【返回】 无
【参数】 无
【示例】 rexseeGps.openSettings();运行示例  

通过这个函数,你可以打开GPS配置界面,在配置界面中,你可以把GPS设置为就绪状态。GPS就绪后,你就可以去启动GPS,启动GPS的函数如下
【函数】 void start()
【说明】 启动GPS,如果GPS尚未打开会报错。
【返回】 无
【参数】 无
【示例】 rexseeGps.start();
rexseeDialog.toast('开始定位......');运行示例  

启动后,你可能会需要关闭,关闭的函数如下
【函数】 void stop()
【说明】 关闭GPS。
【返回】 无
【参数】 无
【示例】 rexseeGps.stop();
rexseeDialog.toast('停止定位。');运行示例  

Rexsee应该是与高德有比较密切的合作吧?在它的API里包括了高德地图的API,通过高德地图对象内的函数,可以很轻松的制作出类似谷歌地图这样的导航软件。对于高德地图对象,在使用前需要注意:所有的操作都必须先打开地图插件后才可以进行;在地图插件打开后,当数据没有在插件框体内加载完毕前关闭插件或按下回退键,极易造成程序崩溃。所以再打开插件的时候最好设置为不可回退取消。

插件窗口的设置十分讲究,首先需要考虑到屏幕的密度。拿现在主流的ANDROID手机来说,分辨率普遍在480*800,密度1.5。那么它的标准分辨率就应该是320*534。也就是说,320宽度的图片在480*800的手机上宽度是帐号满屏的。

Rexsee因为是基于WEB的开发,所以可以将程序做成全机型自动适配,那么在调整窗口的位置的时候就需要在位置上编写一定的逻辑。当然,屏幕像素获取方式不同,值也不同。直接用document.body.clientHeight之类的函数获得的是没有密度的分辨率,而用rexseeSreen对象获取到的则是带密度的,因为这里不能用百分比设定,而且插件窗口会盖住下面的浮出菜单。并且,在平板上,有的没有通知栏,或者通知栏在下面,有的需要减去通知栏的高度,有的则不需要。这都是需要去判断的。

rexseeMapAbc.start('window-cancelable:false;window-moveable:false;border-width:10px;border-color:#0000FF;window-align:center;window-vertical-align:top;width:'+Math.round(rexseeScreen.getScreenWidth()/rexseeScreen.getScreenDensityScale())+';height:'+Math.round(rexseeScreen.getScreenHeight()/(2*rexseeScreen.getScreenDensityScale()))+';window-modeless:true;window-dim-amount:0;');

基本操作中还包含了中心点设置,定位,路况。
高德地图中的数据操作,导航操作,兴趣点操作返回值都是已数组的形式(前提是EVAL过)出现的,也就是所在导航时我们有多条路供选择,随后有一个实例,当然,本人很偷懒的默认第一条线路。实例和教程目前已经在Rexsee的项目中心放出,当然大家可以自行改动。

由于导航需要提供2地的经纬度,所以请大家配合数据转换中的地名获得目的地信息的函数方法使用,当然最好是限制经纬度范围,否则必须要拼写详细,如XX省XX市XX地名。请求出来的则是数跳线路,请根据需要取其中的1条或生成选择菜单。

        function getRoute()
        {
        rexseeMapAbc.hideRoute();
        var places=eval('('+prompt('prompt','title=导航输入框;message=请输入起始地和目的地:;options=起始地:|目的地:;defaultValue=北京市北京西站|北京市北京南站;inputType=text|text;')+')');
        var startPlace=places[0];
        var endPlace=places[1];
       
        var tempsp=eval('('+rexseeMapAbc.getAddressFromLocationName(startPlace,1)+')');
        var tempep=eval('('+rexseeMapAbc.getAddressFromLocationName(endPlace,1)+')');
        var splong=tempsp[0].Longitude+"";
        var splat=tempsp[0].Latitude+"";
        //alert(splong+" "+splat);
        var eplong=tempep[0].Longitude+"";
        var eplat=tempep[0].Latitude+"";
        rexseeMapAbc.requestRoute('routeRequest01',splong,splat,eplong,eplat,role);
        }
        function onRouteReady(id){
        //      alert(rexseeMapAbc.getRequesedRoute(id));
                var temps=rexseeMapAbc.getRequestedRoute(id);
                //temps = temps.replace(/\r\n","");
                temps = temps.replace(/\n/g,"");
                temps = temps.replace(/\r/g,"");
        //    alert(temps);
        temps=eval('('+temps+')');
        //  alert(temps.length);
                 var longs=temps[0].startLongitude;
                 var lat=temps[0].startLatitude;
        //      alert(long+" "+lat);
                 rexseeMapAbc.setCenter(longs,lat);
                 rexseeMapAbc.showRoute(id,0)
        }

兴趣点的控制和路线控制属于同一个,如果关闭兴趣点,那么地图上的导航线也会一起消失。高德地图如果配合GPS使用的话,需要按照国家标准偏移,请偏移后(对象有提供相应函数)再进行定位,否则会有偏差。

最后,提供经纬度作为参数时,请先转换为字符串,不然偏差很大。

附上Rexsee的GPS全部源码,有兴趣的也可以去Rexsee的开源社区查询:http://www.rexsee.com/。近期新上线的项目中心还支持在线开发,应用源码的共享功能很赞。。

package rexsee.location;  

import java.io.IOException;  
import java.util.List;  

import rexsee.core.browser.JavascriptInterface;  
import rexsee.core.browser.RexseeBrowser;  
import rexsee.core.browser.ActivityResult.ActivityResultListener;  
import rexsee.core.utilities.RexseeUtilities;  
import android.content.Context;  
import android.content.Intent;  
import android.location.Address;  
import android.location.Geocoder;  
import android.location.Location;  
import android.location.LocationListener;  
import android.location.LocationManager;  
import android.os.Bundle;  
import android.provider.Settings;  

public class RexseeGps implements JavascriptInterface {  

       private static final String INTERFACE_NAME = "Gps";  
       @Override  
       public String getInterfaceName() {  
               return mBrowser.application.resources.prefix + INTERFACE_NAME;  
       }  
       @Override  
       public JavascriptInterface getInheritInterface(RexseeBrowser childBrowser) {  
               return this;  
       }  
       @Override  
       public JavascriptInterface getNewInterface(RexseeBrowser childBrowser) {  
               return new RexseeGps(childBrowser);  
       }  

       public static final String EVENT_ONGPSSETTINGSUCCESSED = "onGpsSettingSuccessed";  
       public static final String EVENT_ONGPSSETTINGFAILED = "onGpsSettingFailed";  
       public static final String EVENT_ONGPSENABLED = "onGpsEnabled";  
       public static final String EVENT_ONGPSDISABLED = "onGpsDisabled";  
       public static final String EVENT_ONGPSSTATUSCHANGED = "onGpsStatusChanged";  
       public static final String EVENT_ONGPSLOCATIONCHANGED = "onGpsLocationChanged";  

       public static String address2Json(Address address) {  
               if (address == null) return "{}";  
               String rtn = "";  
               rtn += "{";  
               rtn += "\"Premises\":\"" + address.getPremises() + "\""; //Type of the location. Cross, road or POI.  
               rtn += ",\"Latitude\":" + address.getLatitude();  
               rtn += ",\"Longitude\":" + address.getLongitude();  
               rtn += ",\"address\":[";  
               for (int j = 0; j < address.getMaxAddressLineIndex(); j++) {  
                       if (j != 0) rtn += ",";  
                       rtn += "\"" + address.getAddressLine(j) + "\"";  
               }  
               rtn += "]";  
               rtn += ",\"CountyCode\":\"" + address.getCountryCode() + "\"";  
               rtn += ",\"CountryName\":\"" + address.getCountryName() + "\"";  
               rtn += ",\"AdminArea\":\"" + address.getAdminArea() + "\"";  
               rtn += ",\"SubAdminArea\":\"" + address.getSubAdminArea() + "\"";  
               rtn += ",\"Locality\":\"" + address.getLocality() + "\"";  
               //rtn += ",\"SubLocality\":\"" + address.getSubLocality() + "\"";Not support SDK3  
               rtn += ",\"Thoroughfare\":\"" + address.getThoroughfare() + "\"";  
               //rtn += ",\"SubThoroughfare\":\"" + address.getSubThoroughfare() + "\"";Not support SDK3  
               rtn += ",\"PostalCode\":\"" + address.getPostalCode() + "\"";  
               rtn += ",\"FeatureName\":\"" + address.getFeatureName() + "\"";  
               rtn += ",\"Phone\":\"" + address.getPhone() + "\"";  
               //rtn += ",\"Premises\":\"" + address.getPremises() + "\"";Not support SDK3  
               rtn += ",\"Url\":\"" + address.getUrl() + "\"";  
               rtn += ",\"Language\":\"" + address.getLocale().getDisplayLanguage() + "\"";  
               rtn += "}";  
               return rtn;  
       }  
       public static String addresses2Json(List<Address> addresses) {  
               String rtn = "[";  
               for (int i = 0; i < addresses.size(); i++) {  
                       if (i != 0) rtn += ",";  
                       rtn += address2Json(addresses.get(0));  
               }  
               rtn += "]";  
               return rtn;  
       }  

       private int minUpdateDuration = 60;  
       private int minUpdateDistance = 500;  

       private final Context mContext;  
       private final RexseeBrowser mBrowser;  

       private final LocationListener mListener;  

       public RexseeGps(final RexseeBrowser browser) {  
               mContext = browser.getContext();  
               mBrowser = browser;  
               browser.eventList.add(EVENT_ONGPSSETTINGSUCCESSED);  
               browser.eventList.add(EVENT_ONGPSSETTINGFAILED);  
               browser.eventList.add(EVENT_ONGPSENABLED);  
               browser.eventList.add(EVENT_ONGPSDISABLED);  
               browser.eventList.add(EVENT_ONGPSSTATUSCHANGED);  
               browser.eventList.add(EVENT_ONGPSLOCATIONCHANGED);  
               browser.destroyListeners.add(new Runnable() {  
                       @Override  
                       public void run() {  
                               stop();  
                       }  
               });  
               mListener = new LocationListener() {  
                       @Override  
                       public void onLocationChanged(Location location) {  
                               if (browser != null) {  
                                       browser.eventList.run(EVENT_ONGPSLOCATIONCHANGED, new String[]{  
                                                               String.valueOf(location.getTime()),  
                                                               String.valueOf(location.getAccuracy()),  
                                                               String.valueOf(location.getLongitude()),  
                                                               String.valueOf(location.getLatitude()),  
                                                               String.valueOf(location.getSpeed()),  
                                                               String.valueOf(location.getBearing()),  
                                                               String.valueOf(location.getAltitude())  
                                               });  
                               }  
                       }  
                       @Override  
                       public void onProviderDisabled(String provider) {  
                               if (browser != null) {  
                                       browser.eventList.run(EVENT_ONGPSDISABLED);  
                               }  
                       }  
                       @Override  
                       public void onProviderEnabled(String provider) {  
                               if (browser != null) {  
                                       browser.eventList.run(EVENT_ONGPSENABLED);  
                               }  
                       }  
                       @Override  
                       public void onStatusChanged(String provider, int status, Bundle extras) {  
                               if (browser != null) {  
                                       browser.eventList.run(EVENT_ONGPSSTATUSCHANGED, new String[]{String.valueOf(status)});  
                               }  
                       }  
               };  
       }  

       //JavaScript Interface  
       public boolean isReady() {  
               return (((LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE)).isProviderEnabled(LocationManager.GPS_PROVIDER)) ? true : false;  
       }  
       public void openSettings() {  
               Intent intent = new Intent(Settings.ACTION_SECURITY_SETTINGS);  
               mBrowser.activityResult.start(intent, new ActivityResultListener() {  
                       @Override  
                       public void run(int resultCode, Intent resultIntent) {  
                               if (isReady()) {  
                                       mBrowser.eventList.run(EVENT_ONGPSSETTINGSUCCESSED);  
                               } else {  
                                       mBrowser.eventList.run(EVENT_ONGPSSETTINGFAILED);  
                               }  
                       }  
               });  
       }  
       public void start() {  
               if (isReady()) {  
                       LocationManager locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);  
                       locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, minUpdateDuration * 1000, minUpdateDistance, mListener);  
               } else {  
                       mBrowser.exception(getInterfaceName(), "GPS is not available.");  
               }  
       }  
       public void stop() {  
               try {  
                       ((LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE)).removeUpdates(mListener);  
               } catch (Exception e) {  
               }  
       }  

       public void setMinimumUpdateDuration(int seconds) {  
               minUpdateDuration = seconds;  
       }  
       public int getMinimumUpdateDuration() {  
               return minUpdateDuration;  
       }  
       public void setMinimumUpdateDistance(int meter) {  
               minUpdateDistance = meter;  
       }  
       public int getMinimumUpdateDistance() {  
               return minUpdateDistance;  
       }  

       public String getLastKnownLocation() {  
               if (!isReady()) return "{}";  
               try {  
                       Location location = ((LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE)).getLastKnownLocation(LocationManager.GPS_PROVIDER);  
                       if (location == null) return "";  
                       String rtn = "{";  
                       rtn += "\"time\":" + location.getTime();  
                       rtn += ",\"accuracy\":" + location.getAccuracy();  
                       rtn += ",\"longitude\":" + location.getLongitude();  
                       rtn += ",\"latitude\":" + location.getLatitude();  
                       rtn += ",\"speed\":" + location.getSpeed();  
                       rtn += ",\"bearing\":" + location.getBearing();  
                       rtn += ",\"altitude\":" + location.getAltitude();  
                       rtn += "}";  
                       return rtn;  
               } catch (Exception e) {  
                       mBrowser.exception(getInterfaceName(), e);  
                       return "{}";  
               }  
       }  
       public String getLastKnownGeo(int maxNumber) {  
               if (!isReady()) return "[]";  
               try {  
                       Location location = ((LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE)).getLastKnownLocation(LocationManager.GPS_PROVIDER);  
                       if (location == null) return "";  
                       Geocoder geo = new Geocoder(mContext);  
                       List<Address> addresses = geo.getFromLocation(location.getLatitude(), location.getLongitude(), maxNumber);  
                       return addresses2Json(addresses);  
               } catch (IOException e) {  
                       mBrowser.exception(getInterfaceName(), e);  
                       return "[]";  
               }  
       }  

       public float getDistanceBetween(String startLongitude, String startLatitude, String endLongitude, String endLatitude) {  
               double sLatitude = RexseeUtilities.getDouble(startLatitude, 0);  
               double sLongitude = RexseeUtilities.getDouble(startLongitude, 0);  
               double eLatitude = RexseeUtilities.getDouble(endLatitude, 0);  
               double eLongitude = RexseeUtilities.getDouble(endLongitude, 0);  
               float results[] = new float[3];  
               Location.distanceBetween(sLatitude, sLongitude, eLatitude, eLongitude, results);  
               return results[0];  
       }  

}
发表于 2011-12-22 16:04:43 | 显示全部楼层
这帖子也太长了吧,LZ辛苦了。Rexsee的项目中心昨天去了,挺不错,直接在线开发,测试起来会很方便
点评回复

使用道具 举报

高级模式
B Color Image Link Quote Code Smilies

本版积分规则

Archiver|手机版|小黑屋|52RD我爱研发网 ( 沪ICP备2022007804号-2 )

GMT+8, 2024-11-23 11:36 , Processed in 0.045535 second(s), 16 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表