Android GPS應用程序設計

jopen 10年前發布 | 46K 次閱讀 Android Android開發 移動開發

GPS簡介

GPS是英文Global Positioning System(全球定位系統)的簡稱。GPS是20世紀70年代由美國陸海空三軍聯合研制的

新一代空間衛星導航定位系統 。其主要目的是為陸、海、空三大領域提供實時、 全天候和全球性的導航服務,并用于

情報收集、核爆監測和應急通訊等一些軍事目的,經過20余年的研究實驗,耗資300億美元,到1994年3月,全球覆蓋

率高達98%的24顆GPS衛星星座己布設完成。 


GPS定位原理 

GPS定位的基本原理是根據高速運動的衛星瞬間位置作為已知的起算數據,采用空間距離后方交會的方法,確定待測

點的位置。如圖所示,假設t時刻在地面待測點上安置GPS接收機,可以測定GPS信號到達接收機的時間△t,再加上接

收機所接收到的衛星星歷等其它數據可以確定以下四個方程式) 

20140424152355140.png


GPS的基本類

Android平臺提供了一個android.location的包,有8個類。核心的3個類:

LocationManager類:作用與WifiManager、TelephonyManager等服務類的作用相似,所有與GPS定位相關的服務、

對象都由該對象產生。

LocationProvider類:定位提供者,GPS定位組件的抽象表示,通過該對象可以獲取該定位組件的相關信息。

Location類:一個代表位置信息的抽象類。


使用它們來獲取GPS定位信息的通用步驟為:

獲取系統LocationManager對象

使用LocationManager,通過指定的定位設備LocationProvider來獲取定位信息Location。

從Location對象中獲取定位信息


LocationManager

LocationManager對象的獲取:

LocationManager  lm= (LocationManager)getSystemService(Context.LOCATION_SERVICE); 

常用方法

List<String> getAllProviders() 獲得所有的LocationProvider列表

LocationProvider getProvider(String name) 根據名稱來獲取LocationProvider

List<String> getProviders(boolean enabledOnly) 獲取所有可用的LocationProvider

List<String> getProviders(Criteria criteria, boolean enabledOnly) 根據指定條件獲取滿足該條件的全部LocationProvider的名稱

String getBestProvider(Criteria criteria, boolean enabledOnly) 根據指定條件返回最優的LocationProvider對象

boolean isProviderEnabled(String provider) 判斷指定名稱的LocationProvider是否可用

Location getLastKnownLocation(String provider) 獲取最近一次已知的Location

addProximityAlert(double latitude, double longitude, float radius, long expiration, PendingIntent intent) :添加一個趨近

警告

void removeProximityAlert(PendingIntent intent) 刪除一個臨近警告

void requestLocationUpdates(long minTime, float minDistance, Criteria criteria, PendingIntent intent) 

void requestLocationUpdates(String provider, long minTime, float minDistance, LocationListener listener) 通過指定的

LocationProvider周期性地獲取定位信息,并通過intent啟動相應的組件

void requestLocationUpdates(String provider, long minTime, float minDistance, PendingIntent intent)  通過指定的

LoctionProvider周期性地獲取定位信息,并通過intent啟動相應的組件



LocationProvider (定位提供者)

abstract int getAccuracy() 返回該LocationProvider的精度

String getName() 返回該LocationProvider的名稱

int getPowerRequirement() 獲取該LoctionProvider的電源需求

boolean hasMonetaryCost() 獲取該LocationProvider是收費的還是免費的

boolean meetsCriteria(Criteria criteria) 判斷該LocationProvider是否滿足Criteria條件

boolean requiresCell() 判斷該LocationProvider是否需要訪問網絡基站

boolean requiresNetwork() 判斷該LocationProvider是否需要訪問網絡數據

boolean requiresSatellite() 判斷該LoctionProvider是否需要訪問基于衛星的定位系統

boolean supportsAltitude() 判斷該LoctionProvider是否支持高度信息

boolean supportsBearing() 判斷該LocationProvider是否支持方向信息

boolean supportsSpeed() 判斷該LoctionProvider是否支持速度信息


Location(位置信息)

float getAccuracy() 獲取定位信息的精度

double getAltitude() 獲取定位信息的高度

