Adobe Flash Builder 4.5 Android Air 程序开发系列 之九 定位

时间:2022-05-02 20:44:59
地理位置
    地理位置,API能够定位到设备的一些信息。

地理位置类
    flash.events.GeolocationEvent
    权限:
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION">
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION">
    File loaction 是指与GPS的通行,Corase loaction 是指与网络的通信。接下我们将会对这两个概念做详细的介绍。
    在开发或者测试的过程中,设置【设置】|【位置和安全】|使用GPS卫星 和 【设置】|【位置和安全】|【使用无线网络】 都为选

中状态。
    //判断是否支持定位
    import flash.events.GeolocationEvent;
    if(Geolocation.isSupported)
        //Geolocation.supported
    我们写一个简单的应用程序来监听Geolocation 的事件的更新。设置Geolocation为类的实例变量,不是局部变量,以保证我们在使

用他的
时候没有被GC回收。
    import flash.events.GeolocationEvent;
    private var geolocation:Geolocation;
    
    if(Geolocation.isSupported)
    {
        geolocation=new Geolocation();
        geolocation.addEventListener(GeolocationEvent.UPDATE,onTravel);
    }
    private function onTravel(event:GeolocationEvent):void
    {
        trace(event.latitude)
        trace(event.longitude)
    }
    
    用户可以设置启用与禁用GPS装置,所以应用程序必须检查muted 属性,在初始化程序的时候需要访问该属性,还有一种情况是
在程序运行时监听更新的状态。
    import flash.events.StatusEvent;
    
    if(!geolocation.muted)
    {
        geolocation.addEventListener(StatusEvent.STATUS,onStatusChange);
    }
    else
    {
        //inform the user to turn on the location sensor
    }
    
    function onStatusChange(event:StatusEvent):void
    {
        trace("status"+event.code)
        if(event.code=="Geolocation.Muted")
        {
            //inform the user to turn on the location sensor
        }
    }
    GeolocationEvent
    
    GeolocationEvent.UPDATE 事件在第一次创建时就会被触发。如果设备在移动或者其他方式使设备位置发生变化的话,这个事件也

会被触发。
    这样刷新的频率会比较快,为了保护电池的寿命,可以通过设置setRequestUpdateInterval ,使刷新的频率降低,因为你的应用程

