• Android 获取地理位置信息 封装好了 直接用


      前言:花了一个早上研究了以下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("
    ");
                    }
                    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.继续干!!!

     

      

    既然选择了,便不顾风雨兼程。Just follow yourself.
  • 相关阅读:
    SpringMVC学习笔记----
    各种语言学习
    七步精通Python机器学习 转
    开源GIS有用
    sql 语句
    调试windows服务最简单的方法之一
    sqlserver2008 win7下安装 windows installer错误
    高德地图AmapSDKDemo运行
    google mapsDemo示例运行
    android开发环境搭建遇到的问题
  • 原文地址:https://www.cnblogs.com/Jason-Jan/p/7170356.html
Copyright © 2020-2023  润新知