Android 腾讯位置服务使用(详细步骤+源码)

private void initView() {

tvLocationInfo = findViewById(R.id.tv_location_info);

btnContinuousPositioning = findViewById(R.id.btn_continuous_positioning);

btnStopPositioning = findViewById(R.id.btn_stop_positioning);

btnContinuousPositioning.setOnClickListener(this);

btnStopPositioning.setOnClickListener(this);

}

在onCreate方法中调用它。

然后当前的MainActivity实现控件的点击监听。

在这里插入图片描述

之后重写onClick方法。根据不同的控件id来触发点击。

/**

  • 页面控件点击事件

*/

@Override

public void onClick(View v) {

switch (v.getId()) {

case R.id.btn_continuous_positioning:

//连续定位

break;

case R.id.btn_stop_positioning:

//停止定位

break;

default:

break;

}

}

如果想要定位肯定要使用定位SDK中的方法。

首先创建成员变量

//定位管理

private TencentLocationManager mLocationManager;

//定位请求

private TencentLocationRequest locationRequest;

然后新建一个initLocation方法,对里面的变量进行配置。

/**

  • 初始化定位信息

*/

private void initLocation() {

//获取TencentLocationManager实例

mLocationManager = TencentLocationManager.getInstance(this);

//获取定位请求TencentLocationRequest 实例

locationRequest = TencentLocationRequest.create();

//设置定位时间间隔,10s

locationRequest.setInterval(10000);

//位置信息的详细程度 REQUEST_LEVEL_ADMIN_AREA表示获取经纬度,位置所处的中国大陆行政区划

locationRequest.setRequestLevel(TencentLocationRequest.REQUEST_LEVEL_ADMIN_AREA);

//是否允许使用GPS

locationRequest.setAllowGPS(true);

//是否需要获取传感器方向,提高室内定位的精确度

locationRequest.setAllowDirection(true);

//是否需要开启室内定位

locationRequest.setIndoorLocationMode(true);

}

同样的要在onCreate方法中调用,顺序在initView之后。

然后MainActivity要实现对定位的监听,

在这里插入图片描述

一个类实现多个方法要用逗号隔开。

然后重写onLocationChangedonStatusUpdate方法,如下所示

/**

  • 接收定位结果

*/

@Override

public void onLocationChanged(TencentLocation location, int error, String reason) {

//显示定位信息

showLocationInfo(location);

}

/**

  • 用于接收GPS、WiFi、Cell状态码

*/

@Override

public void onStatusUpdate(String name, int status, String desc) {

}

这里调用了一个显示位置信息的showLocationInfo方法。

/**

  • 显示定位信息

  • @param location

*/

private void showLocationInfo(TencentLocation location) {

//经度

double longitude = location.getLongitude();

//纬度

double latitude = location.getLatitude();

//准确性

float accuracy = location.getAccuracy();

//地址信息

String address = location.getAddress();

//海拔高度

double altitude = location.getAltitude();

//面积统计

Integer areaStat = location.getAreaStat();

//方向

float bearing = location.getBearing();

double direction = location.getDirection();

//城市

String city = location.getCity();

//城市代码

String cityCode = location.getCityCode();

//城市电话代码

String cityPhoneCode = location.getCityPhoneCode();

//坐标类型

int coordinateType = location.getCoordinateType();

//区

String district = location.getDistrict();

//经过时间

long elapsedRealtime = location.getElapsedRealtime();

//Gps信息

int gpsRssi = location.getGPSRssi();

//室内建筑

String indoorBuildingFloor = location.getIndoorBuildingFloor();

//室内建筑编码

String indoorBuildingId = location.getIndoorBuildingId();

//室内位置类型

int indoorLocationType = location.getIndoorLocationType();

//名称

String name = location.getName();

//国家

String nation = location.getNation();

//周边poi信息列表

List poiList = location.getPoiList();

//提供者

String provider = location.getProvider();

//省

String province = location.getProvince();

//速度

float speed = location.getSpeed();

//街道

String street = location.getStreet();

//街道编号

String streetNo = location.getStreetNo();

//时间

long time = location.getTime();

//镇

String town = location.getTown();

//村

String village = location.getVillage();

StringBuffer buffer = new StringBuffer();

buffer.append(“经度:” + longitude + “\n”);

buffer.append(“纬度:” + latitude + “\n”);

buffer.append(“国家:” + nation + “\n”);

buffer.append(“省:” + province + “\n”);

buffer.append(“市:” + city + “\n”);

buffer.append(“县/区:” + district + “\n”);

buffer.append(“街道:” + street + “\n”);

buffer.append(“名称:” + name + “\n”);

buffer.append(“提供者:” + provider + “\n”);

buffer.append(“详细地址:” + address + “\n”);

tvLocationInfo.setText(buffer.toString());

}