序本身不需要刷新很快。
    
    Geolocation.setRequestUpdateInterval(10000);
    event.latitude event.longitude 表示经纬度
    
    event.horizontalAccuracy event.verticalAccuracy 单位是米
    
    event.timeStamp 是以毫秒为单位,计算从程序初始化到移动的时间。
    
    event.altitude 单位是米,event.speed 单位是米/秒
    
    全球定位系统 和网络
    
    GPS 或者是WIFI 是否打开
    
    flash.net.NetworkInfo 类提供了 在电脑以及设备上的网络接口。权限:
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE">
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE">
    //检查是否支持
    if(NetworkInfo.isSupported)
    {
        //network information supported
    }
    NetworkInfo 存储了一些网络接口。
    var network:NetwrkInfo=NetworkInfo.networkInfo;
    for each(var object:NetworkInterface in network.findInterfaces())
    {
        trace(object.name);
    }
    
    方向地理编码
    我们从设备获取的仅仅是经纬度,只有在地图中会比较有用。有一种技术就是反向地理编码,传递过去经纬度,发送过来的是地址


    
    查看一下的实例:
    权限:
    <uses-permission android:name="android.permission.INTERNET"/>
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.IOErrorEvent;
    import flash.events.GeolocationEvent;
    import flash.events.StatusEvent;
    import flash.net.URLLoader;
    import flash.net.URLRequest;
    import flash.net.URLRequestMethod;
    import flash.net.URLVariables;
    import flash.sensors.Geolocation;
    
    public class ReverseGeo extends Sprite
    {
        private const YAHOO_URL:String = "http://where.yahooapis.com/geocode";
        private const ID:String = "YOUR_ID";
        private var _geo:Geolocation;
        private var _loader:URLLoader;
        
        public function ReverseGeo()
        {
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;
            if (Geolocation.isSupported)
            {
                init();
            }
        }
        
        private function init():void
        {
            _geo = new Geolocation();
            _geo.addEventListener(GeolocationEvent.UPDATE, onUpdate);
        }
        
        private function onUpdate(event:GeolocationEvent):void
        {
            var request:URLRequest = new URLRequest(YAHOO_URL);
            var variables:URLVariables = new URLVariables();
            variables.q =     event.latitude.toString() + "\n" + event.longitude.toString();
            
            variables.gflags = "R";
            variables.appid = ID;
            request.data = variables;
            request.method = URLRequestMethod.GET;
            
            _loader = new URLLoader();
            _loader.addEventListener(Event.COMPLETE, onLocationLoaded);
            _loader.addEventListener(IOErrorEvent.IO_ERROR, onError);
            _loader.load(request);
        }
        
        private function onLocationLoaded(event:Event):void
        {
            trace("*** event", event);
            _loader.removeEventListener(Event.COMPLETE, onLocationLoaded);
            _geo.removeEventListener(GeolocationEvent.UPDATE, onUpdate);
            var xml:XML = new XML(event.target.data);
            trace(xml);
            var city:String = xml.Result.city.text();
            var country:String = xml.Result.country.text();
            trace(city, country);
        }
        
        private function onError(event:IOErrorEvent):void
        {
            trace("*** error", event);
        }
        
    }
    
     地图
    
    提供地图服务的有 Google Maps,Yahoo Maps,Bing Maps 等等。
    
     加载google 地图:
    <uses-permission android:name="android.permission.INTERNET">
    
    import flash.events.GeolocationEvent;
    import flash.net.navigateToURL;
    import flash.net.URLRequest;
    import flash.sensors.Geolocation;
    
    private function onLocationUpdate(event:GeolocationEvent):void
    {
        geolocation.removeEventListener(GeolocationEvent.UPDATE,onLocationUpdate);
        var long:String=event.longitde.toString();
        var lat:String=event.latitude.toString();
        navigateToURL(new URLRequest("http://maps.google.com/?q="+lat+","+long));
    }
    
    静态地图
    静态地图提供了一种比较好的解决方案。在AIR程序中时比较轻量级的显示地图。他是对一个位置的快照,但是不能平移和缩放,但

