標籤:hand change 方便 exce out run request api 位置
前言:花了一個早上研究了以下android擷取經緯度,然後網上的參考資料都是雜七雜八,基本上都是過去幾年的,現在我用 android6.0參照別人的結果發生好多錯誤,我的內心幾乎是崩潰的。後來,不斷百度,不斷goole,不斷尋找資料,終於解決了,而且完美打包,以後直接用就可以了。
1.這個類原來是用kotlin寫的,後來有些東西和java又不同,索性就改成java吧,反正他們相容性很強-----封裝的類名為:LocationUtil
package com.example.jason_jan.guangdamiao.Util;import android.content.Context;import android.content.pm.PackageManager;import android.location.Address;import android.location.Geocoder;import android.location.Location;import android.location.LocationListener;import android.location.LocationManager;import android.os.Build;import android.os.Bundle;import android.support.v4.content.ContextCompat;import android.widget.Toast;import com.example.jason_jan.guangdamiao.GlobalConstant.LogUtils;import java.io.IOException;import java.util.List;/** * Created by Jason_Jan on 2017/7/14. */public class LocationUtil { // 緯度 public static double latitude = 0.0; // 經度 public static double longitude = 0.0; public static LocationManager locationManager; public static Location location; private static String provider; /** * 初始化位置資訊 * * @param context */ public static void initLocation(Context context) { LocationListener locationListener = new LocationListener() { @Override public void onStatusChanged(String arg0, int arg1, Bundle arg2) { // TODO Auto-generated method stub } @Override public void onProviderEnabled(String arg0) { // TODO Auto-generated method stub } @Override public void onProviderDisabled(String arg0) { // TODO Auto-generated method stub } @Override public void onLocationChanged(Location arg0) { // TODO Auto-generated method stub // 更新當前經緯度 } }; //擷取定位服務 locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); //擷取當前可用的位置控制器 List<String> list = locationManager.getProviders(true); if (list.contains(LocationManager.GPS_PROVIDER)) { //是否為GPS位置控制器 provider = LocationManager.GPS_PROVIDER; } else if (list.contains(LocationManager.NETWORK_PROVIDER)) { //是否為網路位置控制器 provider = LocationManager.NETWORK_PROVIDER; } else { Toast.makeText(context, "請檢查網路或GPS是否開啟", Toast.LENGTH_LONG).show(); return; } if ( Build.VERSION.SDK_INT >= 23 && ContextCompat.checkSelfPermission( context, android.Manifest.permission.ACCESS_FINE_LOCATION ) != PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission( context, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { return ; } location = locationManager.getLastKnownLocation(provider); if (location != null) { //擷取當前位置,這裡只用到了經緯度 String stringPosition = "緯度為:" + location.getLatitude() + ",經度為:" + location.getLongitude(); longitude=location.getLongitude(); latitude=location.getLatitude(); Toast.makeText(context, stringPosition, Toast.LENGTH_LONG).show(); } //綁定定位事件,監聽位置是否改變 //第一個參數為控制器類型第二個參數為監聽位置變化的時間間隔(單位:毫秒) //第三個參數為位置變化的間隔(單位:米)第四個參數為位置監聽器 locationManager.requestLocationUpdates(provider, 2000, 2, locationListener); } public static String getAddress(Location location,Context context) throws IOException { if(location==null){ LogUtils.INSTANCE.d_debugprint("錯誤","未找到location"); return ""; } Geocoder geocoder = new Geocoder(context); boolean flag = geocoder.isPresent(); LogUtils.INSTANCE.d_debugprint("位置資訊","the flag is "+flag); StringBuilder stringBuilder = new StringBuilder(); try { //根據經緯度擷取地理位置資訊 List<Address> addresses = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1); LogUtils.INSTANCE.d_debugprint("經度",Double.toString(location.getLatitude())); LogUtils.INSTANCE.d_debugprint("緯度",Double.toString(location.getLongitude())); //根據地址擷取地理位置資訊 //List<Address> addresses = geocoder.getFromLocationName( "廣東省珠海市香洲區沿河路321號", 1); if (addresses.size() > 0) { Address address = addresses.get(0); for (int i = 0; i < address.getMaxAddressLineIndex(); i++) { stringBuilder.append(address.getAddressLine(i)).append("\n"); } stringBuilder.append(address.getCountryName()).append("_");//國家 stringBuilder.append(address.getFeatureName()).append("_");//周邊地址 stringBuilder.append(address.getLocality()).append("_");//市 stringBuilder.append(address.getPostalCode()).append("_"); stringBuilder.append(address.getCountryCode()).append("_");//國家編碼 stringBuilder.append(address.getAdminArea()).append("_");//省份 stringBuilder.append(address.getSubAdminArea()).append("_"); stringBuilder.append(address.getThoroughfare()).append("_");//道路 stringBuilder.append(address.getSubLocality()).append("_");//香洲區 stringBuilder.append(address.getLatitude()).append("_");//經度 stringBuilder.append(address.getLongitude());//維度 /*System.out.println(stringBuilder.toString());*/ LogUtils.INSTANCE.d_debugprint("擷取到的地理位置為:",stringBuilder.toString()); } } catch (IOException e) { // TODO Auto-generated catch block Toast.makeText(context, "報錯", Toast.LENGTH_LONG).show(); e.printStackTrace(); } return stringBuilder.toString(); }}
2.簡單解釋以上的代碼吧
-----5個靜態變數,都很重要。LocationManager是老大。經度緯度是我們需要的東西。
-----初始化位置資訊,在用的時候,先就初始化一下就ok了。
-----裡面一個監聽位置資訊,不用管,直接照抄。
-----後面是從LocationManager那裡得到位置服務。
-----最後一個是綁定位置時間,監聽位置是否改變。
-----值得注意的是,有一個版本判斷,不寫的話,有tm來一些版本不同,然後怎麼怎麼樣,煩死了,這個先加上,作用也不知道有沒有,不過後面用的時候還要注意一些許可權問題,我在後面提一下。
3.然後就是一個靜態方法,getAddress來通過經度緯度,來擷取我們需要的位置資訊。直接複製就行。不過有一個日誌列印的東西,直接刪掉就好。就是這個東西-----LogUtils.INSTANCE.d_debugprint()。這個東西是我封裝好來列印堆棧資訊在多少行在哪個函數,而且只在調試的時候有效。後面有時間我會寫這方面的部落格的。
4.調用的時候就比較輕鬆了。注意這裡調用的話,因為服務在後台運行,要用一個線程處理尋找地理位置的函數,因為主線程是很忙的,動不動就崩潰了。
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, REQUEST_PERMISSION_LOCATION); } else { LocationUtil.initLocation(this); LogUtils.INSTANCE.d_debugprint("經度:",Double.toString(LocationUtil.longitude)); LogUtils.INSTANCE.d_debugprint("緯度:",Double.toString(LocationUtil.latitude)); }
對於上面的if,非常重要,我一早上就在找這方面的東西,就這麼解決就好,不過這樣還是會報錯=====
@TargetApi(Build.VERSION_CODES.M)
@Override
protected void onCreate(Bundle savedInstanceState)
{。。。}
加一個@TargetApi(Build.VERSION_CODES.M)這樣就沒事了。
5.線程呢,線程呢?不要急,在下面=====
new Thread(new Runnable() { @Override public void run() { try { str_location= LocationUtil.getAddress(LocationUtil.location,getApplicationContext()); //位置資訊-----一個字串 }catch (IOException e){ e.printStackTrace(); } handler_location.post(new Runnable() { @Override public void run() { Toast.makeText(getApplicationContext(),str_location,Toast.LENGTH_LONG).show(); } }); } }).start();
6.就是這樣用,很方便吧。注意還有在=====AndroidManifest.xml中加必要的許可權
<!--擷取當前地理位置要的許可權--> <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" />
這個東西也是十分坑人的。注意加上。
7.That‘s all.繼續幹!!!
Android 擷取地理位置資訊 封裝好了 直接用