Android之GPS定位详解
生活随笔
收集整理的這篇文章主要介紹了
Android之GPS定位详解
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
2019獨角獸企業重金招聘Python工程師標準>>>
一、LocationManagerLocationMangager,位置管理器。要想操作定位相關設備,必須先定義個LocationManager。我們可以通過如下代碼創建LocationManger對象。
LocationManger locationManager=(LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
二、LocationListener
LocationListener,位置監聽,監聽位置變化,監聽設備開關與狀態。
? ?
? ? private LocationListener locationListener= new LocationListener() {
? ?? ???
? ?? ??? /**
? ?? ?? ?* 位置信息變化時觸發
? ?? ?? ? */
? ?? ??? public void onLocationChanged(Location location) {
? ?? ?? ?? ?updateView(location);
? ?? ?? ?? ?Log.i(TAG, "時間:"+location.getTime());
? ?? ?? ?? ?Log.i(TAG, "經度:"+location.getLongitude());
? ?? ?? ?? ?Log.i(TAG, "緯度:"+location.getLatitude());
? ?? ?? ?? ?Log.i(TAG, "海拔:"+location.getAltitude());
? ?? ???}
? ?? ???
? ?? ??? /**
? ?? ?? ?* GPS狀態變化時觸發
? ?? ?? ? */
? ?? ??? public void onStatusChanged(String provider, int status, Bundle extras) {
? ?? ?? ?? ? switch (status) {
? ?? ?? ?? ? // GPS狀態為可見時
? ?? ?? ?? ? case LocationProvider.AVAILABLE:
? ?? ?? ?? ?? ? Log.i(TAG, "當前GPS狀態為可見狀態");
? ?? ?? ?? ?? ? break;
? ?? ?? ?? ? // GPS狀態為服務區外時
? ?? ?? ?? ? case LocationProvider.OUT_OF_SERVICE:
? ?? ?? ?? ?? ? Log.i(TAG, "當前GPS狀態為服務區外狀態");
? ?? ?? ?? ?? ? break;
? ?? ?? ?? ? // GPS狀態為暫停服務時
? ?? ?? ?? ? case LocationProvider.TEMPORARILY_UNAVAILABLE:
? ?? ?? ?? ?? ? Log.i(TAG, "當前GPS狀態為暫停服務狀態");
? ?? ?? ?? ?? ? break;
? ?? ?? ?? ?}
? ?? ???}
? ?
? ?? ??? /**
? ?? ?? ?* GPS開啟時觸發
? ?? ?? ? */
? ?? ??? public void onProviderEnabled(String provider) {
? ?? ?? ?? ?Location location=lm.getLastKnownLocation(provider);
? ?? ?? ?? ?updateView(location);
? ?? ???}
? ?
? ?? ??? /**
? ?? ?? ?* GPS禁用時觸發
? ?? ?? ? */
? ?? ??? public void onProviderDisabled(String provider) {
? ?? ?? ?? ?updateView( null);
? ?? ???}
? ?
? ? };
三、Location
Location,位置信息,通過Location可以獲取時間、經緯度、海拔等位置信息。上面采用locationListener里面的onLocationChanged()來獲取location,下面講述如何主動獲取location。
Location location=locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);? ?
system.out.println("時間:"+location.getTime());? ?
system.out.println("經度:"+location.getLongitude());??
注意:Location location=new Location(LocationManager.GPS_PROVIDER)方式獲取的location的各個參數值都是為0。
四、GpsStatus.Listener
GpsStatus.Listener ,GPS狀態監聽,包括GPS啟動、停止、第一次定位、衛星變化等事件。
? ? // 狀態監聽
? ? GpsStatus.Listener listener = new GpsStatus.Listener() {
? ?? ??? public void onGpsStatusChanged( int event) {
? ?? ?? ?? ? switch (event) {
? ?? ?? ?? ? // 第一次定位
? ?? ?? ?? ? case GpsStatus.GPS_EVENT_FIRST_FIX:
? ?? ?? ?? ?? ? Log.i(TAG, "第一次定位");
? ?? ?? ?? ?? ? break;
? ?? ?? ?? ? // 衛星狀態改變
? ?? ?? ?? ? case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
? ?? ?? ?? ?? ? Log.i(TAG, "衛星狀態改變");
? ?? ?? ?? ?? ? // 獲取當前狀態
? ?? ?? ?? ?? ? GpsStatus gpsStatus=lm.getGpsStatus( null);
? ?? ?? ?? ?? ? // 獲取衛星顆數的默認最大值
? ?? ?? ?? ?? ? int maxSatellites = gpsStatus.getMaxSatellites();
? ?? ?? ?? ?? ? // 創建一個迭代器保存所有衛星?
? ?? ?? ?? ?? ? Iterator<GpsSatellite> iters = gpsStatus.getSatellites().iterator();
? ?? ?? ?? ?? ? int count = 0;? ???
? ?? ?? ?? ?? ? while (iters.hasNext() && count <= maxSatellites) {? ???
? ?? ?? ?? ?? ?? ???GpsSatellite s = iters.next();? ???
? ?? ?? ?? ?? ?? ???count++;? ???
? ?? ?? ?? ?? ? }? ?
? ?? ?? ?? ?? ? System.out.println("搜索到:"+count+"顆衛星");
? ?? ?? ?? ?? ? break;
? ?? ?? ?? ? // 定位啟動
? ?? ?? ?? ? case GpsStatus.GPS_EVENT_STARTED:
? ?? ?? ?? ?? ? Log.i(TAG, "定位啟動");
? ?? ?? ?? ?? ? break;
? ?? ?? ?? ? // 定位結束
? ?? ?? ?? ? case GpsStatus.GPS_EVENT_STOPPED:
? ?? ?? ?? ?? ? Log.i(TAG, "定位結束");
? ?? ?? ?? ?? ? break;
? ?? ?? ?? ?}
? ?? ???};
? ? };
// 綁定監聽狀態
lm.addGpsStatusListener(listener);
五、GpsStatus
GpsStatus,GPS狀態信息,上面在衛星狀態變化時,我們就用到了GpsStatus。
// 實例化? ??
GpsStatus gpsStatus = locationManager.getGpsStatus( null); // 獲取當前狀態? ??
// 獲取默認最大衛星數? ??
int maxSatellites = gpsStatus.getMaxSatellites();? ???
// 獲取第一次定位時間(啟動到第一次定位)? ??
int costTime=gpsStatus.getTimeToFirstFix();? ?
// 獲取衛星? ??
Iterable<GpsSatellite> iterable=gpsStatus.getSatellites();? ?
// 一般再次轉換成Iterator? ??
Iterator<GpsSatellite> itrator=iterable.iterator();??
六、GpsSatellite
? ?
GpsSatellite,定位衛星,包含衛星的方位、高度、偽隨機噪聲碼、信噪比等信息。
? ???
// 獲取衛星? ??
Iterable<GpsSatellite> iterable=gpsStatus.getSatellites();? ?
// 再次轉換成Iterator? ??
Iterator<GpsSatellite> itrator=iterable.iterator();? ?
// 通過遍歷重新整理為ArrayList? ??
ArrayList<GpsSatellite> satelliteList= new ArrayList<GpsSatellite>();? ?
int count=0;? ?
int maxSatellites=gpsStatus.getMaxSatellites();? ?
while (itrator.hasNext() && count <= maxSatellites) {? ???
? ? GpsSatellite satellite = itrator.next();? ???
? ? satelliteList.add(satellite);? ???
? ? count++;? ?
}? ?
System.out.println("總共搜索到"+count+"顆衛星");? ?
// 輸出衛星信息? ??
for( int i=0;i<satelliteList.size();i++){? ?
? ? // 衛星的方位角,浮點型數據? ??
? ? System.out.println(satelliteList.get(i).getAzimuth());? ?
? ? // 衛星的高度,浮點型數據? ??
? ? System.out.println(satelliteList.get(i).getElevation());? ?
? ? // 衛星的偽隨機噪聲碼,整形數據? ??
? ? System.out.println(satelliteList.get(i).getPrn());? ?
? ? // 衛星的信噪比,浮點型數據? ??
? ? System.out.println(satelliteList.get(i).getSnr());? ?
? ? // 衛星是否有年歷表,布爾型數據? ??
? ? System.out.println(satelliteList.get(i).hasAlmanac());? ?
? ? // 衛星是否有星歷表,布爾型數據? ??
? ? System.out.println(satelliteList.get(i).hasEphemeris());? ?
? ? // 衛星是否被用于近期的GPS修正計算? ??
? ? System.out.println(satelliteList.get(i).hasAlmanac());? ?
}??
為了便于理解,接下來模擬一個案例,如何在程序代碼中使用GPS獲取位置信息。
第一步:新建一個Android工程項目,命名為mygps,目錄結構如下
第二步:修改main.xml布局文件,修改內容如下:
<? xml version="1.0" encoding="utf-8" ?>
< LinearLayout? xmlns:android ="http://schemas.android.com/apk/res/android"
? ? android:orientation ="vertical"
? ? android:layout_width ="fill_parent"
? ? android:layout_height ="fill_parent" >
? ? < EditText? android:layout_width ="fill_parent"
? ?? ???android:layout_height ="wrap_content"
? ?? ???android:cursorVisible ="false"
? ?? ???android:editable ="false"
? ?? ???android:id ="@+id/editText" />
</ LinearLayout >
第三步:實用Adnroid平臺的GPS設備,需要添加上權限
? ? < uses-permission? android:name ="android.permission.ACCESS_FINE_LOCATION" />
? ? < uses-permission? android:name ="android.permission.ACCESS_COARSE_LOCATION" />
第四步:修改核心組件activity,修改內容如下
package com.ljq.activity;
import java.util.Iterator;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.location.Criteria;
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.provider.Settings;
import android.util.Log;
import android.widget.EditText;
import android.widget.Toast;
public class GpsActivity extends Activity {
? ? private EditText editText;
? ? private LocationManager lm;
? ? private static final String TAG="GpsActivity"; @Override
protected void onDestroy() {
??// TODO Auto-generated method stub
??super.onDestroy();
??lm.removeUpdates(locationListener);
}
? ? @Override
? ? public void onCreate(Bundle savedInstanceState) {
? ?? ??? super.onCreate(savedInstanceState);
? ?? ???setContentView(R.layout.main);
? ?? ???
? ?? ???editText=(EditText)findViewById(R.id.editText);
? ?? ???lm=(LocationManager)getSystemService(Context.LOCATION_SERVICE);
? ?? ???
? ?? ??? // 判斷GPS是否正常啟動
? ?? ??? if(!lm.isProviderEnabled(LocationManager.GPS_PROVIDER)){
? ?? ?? ?? ?Toast.makeText( this, "請開啟GPS導航...", Toast.LENGTH_SHORT).show();
? ?? ?? ?? ? // 返回開啟GPS導航設置界面
? ?? ?? ?? ?Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);? ?
? ?? ?? ?? ?startActivityForResult(intent,0);
? ?? ?? ?? ? return;
? ?? ???}
? ?? ???
? ?? ??? // 為獲取地理位置信息時設置查詢條件
? ?? ???String bestProvider = lm.getBestProvider(getCriteria(), true);
? ?? ??? // 獲取位置信息
? ?? ??? // 如果不設置查詢要求,getLastKnownLocation方法傳人的參數為LocationManager.GPS_PROVIDER
? ?? ???Location location= lm.getLastKnownLocation(bestProvider);? ?
? ?? ???updateView(location);
? ?? ??? // 監聽狀態
? ?? ???lm.addGpsStatusListener(listener);
? ?? ??? // 綁定監聽,有4個參數? ??
? ?? ??? // 參數1,設備:有GPS_PROVIDER和NETWORK_PROVIDER兩種
? ?? ??? // 參數2,位置信息更新周期,單位毫秒? ??
? ?? ??? // 參數3,位置變化最小距離:當位置距離變化超過此值時,將更新位置信息? ??
? ?? ??? // 參數4,監聽? ??
? ?? ??? // 備注:參數2和3,如果參數3不為0,則以參數3為準;參數3為0,則通過時間來定時更新;兩者為0,則隨時刷新? ?
? ?? ???
? ?? ??? // 1秒更新一次,或最小位移變化超過1米更新一次;
? ?? ??? // 注意:此處更新準確度非常低,推薦在service里面啟動一個Thread,在run中sleep(10000);然后執行handler.sendMessage(),更新位置
? ?? ???lm.requestLocationUpdates( LocationManager.GPS_PROVIDER, 1000, 1, locationListener);
? ? }
? ?
? ? // 位置監聽
? ? private LocationListener locationListener= new LocationListener() {
? ?? ???
? ?? ??? /**
? ?? ?? ?* 位置信息變化時觸發
? ?? ?? ? */
? ?? ??? public void onLocationChanged(Location location) {
? ?? ?? ?? ?updateView(location);
? ?? ?? ?? ?Log.i(TAG, "時間:"+location.getTime());
? ?? ?? ?? ?Log.i(TAG, "經度:"+location.getLongitude());
? ?? ?? ?? ?Log.i(TAG, "緯度:"+location.getLatitude());
? ?? ?? ?? ?Log.i(TAG, "海拔:"+location.getAltitude());
? ?? ???}
? ?? ???
? ?? ??? /**
? ?? ?? ?* GPS狀態變化時觸發
? ?? ?? ? */
? ?? ??? public void onStatusChanged(String provider, int status, Bundle extras) {
? ?? ?? ?? ? switch (status) {
? ?? ?? ?? ? // GPS狀態為可見時
? ?? ?? ?? ? case LocationProvider.AVAILABLE:
? ?? ?? ?? ?? ? Log.i(TAG, "當前GPS狀態為可見狀態");
? ?? ?? ?? ?? ? break;
? ?? ?? ?? ? // GPS狀態為服務區外時
? ?? ?? ?? ? case LocationProvider.OUT_OF_SERVICE:
? ?? ?? ?? ?? ? Log.i(TAG, "當前GPS狀態為服務區外狀態");
? ?? ?? ?? ?? ? break;
? ?? ?? ?? ? // GPS狀態為暫停服務時
? ?? ?? ?? ? case LocationProvider.TEMPORARILY_UNAVAILABLE:
? ?? ?? ?? ?? ? Log.i(TAG, "當前GPS狀態為暫停服務狀態");
? ?? ?? ?? ?? ? break;
? ?? ?? ?? ?}
? ?? ???}
? ?
? ?? ??? /**
? ?? ?? ?* GPS開啟時觸發
? ?? ?? ? */
? ?? ??? public void onProviderEnabled(String provider) {
? ?? ?? ?? ?Location location=lm.getLastKnownLocation(provider);
? ?? ?? ?? ?updateView(location);
? ?? ???}
? ?
? ?? ??? /**
? ?? ?? ?* GPS禁用時觸發
? ?? ?? ? */
? ?? ??? public void onProviderDisabled(String provider) {
? ?? ?? ?? ?updateView( null);
? ?? ???}
? ?
? ? };
? ?
? ? // 狀態監聽
? ? GpsStatus.Listener listener = new GpsStatus.Listener() {
? ?? ??? public void onGpsStatusChanged( int event) {
? ?? ?? ?? ? switch (event) {
? ?? ?? ?? ? // 第一次定位
? ?? ?? ?? ? case GpsStatus.GPS_EVENT_FIRST_FIX:
? ?? ?? ?? ?? ? Log.i(TAG, "第一次定位");
? ?? ?? ?? ?? ? break;
? ?? ?? ?? ? // 衛星狀態改變
? ?? ?? ?? ? case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
? ?? ?? ?? ?? ? Log.i(TAG, "衛星狀態改變");
? ?? ?? ?? ?? ? // 獲取當前狀態
? ?? ?? ?? ?? ? GpsStatus gpsStatus=lm.getGpsStatus( null);
? ?? ?? ?? ?? ? // 獲取衛星顆數的默認最大值
? ?? ?? ?? ?? ? int maxSatellites = gpsStatus.getMaxSatellites();
? ?? ?? ?? ?? ? // 創建一個迭代器保存所有衛星?
? ?? ?? ?? ?? ? Iterator<GpsSatellite> iters = gpsStatus.getSatellites().iterator();
? ?? ?? ?? ?? ? int count = 0;? ???
? ?? ?? ?? ?? ? while (iters.hasNext() && count <= maxSatellites) {? ???
? ?? ?? ?? ?? ?? ???GpsSatellite s = iters.next();? ???
? ?? ?? ?? ?? ?? ???count++;? ???
? ?? ?? ?? ?? ? }? ?
? ?? ?? ?? ?? ? System.out.println("搜索到:"+count+"顆衛星");
? ?? ?? ?? ?? ? break;
? ?? ?? ?? ? // 定位啟動
? ?? ?? ?? ? case GpsStatus.GPS_EVENT_STARTED:
? ?? ?? ?? ?? ? Log.i(TAG, "定位啟動");
? ?? ?? ?? ?? ? break;
? ?? ?? ?? ? // 定位結束
? ?? ?? ?? ? case GpsStatus.GPS_EVENT_STOPPED:
? ?? ?? ?? ?? ? Log.i(TAG, "定位結束");
? ?? ?? ?? ?? ? break;
? ?? ?? ?? ?}
? ?? ???};
? ? };
? ?
? ? /**
? ???* 實時更新文本內容
? ???*?
? ???*? @param location
? ??? */
? ? private void updateView(Location location){
? ?? ??? if(location!= null){
? ?? ?? ?? ?editText.setText("設備位置信息\n\n經度:");
? ?? ?? ?? ?editText.append(String.valueOf(location.getLongitude()));
? ?? ?? ?? ?editText.append("\n緯度:");
? ?? ?? ?? ?editText.append(String.valueOf(location.getLatitude()));
? ?? ???} else{
? ?? ?? ?? ? // 清空EditText對象
? ?? ?? ?? ?editText.getEditableText().clear();
? ?? ???}
? ? }
? ?
? ? /**
? ???* 返回查詢條件
? ???*? @return
*/
? ? private Criteria getCriteria(){
? ?? ???Criteria criteria= new Criteria();
? ?? ??? // 設置定位精確度 Criteria.ACCURACY_COARSE比較粗略,Criteria.ACCURACY_FINE則比較精細?
? ?? ???criteria.setAccuracy(Criteria.ACCURACY_FINE);? ?
? ?? ??? // 設置是否要求速度
? ?? ???criteria.setSpeedRequired( false);
? ?? ??? // 設置是否允許運營商收費??
? ?? ???criteria.setCostAllowed( false);
? ?? ??? // 設置是否需要方位信息
? ?? ???criteria.setBearingRequired( false);
? ?? ??? // 設置是否需要海拔信息
? ?? ???criteria.setAltitudeRequired( false);
? ?? ??? // 設置對電源的需求??
? ?? ???criteria.setPowerRequirement(Criteria.POWER_LOW);
? ?? ??? return criteria;
? ? }
}
第五步:啟動模擬器,如果啟動完成,請在Myeclipse中按如下選項一步一步操作:Emulator Control->Location Controls->Manual->選中Decimal->輸入經緯度,類似如下
演示效果如下:
轉載于:https://my.oschina.net/yuanxulong/blog/322923
總結
以上是生活随笔為你收集整理的Android之GPS定位详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux Guide for Deve
- 下一篇: 计算机中浮点度存储