是可以
根据GPS很快的加载。
    Yahoo 静态地图
    import flash.display.Loader;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.GeolocationEvent;
    import flash.net.URLLoader;
    import flash.net.URLRequest;
    import flash.sensors.Geolocation;
    
    public class StaticMap extends Sprite
    {
        private const YAHOO_URL:String = "http://local.yahooapis.com/MapsService/V1/mapImage";
        private const ID:String = "YOUR_ID";
        private var _geo:Geolocation;
        
        public function StaticMap()
        {
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;
            if (Geolocation.isSupported)
            {
                init();
            }
        }
        
        private function init():void
        {
            _geo = new Geolocation();
            _geo.addEventListener(GeolocationEvent.UPDATE, onUpdate);
        }
        
        // get current latitude and longitude
        private function onUpdate(event:GeolocationEvent):void
        {
            trace("travel", event.latitude, event.longitude);
            var request:String = "?appid="
                + ID
                + "&latitude="
                + event.latitude
                + "&longitude="
                + event.longitude
                + "&zoom=1&image_height="
                + stage.stageHeight
                + "&image_width="
                + stage.stageWidth;
            
            // request a map image for the location
            var urlLoader:URLLoader = new URLLoader();
            urlLoader.addEventListener(Event.COMPLETE, onXMLReceived);
            urlLoader.load(new URLRequest(YAHOO_URL + request));
        }
        
        // get an XML with path to static map
        private function onXMLReceived(event:Event):void
        {
            event.target.removeEventListener(Event.COMPLETE, onXMLReceived);
            _geo.removeEventListener(GeolocationEvent.UPDATE, onUpdate);
            
            var xml:XML = XML(event.currentTarget.data);
            trace("xml", xml);
            // load static map
            var loader:Loader = new Loader();
            loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onImageLoaded);
            loader.load(new URLRequest(xml));
        }
        
        // display static map
        private function onImageLoaded(event:Event):void
        {
            event.currentTarget.removeEventListener(Event.COMPLETE, onImageLoaded);
            this.addChild(event.currentTarget.content);
        }
        
    }
    
    Google 静态地图
    
    import flash.display.Loader;
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.GeolocationEvent;
    import flash.net.URLLoader;
    import flash.net.URLRequest;
    import flash.sensors.Geolocation;
    
    public class StaticMapGoogle extends Sprite
    {
        private const GOOGLE_URL:String = "http://maps.google.com/maps/api/staticmap?";
        private var _geo:Geolocation;
        
        public function StaticMapGoogle()
        {
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;
            if (Geolocation.isSupported)
            {
                init();
            }
        }
        
        private function init():void
        {
            _geo = new Geolocation();
            _geo.addEventListener(GeolocationEvent.UPDATE, onUpdate);
        }
        
        // get current latitude and longitude
        private function onUpdate(event:GeolocationEvent):void
        {
            // Google API limits image size to 640 pixels
            var width:int = Math.min(640, stage.stageWidth);
            var height:int = Math.min(640, stage.stageHeight);
            
            var request:String =
                "?&markers=size:large|color:blue|label:L|"
                + event.latitude + "," + event.longitude
                + "&zoom=15&size="
                + width
                + "x"
                + height
                + "&maptype=roadmap&mobile=true&sensor=true";
            
            // display static map
            var loader:Loader = new Loader();
            loader.y = 75;
            addChild(loader);
            loader.load(new URLRequest(GOOGLE_URL + request));
        }
        
    }
    
    动态地图:
        
        Google Maps API
        从google 的网站下载http://code.google.com/intl/zh-CN/apis/maps/documentation/flash/ 包括两个swc

