Android 擷取地理位置資訊 封裝好了 直接用

來源:互聯網
上載者:User

標籤: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 擷取地理位置資訊 封裝好了 直接用

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.