Baidu Map 周边雷达

在上一篇博文(Baidu Map 自动定位)中,记录了地图自动定位功能的实现,并将当前位置设置为中心点。本篇博文将基于此,添加周边雷达功能。为之后的社交通讯做基础。

周边雷达,可以帮助APP使用者,了解周围使用相同APP或其他关联APP的用户位置。可通过七个步骤,实现该功能。

(一)注册

需要在平台(注册链接)注册APP信息。
Baidu Map 周边雷达_第1张图片

这里不再详细,步骤比较简单。
但值得吐槽的是,Baidu提供的注册页面实在不敢恭维。注册过程中,页面显示速度慢。当然,可能与网速有关。
但提示“表的name重复,请稍后再试”,是几个意思?哪儿重复了?稍后再试就好了?
无奈,重新起名,竟然过了!

(二)初始化雷达服务

private RadarSearchManager m_RadarManager=null;
m_RadarManager = RadarSearchManager.getInstance();
m_RadarManager.setUserID(null);

其中setUserID(),用于设置雷达标识。若设置为null,则使用设备ID。

(三)上传当前位置信息

要搜索周边,当然需要有其他用户的位置信息。如果所有人,都不上传位置信息,结果应该很明了。当然,大家也可以尝试一下,不上传自己的位置信息,看是否能够搜索到周边的用户。

SDK文档中提供了两种上传模式,单次上传和自动周期性上传。此处,以自动周期性上传为例,进行记录(单次上传,将在之后进行简单介绍)。

(1)实现周期性自动上传,需要实现RadarUploadInfoCallback接口。

public class AroundActivity extends AppCompatActivity implements BDLocationListener, RadarUploadInfoCallback{
...
}

(2)该接口仅有一个实现方法onUploadInfoCallback()。

public RadarUploadInfo onUploadInfoCallback() {
    if(m_CurrentLocation !=null){
        RadarUploadInfo info = new RadarUploadInfo();
        info.comments ="...";
        info.pt = new LatLng(m_CurrentLocation.getLatitude(),m_CurrentLocation.getLongitude());
        return info;
    }
    return null;
}

在onUploadInfoCallback()方法中,我们仅需要将当前位置封装成RadarUploadInfo对象,并返回,即可。RadarUploadInfo对象中还提供了String类型的Comments属性。也许,社交交互可以借用该属性来做文章。

关于当前位置的获取,我们已经在上一篇博文(Baidu Map 自动定位)中进行了描述,此处不再啰嗦。

(3)接着,调用startUploadAuto()方法,启动自动周期性上传。

m_RadarManager.startUploadAuto(this, 5000);

其中this为onUploadInfoCallback Listener。5000为自动上传的时间间隔,单位为毫秒。

此处有坑!!!!!!间隔时间最小为5000ms,若小于5000ms,将无法自动周期上传!!!SDK文档中没有明确描述!通过查看SDK.class文件了解。

注:该方法将触发onGetUploadState()接口方法(见本文第四部分“创建雷达监听器”)。

(四)创建雷达监听器

接下来,将实现雷达监听部分。通过监听,可以知道,自己的位置信息是否上传成功?有没有搜索到任何信息?停止监听时,自己的位置信息有没有清空?
为完成以上功能,需要实现RadarSearchListener接口。

public class AroundActivity extends AppCompatActivity implements BDLocationListener, RadarUploadInfoCallback, RadarSearchListener{
...
}

并通过addNearbyInfoListener方法,进行关联。

m_RadarManager.addNearbyInfoListener(this);

RadarSearchListener接口共有3个方法。

@Override
public void onGetNearbyInfoList(RadarNearbyResult radarNearbyResult, RadarSearchError radarSearchError) {
    Log.i(TAG, "onGetNearbyInfoList");
    if (radarSearchError == RadarSearchError.RADAR_NO_ERROR) {
        if(null==radarNearbyResult){
            Log.i(TAG, "radarNearbyResult is Null");
            return;
        }

        if(radarNearbyResult.infoList.size()>0){
            //Todo, to show markers nearby
        }else{
            Log.i(TAG, "radarNearbyResult is not Null but size is 0");
        }
    } else if((radarSearchError == RadarSearchError.RADAR_NO_RESULT )){
        Log.i(TAG, "No Result");
    } else{
        Log.i(TAG, "onGetNearbyInfoList Search Failed");
    }
}

