LocationManager、Geocoder获取当前位置

参考:Android获取当前位置的经纬度

示例:

public class MainActivityI extends Activity {

    private LocationUtils locationUtil;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        locationUtil = LocationUtils.getInstance(this);
    }

    protected void onDestroy() {
        super.onDestroy();

        locationUtil.removeLocationUpdatesListener();
    }
}

所需权限:

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

工具类:

package com.example.locationdemo;

import android.content.Context;
import android.content.Intent;
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.provider.Settings;
import android.widget.Toast;

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

/*
* 注意
* 1、Android6.0动态权限, 
* 2、Geocoder获取地理位置信息是一个后台的耗时操作,
* 为了不阻塞主线程,强力建议在使用Geocoder获取地理位置信息时采用异步线程的方式来请求服务,这样不会造成主线程的阻塞。
* */
public class LocationUtils {

    private volatile static LocationUtils uniqueInstance;
    private LocationManager locationManager;
    private Context mContext;

    private LocationUtils(Context context) {
        mContext = context;
        getLocation();
    }

    //采用Double CheckLock(DCL)实现单例
    public static LocationUtils getInstance(Context context) {
        if (uniqueInstance == null) {
            synchronized (LocationUtils.class) {
                if (uniqueInstance == null) {
                    uniqueInstance = new LocationUtils(context);
                }
            }
        }
        return uniqueInstance;
    }

    private void getLocation() {
        //1.获取位置管理器
        locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);

        //2.获取位置提供器,GPS或是NetWork
        // 获取所有可用的位置提供器
        List providerList = locationManager.getProviders(true);
        String locationProvider;
        if (providerList.contains(LocationManager.GPS_PROVIDER)) {
            //GPS 定位的精准度比较高,但是非常耗电。
            System.out.println("=====GPS_PROVIDER=====");
            locationProvider = LocationManager.GPS_PROVIDER;
        } else if (providerList.contains(LocationManager.NETWORK_PROVIDER)) {//Google服务被墙不可用
            //网络定位的精准度稍差,但耗电量比较少。
            System.out.println("=====NETWORK_PROVIDER=====");
            locationProvider = LocationManager.NETWORK_PROVIDER;
        } else {
            System.out.println("=====NO_PROVIDER=====");
            // 当没有可用的位置提供器时,弹出Toast提示用户
            Toast.makeText(mContext, "No location provider to use", Toast.LENGTH_SHORT).show();
            Intent intent = new Intent();
            intent.setAction(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            mContext.startActivity(intent);
            return;
        }

        //3.获取上次的位置,一般第一次运行,此值为null
        Location location = locationManager.getLastKnownLocation(locationProvider);
        if (location != null) {
            // 显示当前设备的位置信息
            System.out.println("==显示当前设备的位置信息==");
            showLocation(location);
        } else {//当GPS信号弱没获取到位置的时候可从网络获取
            System.out.println("==Google服务被墙的解决办法==");
            getLngAndLatWithNetwork();//Google服务被墙的解决办法
        }
        // 监视地理位置变化,第二个和第三个参数分别为更新的最短时间minTime和最短距离minDistace
        //LocationManager 每隔 5 秒钟会检测一下位置的变化情况,当移动距离超过 10 米的时候,
        // 就会调用 LocationListener 的 onLocationChanged() 方法,并把新的位置信息作为参数传入。
        locationManager.requestLocationUpdates(locationProvider, 5000, 10, locationListener);
    }

    //获取经纬度
    private void showLocation(Location location) {
        double latitude = location.getLatitude();//纬度
        double longitude = location.getLongitude();//经度
        getAddress(latitude, longitude);
    }

    private void getAddress(double latitude, double longitude) {
        //Geocoder通过经纬度获取具体信息
        Geocoder gc = new Geocoder(mContext, Locale.getDefault());
        try {
            List
locationList = gc.getFromLocation(latitude, longitude, 1); if (locationList != null) { Address address = locationList.get(0); String countryName = address.getCountryName();//国家 String countryCode = address.getCountryCode(); String adminArea = address.getAdminArea();//省 String locality = address.getLocality();//市 String subAdminArea = address.getSubAdminArea();//区 String featureName = address.getFeatureName();//街道 for (int i = 0; address.getAddressLine(i) != null; i++) { String addressLine = address.getAddressLine(i); //街道名称:广东省深圳市罗湖区蔡屋围一街深圳瑞吉酒店 System.out.println("addressLine=====" + addressLine); } String currentPosition = "latitude is " + latitude//22.545975 + "\n" + "longitude is " + longitude//114.101232 + "\n" + "countryName is " + countryName//null + "\n" + "countryCode is " + countryCode//CN + "\n" + "adminArea is " + adminArea//广东省 + "\n" + "locality is " + locality//深圳市 + "\n" + "subAdminArea is " + subAdminArea//null + "\n" + "featureName is " + featureName;//蔡屋围一街深圳瑞吉酒店 System.out.println(currentPosition); } } catch (IOException e) { e.printStackTrace(); } } public void removeLocationUpdatesListener() { if (locationManager != null) { uniqueInstance = null; locationManager.removeUpdates(locationListener); } } private LocationListener locationListener = new LocationListener() { // Provider的状态在可用、暂时不可用和无服务三个状态直接切换时触发此函数 @Override public void onStatusChanged(String provider, int status, Bundle arg2) { } // Provider被enable时触发此函数,比如GPS被打开 @Override public void onProviderEnabled(String provider) { } // Provider被disable时触发此函数,比如GPS被关闭 @Override public void onProviderDisabled(String provider) { } //当坐标改变时触发此函数,如果Provider传进相同的坐标,它就不会被触发 @Override public void onLocationChanged(Location location) { System.out.println("==onLocationChanged=="); showLocation(location); } }; //从网络获取经纬度 private void getLngAndLatWithNetwork() { LocationManager locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE); locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 5000, 10, locationListener); Location location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); showLocation(location); } }

你可能感兴趣的:(地图定位)