这里我获取常用的数据拼接起来,然后显示在TextView上。

然后进行下一步,定位是需要定位权限的,而这个权限属于危险权限,要在AndroidManifest.xml中静态配置,而在Android6.0之后还要在使用之前动态申请,用户同意之后才能使用。

下面先创建一个变量。

//权限

private RxPermissions rxPermissions;

然后在initView方法中增加实例化的代码,在页面创建的时候就进行实例化。

//实例化

rxPermissions = new RxPermissions(this);

之后就是对当前Android版本的判断了。

/**

  • 检查Android版本

*/

private void checkVersion() {

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

//6.0或6.0以上

//动态权限申请

permissionsRequest();

} else {

showMsg(“您不需要动态获得权限,可以直接定位”);

}

}

Toast提示

/**

  • Toast提示

  • @param msg 内容

*/

private void showMsg(String msg) {

Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();

}

动态权限申请,新增permissionsRequest方法。

/**

  • 动态权限申请

*/

private void permissionsRequest() {//使用这个框架使用了Lambda表达式,设置JDK版本为 1.8或者更高

rxPermissions.request(Manifest.permission.ACCESS_COARSE_LOCATION,

Manifest.permission.ACCESS_FINE_LOCATION,

Manifest.permission.READ_PHONE_STATE,

Manifest.permission.WRITE_EXTERNAL_STORAGE)

.subscribe(granted -> {

if (granted) {//申请成功

//发起连续定位请求

showMsg(“您已获得权限,可以定位了”);

} else {//申请失败

showMsg(“权限未开启”);

}

});

}

获取权限之后告知用户。

下面万事具备,点击按钮就可以了,修改onClick方法。

/**

  • 页面控件点击事件

*/

@Override

public void onClick(View v) {

switch (v.getId()) {

case R.id.btn_continuous_positioning:

//连续定位

tvLocationInfo.setText(“定位中”);

mLocationManager.requestLocationUpdates(locationRequest, this);

break;

case R.id.btn_stop_positioning:

//停止定位

mLocationManager.removeUpdates(this);

showMsg(“定位已停止”);

break;

default:

break;

}

}

点击连续定位按钮时,显示定位中,给用户一个好的感知,然后请求定位。

停止定位则就是移除这个定位监听。

下面我简要的说明一下刚才的逻辑,当页面创建时,你初始化页面控件、权限、定位相关配置。然后进行版本判断,Android6.0及以上则动态请求权限,6.0一下和权限通过之后都给一个Toast提示一下。之后通过点击连续定位按钮,开始请求定位,定位的信息则会通过定位回调返回到onLocationChanged方法中,通过传递来的TencentLocation对象拿到定位的具体信息,然后再选取常用的显示在TextView上。

下面运行一下,请运行在自己的手机上,不要使用虚拟机或者模拟器,看是否能够获取到定位信息。

在这里插入图片描述

OK,很明显这里已经显示出来了,当然刚才说是连续定位,只不过是10s定位一次,这个周期有点长了,看的效果并不是很好,下面改成1s一次。

locationRequest.setInterval(1000);

然后再运行一下,这一次我录制一个GIF图,来看看。

在这里插入图片描述

这个GIF是我在回家路上定位的,仔细的看你就会发现经纬度的变化。

当你点击停止定位时,这个经纬度就不会再发生变化了。

那么连续定位的演示就结束了。

② 单次定位

顾名思义,就是只定位一次,其实很简单,一行代码解决问题,不过首先还是在activity_main.xml中增加一个单次定位的按钮吧。

<Button

android:id=“@+id/btn_single_positioning”

android:layout_width=“match_parent”