@Override
public oid onGetUploadState(RadarSearchError radarSearchError) {
    if (radarSearchError == RadarSearchError.RADAR_NO_ERROR) {
        Log.i(TAG, "onGetUploadState: Update Finished");
    } else {
        Log.i(TAG, "onGetUploadState: Update Failed");
    }
}

@Override
public void onGetClearInfoState(RadarSearchError radarSearchError) {
    if (radarSearchError == RadarSearchError.RADAR_NO_ERROR) {
        Log.i(TAG, "onGetClearInfoState: Clean Finished");
    } else {
         Log.i(TAG, "onGetClearInfoState: Clean Failed");
    }
}

其中onGetNearbyInfoList()方法最为重要。该方法用于接收服务器发回的位置信息列表。我们将会在该方法中,调用绘制周边marker的自定义方法showNearbyMarkerByAddOverLay()。关于周边marker的绘制,我们在本文第六部分记录。
onGetUploadState方法,在上传位置后被调用。
onGetClearInfoState方法,在清理个人信息后被调用。

(五)提交搜索请求

在添加好雷达监听器后,我们需要提交搜索请求,来触发监听。
提交信息包括:中心点位置信息,搜索距离(单位为米),以及结果的选取范围(按某一数量,对查询结果进行分表,返回某一表内的数据)。

LatLng pt=new LatLng(m_CurrentLocation.getLatitude(),m_CurrentLocation.getLongitude());
RadarNearbySearchOption option = new RadarNearbySearchOption().centerPt(pt).pageNum(0).pageCapacity(2).radius(2000);
m_RadarManager.nearbyInfoRequest(option);

在接收位置信息列表时,有时会发现RadarSearchError的值为RADAR_NO_RESULT
可能跟pageNum和pageCapacity的设置有关。SDK文档中,并未对两个方法进行详细的解释。通过N尝试,才发现其设计思路。

(1)服务器将中心点附近,指定距离内的所有信息,生成表A。
(2)将表A按照pageCapacity分成多张表B0,B1….,BN,本例为2,默认为10。
(3)将索引为pageNum的表B返回。

所以,假如共搜索到5条记录,将pageCapacity设置为4,而pageNum却设置为2,系统将无法返回数据列表(5条记录,仅能分成2张表,索引为2的表,实际为第3张表)。这将导致RadarSearchError的值为RADAR_NO_RESULT

有了搜索结果,接下来就是将对应的marker显示在地图上了。

(六)绘制周边marker

上一篇博文(Baidu Map 自动定位)中,记录了两种添加marker的方法。第一种是开启定位图层,第二种是添加新图层。
此处,将使用第二种方法。原因在于每张定位图层中,只有一个marker,无法将多个marker都加入同一图层(若同学有解决方案,或者找到新的API,还望赐教)。因此,采用多个图层累加显示的方式。

private void showNearbyMarkerByAddOverLay(RadarNearbyResult radarNearbyResult){
    m_Map.clear();
    if(radarNearbyResult.infoList.size()>0){
        for (RadarNearbyInfo Info :
                radarNearbyResult.infoList) {
            BitmapDescriptor bitmap = BitmapDescriptorFactory
                    .fromResource(R.mipmap.ic_marker_blue);
            //构建MarkerOption,用于在地图上添加Marker
            OverlayOptions option = new MarkerOptions()
                    .position(Info.pt)
                    .icon(bitmap);
            //在地图上添加Marker,并显示
            m_Map.addOverlay(option);
        }
    }
}

注:每次绘制前,需要对Map进行一次清空(m_Map.clear())。

(七)关闭雷达

在停止使用周边雷达功能时,需释放资源,到达离线效果。

//移除监听
mManager.removeNearbyInfoListener(this);
//清除用户信息
mManager.clearUserInfo();
//释放资源
mManager.destroy();
mManager = null;

*如果忘记清除用户信息,用户将永久显示。
可通过删除周边雷达注册记录的方式,进行清除。*

如果在关闭Activity时关闭雷达,建议在onStop()中进行用户信息进行清除。原因在于,该操作耗时,若放在onDestroy中,未必能够完成。

注:clearUserInfo方法将触发onGetClearInfoState()接口方法。

效果图如下:
Baidu Map 周边雷达_第2张图片

附录:单次上传当前定位信息

RadarUploadInfo info = new RadarUploadInfo();
info.comments = “用户备注信息”;
info.pt = new LatLng(m_CurrentLocation.getLatitude(),m_CurrentLocation.getLongitude());
mManager.uploadInfoRequest(info);

至此,周边雷达功能基本完结。之后将会尝试使用地图上的信息交互。

你可能感兴趣的:(android,map,定位)