论坛首页 移动开发技术论坛

Android地图和GPS功能实现,附GPS原生源码分享

浏览 3426 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-12-08  
地图和GPS会是比较常用的一个功能了,网上能找到相当多的示例,同时几个地图引擎的公司也有开放他们的地图SDK,可以加以利用。这次是重点研究了基于Rexsee实现地图路线控制这个功能,分享出来。同时把Rexsee写的GPS功能源码也全部贴出来,有点多。看不明白的自己去Rexsee的社区:http://www.rexsee.com/

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

插件窗口的设置十分讲究,首先我们需要考虑到屏幕的密度。拿现在主流的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过)出现的,也就是所在导航时有多条路供选择,随后有一个实例,当然,本人很偷懒的默认第一条线路。实例和教程随后会一起放出,当然大家可以自行改动。由于导航需要提供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源码,搞原生的可以直接看这个
/*
* Copyright (C) 2011 The Rexsee Open Source Project
*
* Licensed under the Rexsee License, Version 1.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.rexsee.com/CN/legal/license.html
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

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; 
mport 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]; 
       } 

}
论坛首页 移动开发技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics