转自:http://www.linuxidc.com/Linux/2011-09/42454.htm
概念与基本类
前不久学习GPS,故在Android系统(HTC G7手机)上做了一个GPS信号解析工具,现总结如下,欢迎各位指正
功能:
1. 获取了location的GPS信息,包括经纬度,速度,方向等
2. 卫星信息,包括卫星数,仰角,方位角,信噪比等。
并画了一个地球的形状的图显示卫星信息,由于没有时间,还没有去获取磁场传感器信息
先来了解下GPS的基本概念:
GPS是Global positioning system 的缩写,即全球定位系统,目的是在全球范围内对地面和空中目标进行准确定位和检测
GPS系统一般由地面控制站,导航卫星和接收机三大部分组成
而手机带GPS功能,它首先必须有GPS模块,才能接收GPS信号,GPS模块通过异步串行通信方式与微处理器控制模块进行通信。GPS模块会每隔1秒就向串口发送GPS数据
在Android平台上,从窗口获取GPS数据已经被系统做了,为我们提供接口,只需去调用这些接口,就可以获取GPS数据,而不用去读串口;如果在WINCE平台上,要获取GPS数据就得去读取串口,而且WINCE中的串口是独占设备,如果在在程序中打开了串口进行数据的监控,那么打开导航软件之前必须把串口关闭,当然也可以使用虚拟串口的方式,让多个进程能同时获取数据,以下我只要提供了一些主要的模块。
主要用到的类:
LocationManager;
Location;
GpsStatus;
Criteria;
主要的变量定义:
private Location location;
// 定位管理类
private LocationManager locationManager;
//监听卫星变量
private GpsStatus gpsStatus;
Iterable
protected Iterator
private Criteria criteria;
1.打开GPS服务,LocationManger是获取位置管理服务,GPS信息和卫星信息都需要它:
LocationManager locationManager;
private void openGPSSettings()
{
// 获取位置管理服务
locationManager = (LocationManager)this.getSystemService(Context.LOCATION_SERVICE);
if (locationManager.isProviderEnabled(Android.location.LocationManager.GPS_PROVIDER))
{
Toast.makeText(this, "GPS模块正常", Toast.LENGTH_SHORT).show();
return;
}
status = false;
Toast.makeText(this, "请开启GPS!", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(Settings.ACTION_SECURITY_SETTINGS);
startActivityForResult(intent,0); //此为设置完成后返回到获取界面
}
2.填充Criteria位置数据标准类,并调用位置监听函数和卫星监听函数,将所要操作的设置在Criteria数据标准类中设置,为true时可以使用
private void getLocation()
{
// 查找到服务信息 位置数据标准类
Criteria criteria = new Criteria();
//查询精度:高
criteria.setAccuracy(Criteria.ACCURACY_FINE);
// 是否查询海拔:是
criteria.setAltitudeRequired(true);
//是否查询方位角:是
criteria.setBearingRequired(true);
//是否允许付费
criteria.setCostAllowed(true);
// 电量要求:低
criteria.setPowerRequirement(Criteria.POWER_LOW);
//是否查询速度:是
criteria.setSpeedRequired(true);
provider = locationManager.getBestProvider(criteria, true);
// 获取GPS信息 获取位置提供者provider中的位置信息
location = locationManager.getLastKnownLocation(provider);
// 通过GPS获取位置
updateToNewLocation(location);
// 设置监听器,自动更新的最小时间为间隔N秒(1秒为1*1000,这样写主要为了方便)或最小位移变化超过N米
//实时获取位置提供者provider中的数据,一旦发生位置变化 立即通知应用程序locationListener
locationManager.requestLocationUpdates(provider, 1000, 0,locationListener);
//监听卫星,statusListener为响应函数
locationManager.addGpsStatusListener(statusListener);
}
响应与信号解析
接下来是监听函数的响应函数:
1.location响应函数,当手机终端移动时,位置会发生改变,就会触发下面的location响应函数
//定位监听类负责监听位置信息的变化情况
private final LocationListener locationListener = new LocationListener()
{
//当位置改变时调用下面的函数
@Override
public void onLocationChanged(Location location)
{
//通过GPS获取位置,新的位置信息放在location中,调用updateToNewLocation函数显示位置信息
updateToNewLocation(location);
}
//当Provider不可用时调用下面的函数
@Override
public void onProviderDisabled(String arg0)
{
}
@Override
public void onProviderEnabled(String arg0)
{
}
@Override
public void onStatusChanged(String arg0, int arg1, Bundle arg2)
{
updateToNewLocation(null);
}
};
2.显示GPS位置信息,location响应函数中,当location发生变化时调用下面的函数
private void updateToNewLocation(Location location)
{
if (location != null)
{
bear = location.getBearing(); //偏离正北方的度数
float latitude = (float)location.getLatitude(); //维度
float longitude= (float)location.getLongitude(); //经度
float GpsSpeed = (float)location.getSpeed(); //速度
long GpsTime = location.getTime(); //时间
Date date = new Date(GpsTime); //利用Date进行时间的转换
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //设置时间的显示格式 也可以设置为:yyyy/MM/dd HH:mm:ss
float GpsAlt = (float)location.getAltitude(); //海拔
latitudeview.setText("" + latitude);
longitudeview.setText("" + longitude);
speedview.setText(""+GpsSpeed);
timeview.setText(""+df.format(date));
altitudeview.setText(""+GpsAlt);
bearingview.setText(""+bear);
}
else
{
Toast.makeText(this, "无法获取地理信息", Toast.LENGTH_SHORT).show();
}
}
}
3.Status 响应函数,当接收到的卫星的参数发生改变时,就会调用下面的响应函数
//添加监听卫星
private final GpsStatus.Listener statusListener= new GpsStatus.Listener(){
@Override
public void onGpsStatusChanged(int event) {
// TODO Auto-generated method stub
//获取GPS卫星信息,与获取location位置信息一样,还是通过locationManager类,方法为getGpsStatus,返回的是一个GpsStatus类型的结构
gpsStatus = locationManager.getGpsStatus(null);
//触发事件event
switch(event)
{
case GpsStatus.GPS_EVENT_STARTED:
break;
//第一次定位时间
case GpsStatus.GPS_EVENT_FIRST_FIX:
break;
//收到卫星信息,并调用DrawMap()函数,进行卫星信号解析并显示到屏幕上
case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
DrawMap();
break;
case GpsStatus.GPS_EVENT_STOPPED:
break;
}
}
;
4.卫星信号解析
private int heightp;
private int widthp;
protected void DrawMap() {
// TODO Auto-generated method stub
int i = 0;
//获取屏幕信息,dm为DisplayMetrics类型的变量
dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm); //调用这三个函数将屏幕信息保存在dm中
heightp = dm.heightPixels; //手机屏幕高度
widthp = dm.widthPixels; //手机屏幕宽度
//获取卫星信息,gpsStatus为卫星响应函数中获得的卫星GpsStatus类型变量
allSatellites = gpsStatus.getSatellites();
Iteratorsate = allSatellites.iterator();
//遍历获取每颗卫星的信息
while(Iteratorsate.hasNext())
{
GpsSatellite satellite = Iteratorsate.next();
alimuth[i] = satellite.getAzimuth(); //坐标方位角
elevation[i] = satellite.getElevation(); //卫星仰角
snr[i] = satellite.getSnr();
i++;
}
satcountview.setText(""+i);
//layout为继承自View的类,并调用其中的redraw显示卫星信息
layout.redraw(bear,alimuth,elevation,snr, widthp,heightp, i);
//调用invalidate()方法刷新view,显示绘制的信息
layout.invalidate();
}
配置与模拟器设置
1.在文件AndroidManifest.xml文件中修改权限:
在uses-permission中,代码如下:
2. 在运行中若要在模拟器中运行,还需要模拟器支持GPS,这一点开启模拟器的时候不一定开启了,模拟器对GPS的支持设置如下:
Eclipse软件中:window--->Android sdk and avd manager ,打开模拟器管理窗口,如果已经有可用的模拟器,则打开edit,如果没有就新建一个模拟器,如下图:
然后在HardWare右边的窗口中可以看到是否有对GPS的支持,如果没有,则点击右边的new,弹出如下的窗口:
从中选择对GPS的支持,然后ok退出。
这样模拟器就支持GPS了,可以利用模拟器来测试你的程序,
3.利用Eclipse中的Emulator Control来测试定位;
window-->show view --> Emulator Control(如果在show view当中没有Emulator Control,则在other菜单中),如果没有开启模拟器,则emulator control中为灰色,不能编辑,如果模拟器开启之后还是为灰色,则重启eclipse(模拟器不要关)