上一节我们介绍了android studio中配置百度地图sdk,这一节我们做一个定位的实例:
首先我们在布局文件中添加一个textview:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.lbstest.MainActivity">

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView" />

</android.support.constraint.ConstraintLayout>

接着我们在Activity的oncreate()方法中创建一个LocationClient实例,注意LocationClient的实例化要放在setContentView()之前,实例化后对LocationClient设置监听:

public TextView positionText;
    public LocationClient mlocation;
    private List<String> permissionList;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mlocation = new LocationClient(getApplicationContext());
        //注册监听事件
        mlocation.registerLocationListener(new MyLocationListener());
        setContentView(R.layout.activity_main);
        positionText = (TextView) findViewById(R.id.textView);
        //申请权限
        initPermission();
    }

还记得我们在AndroidManifest.xml中添加的权限吗,其中有一些是敏感权限,在android6.0中需要动态申请,下面介绍一种同时申请多个权限的方法:

List<String> permissionList = new ArrayList<>();
        if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            permissionList.add(Manifest.permission.ACCESS_FINE_LOCATION);
        }
        if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
            permissionList.add(Manifest.permission.READ_PHONE_STATE);
        }
        if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            permissionList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
        }
        if (!permissionList.isEmpty()) {
            String[] permissions = permissionList.toArray(new String[permissionList.size()]);
            ActivityCompat.requestPermissions(MainActivity.this, permissions, 1);
        } else {
            requestLocation();
        }

这里创建一个list集合,然后依次判断这三个权限有没有被授权,如果没授权就添加到list集合中,最后将list集合转换成数组,在一次性申请。

申请的回调:

@Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode) {
            case 1:
                if (grantResults.length > 0) {
                    for (int result : grantResults) {
                        if (result != PackageManager.PERMISSION_GRANTED) {
                            Toast.makeText(MainActivity.this, "必须同意所以权限", Toast.LENGTH_LONG).show();
                            finish();
                            return;
                        }
                    }
                    requestLocation();
                } else {
                    finish();
                }
                break;
            default:
        }
    }

当全部权限都授权后调用requestLocation()方法,在start后开始调用监听回调:

private void requestLocation() {
        initLocation();
        mlocation.start();
    }

    private void initLocation() {
        LocationClientOption option = new LocationClientOption();
        //可选,默认高精度,设置定位模式,高精度,低功耗,仅设备
        option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
        //可选,默认0,即仅定位一次,设置发起定位请求的间隔需要大于等于1000ms才是有效的
        option.setScanSpan(5000);
         //设置百度坐标
        option.setCoorType("bd09ll");
        option.setOpenGps(true); // 打开gps
        //可选,设置是否需要地址信息,默认不需要
        option.setIsNeedAddress(true);
        mlocation.setLocOption(option);
    }

这里说一下定位mode:

  • Hight_Accuracy:表示高精度模式,优先使用GPS,无法使用GPS的时候使用网络定位。
  • Battery_Saving:节电模式,只是用网络定位。
  • Device_Sensors:传感器模式,只是用GPS定位。

LocationClient的监听:

public class MyLocationListener implements BDLocationListener {
        @Override
        public void onReceiveLocation(BDLocation bdLocation) {
            Log.i("info", "listener");
            final StringBuilder currentPosition = new StringBuilder();
            currentPosition.append("经度:").append(bdLocation.getLatitude()).append("\n");
            currentPosition.append("纬度:").append(bdLocation.getLongitude()).append("\n");
            currentPosition.append("省:").append(bdLocation.getProvince()).append("\n");
            currentPosition.append("市:").append(bdLocation.getCity()).append("\n");
            currentPosition.append("区:").append(bdLocation.getDistrict()).append("\n");
            currentPosition.append("街道:").append(bdLocation.getStreet()).append("\n");
            currentPosition.append("定位方式:");
            if (bdLocation.getLocType()== BDLocation.TypeGpsLocation) {
                currentPosition.append("gps");
            } else if (bdLocation.getLocType()==BDLocation.TypeNetWorkLocation) {
                currentPosition.append("net");
            }
            Log.i("info", currentPosition.toString());
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    positionText.setText(currentPosition);
                }
            });

        }

        @Override
        public void onConnectHotSpotMessage(String s, int i) {

        }
    }

