Android APP - GPS定位并获取地理位置

1. 相关知识简介

    通过LocationManagerService可以获取位置,这个service的aidl文件在frameworks/base/location/java/android/location/里,从LocationManager.java可以看到应该如何调用它。在定位的时候需要指定采用哪种provider,常用有三种:

      LocationManager.GPS_PROVIDER                   精确定位,精度在十几米内

      LocationManager.NETWORK_PROVIDER         粗略定位,精度在上百米

      LocationManager.PASSIVE_PROVIDER           悄悄定位,也就是不启动定位,但是当别的应用使用gps/network定到位了就会把location告诉给它

    要使用LocationManagerService,首先需要获取到LocationManager,然后通过这个LocationManager执行启动定位、关闭定位等操作。

        import android.location.LocationManager;

        private LocationManager mLocationManager;

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

    接下来看下通过LocationManager启动定位的方法:

        public void requestLocationUpdates(String provider, long minTime, float minDistance, LocationListener listener)

        public void requestLocationUpdates(String provider, long minTime, float minDistance, PendingIntent intent)

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

        minTime - 最小时间,单位毫秒,

        如果本次得到的location离上次的location时间间隔小于minTime,那么LocationManagerService就不会把这个location报告给我们

        minDistance - 最小距离,单位米,

        如果本次得到的location与上次的location距离小于minDistance,那么LocationManagerService就不会把这个location报告给我们

        criteria - 选择provider的规则,例如高精度、低电量等等,最后由LocationManager根据我们提供的规则选择一个合适的provider

        listener - 用来接收location的接口,需要重写四个方法:onLocationChanged、onStatusChanged、onProviderEnabled、onProviderDisabled

                      对应四个事件:location更新、状态更新(启动、停止)、provider打开、provider关闭(例如系统设置里关闭GPS)

        intent - 可以通过PendingIntent.getBroadcast(this,0,new Intent(LOCATION_EVENT),0)获取一个PendingIntent,

                   这个LOCATION_EVENT是自己定义的action

        当位置事件发生后,从LocationManagerService里发送我们自定义的LOCATION_EVENT广播,对应的数据在Intent的Extra里

            putExtra(LocationManager.KEY_LOCATION_CHANGED, new Location(location))

            putExtra(LocationManager.KEY_STATUS_CHANGED, status)

            putExtra(LocationManager.KEY_PROVIDER_ENABLED, enabled)

    通过LocationManager关闭定位的方法:

        public void removeUpdates(LocationListener listener)

        public void removeUpdates(PendingIntent intent)

    可以使用LocationListener或者PendingIntent来接收位置事件,不过只能选择其中一种方法,一般常用LocationListener。


    获取到location之后,我们可以从location里得到经纬度数据,然后通过Geocoder的getFromLocation方法得到地理位置信息,

    如: 中国 上海市浦东新区 滨江大道

        Geocoder(Context context, Locale locale)              根据指定的Locale构造Geocoder,Locale.getDefault()即本地

        List

   getFromLocation(double latitude, double longitude, int maxResults)     获取指定经纬度附近的地理位置信息

        Address提供getAddressLine来获取位置字串String   getAddressLine(int index) 

        一般位置信息字串有好几段,index=0为国家,1为城区,可以通过int  getMaxAddressLineIndex()来查看最后一段的编号

2.  实例代码

    打开app后,立即启动gps定位,定到位后将第一个location的经纬度数据放到两个EditText里,并利用这个经纬度来计算地理位置信息,通过Toast显示出来。另外可以修改EditText里的经纬度数据,然后点击查询来得到给定经纬度的地理位置。

package com.example.locationview;

import java.io.IOException;
import java.util.List;
import java.util.Locale;

import android.app.Activity;
import android.content.Context;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class MainActivity extends Activity {

	private final String TAG = "LocationView";
	
	private MyHandler mHandler;
	private final int MSG_SHOW = 1;
	
	private EditText mEditLat,mEditLong;
	private Button mButtonFind;
	
	private LocationManager mLocationManager;
	private Geocoder mGeocoder;
	
	private int fixCount;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		mEditLat = (EditText)findViewById(R.id.latitudeEdit);
		mEditLong = (EditText)findViewById(R.id.longitudeEdit);
		mButtonFind = (Button)findViewById(R.id.findButton);
		
		mHandler = new MyHandler(getMainLooper());
		
		mGeocoder = new Geocoder(getApplicationContext(),Locale.getDefault());	
		mLocationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
		fixCount = 0;
		
		mButtonFind.setOnClickListener(new OnClickListener(){
			
			public void onClick(View view){
			
				String latitude,longitude;
				
				latitude = mEditLat.getText().toString();
				longitude = mEditLong.getText().toString();
				
				if(!latitude.equals("") && !longitude.equals("")){						
					showAddress(latitude,longitude);
				}
			}			
			
		});		
	}
	
	private void showAddress(String latitude,String longitude){
						
		try{		
			List
addrList = mGeocoder.getFromLocation(Double.parseDouble(latitude), Double.parseDouble(longitude), 1); if(addrList.size() > 0){ StringBuilder sb = new StringBuilder(); Address addr = addrList.get(0); for(int i=0;i<=addr.getMaxAddressLineIndex();i++){ sb.append(addr.getAddressLine(i)).append(" "); } showMessage(sb.toString()); }else{ showMessage("address not found!"); } }catch(IOException e){ e.printStackTrace(); } } @Override protected void onStart(){ super.onStart(); mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 0, mListener); Log.d(TAG,"start gps"); } @Override protected void onStop(){ mLocationManager.removeUpdates(mListener); Log.d(TAG,"stop gps"); super.onStop(); } private LocationListener mListener = new LocationListener(){ @Override public void onLocationChanged(Location location){ String latitude,longitude; latitude = Double.toString(location.getLatitude()); longitude = Double.toString(location.getLongitude()); Log.d(TAG, "lat: " + latitude + " long: " + longitude); if(++fixCount == 1){ mEditLat.setText(latitude); mEditLong.setText(longitude); showAddress(latitude,longitude); } } @Override public void onProviderDisabled(String provider) { // TODO Auto-generated method stub } @Override public void onProviderEnabled(String provider) { // TODO Auto-generated method stub } @Override public void onStatusChanged(String provider, int status, Bundle extras) { // TODO Auto-generated method stub } }; private void showMessage(String addr){ mHandler.removeMessages(MSG_SHOW); Bundle bundle = new Bundle(); bundle.putString("ADDR", addr); mHandler.sendMessage(Message.obtain(mHandler, MSG_SHOW, bundle)); } public class MyHandler extends Handler{ public MyHandler(Looper looper){ super(looper); } public void handleMessage(Message msg){ switch(msg.what){ case MSG_SHOW: Bundle bundle = (Bundle)msg.obj; Toast.makeText(getApplicationContext(), bundle.getString("ADDR"), Toast.LENGTH_SHORT).show(); break; } } } }


你可能感兴趣的:(android应用)