- 百度API的简单应用——PoiSearch
创建POI检索实例
在SDK组件初始化之后使用下列代码即可:
1 mPoiSearch = PoiSearch.newInstance();
创建POI检索监听器
在同一个Activity中编写以下代码:
12345678910111213141516171819 OnGetPoiSearchResultListener listener = new OnGetPoiSearchResultListener() {@Overridepublic void onGetPoiResult(PoiResult poiResult) {}@Overridepublic void onGetPoiDetailResult(PoiDetailSearchResult poiDetailSearchResult) {}@Overridepublic void onGetPoiIndoorResult(PoiIndoorResult poiIndoorResult) {}//废弃@Overridepublic void onGetPoiDetailResult(PoiDetailResult poiDetailResult) {}};其中
onGetPoiResult
是主要的回调函数,所以涉及到搜索结果的操作基本都放在这个函数中进行,在我的源码中,我把MainActivity
当作一个OnGetPoiSearchResultListener
,这样有利于简化代码设置检索监听器
1 mPoiSearch.setOnGetPoiSearchResultListener(listener);
设置
PoiCitySearchOption
,发起检索请求
12345678910 /*** PoiCiySearchOption 设置检索属性* city 检索城市* keyword 检索内容关键字* pageNum 分页页码*/mPoiSearch.searchInCity(new PoiCitySearchOption().city("北京") //必填.keyword("美食") //必填.pageNum(10));在我的源码中,使用的是周边检索,应用的接口应该是:
123456789 /*** 以天安门为中心,搜索半径100米以内的餐厅*/mPoiSearch.searchNearby(new PoiNearbySearchOption().location(new LatLng(39.915446, 116.403869)).radius(100);//支持多个关键字并集检索,不同关键字间以$符号分隔,最多支持10个关键字检索。如:”银行$酒店”.keyword("餐厅").pageNum(10));
释放检索实例
重要的声明周期管理:
1 mPoiSearch.destroy();
- 百度地图的简单应用——距离计算
两点距离计算
根据用户指定的两个坐标点,计算这两个点之间的直线实际地理距离。
返回值类型:double
返回值单位:米
核心代码如下:
123 //计算p1、p2两点之间的直线距离,单位:米DistanceUtil.getDistance(p1, p2);其中p1和p2都是LatLng的对象
- 百度地图的简单应用——调起百度地图
由于不可能设计的APP面向的需求是寻找附近的一个可供娱乐的地方,所以导航的功能可以直接使用现成的百度地图来提供
我们使用的是步行导航:
1234567891011121314151617181920 //定义起终点坐标(天安门和百度大厦)LatLng startPoint = new LatLng(39.915291, 116.403857);LatLng endPoint = new LatLng(40.056858, 116.308194);//构建导航参数NaviParaOption para = new NaviParaOption().startPoint(startPoint).endPoint(endPoint).startName("天安门").endName("百度大厦");//调起百度地图try {BaiduMapNavigation.openBaiduMapWalkNavi(para, this);} catch (BaiduMapAppNotSupportNaviException e) {e.printStackTrace();//调起失败的处理}//调起结束时及时调用finish方法以释放相关资源BaiduMapNavigation.finish(this);以上的代码即可完全地调起百度地图并直接进行步行导航
- 综合教程——摇一摇地图
制作百度地图的API的综合运用——显示定位、POI检索、距离计算、调起百度地图
关键代码:
权限:
123456789101112131415161718 <!-- 以下权限开启地图服务 --><!-- 访问网络,进行地图相关业务数据请求,包括地图数据,路线规划,POI检索等 --><uses-permission android:name="android.permission.INTERNET" /> <!-- 获取网络状态,根据网络状态切换进行数据请求网络转换 --><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- 读取外置存储。如果开发者使用了so动态加载功能并且把so文件放在了外置存储区域,则需要申请该权限,否则不需要 --><uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <!-- 写外置存储。如果开发者使用了离线地图,并且数据写在外置存储区域,则需要申请该权限 --><uses-permission android:name="android.permission.VIBRATE" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /><!-- 以下权限用于开启定位服务 --><!-- 这个权限用于进行网络定位 --><uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /><!-- 这个权限用于访问GPS定位 --><uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />...<!-- 以下权限用于开启定位服务 --><service android:name="com.baidu.location.f"android:enabled="true"android:process=":remote"/>显示定位:
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849 // ----------------------------------- 初始化百度地图 --------------------------------- //mMapView = findViewById(R.id.bmapView);mTextView = findViewById(R.id.tv);mPoiSearch = PoiSearch.newInstance();mPoiSearch.setOnGetPoiSearchResultListener(this);// 更改地图类型mBaiduMap = mMapView.getMap();mBaiduMap.setMapType(BaiduMap.MAP_TYPE_SATELLITE);// 设置定位服务开始mBaiduMap.setMyLocationEnabled(true);//定位初始化mLocationClient = new LocationClient(getApplicationContext());//通过LocationClientOption设置LocationClient相关参数LocationClientOption option = new LocationClientOption();option.setLocationMode(LocationClientOption.LocationMode.Device_Sensors); // 定位模式是仅限设备模式,也就是仅允许GPS来定位。option.setOpenGps(true); // 打开gpsoption.setCoorType("bd09ll"); // 设置坐标类型option.setScanSpan(1000);//设置打开自动回调位置模式,该开关打开后,期间只要定位SDK检测到位置变化就会主动回调给开发者option.setIsNeedAddress(true);//可选,是否需要地址信息,默认为不需要,即参数为false//如果开发者需要获得当前点的地址信息,此处必须为trueoption.setNeedNewVersionRgc(true);//可选,设置是否需要最新版本的地址信息。默认需要,即参数为true//设置locationClientOptionmLocationClient.setLocOption(option);//注册LocationListener监听器MyLocationListener myLocationListener = new MyLocationListener();mLocationClient.registerLocationListener(myLocationListener);//开启地图定位图层mLocationClient.start();// 搜索时不重复,使用HashSet来支持mHashLocStr = new HashSet<>();// 一开始搜索的半径和接收的结果数mRadius = 1000;mPageCapacity = 10;// ----------------------------------------------------------------------------------- //POI检索:
12345678910111213141516171819 // 搜索附近的娱乐设施private void searchPoiNearBy() {String cityStr = mCity;// 获取检索关键字String keyWordStr = "娱乐";if (TextUtils.isEmpty(cityStr) || TextUtils.isEmpty(keyWordStr)) {return;}LatLng ll = new LatLng(mBDLocation.getLatitude(), mBDLocation.getLongitude());// 搜索附近的娱乐场所mPoiSearch.searchNearby((new PoiNearbySearchOption()).location(ll).keyword(keyWordStr).pageCapacity(mPageCapacity).pageNum(0).radius(mRadius));}调起百度地图:
123456789101112131415161718192021222324252627282930 @Overridepublic void onBindViewHolder(@NonNull AddressHolder holder, int position) {//定义起终点坐标LatLng startPoint = new LatLng(startLocation.getLatitude(), startLocation.getLongitude());LatLng endPoint = list.get(position).getLocation();int distance = (int)DistanceUtil.getDistance(startPoint, endPoint);String locStr = list.get(position).getName() + ", 距离自己:" + distance + " m";holder.textView.setText(locStr);holder.textView.setOnClickListener(v -> {Toast.makeText(mContext, "点我就跳转到别的APP咯", Toast.LENGTH_SHORT).show();//构建导航参数NaviParaOption para = new NaviParaOption().startPoint(startPoint).endPoint(endPoint).startName("我的位置").endName(list.get(position).getName());//调起百度地图try {BaiduMapNavigation.openBaiduMapWalkNavi(para, mContext);} catch (BaiduMapAppNotSupportNaviException e) {e.printStackTrace();//调起失败的处理}//调起结束时及时调用finish方法以释放相关资源BaiduMapNavigation.finish(mContext);});}
制作摇一摇
初始化
12345678910111213141516171819202122232425 // ---------------------------------初始化摇一摇--------------------------------------- //mHandler = new MyHandler(this);//初始化SoundPoolmSoundPool = new SoundPool(1, AudioManager.STREAM_SYSTEM, 5);mWeiChatAudio = mSoundPool.load(this, R.raw.weichat_audio, 1);//获取Vibrator震动服务mVibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);// 摇一摇的两个分离界面mTopLayout = findViewById(R.id.top_layout);mBottomLayout = findViewById(R.id.bottom_layout);//获取 SensorManager 负责管理传感器mSensorManager = ((SensorManager) getSystemService(SENSOR_SERVICE));if (mSensorManager != null) {//获取加速度传感器mAccelerometerSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);if (mAccelerometerSensor != null) {mSensorManager.registerListener(this, mAccelerometerSensor, SensorManager.SENSOR_DELAY_UI);}}// ----------------------------------------------------------------------------------- //监听Handler:
1234567891011121314151617181920212223242526272829303132333435363738394041 /*** handler 接收摇一摇产生的信息并作出对应的操作* START_SHAKE 开始摇晃* AGAIN_SHAKE 没结束摇晃之前再次摇晃* END_SHAKE 结束摇晃*/private static class MyHandler extends Handler {private WeakReference<MainActivity> mReference;private MainActivity mActivity;public MyHandler(MainActivity activity) {mReference = new WeakReference<MainActivity>(activity);if (mReference != null) {mActivity = mReference.get();}}@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);switch (msg.what) {case START_SHAKE://This method requires the caller to hold the permission VIBRATE.mActivity.mVibrator.vibrate(300);//发出提示音mActivity.mSoundPool.play(mActivity.mWeiChatAudio, 1, 1, 0, 0, 1);mActivity.startAnimation(false);//参数含义: (不是回来) 也就是说两张图片分散开的动画break;case AGAIN_SHAKE:mActivity.mVibrator.vibrate(300);break;case END_SHAKE://整体效果结束, 将震动设置为falsemActivity.isShake = false;// 展示上下两种图片回来的效果mActivity.startAnimation(true);break;}}}编写监听函数:
12345678910111213141516171819202122232425262728293031323334353637383940414243 ///////////////////////////////////////////////////////////////////////////// SensorEventListener回调方法///////////////////////////////////////////////////////////////////////////@Overridepublic void onSensorChanged(SensorEvent event) {int type = event.sensor.getType();if (type == Sensor.TYPE_ACCELEROMETER) {//获取三个方向值float[] values = event.values;float x = values[0];float y = values[1];float z = values[2];if ((Math.abs(x) > 17 || Math.abs(y) > 17 || Math.abs(z) > 17) && !isShake) {isShake = true;Thread thread = new Thread() {@Overridepublic void run() {super.run();try {Log.d(TAG, "onSensorChanged: 摇动");searchPoiNearBy();//开始震动 发出提示音 展示动画效果mHandler.obtainMessage(START_SHAKE).sendToTarget();Thread.sleep(500);//再来一次震动提示mHandler.obtainMessage(AGAIN_SHAKE).sendToTarget();Thread.sleep(500);mHandler.obtainMessage(END_SHAKE).sendToTarget();} catch (InterruptedException e) {e.printStackTrace();}}};thread.start();}}}编写动画:
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758 /*** 开启 摇一摇动画** @param isBack 是否是返回初识状态*/private void startAnimation(boolean isBack) {//动画坐标移动的位置的类型是相对自己的int type = Animation.RELATIVE_TO_PARENT;float topFromY;float topToY;float bottomFromY;float bottomToY;if (!isBack) {topFromY = -0.5f;topToY = 0;bottomFromY = 0.6f;bottomToY = 0;} else {topFromY = 0;topToY = -0.5f;bottomFromY = 0;bottomToY = 0.6f;}//上面图片的动画效果TranslateAnimation topAnim = new TranslateAnimation(type, 0, type, 0, type, topFromY, type, topToY);topAnim.setDuration(200);//动画终止时停留在最后一帧~不然会回到没有执行之前的状态topAnim.setFillAfter(true);//底部的动画效果TranslateAnimation bottomAnim = new TranslateAnimation(type, 0, type, 0, type, bottomFromY, type, bottomToY);bottomAnim.setDuration(200);bottomAnim.setFillAfter(true);//大家一定不要忘记, 当要回来时, 我们中间的两根线需要GONE掉if (isBack) {bottomAnim.setAnimationListener(new Animation.AnimationListener() {@Overridepublic void onAnimationStart(Animation animation) {}@Overridepublic void onAnimationRepeat(Animation animation) {}@Overridepublic void onAnimationEnd(Animation animation) {}});}//设置动画mTopLayout.startAnimation(topAnim);mBottomLayout.startAnimation(bottomAnim);}
使用摇一摇调用POI检索,使用
recyclerView
调起百度地图摇一摇中
onSensorChanged
函数中在开始摇晃时加入POI检索函数:searchPoiNearBy
;
recyclerView
的每个holder加入调起百度地图的监听器;