填坑:监听方法是实现在子线程中的,在这里不能做更新ui的操作。
最后在Activity的onDestroy()方法中调用stop函数:

@Override
    protected void onDestroy() {
        super.onDestroy();
        mlocation.stop();
    }

填坑:我们把定位方式设置为高精度,这样当开启GPS的时候就会使用GPS定位,但是使用GPS的前提是在室外,否则即使开了GPS 也不能用。

运行图:

android编程 打开定位 android定位开发_android

完整代码:

public class MainActivity extends AppCompatActivity {

    public TextView positionText;
    public LocationClient mlocation;
    private List<String> permissionList;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mlocation = new LocationClient(getApplicationContext());
        mlocation.registerLocationListener(new MyLocationListener());
        setContentView(R.layout.activity_main);
        positionText = (TextView) findViewById(R.id.textView);

        initPermission();
    }

    private void initPermission() {
        permissionList = new ArrayList<>();
        if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            permissionList.add(Manifest.permission.ACCESS_FINE_LOCATION);
        }
        if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
            permissionList.add(Manifest.permission.READ_PHONE_STATE);
        }
        if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            permissionList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
        }
        if (!permissionList.isEmpty()) {
            String[] permissions = permissionList.toArray(new String[permissionList.size()]);
            ActivityCompat.requestPermissions(MainActivity.this, permissions, 1);
        } else {
            requestLocation();
        }
    }

    private void requestLocation() {
        initLocation();
        mlocation.start();
    }

    private void initLocation() {
        LocationClientOption option = new LocationClientOption();
        //可选,默认高精度,设置定位模式,高精度,低功耗,仅设备
        option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
        //可选,默认0,即仅定位一次,设置发起定位请求的间隔需要大于等于1000ms才是有效的
        option.setScanSpan(5000);
        //可选,设置是否需要地址信息,默认不需要
        option.setIsNeedAddress(true);
        mlocation.setLocOption(option);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode) {
            case 1:
                if (grantResults.length > 0) {
                    for (int result : grantResults) {
                        if (result != PackageManager.PERMISSION_GRANTED) {
                            Toast.makeText(MainActivity.this, "必须同意所以权限", Toast.LENGTH_LONG).show();
                            finish();
                            return;
                        }
                    }
                    requestLocation();
                } else {
                    finish();
                }
                break;
            default:
        }
    }


    public class MyLocationListener implements BDLocationListener {
        @Override
        public void onReceiveLocation(BDLocation bdLocation) {
            Log.i("info", "listener");
            final StringBuilder currentPosition = new StringBuilder();
            currentPosition.append("经度:").append(bdLocation.getLatitude()).append("\n");
            currentPosition.append("纬度:").append(bdLocation.getLongitude()).append("\n");
            currentPosition.append("省:").append(bdLocation.getProvince()).append("\n");
            currentPosition.append("市:").append(bdLocation.getCity()).append("\n");
            currentPosition.append("区:").append(bdLocation.getDistrict()).append("\n");
            currentPosition.append("街道:").append(bdLocation.getStreet()).append("\n");
            currentPosition.append("定位方式:");
            if (bdLocation.getLocType()== BDLocation.TypeGpsLocation) {
                currentPosition.append("gps");
            } else if (bdLocation.getLocType()==BDLocation.TypeNetWorkLocation) {
                currentPosition.append("net");
            }
            Log.i("info", currentPosition.toString());
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    positionText.setText(currentPosition);
                }
            });

        }

        @Override
        public void onConnectHotSpotMessage(String s, int i) {

        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mlocation.stop();
    }
}