1. 程式人生 > >Android獲取當前位置,location為空

Android獲取當前位置,location為空

     通過最後一次的地理位置來獲得Location物件:location = locationManager.getLastKnownLocation(provider);得出location為空。檢視各種資料發現,getLastKnownLocation僅僅是獲取當快取中的上一次開啟地圖快取起來的位置,不可能一次就能獲取,那唯有location為空的時候繼續獲取,採用locationManager.requestLocationUpdates("gps", 60000, 1, locationListener); 這樣解決了問題,貼出整合修改的程式碼。

package com.belle.tools;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.List;

import android.content.Context;
import android.location.Address;
import android.location.Criteria;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

public class LocationUtils {
	public String cityName;
	// 此物件能通過經緯度來獲取相應的城市等資訊
	private Geocoder geocoder;	
	 private LocationManager locationManager;  
	 private String provider;  
	 private Location location; 
	 private Context context;
	/*
	 * 通過地理座標獲取城市名 其中CN分別是city和name的首字母縮寫
	 */
	public String getCNBylocation(Context context) {
		geocoder = new Geocoder(context);
		String serviceName = Context.LOCATION_SERVICE;
		// 例項化一個LocationManager物件
		locationManager = (LocationManager) context.getSystemService(serviceName);
		// provider的型別
		// String provider = LocationManager.NETWORK_PROVIDER;
		getProvider();
		//openGPS();
		// 通過最後一次的地理位置來獲得Location物件
		location = locationManager.getLastKnownLocation(provider);
		if(location == null){
			locationManager.requestLocationUpdates("gps", 60000, 1, locationListener); 
		}
		String queryed_name = updateWithNewLocation(location);
		if ((queryed_name != null) && (0 != queryed_name.length())) {
			cityName = queryed_name;
		}
		/**
		 * 第二個引數表示更新的週期,單位為毫秒;第三個引數表示最小距離間隔,單位是米 設定每30秒進行一次自動定位
		 */
		locationManager.requestLocationUpdates(provider, 30000, 50,
				locationListener);
		return cityName;
	}

	/**
	 * 方位改變時觸發,進行呼叫
	 */
	private final LocationListener locationListener = new LocationListener() {
		String tempCityName;

		public void onLocationChanged(Location location) {
			tempCityName = updateWithNewLocation(location);
			if ((tempCityName != null) && (tempCityName.length() != 0)) {
				cityName = tempCityName;
			}
		}

		public void onProviderDisabled(String provider) {
			tempCityName = updateWithNewLocation(null);
			if ((tempCityName != null) && (tempCityName.length() != 0)) {
				cityName = tempCityName;
			}
		}
		public void onProviderEnabled(String provider) {
		}
		public void onStatusChanged(String provider, int status, Bundle extras) {
		}
	};

	/**
	 * 更新location
	 */
	private String updateWithNewLocation(Location location1) {
		String mcityName = "";
		double lat = 0;
		double lng = 0;
		List<Address> addList = null;
		if (location1 != null) {
			lat = location1.getLatitude();
			lng = location1.getLongitude();
		} else {
			System.out.println("無法獲取地理資訊");
		}
		try {
			addList = geocoder.getFromLocation(lat, lng, 1);
		} catch (IOException e) {
			e.printStackTrace();
		}
		if (addList != null && addList.size() > 0) {
			for (int i = 0; i < addList.size(); i++) {
				Address add = addList.get(i);
				mcityName += add.getLocality();
			}
		}
		if (mcityName.length() != 0) {
			return mcityName.substring(0, (mcityName.length() - 1));
		} else {
			return mcityName;
		}
	}

	/**
	 * 通過經緯度獲取地址資訊的另一種方法
	 */
	public String GetAddr(String latitude, String longitude) {
		String addr = "";
		/*
		 * 也可以是http://maps.google.cn/maps/geo?output=csv&key=abcdef&q=%s,%s,
		 * 不過解析出來的是英文地址 金鑰可以隨便寫一個key=abc
		 * output=csv,也可以是xml或json,不過使用csv返回的資料最簡潔方便解析
		 */
		String url = String.format(
				"http://maps.google.cn/maps/geo?output=csv&key=abcdef&q=%s,%s",
				latitude, longitude);
		URL myURL = null;
		URLConnection httpsConn = null;
		try {
			myURL = new URL(url);
		} catch (MalformedURLException e) {
			e.printStackTrace();
			return null;
		}
		try {
			httpsConn = (URLConnection) myURL.openConnection();
			if (httpsConn != null) {
				InputStreamReader insr = new InputStreamReader(
						httpsConn.getInputStream(), "UTF-8");
				BufferedReader br = new BufferedReader(insr);
				String data = null;
				if ((data = br.readLine()) != null) {
					String[] retList = data.split(",");
					if (retList.length > 2 && ("200".equals(retList[0]))) {
						addr = retList[2];
					} else {
						addr = "";
					}
				}
				insr.close();
			}
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
		return addr;
	}
	
	private void openGPS() {  
   
        if (locationManager.isProviderEnabled(android.location.LocationManager.GPS_PROVIDER)  
        		|| locationManager.isProviderEnabled(android.location.LocationManager.NETWORK_PROVIDER)  
        ){  
            Toast.makeText(context, " 位置源已設定! ", Toast.LENGTH_SHORT).show();  
            return;  
        }   
        Toast.makeText(context, " 位置源未設定!", Toast.LENGTH_SHORT).show();  
    }  
	
	private void getProvider() {  
        // TODO Auto-generated method stub  
        // 構建位置查詢條件  
        Criteria criteria = new Criteria();  
        criteria.setAccuracy(Criteria.ACCURACY_FINE);  //高精度
        criteria.setAltitudeRequired(false);  //不查詢海拔
        criteria.setBearingRequired(false);  //不查詢方位
        criteria.setCostAllowed(true);  //不允許付費 
        criteria.setPowerRequirement(Criteria.POWER_LOW);  //低耗
        // 返回最合適的符合條件的 provider ,第 2 個引數為 true 說明 , 如果只有一個 provider 是有效的 , 則返回當前  provider
        provider = locationManager.getBestProvider(criteria, true);  
    }  
}