最近公司做了一个关于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;
}
}
}
//位置信息
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;
}
}