Android---58---初學GPS定位,android---58---gps
GPS英文是Global Positioning System 全球定位系統的簡稱。
Android為GPS功能支援專門提供了一個LocationManager,位置管理器。所有GPS定位相關的服務、對象都將由該對象產生。
擷取LocationManager執行個體:
LocationManager lm = (LocationManager)getSystemService (Context.LOCATION_SERVICE)
三個核心API:LocationManager、LocationProvider、Location
LocationManager提供如下方法:
boolean addGpsStatusListener(GpsStatus.Listener listener):添加一個監聽GPS狀態的監聽器;
void addProximityAlert(double latitude,double longitude,float radius,long expiration,PendingIntent intent):添加一個臨近警告;
List getAllProviders():擷取所有的LocationProvider列表;
String getBestProvider(Criteria criteria,boolean enabledOnly):根據制定條件返回最優的LocationProvider對象;
GpsStatus getGpsStatus(GpsStatus status):擷取GPS狀態;
Location getLastKnownLocation(String provider):根據LocationProvider擷取最近一次已知的Location;
LocationProvider getProvider(String name):根據名稱來擷取LocationProvider;
List getProviders(Criteria criteria,boolean enabledOnly):根據制定條件擷取滿足條件的全部LocationProvier的名稱;
List getProviders(boolean enabledOnly):擷取所有可用的LocationProvider;
boolean isProviderEnabled(String provider):判斷制定名稱的LocationProvider是否可用;
void removeGpsStatusListener(GpsStatus.Listener listener):刪除GPS狀態監聽器;
void removeProximityAlert(PendingIntent intent):刪除一個趨近警告;
void requestLocationUpdates(String provider,long minTime,float minDistance,PendingIntent intent):通過指定的LocationProvider周期性擷取定位資訊,並通過Intent啟動相應的組件;
void requestLocationUpdates(String provider,long minTime,float minDistance,LcoationListener listener):通過指定的LocationProvider周期性的擷取定位資訊,並觸發listener對應的觸發器;
LocationProvider類
定位組件的抽象標識,通過它可以擷取定位的相關資訊;
提供如下常用方法:
String getName():返回該LocationProvider的名稱;
int getAccuracy():返回該LocationProvider的精度;
int getPowerRequirement():返回該LocationProvider的電源需求;
boolean hasMonetaryCost():返回LocationProvider是收費還是免費;
boolean meetsCriteria(Criteria criteria):判斷該LocationProvider是否滿足Criteria條件;
boolean requiresCell():判斷該LocationProvider是否需要訪問網路基站;
boolean requiresNetword():判斷該LocationProvider是否需要網路資料;
boolean requiresStatellite():判斷該LocationProvider是否需要訪問衛星的定位系統;
boolean supportsAltitude():判斷該LocationProvider是否支援高度資訊;
boolean supportsBearing():判斷該LocationProvider是否支援方向資訊;
boolean supportsSpeed():判斷該LocationProvider是否支援速度資訊;
LocationListener:位置監聽器,監聽位置變化,監聽裝置開關與狀態
Location類
代表位置資訊的抽象類別;
提供如下方法來擷取定位資訊:
float getAccuracy():擷取定位資訊的精度;
double getAltitude():擷取定位資訊的高度;
float getBearing():擷取定位資訊的方向;
double getLatitude():擷取定位資訊的經度;
double getLongitude():擷取定位資訊的緯度;
String getProvider():擷取提供該定位資訊的LocationProvider;
float getSpeed():擷取定位資訊的速度;
boolean hasAccuracy():判斷該定位資訊是否有經度資訊;
boolean hasAltitude():判斷定位資訊是否有高度資訊;
boolean hasBearing():判斷定位資訊是否有方向資訊;
boolean hasSpeed():判斷定位資訊是否有速度資訊;
LocationListener:位置監聽器,監聽位置變化,監聽裝置開關與狀態
步驟:
1.擷取系統的LocationManager對象
2.使用LocationManager,通過指定LocationProvider來擷取定位資訊,定位資訊由Location對象來表示
3.從Location對象中擷取定位資訊
下面是幾個例子:
1.擷取所有可用的LocationProvider:
布局檔案:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.allproviderstest.AllProvidersTest" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/providerList" /> <ListView android:id="@+id/providers" android:layout_width="fill_parent" android:layout_height="fill_parent" > </ListView></LinearLayout>
Activity:
public class AllProvidersTest extends Activity {ListView providers;LocationManager lm;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_all_providers_test);providers = (ListView) findViewById(R.id.providers);lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);List<String> providerNames = lm.getAllProviders();ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, providerNames);providers.setAdapter(adapter);}}
模擬器中所有可用的LocationProvider有兩個:
passive:由LocationProvider.PASSIVE_PROVIDER常量表示
gps:由LocationProvider.GPS_PROVIDER常量表示。代表通過GPS擷取定位資訊的LocationProvider對象
還有一個名為network的LocationProvider,由LocationProvider.NETWORK_PROVIDER常量表示,
代表通過移動通訊網路擷取定位資訊的LocationProvider對象。
2.通過名稱來擷取指定的LocationProvider:
例如:
擷取基於GPS的LocationProvider:
LocationProvider locProvider = lm.getProvider(LocationManager.GPS_PROVIDER)
根據Criteria獲得LocationProvider:
布局檔案:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.freeproviderstest.FreeProvidersTest" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/providerList" /> <ListView android:id="@+id/providers" android:layout_width="fill_parent" android:layout_height="fill_parent" /></LinearLayout>
Activity:
public class FreeProvidersTest extends Activity {ListView providers;LocationManager lm;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_free_providers_test);providers = (ListView) findViewById(R.id.providers);lm = (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 = lm.getProviders(cri, false);System.out.println(providerNames.size());ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, providerNames);// 使用ListView來顯示所有可用的LocationProviderproviders.setAdapter(adapter);}}
3.
擷取定位元據:
通過模擬器發送GPS資訊:
啟動模擬器之後,在DDMS下的Emulator Control 面板即可發送GPS定位資訊。
布局檔案:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.locationtest.LocationTest" > <EditText android:id="@+id/show" android:layout_width="fill_parent" android:layout_height="wrap_content" android:cursorVisible="false" android:editable="false" /></LinearLayout>
Activity:
public class LocationTest extends Activity {// 定義LocationManager對象LocationManager locManager;// 定義程式介面中的EditText組件EditText show;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_location_test);show = (EditText) findViewById(R.id.show);locManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);// 從GPS擷取最近的最近的定位資訊Location location = locManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);// 使用location根據EditText的顯示updateView(location);// 設定每3秒擷取一次GPS的定位資訊locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 3000,8, new LocationListener() // ①{@Overridepublic void onLocationChanged(Location location) {// 當GPS定位資訊發生改變時,更新位置updateView(location);}@Overridepublic void onProviderDisabled(String provider) {updateView(null);}@Overridepublic void onProviderEnabled(String provider) {// 當GPS LocationProvider可用時,更新位置updateView(locManager.getLastKnownLocation(provider));}@Overridepublic 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());show.setText(sb.toString());} else {// 如果傳入的Location對象為空白則清空EditTextshow.setText("");}}}
4.
臨近警告:
通過LocationManager.addProximityAlert(double latitude,double longitude , float radius , long expiration ,PendingIntent intent)添加一個臨近警告
參數:
latitude:指定固定點的經度
longitude:指定固定點的緯度
radius:半徑長度
expiration:該參數指定經過多少毫秒後該臨近警告就會到期失效
intent:該參數指定臨近該固定點時出發該intent對應的組件。
布局檔案:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.proximitytest.ProximityTest" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" /></LinearLayout>
Activity:
public class ProximityTest extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_proximity_test);// 定位服務常量String locService = Context.LOCATION_SERVICE;// 定位服務管理器執行個體LocationManager locationManager;// 通過getSystemService方法獲得LocationManager執行個體locationManager = (LocationManager) getSystemService(locService);// 定義山東淄博的大致經度、緯度double longitude = 117.3;double latitude = 36.5;// 定義半徑(5公裡)float radius = 5000;// 定義IntentIntent intent = new Intent(this, ProximityAlertReciever.class);// 將Intent封裝成PendingIntentPendingIntent pi = PendingIntent.getBroadcast(this, -1, intent, 0);// 添加臨近警告locationManager.addProximityAlert(latitude, longitude, radius, -1, pi);}}
ProximityAlertReciever:
public class ProximityAlertReciever extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {// 擷取是否為進入指定地區boolean isEnter = intent.getBooleanExtra(LocationManager.KEY_PROXIMITY_ENTERING, false);if (isEnter) {// 顯示提示資訊Toast.makeText(context, "您已經進入廣州天河區", Toast.LENGTH_LONG).show();} else {// 顯示提示資訊Toast.makeText(context, "您已經離開廣州天河區", Toast.LENGTH_LONG).show();}}}