오늘은 업무상 예전에 작성했던 GPS 테스트 프로그램을 꺼내서 수정했습니다. 이 프로그램은 역사가 좀 있는 편인데, 안드로이드 개발을 배운 지 얼마 되지 않은 2011년에 썼는데, 실험적인 작품으로 여겨졌죠. 이제 작업에 필요한 부분이라 다시 꺼내서 수리해야겠습니다. 그러다가 안드로이드의 GPS 서비스에 대해 잘 모른다는 것을 알게 되어서 오늘 GPS 서비스에 대한 정보를 좀 읽고 관련 지식 포인트를 기록해 봤습니다.
저는 수년간 GPS 관련 임베디드 소프트웨어를 만들어 왔기 때문에 GPS 측위 모듈을 테스트하는 프로그램을 만들 때 가장 먼저 하는 반응은 직렬 포트를 통해 GPS 모듈의 데이터를 읽는 것입니다. , GPS 형식 데이터의 NMEA를 분석합니다. NMEA는 GPS뿐만 아니라 기타 산업 통신에도 사용되는 표준화된 데이터 형식입니다. 관련 데이터를 분석한 후 표시함으로써 기본적인 GPS 위치 확인 테스트 기능이 완성됩니다.
1. Android 포지셔닝 서비스
먼저 포지셔닝 서비스에 대해 Android에서 제공하는 지원을 살펴보겠습니다.안드로이드 위치 서비스는 모두 위치 아래에 위치해 있으니 여기서는 자세히 분석하지 않겠습니다. 언급해야 할 한 가지
는 다음과 같습니다. GpsStatus.NmeaListener. 공식적인 설명은 NMEA 데이터를 읽을 수 있다는 것이지만 여기서 테스트한 결과 NMEA 데이터가 읽히지 않은 것으로 나타났습니다. 일부 정보를 상담한 결과 Google은 하위 수준에서 데이터 피드백 기능을 구현하지 않는다고 합니다. 시간나시면 소스코드도 확인해 보시기 바랍니다.
2. LocationManager 포지셔닝
//获取定位服务 LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE); //判断是否已经打开GPS模块 if (locationManager.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER)) { //GPS模块打开,可以定位操作 }
// 通过GPS定位 String LocateType= locationManager.GPS_PROVIDER; Location location = locationManager.getLastKnownLocation(LocateType); // 设置监听器,设置自动更新间隔这里设置1000ms,移动距离:0米。 locationManager.requestLocationUpdates(provider, 1000, 0, locationListener); // 设置状态监听回调函数。statusListener是监听的回调函数。 locationManager.addGpsStatusListener(statusListener); //另外给出 通过network定位设置 String LocateType= locationManager.NETWORK_PROVIDER; Location location = locationManager.getLastKnownLocation(LocateType);
private final GpsStatus.Listener statusListener = new GpsStatus.Listener() { public void onGpsStatusChanged(int event) { // GPS状态变化时的回调,获取当前状态 GpsStatus status = locationManager.getGpsStatus(null); //自己编写的方法,获取卫星状态相关数据 GetGPSStatus(event, status); } };
private void GetGPSStatus(int event, GpsStatus status) { Log.d(TAG, "enter the updateGpsStatus()"); if (status == null) { } else if (event == GpsStatus.GPS_EVENT_SATELLITE_STATUS) { //获取最大的卫星数(这个只是一个预设值) int maxSatellites = status.getMaxSatellites(); Iterator<GpsSatellite> it = status.getSatellites().iterator(); numSatelliteList.clear(); //记录实际的卫星数目 int count = 0; while (it.hasNext() && count <= maxSatellites) { //保存卫星的数据到一个队列,用于刷新界面 GpsSatellite s = it.next(); numSatelliteList.add(s); count++; Log.d(TAG, "updateGpsStatus----count="+count); } mSatelliteNum = numSatelliteList.size(); } else if(event==GpsStatus.GPS_EVENT_STARTED) { //定位启动 } else if(event==GpsStatus.GPS_EVENT_STOPPED) { //定位结束 } }
위치 변경을 모니터링하는 위치 지정 리스너도 모니터링해야 합니다. 이는 위치 서비스를 제공하는 애플리케이션에 매우 중요합니다.
5. LocationListener 리스너
private final LocationListener locationListener = new LocationListener() { public void onLocationChanged(Location location) { //当坐标改变时触发此函数,如果Provider传进相同的坐标,它就不会被触发 updateToNewLocation(location); Log.d(TAG, "LocationListener onLocationChanged"); } public void onProviderDisabled(String provider) { //Provider被disable时触发此函数,比如GPS被关闭 Log.d(TAG, "LocationListener onProviderDisabled"); } public void onProviderEnabled(String provider) { // Provider被enable时触发此函数,比如GPS被打开 Log.d(TAG, "LocationListener onProviderEnabled"); } public void onStatusChanged(String provider, int status, Bundle extras) { Log.d(TAG, "LocationListener onStatusChanged"); // Provider的转态在可用、暂时不可用和无服务三个状态直接切换时触发此函数 if (status == LocationProvider.OUT_OF_SERVICE || status == LocationProvider.TEMPORARILY_UNAVAILABLE) { } } };
6. 지리적 위치 정보 획득(위도 및 경도, 위성 수, 고도, 위치 상태)
//location对象是从上面定位服务回调函数的参数获取。 mLatitude = location.getLatitude(); // 经度 mLongitude = location.getLongitude(); // 纬度 mAltitude = location.getAltitude(); //海拔 mSpeed = location.getSpeed(); //速度 mBearing = location.getBearing(); //方向
//temgGpsSatellite就是我们上面保存的搜索到的卫星 //方向角 float azimuth = temgGpsSatellite.getAzimuth(); //高度角 float elevation = temgGpsSatellite.getElevation(); //信噪比 float snr = temgGpsSatellite.getSnr();
8. 2차원 위성 위치 지도 그리기
다음은 방향각과 고도각을 기준으로 2차원 위성지도에서 위치를 계산하는 방법이다. 위 렌더링의 왼쪽에 있는 녹색 점은 위성 위치를 나타낸다.
오른쪽의 신호 대 잡음비 히스토그램은 위성의 신호 수신 능력을 나타냅니다.
신호 대 잡음비 그림은 단위 변환일 뿐이므로 여기서는 코드를 제공하지 않겠습니다.//根据方向角和高度角计算出,卫星显示的位置 Point point = new Point(); int x = mEarthHeartX; //左边地球圆形的圆心位置X坐标 int y = mEarthHeartY; //左边地球圆形的圆心位置Y坐标 int r = mEarthR; x+=(int)((r*elevation*Math.sin(Math.PI*azimuth/180)/90)); y-=(int)((r*elevation*Math.cos(Math.PI*azimuth/180)/90)); point.x = x; point.y = y; //point就是你需要绘画卫星图的起始坐标
9. 요약:
Android는 주로 GpsStatus, LocationManager 및 GpsSatellite를 통해 관련 서비스 및 모니터링을 구현하는 등 매우 편리한 위치 서비스를 제공합니다.
그러나 개인적으로 NMEA 데이터를 직접 읽을 수 있다면 적어도 일부 애플리케이션에서는 더 많은 정보를 얻을 수 있다면 매우 편리할 것이라고 생각합니다.
더 많은 Android GPS 위치 확인 테스트(렌더링 및 예제 포함) 관련 기사를 보려면 PHP 중국어 웹사이트를 주목하세요!