美文网首页
位置定位LocationManager

位置定位LocationManager

作者: 勤学奋进小郎君 | 来源:发表于2018-10-16 10:10 被阅读0次

    简单的获取当前位置对象

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            //提供位置定位服务的位置管理器对象,中枢控制系统
            LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
            //位置提供器,也就是实际上来定位的对象,这里选择的是GPS定位
            String locationProvider = LocationManager.NETWORK_PROVIDER;
            //开始定位,获取包含上次记录的位置数据的位置对象
            Location location = locationManager.getLastKnownLocation(locationProvider);
            //获取纬度
            Double latitude = location.getLatitude();
            //获取经度
            Double longitude = location.getLongitude();
            Log.e("Latitude", String.valueOf(latitude));
            Log.e("Longitude", String.valueOf(longitude));
        }
    

    执行时,会出现getLastKnownLocation获取不到对象,抛出NullException。使用getProvider方法获取手机上的位置提供器,可以看到高精度定位下,有三种位置提供器可供使用
    其实从这个方法名可以知道他是获取上次记录下的位置信息,如果是新设备,或者恢复工厂设置的手机,就会报出异常,这里用的模拟器还没记录过位置信息,所以一直报空异常

    高精度定位

    根据 getLastKnownLocation()返回null的解决这个,发现可以使用requestLocationUpdates方法注册位置更新

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            //提供位置定位服务的位置管理器对象,中枢控制系统
            LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
            //位置提供器,也就是实际上来定位的对象,这里选择的是GPS定位
            String locationProvider = LocationManager.PASSIVE_PROVIDER;
            //获取手机中开启的位置提供器
            List<String> providers = locationManager.getProviders(true);
            //开始定位,获取当前位置对象
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                // TODO: Consider calling
                //    ActivityCompat#requestPermissions
                // here to request the missing permissions, and then overriding
                //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
                //                                          int[] grantResults)
                // to handle the case where the user grants the permission. See the documentation
                // for ActivityCompat#requestPermissions for more details.
                return;
            }
            Location location = locationManager.getLastKnownLocation(locationProvider);
            while (location == null) {
                //每1s监听一次位置信息,如果位置距离改变超过1m。就执行onLocationChanged方法
                //如果第一次打开没有显示位置信息,可以退出程序重新进入,就会显示
                locationManager.requestLocationUpdates("gps", 1000,1,new locationListener());
            }
            //获取纬度
            Double latitude = location.getLatitude();
            //获取经度
            Double longitude = location.getLongitude();
            Log.e("Latitude", String.valueOf(latitude));
            Log.e("Longitude", String.valueOf(longitude));
        }
    

    locationListener.java位置监听器

    可以理解为,先开启监听器监听位置信息,位置更改后记录有了位置数据,然后就可以使用getLastKnownLocation获取上一次的位置数据,所以

    
    public class locationListener implements LocationListener {
        @Override
        public void onLocationChanged(Location location) {
    
        }
    
        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
    
        }
    
        @Override
        public void onProviderEnabled(String provider) {
            Log.e("位置提供器:", "启用");
        }
    
        @Override
        public void onProviderDisabled(String provider) {
    
        }
    }
    

    反向编码经纬度获得可理解地理位置

    1、注册为高德地图开放平台的开发者
    2、在控制台添加新key,选择Web服务,获取key,才可以使用高德地图的api

    AndroidManifest.xml

    <uses-permission android:name="android.permission.INTERNET" />
    

    MainActivity.java
    异步处理回调函数返回的相应地址数据,进行UI展示

    public class MainActivity extends Activity {
        TextView textview;
        private Handler handler = new Handler(){
    
            @Override
            public void handleMessage(Message msg) {
                if (msg.what == 1){
                    textview = findViewById(R.id.textview0);
                    textview.setText(msg.obj.toString());
                }
            }
        };
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            httputils.requestHttp("116.310003", "39.991957", new callback2showcontent() {
                @Override
                public void showJSON(String response) {
                    //这个方法还是在子线程中,想要处理UI操作,异步线程
                    Message message = new Message();
                    message.what = 1;
                    message.obj = response;
                    handler.sendMessage(message);
                }
            });
            Toast.makeText(this,"successful", Toast.LENGTH_LONG);
        }
    }
    

    httputils.java
    封装的http请求

    public class httputils {
        private static URL url;
        public static void requestHttp(final String latitude, final String longitude, final callback2showcontent func){
    
            new Thread(new Runnable() {
                HttpResponse response;
                String returnResutJSON;
                @Override
                public void run() {
                    StringBuilder stringbuilder = new StringBuilder("https://restapi.amap.com/v3/geocode/regeo?output=JSON&key=<你的web服务key>&radius=1000&extensions=all");
                    stringbuilder.append("&location=" + latitude + "," + longitude);
                    try {
                        url = new URL(stringbuilder.toString());
                    } catch (MalformedURLException e) {
                        e.printStackTrace();
                    }
                    HttpClient httpclient = new DefaultHttpClient();
                    HttpGet get = new HttpGet(url.toString());
                    try {
                        //http相应数据
                        response = httpclient.execute(get);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    if(response.getStatusLine().getStatusCode() == 200){
    
                        try {
                            returnResutJSON = EntityUtils.toString(response.getEntity());
                            func.showJSON(returnResutJSON);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }).start();
        }
    }
    

    使用高德地图显示位置

    需要使用第三方平台的API接口,来返回具体位置,这里我使用的是高德地图API
    1、注册为高德地图开放平台的开发者
    2、在控制台创建应用,然后获取API key(keytool -list -v -keystore <.keystore文件的路径>)可见说明https://lbs.amap.com/faq/top/hot-questions/249
    3、在android studio的编辑器的文件配置

    https://lbs.amap.com/api/android-sdk/guide/create-project/android-studio-create-project

    1、将jar包放入libs目录,然后右键add as library
    2、获取密钥,默认密码android
    keytool -list -keystore C:\Users\xxxx\.android\debug.keystore -v
    AndroidManifest.xml

        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
            <meta-data
                android:name="com.amap.api.v2.apikey"
                android:value="<你的密钥>"/>
    ......
        </application>
       <!--允许程序打开网络套接字-->
        <uses-permission android:name="android.permission.INTERNET" />
        <!--允许程序设置内置sd卡的写权限-->
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
        <!--允许程序获取网络状态-->
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
        <!--允许程序访问WiFi网络信息-->
        <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
        <!--允许程序读写手机状态和身份-->
        <uses-permission android:name="android.permission.READ_PHONE_STATE" />
        <!--允许程序访问CellID或WiFi热点来获取粗略的位置-->
        <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    

    activity_layout.xml
    地图容器控件

        <com.amap.api.maps.MapView
            android:id="@+id/mapview"
            android:layout_height="match_parent"
            android:layout_width="match_parent"/>
    

    MainActivity.java

        private MapView mapview = null;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            //引用地图控件
            mapview = (MapView)findViewById(R.id.mapview);
            //创建地图
            mapview.onCreate(savedInstanceState);
        }
    
    展示结果

    定位自己所在位置

    public class MainActivity extends Activity {
    
        private MapView mapview = null;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            //引用地图控件
            mapview = (MapView)findViewById(R.id.mapview);
            //创建地图
            mapview.onCreate(savedInstanceState);
            //地图管理器:显示地图
            AMap amap = mapview.getMap();
            /*
             显示当前自己的位置
              */
            //初始化蓝点对象
            MyLocationStyle mylocation = new MyLocationStyle();
            //定位时间间隔
            mylocation.interval(1000);
            //将配置好的蓝点对象由管理器进行设置
            amap.setMyLocationStyle(mylocation);
            //设置默认定位按钮
    //        amap.getUiSettings().setMyLocationButtonEnabled(true);
            //启动定位蓝点
            amap.setMyLocationEnabled(true);
        }
    

    相关文章

      网友评论

          本文标题:位置定位LocationManager

          本文链接:https://www.haomeiwen.com/subject/bndoaftx.html