简单的位置定位

设备位置定位的方式有两种:GPS定位和网络定位。

1.GPS准确度高但耗电多,

2.网络定位耗电少但准确度低

下面介绍Android中最简单的获得手机地理位置的方法:

1.添加权限

<!-- provider的权限 -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <!-- 仅网络定位的权限 -->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

2.获取定位管理对象

//定义数据
     //定位都要通过LocationManager这个类实现
    private LocationManager locationManager;
    private String provider; //是否为网络位置控制器或GPS定位
    //当前可用的位置控制器
    List<String> list;

//实例化   
        //获取定位服务管理对象
        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        //获取当前可用的位置控制器
        list = locationManager.getProviders(true);

3.选择GPS定位还是选择网络定位,最好选择GPS。

//检查是否打开了GPS或网络定位
        if (list.contains(LocationManager.GPS_PROVIDER)) {
            //是否为GPS位置控制器
            provider = LocationManager.GPS_PROVIDER;
            textView.append("GPS位置控制器" + "\n");
        } else if (list.contains(LocationManager.NETWORK_PROVIDER)) {
            //是否为网络位置控制器
            provider = LocationManager.NETWORK_PROVIDER;
            textView.append("网络位置控制器" + "\n");
        } else {
            Toast.makeText(this, "请检查网络或GPS是否打开", Toast.LENGTH_LONG).show();
            return;
        }

4.获取地理位置

Location location = locationManager.getLastKnownLocation(provider);
        if (location != null) {
            //获取当前位置,这里只用到了经纬度
            String string = " 纬度为:" + location.getLatitude() + ",经度为:"
                    + location.getLongitude();
            Toast.makeText(this, string, Toast.LENGTH_SHORT).show();
            textView.append(string + "\n");
        }

5.绑定监听事件,如果位置改变就回调相应的方法

//绑定定位事件,监听位置是否改变
        //第一个参数为控制器类型第二个参数为监听位置变化的时间间隔(单位:毫秒)
        //第三个参数为位置变化的间隔(单位:米)第四个参数为位置监听器
        locationManager.requestLocationUpdates(provider, 2000, 2,
                locationListener);

执行上面的代码前还要创建一个监听对象:

LocationListener locationListener = new LocationListener() {

        @Override
        //状态改变的回调方法
        public void onStatusChanged(String arg0, int arg1, Bundle arg2) {

        }

        @Override
        //提供者(网络或GPS)被打开的回调方法
        public void onProviderEnabled(String arg0) {
        }

        @Override
        //提供者(网络或GPS)被关闭的回调方法
        public void onProviderDisabled(String arg0) {
        }

        @Override
        //经纬度改变的回调方法,基本都是使用这个回调方法
        public void onLocationChanged(Location arg0) {
            // 更新当前经纬度
            // Toast.makeText(MainActivity.this, "" + arg0.toString(), Toast.LENGTH_SHORT).show();
            textView.append("经度:" + arg0.getLongitude() + ",纬度:" + arg0.getLatitude() + "\n");
        }
    };

上面就是最简单的定位的功能代码。但是实际中会报错!因为权限的请求问题!还有API的等级问题!
这里就需要多加几行代码:

if (Build.VERSION.SDK_INT >= 23) {

            //如果用户并没有同意该权限
            if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                //申请权限
                // requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 100);
            } else {
                //有权限直接获取地理位置

            }

        } else {//低版本手机,直接获取位置信息

        }

实际上,上面代码方法里面不写东西也是可以的,但是如果没有上面的代码,编译就不通过!

下面是一个简单请求地理位置的程序:

效果:


这里已经打开GPS定位功能了,所以默认显示的GPS定位,否则只能显示网络定位!

1.添加权限

<!-- provider的权限 -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <!-- 仅网络定位的权限 -->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

2.布局设置

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="getLocation"
        android:text="获取我所在的位置的经纬度" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="bandLocationListener"
        android:text="一直监听位置" />

    <TextView
        android:id="@+id/tv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

3.代码设计

package fuxi.location;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import java.util.List;

public class MainActivity extends AppCompatActivity {
    //定位都要通过LocationManager这个类实现
    private LocationManager locationManager;
    private String provider; //是否为网络位置控制器
    //当前可用的位置控制器
    List<String> list;
    TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.tv);
        //获取定位服务
        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        //获取当前可用的位置控制器
        list = locationManager.getProviders(true);
        //检查是否打开了GPS或网络定位
        if (list.contains(LocationManager.GPS_PROVIDER)) {
            //是否为GPS位置控制器
            provider = LocationManager.GPS_PROVIDER;
            textView.append("GPS位置控制器" + "\n");
        } else if (list.contains(LocationManager.NETWORK_PROVIDER)) {
            //是否为网络位置控制器
            provider = LocationManager.NETWORK_PROVIDER;
            textView.append("网络位置控制器" + "\n");
        } else {
            Toast.makeText(this, "请检查网络或GPS是否打开", Toast.LENGTH_LONG).show();
            return;
        }

    }

    //获得我所在的位置的经纬度
    public void getLocation(View view) {
        if (Build.VERSION.SDK_INT >= 23) {
            //如果用户并没有同意该权限
            if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                //申请权限
            }
        } else {//低版本手机,直接获取位置信息

        }
        Location location = locationManager.getLastKnownLocation(provider);
        if (location != null) {
            //获取当前位置,这里只用到了经纬度
            String string = " 纬度为:" + location.getLatitude() + ",经度为:"
                    + location.getLongitude();
            Toast.makeText(this, string, Toast.LENGTH_SHORT).show();
            textView.append(string + "\n");
        }

    }

    //位置的监听
    public void bandLocationListener(View view) {
        //绑定定位事件,监听位置是否改变
        //第一个参数为控制器类型第二个参数为监听位置变化的时间间隔(单位:毫秒)
        //第三个参数为位置变化的间隔(单位:米)第四个参数为位置监听器
        locationManager.requestLocationUpdates(provider, 2000, 2,
                locationListener);
        if (Build.VERSION.SDK_INT >= 23) {

            //如果用户并没有同意该权限
            if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                //申请权限
                // requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 100);
            } else {
                //有权限直接获取地理位置

            }


        } else {//低版本手机,直接获取位置信息


        }
    }

    LocationListener locationListener = new LocationListener() {

        @Override
        //状态改变的回调方法
        public void onStatusChanged(String arg0, int arg1, Bundle arg2) {

        }

        @Override
        //提供者(网络或GPS)被打开的回调方法
        public void onProviderEnabled(String arg0) {
        }

        @Override
        //提供者(网络或GPS)被关闭的回调方法
        public void onProviderDisabled(String arg0) {
        }

        @Override
        //经纬度改变的回调方法,基本都是使用这个回调方法
        public void onLocationChanged(Location arg0) {
            // 更新当前经纬度
            // Toast.makeText(MainActivity.this, "" + arg0.toString(), Toast.LENGTH_SHORT).show();
            textView.append("经度:" + arg0.getLongitude() + ",纬度:" + arg0.getLatitude() + "\n");
        }
    };

    //关闭时解除监听器
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (locationManager != null) {
            if (Build.VERSION.SDK_INT >= 23) {

                //如果用户并没有同意该权限
                if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                    //申请权限
                }
            }
            locationManager.removeUpdates(locationListener);
        }
    }


}

上面程序在真机上面跑,是可以看到经纬度的实际变化的。
当然这里只是最简单的位置的请求,可以把请求的位置放到百度地图上。
但是使用百度的地图的SDK,可以很方便的请求到位置并且显示到地图上面,这个另作总结。