最近公司做了一个关于android手机打车的应用,主要功能都在地图上了,正好研究了一下,总结了些技术点,基本都是网上翻得,加上了自己的理解。废话不多说,上码!
GPS状态监听:
package com.map; import java.util.Iterator; import com.dlvct.sns.socket.LogicServer; import com.dlvct.sns.socket.clientpackets.CM_PLAYER_UP_DOWN_REQUEST; import com.dlvct.sns.socket.model.MapInfo; import android.content.Context; import android.location.GpsSatellite; import android.location.GpsStatus; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.location.LocationProvider; import android.os.Bundle; import android.os.Handler; import android.util.Log; import android.widget.Toast; /** * GPS * * GPS相关设置及位置取得等 * * @author */ public class GPS implements LocationListener{ private Context context; private Handler mHandler; Location currentLocation ; LocationManager locationManager; // private GpsStatus gpsstatus; /** * 机能说明:构造函数 * * @param IN * Context * @param OUT * */ public GPS(Context appContext,Handler mHandler,LocationManager locationManager,Location currentLocation) { this.context = appContext; this.mHandler = mHandler; this.locationManager = locationManager; this.currentLocation = currentLocation; } //位置变化时触发 @Override public void onLocationChanged(Location location) { // Toast.makeText(context, "location.getProvider():"+location.getProvider(), Toast.LENGTH_SHORT).show(); Log.v("GPSTEST", "Got New Location of provider:"+location.getProvider()); if(currentLocation!=null){ if(isBetterLocation(location, currentLocation)){ Log.v("GPSTEST", "It's a better location"); this.currentLocation= location; showLocation(location); } else { Log.v("GPSTEST", "Not very good!"); } } else{ Log.v("GPSTEST", "It's first location"); this.currentLocation=location; showLocation(location); } MapInfo.getInstance().setLoc(location.getLongitude(), location.getLatitude()); LogicServer.logicServerConn.sendPacket(new CM_PLAYER_UP_DOWN_REQUEST(), mHandler); //移除基于LocationManager.NETWORK_PROVIDER的监听器 if(LocationManager.NETWORK_PROVIDER.equals(location.getProvider())){ locationManager.removeUpdates(this); } // // MapInfo.getInstance().setLoc(location.getLongitude(), location.getLatitude()); // // LogicServer.logicServerConn.sendPacket(new CM_PLAYER_UP_DOWN_REQUEST(), mHandler); } //gps禁用时触发 @Override public void onProviderDisabled(String provider) { Log.d("Location", "onProviderDisabled"); //这里可以执行提醒用户开启GPS操作 Toast.makeText(context, "请开启GPS!", Toast.LENGTH_SHORT).show(); } //gps开启时触发 @Override public void onProviderEnabled(String provider) { Log.d("Location", "onProviderEnabled"); //这里可以提醒用户GPS已经正常开启 } //gps状态变化时触发 @Override public void onStatusChanged(String provider, int status, Bundle extras) { Log.d("Location", "onStatusChanged"); if(status==LocationProvider.AVAILABLE){ Log.e(null, "当前GPS状态:可见的"); }else if(status==LocationProvider.OUT_OF_SERVICE){ Log.e(null, "当前GPS状态:服务区外"); }else if(status==LocationProvider.TEMPORARILY_UNAVAILABLE){ Log.e(null, "当前GPS状态:暂停服务"); } } private void showLocation(Location location){ //纬度 Log.v("GPSTEST","Latitude:"+location.getLatitude()); //经度 Log.v("GPSTEST","Longitude:"+location.getLongitude()); //精确度 Log.v("GPSTEST","Accuracy:"+location.getAccuracy()); //Location还有其它属性,请自行探索 } public void removeListener(){ locationManager.removeUpdates(this); } private static final int CHECK_INTERVAL = 1000 * 30; /** * 判断获取的位置是否更好 * @author Administrator */ protected boolean isBetterLocation(Location location, Location currentBestLocation) { if (currentBestLocation == null) { // A new location is always better than no location return true; } // Check whether the new location fix is newer or older long timeDelta = location.getTime() - currentBestLocation.getTime(); boolean isSignificantlyNewer = timeDelta > CHECK_INTERVAL; boolean isSignificantlyOlder = timeDelta < -CHECK_INTERVAL; boolean isNewer = timeDelta > 0; // If it's been more than two minutes since the current location, // use the new location // because the user has likely moved if (isSignificantlyNewer) { return true; // If the new location is more than two minutes older, it must // be worse } else if (isSignificantlyOlder) { return false; } // Check whether the new location fix is more or less accurate int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation .getAccuracy()); boolean isLessAccurate = accuracyDelta > 0; boolean isMoreAccurate = accuracyDelta < 0; boolean isSignificantlyLessAccurate = accuracyDelta > 200; // Check if the old and new location are from the same provider boolean isFromSameProvider = isSameProvider(location.getProvider(), currentBestLocation.getProvider()); // Determine location quality using a combination of timeliness and // accuracy if (isMoreAccurate) { return true; } else if (isNewer && !isLessAccurate) { return true; } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) { return true; } return false; } /** Checks whether two providers are the same */ private boolean isSameProvider(String provider1, String provider2) { if (provider1 == null) { return provider2 == null; } return provider1.equals(provider2); } // private GpsStatus.Listener gpsListener = new GpsStatus.Listener(){ // // @Override // public void onGpsStatusChanged(int event) { // //获取当前状态 // gpsstatus=locationManager.getGpsStatus(null); // // switch(event){ // //第一次定位时的事件 // case GpsStatus.GPS_EVENT_FIRST_FIX: // Log.e("Location", "第一次定位时的事件"); // break; // //开始定位的事件 // case GpsStatus.GPS_EVENT_STARTED: // Log.e("Location", "开始定位的事件"); // break; // //发送GPS卫星状态事件 // case GpsStatus.GPS_EVENT_SATELLITE_STATUS: // Log.e("Location", "发送GPS卫星状态事件"); // // //获取卫星颗数的默认最大值 // int count1 = gpsstatus.getMaxSatellites(); // Log.e(null, "卫星列表的最大卫星数:"+count1); // //创建一个迭代器保存所有卫星 //// Iterable<GpsSatellite> allSatellites = gpsstatus.getSatellites(); //// Iterator<GpsSatellite> it = allSatellites.iterator(); // //// int count = 0; //// while(it.hasNext() && count <= maxSatellites){ //// Log.e(null, "while count:"+count); //// count++; //// } //// Toast.makeText(context, "Satellite Count:" + count, Toast.LENGTH_SHORT).show(); //// Log.e("Satellite Count:", "count:"+count); // break; // //停止定位事件 // case GpsStatus.GPS_EVENT_STOPPED: // Log.e("Location", "停止定位事件 "); // break; // } // } // }; // /** * 机能说明:判断GPS是否开启 * * @param IN * @param OUT * */ public boolean openGPSSettings() { LocationManager alm = (LocationManager) context .getSystemService(Context.LOCATION_SERVICE); if (alm.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER)) { return true; } else { return false; } } }
activity继承MapActivity 并创建监听,调用GPS:
//位置信息 Location currentLocation ; //位置服务 private LocationManager locationManager; //GPS监听 private LocationListener gpsListener=null; //network监听 private LocationListener networkListner=null; public void getLocation() { /* 获取位置管理服务 */ String serviceName = Context.LOCATION_SERVICE; locationManager = (LocationManager) this.getSystemService(serviceName); registerLocationListener(); } /** * 以下是开始监听:同时开启两个监听 * @author Administrator */ private void registerLocationListener(){ networkListner=new GPS(MapControllerActivity.this,mHandler,locationManager,currentLocation); locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 3000, 0, networkListner); gpsListener=new GPS(MapControllerActivity.this,mHandler,locationManager,currentLocation); locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 6000*10, 0, gpsListener); }
以上代码就是GPS定位了,包括network和GPS定位,network定位后将监听销毁,保留GPS监听。
下一步就是讲获得的经纬度以画布的形式画到地图上显示。
package com.map; import java.util.*; import android.app.AlertDialog; import android.app.ProgressDialog; import android.content.Context; import android.content.DialogInterface; import android.graphics.Canvas; import android.graphics.drawable.Drawable; import android.util.Log; import android.view.GestureDetector; import android.view.MotionEvent; import com.dlvct.sns.R; import com.google.android.maps.*; /** * 位置表示 * * 地图上显示位置PIN等信息 * * @author */ public class PlaceOverlay extends ItemizedOverlay<OverlayItem> implements GestureDetector.OnGestureListener { private List<OverlayItem> mOverlays = new ArrayList<OverlayItem>(); private Context context; public static Boolean longDown=false; public static float lat; public static float lon; GeoPoint point; MapView mapView; /** * 构造方法 * 机能说明:地图上描绘PIN * * @param IN * Drawable * @param OUT * */ public PlaceOverlay(Drawable defaultMarker,Context context) { super(boundCenterBottom(defaultMarker)); this.context = context; } /** * 机能说明:追加PIN * * @param IN * OverlayItem * @param OUT * */ public void addOverlay(OverlayItem overlay) { mOverlays.add(overlay); populate(); } /** * 机能说明:移除PIN * * @param IN * @param OUT * */ public void removeAllOverlay() { mOverlays.clear(); populate(); } /** * 机能说明:创建项目 * * @param IN * @param OUT * */ @Override protected OverlayItem createItem(int i) { return mOverlays.get(i); } /** * 机能说明:取得PIN个数 * * @param IN * @param OUT * */ @Override public int size() { return mOverlays.size(); } /** * 机能说明:点击PIN * * @param IN * @param OUT * */ @Override public boolean onTap(int index) { setFocus(mOverlays.get(index)); Log.e(null, "点击图标编号:"+index); return super.onTap(index); } /** * 点击地图任意点获取经纬度 */ @Override public boolean onTap(GeoPoint point, MapView mapView) { //p获取的经纬度数据是整型变量,需要转换为float类型 lat=point.getLatitudeE6(); lon=point.getLongitudeE6(); if(longDown==true){ this.point=point; this.mapView=mapView; List<Overlay> mapOverlays = mapView.getOverlays(); Log.e(null, "mapOverlays的长度:"+mapOverlays.size()); if(mapOverlays.size()>1){ mapOverlays.remove(1); } if(mapOverlays.size()==1){ Log.e(null, "mapOverlays的长度2:"+mapOverlays.size()); Drawable drawable = context.getResources().getDrawable(R.drawable.pin_red); //创建画布,将图标画到画布上 PlaceOverlay overlay = new PlaceOverlay(drawable,context); /* 创建标记 */ OverlayItem overlayItem = new OverlayItem(point, "标记title","标记摘要"); overlay.addOverlay(overlayItem); mapOverlays.add(overlay); Log.e(null, "what?????!"); } } //将当前的经纬度显示出来 Log.e(null, "lat:"+lat); Log.e(null, "lon:"+lon); // return super.onTap(point, mapView); return false; } @Override public void draw(Canvas canvas, MapView mapView, boolean shadow) { // TODO Auto-generated method stub super.draw(canvas, mapView, shadow); } private void DeleteOnClick() { // 创建AlertDialog.Builder对象 AlertDialog.Builder builder = new AlertDialog.Builder( context); // alert绑定图标 builder.setIcon(R.drawable.icon); // 表头 builder.setTitle(R.string.Common_GpsOpen); builder.setMessage(""); // 同意按钮 builder.setPositiveButton(R.string.Button_OK, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { List<Overlay> mapOverlays = mapView.getOverlays(); if(mapOverlays.size()>1){ mapOverlays.remove(1); } Drawable drawable = context.getResources().getDrawable(R.drawable.pin_red); //创建画布,将图标画到画布上 PlaceOverlay overlay = new PlaceOverlay(drawable,context); /* 创建标记 */ OverlayItem overlayItem = new OverlayItem(point, "标记title","标记摘要"); overlay.addOverlay(overlayItem); mapOverlays.add(overlay); // 关闭提示框 dialog.dismiss(); } }); // 取消按钮 builder.setNegativeButton(R.string.Button_cancel, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { dialog.dismiss(); } }); builder.create().show(); } @Override public boolean onDown(MotionEvent e) { // TODO Auto-generated method stub return true; } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { // TODO Auto-generated method stub return true; } @Override public void onLongPress(MotionEvent e) { // TODO Auto-generated method stub Log.e(null, "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { // TODO Auto-generated method stub return false; } @Override public void onShowPress(MotionEvent e) { // TODO Auto-generated method stub } @Override public boolean onSingleTapUp(MotionEvent e) { // TODO Auto-generated method stub return false; } }