天天看點

Android之GPS定位類 LocationManager、LocationListener、GpsStatus.Listener、Location詳解

轉自:http://bbs.51cto.com/viewthread.php?tid=955194&extra=&page=1  

很好的文章,學習了,轉過來記錄一下

一、LocationManager

LocationMangager,位置管理器。要想操作定位相關裝置,必須先定義個LocationManager。我們可以通過如下代碼建立LocationManger對象。

LocationManger locationManager=(LocationManager)this.getSystemService(Context.LOCATION_SERVICE); 

二、LocationListener

LocationListener,位置監聽,監聽位置變化,監聽裝置開關與狀态。

Android之GPS定位類 LocationManager、LocationListener、GpsStatus.Listener、Location詳解

    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()); 

        }

        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;

            }

        }

        public void onProviderEnabled(String provider) {

            Location location=lm.getLastKnownLocation(provider);

            updateView(location);

        }

        public void onProviderDisabled(String provider) {

            updateView(null);

        }

    };

Android之GPS定位類 LocationManager、LocationListener、GpsStatus.Listener、Location詳解

三、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啟動、停止、第一次定位、衛星變化等事件。

Android之GPS定位類 LocationManager、LocationListener、GpsStatus.Listener、Location詳解

    //狀态監聽

    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);

Android之GPS定位類 LocationManager、LocationListener、GpsStatus.Listener、Location詳解

五、GpsStatus

Android之GPS定位類 LocationManager、LocationListener、GpsStatus.Listener、Location詳解

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();  

Android之GPS定位類 LocationManager、LocationListener、GpsStatus.Listener、Location詳解

六、GpsSatellite

GpsSatellite,定位衛星,包含衛星的方位、高度、僞随機噪聲碼、信噪比等資訊。

Android之GPS定位類 LocationManager、LocationListener、GpsStatus.Listener、Location詳解

//擷取衛星    

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());   

}  

Android之GPS定位類 LocationManager、LocationListener、GpsStatus.Listener、Location詳解

為了便于了解,接下來模拟一個案例,如何在程式代碼中使用GPS擷取位置資訊。

第一步:建立一個Android工程項目,命名為mygps,目錄結構如下

Android之GPS定位類 LocationManager、LocationListener、GpsStatus.Listener、Location詳解

第二步:修改main.xml布局檔案,修改内容如下:

Android之GPS定位類 LocationManager、LocationListener、GpsStatus.Listener、Location詳解

<?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>

Android之GPS定位類 LocationManager、LocationListener、GpsStatus.Listener、Location詳解

第三步:實用Adnroid平台的GPS裝置,需要添加上權限

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

第四步:修改核心元件activity,修改内容如下

Android之GPS定位類 LocationManager、LocationListener、GpsStatus.Listener、Location詳解

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()); 

        }

        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;

            }

        }

        public void onProviderEnabled(String provider) {

            Location location=lm.getLastKnownLocation(provider);

            updateView(location);

        }

        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;

            }

        };

    };

    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();

        }

    }

    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;

    }

}

Android之GPS定位類 LocationManager、LocationListener、GpsStatus.Listener、Location詳解

第五步:啟動模拟器,如果啟動完成,請在Myeclipse中按如下選項一步一步操作:Emulator Control->Location Controls->Manual->選中Decimal->輸入經緯度,類似如下

Android之GPS定位類 LocationManager、LocationListener、GpsStatus.Listener、Location詳解

示範效果如下:

Android之GPS定位類 LocationManager、LocationListener、GpsStatus.Listener、Location詳解