android:layout_height=“wrap_content”

android:text=“单次定位” />

就放在连续定位下面。

然后进入MainActivity

//单次定位

private Button btnSinglePositioning;

initView中

在这里插入图片描述

onClick中

在这里插入图片描述

注意看这一行代码:

mLocationManager.requestSingleFreshLocation(null,this, Looper.getMainLooper());

它与连续定位是不同的方法,它还多了一个Looper的参数,其余的两个参数与连续定位一致,而我在定位请求里面传的是null,也就是说不进行配置,下面来演示一下,看会怎么样。

在这里插入图片描述

很明显,你会发现有一些数据是null,这就是单次定位的默认配置,如果你只是需要经纬度或者一个粗略的地址,你就可以采用这种方式,第一配置少,第二效率要高一些,时间快一点。

那么如果你想单次定位也获取详细的定位信息呢?也很简单,那就是把这个null改成之前配置的locationRequest既可

mLocationManager.requestSingleFreshLocation(locationRequest,this, Looper.getMainLooper());

下面再运行一下:

在这里插入图片描述

这样一来,它与连续定位的区别只是次数上的,其他都一样,在实际开发中可以按照不同的业务需求来进行使用。

还记得之前实现TencentLocationListener时重写的两个方法吗?刚才我一直在使用onLocationChanged,却对这个onStatusUpdate不闻不问,那么它就没有用吗?

当然不是,存在即合理,所以下面来看看这个方法能给我们什么样的惊喜。

定义一个成员变量作为日志的标识

public static final String TAG = “MainActivity”;

然后在onStatusUpdate返回中进行打印

@Override

public void onStatusUpdate(String name, int status, String desc) {

Log.d(TAG, “name:” + name + " status:" + status + " desc:" + desc);

}

下面再运行一下APP,点击连续定位,然后看看日志。

在这里插入图片描述

再点击单次定位和停止定位,你会发现都不会有日志打印,这说明了一个问题,这个状态的改变回调只有在连续定位时才适用,下面来分析一下这个日志给我们什么样的信息。

首先是name,就表示定位所采用的装置,比如wifi、gps、cell(定位硬件模块),状态需要用一个表格来说明,

| Name |

status

|

| — | — |

| | 状态 | 状态码 | 说明 |

| cell | STATUS_DISABLED | 0 | 模块关闭 |

| STATUS_EABLED | 1 | 模块开启 |

| STATUS_DENIED | 2 | 定位权限被禁止,位置权限被拒绝通常发生在禁用当前应用的 ACCESS_COARSE_LOCATION 等定位权限 |

| wifi | STATUS_DISABLED | 0 | Wi-Fi开关关闭 |

| STATUS_EABLED | 1 | Wi-Fi开关打开 |

| STATUS_DENIED | 2 | 权限被禁止,禁用当前应用的 ACCESS_COARSE_LOCATION 等定位权限 |

| STATUS_LOCATION_SWITCH_OFF | 5 | 位置信息开关关闭,在android M系统中,此时禁止进行Wi-Fi扫描 |

| GPS | STATUS_DISABLED | 0 | GPS开关关闭 |

| STATUS_EABLED | 1 | GPS开关打开 |

| STATUS_GPS_AVAILABEL | 3 | GPS可用,代表GPS开关打开,且搜星定位成功 |

| STATUS_GPS_UNAVAILABLE | 4 | GPS不可用,不可用有多种可能,比如:

GPS开关被关闭,GPS开关开着但是没办法搜星或者在室内等定位不成功的情况 |

这也是官方文档上提供的图片,根据这个就可以在返回中做相应的处理了,从而知道当前的状态或者问题所在。

于是可以写一个这样的方法。

/**

  • 定位状态判断

  • @param name GPS、WiFi、Cell

  • @param status 状态码

  • @return

*/

private String statusUpdate(String name, int status) {

if (“gps”.equals(name)) {

switch (status) {

case 0:

return “GPS开关关闭”;

case 1:

return “GPS开关打开”;

case 3:

return “GPS可用,代表GPS开关打开,且搜星定位成功”;

case 4:

return “GPS不可用”;

default:

return “”;

}

} else if (“wifi”.equals(name)) {

  • 20
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值