(map_1_20.swc 和 map_flex_1_20.swc),
    添加swc类库到项目中。
        权限:
        <uses-permission android:name="android.permission.INTERNET">
    创建Map 对象的实例,Map实例需要你注册的时候添加的 APIkey 以及URL,这样你就建立了一个独立的Android 应用程序。
    实例如下:
            import com.google.maps.InfoWindowOptions;
    import com.google.maps.LatLng;
    import com.google.maps.Map;
    import com.google.maps.MapEvent;
    import com.google.maps.MapMouseEvent;
    import com.google.maps.MapType;
    import com.google.maps.controls.ZoomControl;
    import com.google.maps.overlays.Marker;
    import com.google.maps.overlays.MarkerOptions;
    import com.google.maps.styles.FillStyle;
    
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.GeolocationEvent;
    import flash.geom.Point;
    import flash.sensors.Geolocation;
    
    public class DynamicMap extends Sprite
    {
        private const KEY:String = "YOUR_KEY";
        private const SITE:String = "YOUR_SITE";
        private var _geo:Geolocation;
        private var _map:Map;
        
        public function DynamicMap()
        {
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;
            if (Geolocation.isSupported)
            {
                init();
            }
        }
        
        private function init():void
        {
            _geo = new Geolocation();
            
            // prepare Map object
            _map = new Map();
            _map.key = KEY;
            _map.url = SITE;
            _map.sensor = "true";
            
            _map.setSize(new Point(stage.stageWidth, stage.stageHeight));
            _map.addEventListener(MapEvent.MAP_READY, onMapReady);
            addChild(_map);
        }
        
        private function onMapReady(event:MapEvent):void
        {
            _geo.addEventListener(GeolocationEvent.UPDATE, onUpdate);
        }
        
        private function onUpdate(event:GeolocationEvent):void
        {
            _map.setCenter(new LatLng(event.latitude, event.longitude), 18, MapType.NORMAL_MAP_TYPE);
            _map.addControl(new ZoomControl());
            
            // Add a marker with a FillStyle and information window
            var options:Object = {hasShadow:true, fillStyle: new FillStyle({color:0x0099FF, alpha:0.75}),

radius:20};
            var marker:Marker = new Marker(new LatLng(event.latitude, event.longitude), new MarkerOptions

(options));
            marker.addEventListener(MapMouseEvent.CLICK, markerClicked);
            _map.addOverlay(marker);
        }
        
        private function markerClicked(event:MapMouseEvent):void
        {
            event.currentTarget.openInfoWindow(new InfoWindowOptions({content:"Hello\nAIR World"}));
        }
        
    }
    
    Exif 数据 和地图
    
    import com.google.maps.Map;
    import com.google.maps.MapEvent;
    import com.google.maps.LatLng;
    import com.google.maps.MapType;
    import com.google.maps.overlays.Marker;
    import com.google.maps.overlays.MarkerOptions;
    
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.MediaEvent;
    import flash.geom.Point;
    import flash.media.CameraRoll;
    import flash.net.URLRequest;
    
    import jp.shichiseki.exif.ExifInfo;
    import jp.shichiseki.exif.ExifLoader;
    import jp.shichiseki.exif.IFD;
    
    public class ExifMap extends Sprite
    {
        public const KEY:String = "YOUR_KEY";
        public const SITE:String = "YOUR_SITE";
        private var _cameraRoll:CameraRoll;
        private var _map:Map;
        private var _exifLoader:ExifLoader;
        
        public function ExifMap()
        {
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;
            
            if (CameraRoll.supportsBrowseForImage)
            {
                init();
            }
        }
        
        private function init():void
        {
            _map = new Map();
            _map.url = SITE;
            _map.key = KEY;
            _map.sensor = "false";
            _map.setSize(new Point(stage.stageWidth, stage.stageHeight));
            _map.addEventListener(MapEvent.MAP_READY, onMapReady);
            addChild(_map);
        }
        
        private function onMapReady(event:MapEvent):void
        {
            _map.setCenter(new LatLng(40.736072, -73.992062), 14, MapType.NORMAL_MAP_TYPE);
            var camera:CameraRoll = new CameraRoll();
            camera.addEventListener(MediaEvent.SELECT, onImageSelected);
            camera.browseForImage();
        }
        
        private function onImageSelected(event:MediaEvent):void
        {
            _exifLoader = new ExifLoader();
            _exifLoader.addEventListener(Event.COMPLETE, onImageLoaded);
            _exifLoader.load(new URLRequest(event.data.file.url));
        }
        
        private function onImageLoaded(event:Event):void
        {
            var exif:ExifInfo = _exifLoader.exif;
            
            if (exif.ifds.gps["GPSLatitude"] != null)
            {
                var gpsIfd:IFD = exif.ifds.gps;
                var exifLat:Array = gpsIfd["GPSLatitude"] as Array;
                var exifLon:Array = gpsIfd["GPSLongitude"] as Array;
                
                var latitude:Number = shorten(exifLat, gpsIfd["GPSLatitudeRef"]);
                var longitude:Number = shorten(exifLon, gpsIfd["GPSLongitudeRef"]);
                var marker:Marker = new Marker(new LatLng(latitude, longitude));
                _map.addOverlay(marker);
                _map.setCenter(new LatLng(latitude, longitude));
                
            } else {
                trace("no gps info");
            }
        }
        
        private function shorten(info:Array, reference:String):Number
        {
            var degree:Number = info[0] + (info[1]/60) + (info[2]/3600);
            // position from Greenwich and equator
            if (reference == "S" || reference == "W")
            {
                degree *= -1;
            }
            return degree;
        }
    }
    
    速度
    结论