第11章 使用位置信息 位置API 代码实例 位置API 位置API(javax.microedition.location)允许应用程序获取BlackBerry设备的全球定位系统(GPS)位置。GPS位置是BlackBerry设备中的地理坐标(经度和纬度)。根据使用 的位置方法,应用程序也可以获得BlackBerry设备的速度,方向,以及路线。 获得GPS位置的方法 方法 方法 常数 描述 Cellsite GPS_AID_MODE_CELLSITE 本方法使用活动的蜂窝(cellsite) 塔的GPS位置来提供第一个有序GPS信息。它提供最不精确的位置信息;虽说如此,但它是最快的位置模式。 注:如果使用本模式,将得不到方向,路径,以及速度获。这个位置方法需要网络连接以及运营商的支持。 Assisted GPS_AID_MODE_ASSIST 本方法使用网络为设备的芯片提供天文卫星数据。它比自动模式提供GPS位置更快些,并且比蜂窝模式更精确。 注:本位置方法需要网络连接以及运营商的支持。 Autonomous GPS_AID_MODE_AUTONOMOUS 本方法在没有网络的协助下使用BlackBerry上的GPS芯片。自动模式提供第一个GPS位置最慢。 常数 描述 Cellsite GPS_AID_MODE_CELLSITE 本方法使用活动的蜂窝(cellsite) 塔的GPS位置来提供第一个有序GPS信息。它提供最不精确的位置信息;虽说如此,但它是最快的位置模式。 注:如果使用本模式,将得不到方向,路径,以及速度获。这个位置方法需要网络连接以及运营商的支持。 Assisted GPS_AID_MODE_ASSIST 本方法使用网络为设备的芯片提供天文卫星数据。它比自动模式提供GPS位置更快些,并且比蜂窝模式更精确。 注:本位置方法需要网络连接以及运营商的支持。 Autonomous GPS_AID_MODE_AUTONOMOUS 本方法在没有网络的协助下使用BlackBerry上的GPS芯片。自动模式提供第一个GPS位置最慢。 为选择GPS位置方法指定原则 通过创建一个javax.microedition.location.Criteria类,调用合适的set方法,然后传递这个LocationProvider.getInstance()实例来指定需要的原则. 注:为创建一个缺省规则的LocationProvider实例,调用 LocationProvider.getInstance(null). Criteria criteria = new Criteria(); // Allow cost. criteria.setCostAllowed(true); // Require a horizontal accuracy of 50 metres. criteria.setHorizontalAccuracy(50); // Require a vertical accuracy of 50 metres. criteria.setVerticalAccuracy(50); LocationProvider provider = LocationProvider.getInstance(criteria); 选择GPS位置方法的原则 建议的GPS位置方法 注:如果BlackBerry无线设备有一个卫星的障碍视图,GPS可能不可用。当设备在室内或被建筑物,树,以及密云围绕,这是有可能发生的。 获取BlackBerry设备的位置 第一次获取BlackBerry设备位置所花的时间依赖多方面的因素,例如选择的GPS模式,GPS的信号强度。在自动模式中,典型的至少需要2分钟,在协助模式。典型的是至少需要30秒。 如果GPS修正在10秒的请求内发生后,连续请求的平均响应时间为1到2秒,这取决位置条件。 注:如果你使用了一个可能花费用户资费的位置方法,不要经常查询BlackBerry设备的位置。 为了指定一个需要的响应事件,调用Criteaia.setPreferredReponseTime(),以毫秒为单位提供需要的时间。 获取BlackBerry设备的位置 调用LocationProvider.getLocation(int),提供一个以毫秒为单位的超时时间。 注:如果LocationProvider.getLocation(int)早事件线程调用,LocationExcept会抛出。 try { // Specify -1 to have the implementation use its default timeout value // for this provider. Location location = provider.getLocation(-1); } catch (Exception e) { // handle LocationException, InterruptedException, SecurityException // and IllegalArgumentException } 获取位置信息 Location类提供方法来获取位置信息,例如GPS坐标,以及路径。 注:RIM的实现不支持文本地址信息。结果,getAddressInfo()方法会空。 QualifiedCoordinates coordinates = location.getQualifiedCoordinates; float speed = location.getSpeed(); float course = location.getCourse(); 注册一个位置监听者 实现LocationListener方法。调用LocationProvider.setLocationListener()注册你的实现。 注:一个位置监听者可以与一个指定的位置提供者项关联。应用程序在一个独立的线程上典型用来监听更新。 import javax.microedition.LocationProvider.*; public class SampleLocationApp { public static void main (string[] Args) { // ... provider.setLocationListener(new SampleLocationListener(), 0, 60, 60); } } class SampleLocationListener implements LocationListener { void locationUpdated(LocationProvider provider, Location location) { // Respond to the updated location. // If the application registered the location listener with an interval of // 0, the location provider does not provide location updates. } void providerStateChanged(LocationProvider provider, int newState) { switch (newState) { case LocationProvider.AVAILABLE : // The location provider is available. break; case LocationProvider.OUT_OF_SERVICE : // The location provider is permanently unavailable. // Consider cancelling the location listener by calling // provider.setLocationListener() with null as the listener. break; case LocationProvider.TEMPORARILY_UNAVAILABLE : // The location provider is temporarily unavailable. break; } } } 代码实例 例:GPSDemo.java /** * A GPS sample application using the JSR 179 APIs. * * Copyright (C) 2005 Research In Motion Limited. */ package com.rim.samples.docs.gpsdemo; import net.rim.device.api.ui.*; import net.rim.device.api.ui.component.*; import net.rim.device.api.ui.container.*; import com.rim.samples.docs.baseapp.*; import net.rim.device.api.io.*; import net.rim.device.api.system.*; import net.rim.device.api.i18n.*; import javax.microedition.io.*; import java.util.*; import java.io.*; import javax.microedition.location.*; import net.rim.device.api.util.*; import com.rim.samples.docs.resource.*; /* This application acts as a simple travel computer, recording route coordinates, * speed, and altitude. * Recording begins as soon as the application is invoked. */ public class GPSDemo extends BaseApp implements GPSDemoResResource { // Constants. ---------------------------------------------------------------- // The number of updates in seconds over which the altitude is calculated. private static final int GRADE_INTERVAL=5; // com.rim.samples.docs.gpsdemo.GPSDemo.ID private static final long ID = 0x4e94d9bc9c54fed3L; private static final int CAPTURE_INTERVAL=10; // Statics. ------------------------------------------------------------------ private static ResourceBundle _resources = ResourceBundle.getBundle(GPSDemoResResource.BUNDLE_ID, GPSDemoResResource.BUNDLE_NAME); // The period of the position query in seconds. private static int _interval = 1; private static Vector _previousPoints; private static float[] _altitudes; private static float[] _horizontalDistances; private static PersistentObject _store; // Initialize or reload the persistent store. static { _store = PersistentStore.getPersistentObject(ID); if(_store.getContents()==null) { _previousPoints= new Vector(); _store.setContents(_previousPoints); } _previousPoints=(Vector)_store.getContents(); } private long _startTime; private float _wayHorizontalDistance; private float _horizontalDistance; private float _verticalDistance; private ListField _listField; private EditField _status; private StringBuffer _messageString; private String _oldmessageString; private LocationProvider _locationProvider; /* Instantiate the new application object and enter the event loop. * @param args unsupported. no args are supported for this application */ public static void main(String[] args) { new GPSDemo().enterEventDispatcher(); } // Constructors. ------------------------------------------------------------- public GPSDemo() { // Used by waypoints; represents the time since the last waypoint. _startTime = System.currentTimeMillis(); _altitudes=new float[GRADE_INTERVAL]; _horizontalDistances=new float[GRADE_INTERVAL]; _messageString= new StringBuffer(); MainScreen screen = new MainScreen(); screen.setTitle(new LabelField(_resources.getString(GPSDEMO_TITLE), LabelField.USE_ALL_WIDTH)); _status = new EditField(); screen.add(_status); screen.addKeyListener(this); screen.addTrackwheelListener(this); // Start the GPS thread that listens for updates. startLocationUpdate(); // Render our screen. pushScreen(screen); } /* Update the GUI with the data just received. */ private void updateLocationScreen(final String msg) { invokeLater(new Runnable() { public void run() { _status.setText(msg); } }); } // Menu items. --------------------------------------------------------------- // Cache the markwaypoint menu item for reuse. private MenuItem _markWayPoint = new MenuItem(_resources, GPSDEMO_MENUITEM_MARKWAYPOINT, 110, 10) { public void run() { GPSDemo.this.markPoint(); } }; // Cache the view waypoints menu item for reuse. private MenuItem _viewWayPoints = new MenuItem(_resources, GPSDEMO_MENUITEM_VIEWWAYPOINTS, 110, 10) { public void run() { GPSDemo.this.viewPreviousPoints(); } }; // Cache the close menu item for reuse. private MenuItem _close = new MenuItem(_resources, GPSDEMO_MENUITEM_CLOSE, 110, 10) { public void run() { System.exit(0); } }; protected void makeMenu(Menu menu, int instance) { menu.add( _markWayPoint ); menu.add( _viewWayPoints ); menu.add( _close ); menu.addSeparator(); super.makeMenu(menu, instance); } /* Invokes the Location API with the default criteria. */ private void startLocationUpdate() { try { _locationProvider = LocationProvider.getInstance(null); if ( _locationProvider == null ) { Dialog.alert("GPS is not supported on this platform, exiting..."); System.exit(0); } // A single listener can be associated with a provider, // and unsetting it involves the same call but with null, // so there is no need to cache the listener instance. // Request an update every second. _locationProvider.setLocationListener(new LocationListenerImpl(), _interval, 1, 1); } catch (LocationException le) { System.err.println("Failed to add a location listener. Exiting..."); System.err.println(le); System.exit(0); } } /* Marks a point in the persistent store. Calculations are based on * all data collected since the previous way point, or from the start * of the application if no previous waypoints exist. */ private void markPoint() { long current = System.currentTimeMillis(); WayPoint p= new WayPoint(_startTime, current, _wayHorizontalDistance, _verticalDistance); addWayPoint(p); // Reset the waypoint variables. _startTime = current; _wayHorizontalDistance = 0; _verticalDistance = 0; } // View the saved waypoints. private void viewPreviousPoints() { PointScreen pointScreen = new PointScreen(_previousPoints, _resources); pushScreen(pointScreen); } // Called by the framework when this application is losing focus. protected void onExit() { if ( _locationProvider != null ) { _locationProvider.reset(); _locationProvider.setLocationListener(null, -1, -1, -1); } } /* Adds a new WayPoint and commits the set of saved waypoints * to flash memory. * @param p The point to add. */ /*package*/ synchronized static void addWayPoint(WayPoint p) { _previousPoints.addElement(p); commit(); } /* Removes a waypoint from the set of saved points and * commits the modifed set to flash memory. * @param p the point to remove */ /*package*/ synchronized static void removeWayPoint(WayPoint p) { _previousPoints.removeElement(p); commit(); } // Commit the waypoint set to flash memory. private static void commit() { _store.setContents(_previousPoints); _store.commit(); } /* * Implementation of the LocationListener interface. */ private class LocationListenerImpl implements LocationListener { // Members. -------------------------------------------------------------- private int captureCount; // Methods. -------------------------------------------------------------- public void locationUpdated(LocationProvider provider, Location location) { if(location.isValid()) { float heading = location.getCourse(); double longitude = location.getQualifiedCoordinates().getLongitude(); double latitude = location.getQualifiedCoordinates().getLatitude(); float altitude = location.getQualifiedCoordinates().getAltitude(); float speed = location.getSpeed(); // Horizontal distance. float horizontalDistance = speed * _interval; _horizontalDistance += horizontalDistance; // Horizontal distance for this waypoint. _wayHorizontalDistance += horizontalDistance; // Distance over the current interval. float totalDist = 0; // Moving average grade. for(int i = 0; i 0) _verticalDistance = _verticalDistance + altGain; captureCount += _interval; // If we’re mod zero then it’s time to record this data. captureCount %= CAPTURE_INTERVAL; // Information to display on the device. StringBuffer sb = new StringBuffer(); sb.append("Longitude: "); sb.append(longitude); sb.append("\n"); sb.append("Latitude: "); sb.append(latitude); sb.append("\n"); sb.append("Altitude: "); sb.append(altitude); sb.append(" m"); sb.append("\n"); sb.append("Heading relative to true north: "); sb.append(heading); sb.append("\n"); sb.append("Speed : "); sb.append(speed); sb.append(" m/s"); sb.append("\n"); sb.append("Grade : "); if(Float.isNaN(grade))sb.append(" Not available"); else sb.append(grade+" %"); GPSDemo.this.updateLocationScreen(sb.toString()); } } public void providerStateChanged(LocationProvider provider, int newState) { // No operation defined. } } /* WayPoint describes a way point, a marker on a journey or point of interest. * WayPoints are persistable. * package */ static class WayPoint implements Persistable { public long _startTime; public long _endTime; public float _distance; public float _verticalDistance; public WayPoint(long startTime,long endTime,float distance,float verticalDistance) { _startTime=startTime; _endTime=endTime; _distance=distance; _verticalDistance=verticalDistance; } } } public float _verticalDistance; public WayPoint(long startTime,long endTime,float distance,float verticalDistance) { _startTime=startTime; _endTime=endTime; _distance=distance; _verticalDistance=verticalDistance; } } /*PointScreen.java Copyright (C) 2005 Research In Motion Limited. */ package com.rim.samples.docs.gpsdemo; import net.rim.device.api.ui.*; import net.rim.device.api.ui.component.*; import net.rim.device.api.ui.container.*; import com.rim.samples.docs.baseapp.*; import net.rim.device.api.io.*; import net.rim.device.api.system.*; import com.rim.samples.docs.resource.*; import net.rim.device.api.i18n.*; import javax.microedition.io.*; import java.util.*; import java.io.*; import javax.microedition.location.*; import com.rim.samples.docs.gpsdemo.GPSDemo.WayPoint; import com.rim.samples.docs.resource.*; /* * PointScreen is a screen derivative that renders the saved WayPoints. * */ public class PointScreen extends MainScreen implements ListFieldCallback, GPSDemoResResource { private Vector _points; private ListField _listField; private ResourceBundle _resources; public float _verticalDistance; public WayPoint(long startTime,long endTime,float distance,float verticalDistance) { _startTime=startTime; _endTime=endTime; _distance=distance; _verticalDistance=verticalDistance; } } /* * PointScreen.java Copyright (C) 2005 Research In Motion Limited. */ package com.rim.samples.docs.gpsdemo; import net.rim.device.api.ui.*; import net.rim.device.api.ui.component.*; import net.rim.device.api.ui.container.*; import com.rim.samples.docs.baseapp.*; import net.rim.device.api.io.*; import net.rim.device.api.system.*; import com.rim.samples.docs.resource.*; import net.rim.device.api.i18n.*; import javax.microedition.io.*; import java.util.*; import java.io.*; import javax.microedition.location.*; import com.rim.samples.docs.gpsdemo.GPSDemo.WayPoint; import com.rim.samples.docs.resource.*; /* * PointScreen is a screen derivative that renders the saved WayPoints. */ public class PointScreen extends MainScreen implements ListFieldCallback, GPSDemoResResource { private Vector _points; private ListField _listField; private ResourceBundle _resources; } // Menu items. --------------------------------------------------------------- private class ViewPointAction extends MenuItem { private int _index; public ViewPointAction( int index ) { super(PointScreen.this._resources.getString(GPSDEMO_POINTSCREEN_MENUITEM_VIEW), 100000, 10); _index = index; } public void run() { ViewScreen screen = new ViewScreen( (WayPoint)_points.elementAt(_index), index, _resources ); UiApplication.getUiApplication().pushModalScreen( screen ); } } private class DeletePointAction extends MenuItem { private int _index; public DeletePointAction( int index ) { super(PointScreen.this._resources.getString(GPSDEMO_POINTSCREEN_MENUITEM_DELETE), 100000, 10); _index = index; } public void run() { GPSDemo.removeWayPoint((WayPoint)_points.elementAt(_index)); } } protected void makeMenu(Menu menu, int instance) { if( _points.size() > 0 ) { ViewPointAction viewPointAction = new ViewPointAction( listField.getSelectedIndex() ); menu.add( viewPointAction ); menu.addSeparator(); DeletePointAction deletePointAction = new DeletePointAction( listField.getSelectedIndex() ); menu.add( deletePointAction ); } super.makeMenu(menu, instance); } /* * Renders a particular Waypoint. */ private static class ViewScreen extends MainScreen { private ResourceBundle _resources; private MenuItem _cancel; public ViewScreen(WayPoint point, int count, ResourceBundle resources) { super(); _resources = resources; LabelField title = new LabelField(resources.getString(GPSDEMO_VIEWSCREEN_TITLE) + count, LabelField.ELLIPSIS | LabelField.USE_ALL_WIDTH); setTitle(title); Date date = new Date(point._startTime); String startTime = date.toString(); date = new Date(point._endTime); String endTime = date.toString(); float avgSpeed = point._distance/(point._endTime - point._startTime); add(new BasicEditField(resources.getString(GPSDEMO_VIEWSCREEN_STARTFIELD), startTime, 30, Field.READONLY)); add(new BasicEditField(resources.getString(GPSDEMO_VIEWSCREEN_ENDFIELD), endTime, 30, Field.READONLY)); add(new BasicEditField(resources.getString(GPSDEMO_VIEWSCREEN_HORIZONTALDISTANCEFIELD), Float.toString(point._distance), 30, Field.READONLY)); add(new BasicEditField(resources.getString(GPSDEMO_VIEWSCREEN_VERTICALDISTANCEFIELD), Float.toString(point._verticalDistance), 30, Field.READONLY)); add(new BasicEditField(resources.getString(GPSDEMO_VIEWSCREEN_AVESPEEDFIELD), Float.toString(avgSpeed), 30, Field.READONLY)); } private class CancelMenuItem extends MenuItem { public CancelMenuItem() { // Reuse an identical resource below. super(ViewScreen.this._resources, GPSDEMO_OPTIONSSCREEN_MENUITEM_CANCEL, 300000, 10); } public void run() { UiApplication uiapp = UiApplication.getUiApplication(); uiapp.popScreen(ViewScreen.this); } }; protected void makeMenu( Menu menu, int instance ) { if ( _cancel == null ) _cancel = new CancelMenuItem(); // Create on demand. menu.add(_cancel); super.makeMenu(menu, instance); } } }
j2me 位置API
最新推荐文章于 2010-01-07 09:27:00 发布