float getBearing() 獲取定位信息的方向

double getLatitude() 獲取定位信息的緯度

double getLongitude() 獲取定位信息的經度

String getProvider() 獲取提供該定位信息的LocationProvider

float getSpeed() 獲取定位信息的速度

long getTime() 

boolean hasAccuracy() 判斷該定位信息是否有精度信息

boolean hasAltitude() 判斷該定位信息是否有高度信息

boolean hasBearing() 判斷該定位信息是否有方向信息

boolean hasSpeed() 判斷該定位信息是否有速度信息


獲取定位信息

1 獲取所有可用的LocationProvider

LocationManager提供了一個getAllProvider()方法來獲取系統所有可用的LocationProvider

系統共有三種類型的LocationProvider

network : 由LocationManager.NETWORK_PROVIDER常量表示

gps : 由LocationManager.GPS_PROVIDER常量表示

passive : 由LoctionManager.PASSIVE_PROVIDER常量表示

2 通過名稱獲得指定getProvider(String name)

3 根據Criteria獲得getProviders(Criteria criteria, boolean enabledOnly) 

Criteria:代表了一個“過濾”條件,它提供了一些方法來設置條件

void setAccuracy(int accuracy) 

void setAltitudeRequired(boolean altitudeRequired) 

void setBearingAccuracy(int accuracy) 

void setBearingRequired(boolean bearingRequired) 

獲取LocationManager對象后,可通過指定的LocationProvider獲取定位信息,如:經度、維度、高度、移動速度等。

GPS訪問權限

 <uses-permission android:name=“android.permission.ACCESS_FINE_LOCATION”>


趨近警告

趨近警告就是當用戶手機臨近指定點時,當與該點的距離小于指定范圍時,系統可觸發相應的處理,該功能能夠對我們

進入或退出某個設定的區域進行提示。

LocationManager提供方法:addProximityAlert(double latitude, double longitude, float radius, long expiration, 

PendingIntent intent),

latitude經度、longitude緯度, radius區域半徑, expiration指定經過多少毫秒過期,-1為永不過期,PendingIntent指

定觸發的Intent組件。

要實現此功能需要兩個步驟:

一是獲得LocationManager實例,調用其方法addProximityalert并添加趨近提示;

二是定義一個廣播接收器,當設備進入設定區域時提醒用戶。


例子代碼:

獲取LocationProvider:

獲取所有的LocationProvider的名稱

    // 獲取LocationManager對象
mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

// 獲取所有的LocationProvider的名稱  
List<String> providerNames = mLocationManager.getAllProviders();  </pre><a href="/misc/goto?guid=4959555411945580654" target="_blank" title="派生到我的代碼片" style="text-indent:0;"></a></div>

</div> </div> 通過名稱獲取指定LocationProvider

    //獲取基于GPS的LocationProvider  
    LocationProvider locProvider = lm.getProvider(LocatinManager.GPS_PROVIDER)  
</div> </div> 根據Criteria獲得LocationProvider

                  mProviders = (ListView) findViewById(R.id.providers);
// 獲取系統的LocationManager對象
mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
// 創建一個LocationProvider的過濾條件
Criteria cri = new Criteria();
// 設置要求LocationProvider必須是免費的。
cri.setCostAllowed(false);

// 設置要求LocationProvider能提供高度信息  
cri.setAltitudeRequired(true);    
// 設置要求LocationProvider能提供方向信息  
cri.setBearingRequired(true);  
// 獲取系統所有符合條件的LocationProvider的名稱  
List<String> providerNames = mLocationManager.getProviders(cri, true);  </pre><a href="/misc/goto?guid=4959555411945580654" target="_blank" title="派生到我的代碼片" style="text-indent:0;"></a></div>

</div> </div>


獲取定位數據:

    // 創建LocationManager對象
mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
// 從GPS獲取最近的定位信息
Location location = mLocationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
// 使用location根據EditText的顯示
updateView(location);
// 設置每2秒獲取一次GPS的定位信息
mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
2000, 8, new LocationListener() {
@Override
public void onLocationChanged(Location location) {
// 當GPS定位信息發生改變時,更新位置
updateView(location);
}

                    @Override  
                    public void onProviderDisabled(String provider) {  
                        updateView(null);  
                    }  

                    @Override  
                    public void onProviderEnabled(String provider) {  
                        // 當GPS LocationProvider可用時,更新位置  
                        updateView(mLocationManager  
                                .getLastKnownLocation(provider));  
                    }  

                    @Override  
                    public void onStatusChanged(String provider, int status,  
                            Bundle extras) {  
                    }  
                });  

    }  

    // 更新EditText中顯示的內容  
    public void updateView(Location newLocation) {  
        if (newLocation != null) {  
            StringBuilder sb = new StringBuilder();  
            sb.append("實時的位置信息:\n");  
            sb.append("經度:");  
            sb.append(newLocation.getLongitude());  
            sb.append("\n緯度:");  
            sb.append(newLocation.getLatitude());  
            sb.append("\n高度:");  
            sb.append(newLocation.getAltitude());  
            sb.append("\n速度:");  
            sb.append(newLocation.getSpeed());  
            sb.append("\n方向:");  
            sb.append(newLocation.getBearing());  
            mEditText.setText(sb.toString());  
        } else {  
            // 如果傳入的Location對象為空則清空EditText  
            mEditText.setText("");  
        }  </pre><a href="/misc/goto?guid=4959555411945580654" target="_blank" title="派生到我的代碼片" style="text-indent:0;"></a></div>

</div> </div>

    <!-- 授權獲取定位信息 -->  
        <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />  
</div> </div> 該程序需要有訪問GPS信號的權限,因此需要在AndroidManifest.xml文件中增加授權信息. 用于從Location中獲取定位信息,包括用戶的經度,緯度,高度,方向,和移動速度等信息,并通過LocationManager設置了

個監聽器,該監聽器負責每隔3秒向LocationProvider請求一次定位信息,當LocationProvider可用時,不可用時或提供的定

位信息發生改變時,系統會回調對應的方法更新界面.

如果該程序與Google Map結合,讓該程序根據GPS提供的信息實時地顯示用戶在地圖上的位置,即可開發GPS導航系統


趨近警告:

    // 定位服務管理器對象
LocationManager locationManager;
// 通過getSystemService方法獲得LocationManager對象
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
// 定義萬里學院4號樓的大致經度、緯度
double longitude = 123.427109;
double latitude = 41.764998;
// 定義半徑(2000米)
float radius = 2000;

        // 定義Intent  
        Intent intent = new Intent(this, ProximityAlertReciever.class);  
        // 將Intent包裝成PendingIntent  
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 1,  
                intent, 0);  

        // 添加臨近警告  
        locationManager.addProximityAlert(latitude, longitude, radius, -1,  
                pendingIntent);  </pre><a href="/misc/goto?guid=4959555411945580654" target="_blank" title="派生到我的代碼片" style="text-indent:0;"></a></div>

</div> </div> 對應啟動的BroadcastReceiver :

    public class ProximityAlertReciever extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {

        // 獲取是否為進入指定區域  
        boolean isEnter = intent.getBooleanExtra(  
                LocationManager.KEY_PROXIMITY_ENTERING, false);  
        if (isEnter) {  
            // 顯示提示信息  
            Toast.makeText(context, "您已經接近萬里學院4號樓", Toast.LENGTH_LONG).show();  
        } else {  
            // 顯示提示信息  
            Toast.makeText(context, "您已經離開萬里學院4號樓", Toast.LENGTH_LONG).show();  
        }  
    }  
}  </pre><a href="/misc/goto?guid=4959555411945580654" target="_blank" title="派生到我的代碼片" style="text-indent:0;"></a></div>

</div> </div>

    <!-- 授權獲取定位信息 -->  
        <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>  
        <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>  
        <uses-permission android:name="android.permission.INTERNET"/>  
</div> </div>


計算兩點距離:

final float[] results = new float[3];

    Location.distanceBetween(20.123, 30.05644, 30.124, 40.543, results);  
    final float bearing = results[1];  
    mEditText.setText(String.valueOf(results[0]) + "米");  </pre><a href="/misc/goto?guid=4959555411945580654" target="_blank" title="派生到我的代碼片" style="text-indent:0;"></a></div>

</div> </div> 來自:http://blog.csdn.net/coslay/article/details/24416085

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!