当前位置 博文首页 > 文章内容

    GPS技术与移动开发应用

    作者: 栏目:未分类 时间:2020-07-06 9:05:41

    本站于2023年9月4日。收到“大连君*****咨询有限公司”通知
    说我们IIS7站长博客,有一篇博文用了他们的图片。
    要求我们给他们一张图片6000元。要不然法院告我们

    为避免不必要的麻烦,IIS7站长博客,全站内容图片下架、并积极应诉
    博文内容全部不再显示,请需要相关资讯的站长朋友到必应搜索。谢谢!

    另祝:版权碰瓷诈骗团伙,早日弃暗投明。

    相关新闻:借版权之名、行诈骗之实,周某因犯诈骗罪被判处有期徒刑十一年六个月

    叹!百花齐放的时代,渐行渐远!



    GPS技术与移动开发应用

    源码地址:https://github.com/shaoyayu/baidumapDome/tree/master/%E4%BD%9C%E4%B8%9A%E6%BA%90%E7%A0%81

    作业:地图定位

    目的: 搭建Android & GPS 开发环境

    利用GPS在地图上进行本地地理位置的定位

    环境: Android手机带GPS功能,安装有JDK、eclipse集成的Android开发环境的电脑。

    1.内容和原理

    1)内容

    注册成为百度的开发者,下载地图SDK开发包,利用定位到使用Map、location、model

    2)原理

    GPS技术与百度地图开发包结合使用原理:

    使用百度Android定位SDK必须注册GPS和网络使用权限。定位SDK采用GPS、基站、Wi-Fi信号进行定位。当应用程序向定位SDK发起定位请求时,定位SDK会根据应用的定位因素(GPS、基站、Wi-Fi信号)的实际情况(如是否开启GPS、是否连接网络、是否有信号等)来生成相应定位依据进行定位。

    用户可以设置满足自身需求的定位依据:

    若用户设置GPS优先,则优先使用GPS进行定位,如果GPS定位未打开或者没有可用位置信息,且网络连接正常,定位SDK则会返回网络定位(即Wi-Fi与基站)的最优结果。为了使获得的网络定位结果更加精确,请打开手机的Wi-Fi开关。

    2.需求分析

    3.操作方法和步骤

    (1) 申请AK(API Key)

    1、登录注册百度地图开发者:http://lbsyun.baidu.com/apiconsole/key

    2、点击创建应用:

    img

    3、最好写你的当前开发的应用程序名称,记者应用类型一定选择Android SDK

    选择自己所需要的SDK服务模块,我建议全选。

    4、怎么获取SHA1呢。开发版的获取方法:

    进入控制台:进入目录 用户目录/.android

    keytool -list -v -keystore debug.keystore > sha1.txt

    我的建议是输出到文件里面,方便查看,这是开发版的,开发版和发布版的SHA1可以写一样的。

    【如果你有自己的签名,你也可以配置一个发布版的sha1,没有签名的后面可省略配置发布版的SHA1】

    进入你的签名文件目录:在控制台输入:

    keytool -list -v -keystore > sha1.txt

    5、填写你的应用程序的包名,一定跟你的AndroidManifest.xml中的包名是一致的,

    6、点击提交即可;

    (2) 下载SDK开发包

    下载地址:SDK下载

    img

    点击下载开发包即可:

    (3) 在android项目中引用百度SDK

    1、添加jar文件

    打开解压后的开发包文件夹,找到BaiduLBS_Android.jar文件将其拷贝至工程的app/libs目录下

    2、添加so文件

    有两种方法可以往项目中添加so文件。 方法一: 在下载的开发包中拷贝需要的CPU架构对应的so文件文件夹到app/libs目录下,

    在app目录下的build.gradle文件中android块中配置sourceSets标签,如果没有使用该标签则新增,详细配置代码如下:

    sourceSets { main { jniLibs.srcDir 'libs' } }

    注意:Jar文件和so文件的版本号必须一致,并且保证Jar文件与so文件是同一版本包取出的。

    方法二: 在src/main/目录下新建jniLibs目录(如果您的项目中已经包含该目录不用重复创建),在下载的开发包中拷贝项目中需要的CPU架构对应的so文件文件夹到jniLibs目录。

    3、往工程中添加jar文件

    在工程配置中需要将前面添加的jar文件集成到我们的工程中。

    方法一: 在libs目录下,选中每一个jar文件(此处只有一BaiduLbs_Android.jar)右键,选择Add As Library…,

    此时会发现在app目录的build.gradle的dependencies块中生成了工程所依赖的jar文件的对应说明

    注意:最新版本的Android Studio中compile被替换为implementation,具体的写法与您的Android Studio版本有关。

    (4)、你自己添加的功能

    下载百度开发的实例代码:百度地图案例下载

    1、 拷贝案例中的assets文件下面的文件到自己项目中的assets目录下面,

    2、 拷贝百度地图的导航路线覆盖物类到自己的程序中,在导航路线覆盖物使用的时候直接使用。重要的有:

    DrivingRouteOverlay.java

    OverlayManager.java

    PoiOverlay.java

    TransitRouterOverlay.java

    WalkingRouteOverlay.java

    4、记录与处理

    主程序代码如下:

    LocationServiceActivity
    package icu.shaoyayu.android.iearnit.activity.service;
    
    /**
     * @author shaoyayu
     * 导航和定位部分,设计位置签到等功能
     * Activity和Fragment之间的实时交互
     */
    public class LocationServiceActivity extends ModuleActivity {
    
        protected BroadcastReceiver receiver = null;
        //当前Activity涉及的权限
        private String[] purview = {Manifest.permission.ACCESS_NETWORK_STATE
                , Manifest.permission.READ_EXTERNAL_STORAGE
                , Manifest.permission.WRITE_EXTERNAL_STORAGE
                , Manifest.permission.ACCESS_COARSE_LOCATION
                , Manifest.permission.ACCESS_FINE_LOCATION
                , Manifest.permission.ACCESS_WIFI_STATE
                , Manifest.permission.CHANGE_WIFI_STATE
        };
    
        private BDLocation mLocation = null;
        private PoiInfo mPoiInfo = null;
        private double latitude = 0;
        private double longitude = 0;
        private LocationClient locationClient;
        private MapView mMapView;
        private BaiduMap mBaiduMap;
        private FloatingActionButton mMapRouteDialog,mMapSearchDialog,mMapShareDialog;
        private Switch mHeatMap;
        private BottomDialog dialog = null;
        private NavigationMap navigationMap =  new NavigationMap();
    
        private static final String TAG = "LocationServiceActivity";
    
        private SimpleMenu mSimpleMenu ;
    
        @Override
        protected void initWindows() {
            //初始化服务
            registerSDKCheckReceiver();
        }
    
        @Override
        protected int getInterfaceResourceId() {
            return R.layout.activity_location_service;
        }
    
        @Override
        public void onPointerCaptureChanged(boolean hasCapture) {
    
        }
    
        @Override
        protected void initTheControl() {
            super.initTheControl();
            locationClient = new LocationClient(getApplicationContext());
            //初始化位置权限
            mSimpleMenu = findViewById(R.id.menu_location_service);
            mMapView = findViewById(R.id.mp_location_service);
            mMapRouteDialog = findViewById(R.id.fab_map_route);
            mMapSearchDialog = findViewById(R.id.fab_map_search);
            mMapShareDialog = findViewById(R.id.fab_map_share);
            mHeatMap = findViewById(R.id.sc_open_heat_map);
            mBaiduMap = mMapView.getMap();
            Log.d(TAG,"初始化控件");
            //要放在后面执行
            PermissionsUtils.getInstance().checkPermissions(this,
                    purview,
                    new PermissionsUtils.IPermissionsResult() {
                        @Override
                        public void passPermissions() {
                            initData();
                        }
    
                        @Override
                        public void forbidPermissions() {
                            //弹出解释框,确定后前往设置见面
                        }
                    });
        }
    
    
        @Override
        protected void initData() {
            super.initData();
            Log.d(TAG,"初始化数据");
            mSimpleMenu.setTvMenuThemeText("位置服务");
            mMapView.showZoomControls(false);
            //获取地图的最大最小缩放
            Log.i(TAG,"最大缩放:"+mBaiduMap.getMaxZoomLevel()+",最小缩放:"+mBaiduMap.getMinZoomLevel());
            //设置地图的中心,通过工厂进行创建,注意经纬度是反的,
            MapStatusUpdate centerPoint = MapStatusUpdateFactory.newLatLng(new LatLng(26.62587,106.680831));
            mBaiduMap.setMapStatus(centerPoint);
            //设置一个默认的缩放
            MapStatusUpdate defaultZoom = MapStatusUpdateFactory.zoomTo(18);
            mBaiduMap.setMapStatus(defaultZoom);
    
            initLocationOption();
        }
    
        @Override
        protected void initControlBindingEvents() {
            super.initControlBindingEvents();
    
            mHeatMap.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                if (isChecked){
                    //开启热力图
    mBaiduMap.setBaiduHeatMapEnabled(true);
                }else {
                    //显示正常地图
    mBaiduMap.setBaiduHeatMapEnabled(false);
                }
                }
            });
    
            mMapSearchDialog.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(dialog!=null &&  dialog.getDialog()!=null
                            && dialog.getDialog().isShowing()) {
                        //dialog is showing so do something
                        dialog.onStart();
                        dialog = new MapSearchDialog(mLocation,new ImplementCallback());
                        dialog.show(getSupportFragmentManager(),"搜索");
                    } else {
                        //dialog is not showing
                        dialog = new MapSearchDialog(mLocation,new ImplementCallback());
                        dialog.show(getSupportFragmentManager(),"搜索");
                    }
    
                }
            });
    
            mMapRouteDialog.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(dialog!=null &&  dialog.getDialog()!=null
                            && dialog.getDialog().isShowing()) {
                        //dialog is showing so do something
                        dialog.onStart();
                        dialog = new MapRouteDialog(mPoiInfo,mLocation,navigationMap);
                        dialog.show(getSupportFragmentManager(),"路线");
                    } else {
                        //dialog is not showing
                        dialog = new MapRouteDialog(mPoiInfo,mLocation,navigationMap);
                        dialog.show(getSupportFragmentManager(),"路线");
                    }
    
                }
            });
    
    
            mMapShareDialog.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if(dialog!=null &&  dialog.getDialog()!=null
                            && dialog.getDialog().isShowing()) {
                        //dialog is showing so do something
                        dialog.onStart();
                        dialog = new MapShareDialog(mLocation);
                        dialog.show(getSupportFragmentManager(),"分享");
                    } else {
                        //dialog is not showing
                        dialog = new MapShareDialog(mLocation);
                        dialog.show(getSupportFragmentManager(),"分享");
                    }
    
                    //从新定位
                    initLocationOption();
                }
            });
        }
    
        @Override
        protected void onResume() {
            super.onResume();
            //在activity执行onResume时执行mMapView. onResume (),实现地图生命周期管理
            mMapView.onResume();
        }
        @Override
        protected void onPause() {
            super.onPause();
            //在activity执行onPause时执行mMapView. onPause (),实现地图生命周期管理
            mMapView.onPause();
        }
        @Override
        protected void onDestroy() {
            super.onDestroy();
            //在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理
            mMapView.onDestroy();
            unregisterReceiver(receiver);
        }
    
        /**
         * 初始化地图服务
         */
        protected void registerSDKCheckReceiver(){
            receiver = new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    String action = intent.getAction();
                    if (SDKInitializer.SDK_BROADCAST_ACTION_STRING_NETWORK_ERROR.equals(action)){
                        Toast.makeText(context, "网络错误", Toast.LENGTH_SHORT).show();
                        Log.w(TAG,"网络无法连接");
                    }else if (SDKInitializer.SDK_BROADTCAST_ACTION_STRING_PERMISSION_CHECK_ERROR.equals(action)){
                        Toast.makeText(context, "Key验证失败", Toast.LENGTH_SHORT).show();
                        Log.w(TAG,"key验证失败");
                    }
                }
            };
    
            IntentFilter filter = new IntentFilter();
            //监听网络错误
            filter.addAction(SDKInitializer.SDK_BROADCAST_ACTION_STRING_NETWORK_ERROR);
            //监听百度地图的sdk的可以时不时正确
            filter.addAction(SDKInitializer.SDK_BROADTCAST_ACTION_STRING_PERMISSION_CHECK_ERROR);
    
            registerReceiver(receiver,filter);
    
        }
    
        /**
         * 权限申请
         * @param requestCode
         * @param permissions
         * @param grantResults
         */
        @Override
        public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
            PermissionsUtils.getInstance().onRequestPermissionsResult(this,requestCode,permissions,grantResults);
        }
    
        /**
         * 初始化定位参数配置
         */
        private void initLocationOption() {
            LocationClientOption locationOption = new LocationClientOption();
            MyLocationListener myLocationListener = new MyLocationListener();
            locationClient.registerLocationListener(myLocationListener);
            locationOption.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
            locationOption.setCoorType("bd09ll");
            locationOption.setScanSpan(0);
            locationOption.setIsNeedAddress(true);
            locationOption.setIsNeedLocationDescribe(true);
            locationOption.setNeedDeviceDirect(false);
            locationOption.setLocationNotify(true);
            locationOption.setIgnoreKillProcess(true);
            locationOption.setIsNeedLocationDescribe(true);
            locationOption.setIsNeedLocationPoiList(true);
            locationOption.SetIgnoreCacheException(false);
            locationOption.setOpenGps(true);
            locationOption.setIsNeedAltitude(false);
            locationOption.setOpenAutoNotifyMode();
            locationOption.setOpenAutoNotifyMode(3000,1, LocationClientOption.LOC_SENSITIVITY_HIGHT);
            locationClient.setLocOption(locationOption);
            locationClient.start();
        }
    
        /**
         * 实现定位回调
         */
        public class MyLocationListener extends BDAbstractLocationListener {
            @Override
            public void onReceiveLocation(BDLocation location){
                //测试使用 112.193069,30.355534
    /*            location.setLongitude(112.193069);
                location.setLatitude(30.355534);*/
                if (mLocation==null){
                    mLocation = location;
                }
                if (latitude==0){
                    latitude = location.getLatitude();
                }
                if (longitude==0){
                    longitude = location.getLongitude();
                }
                Log.d(TAG,"latitude:"+latitude+",longitude:"+longitude);
                //初始化位置信息
                MapStatusUpdate centerPoint = MapStatusUpdateFactory.newLatLng(new LatLng(latitude,longitude));
                mBaiduMap.setMapStatus(centerPoint);
                //标记
                //构建Marker图标
                MarkerOptions markerOptions = new MarkerOptions();
                BitmapDescriptor bitmapDescriptor4 = BitmapDescriptorFactory.fromResource(R.mipmap.maps_easyicon);
                markerOptions.position(new LatLng(latitude,longitude))
                        //添加图标
                        .icon(bitmapDescriptor4);
                mBaiduMap.addOverlay(markerOptions);
                //---------------------详细信息获取方法---------------------///
                locationClient.stop();
            }
        }
    
    
        //清除标记物
        public void clearMarker(){
            LatLng latLng1 = new LatLng(0,0);
            LatLng latLng2 = new LatLng(9999,9999);
            List<LatLng> latLngs = new ArrayList<>();
            //指定搜索范围
            LatLngBounds bounds = new LatLngBounds.Builder()
                    //设置内容
                    .include(latLng1)
                    .include(latLng2)
                    .build();
            List<Marker> markersInBounds = mBaiduMap.getMarkersInBounds(bounds);
            for (Marker markersInBound : markersInBounds) {
                markersInBound.remove();
            }
        }
    
        /**
         * poi搜索过后描述位置信息的回调
         */
        public class ImplementCallback implements MapSearchDialog.POICallback {
    
            /**
             * 回调显示所有poi检索结果
             * 绑定点击事件
             * @param poiInfos
             */
            @Override
            public void showSearchResults(List<PoiInfo> poiInfos) {
    
            }
    
            /**
             * 搜索到的内容回调到
             * @param view
             * @param poiInfo
             */
            @Override
            public void callbackForDetails(View view, PoiInfo poiInfo) {
                mPoiInfo = poiInfo;
                Log.d(TAG,"POI详情回调"+poiInfo.name);
                clearMarker();
                //构建Marker图标
                //初始化位置信息
                MapStatusUpdate centerPoint = MapStatusUpdateFactory.newLatLng(poiInfo.location);
                mBaiduMap.setMapStatus(centerPoint);
                MarkerOptions markerOptions = new MarkerOptions();
                BitmapDescriptor bitmapDescriptor4 = BitmapDescriptorFactory.fromResource(R.mipmap.maps_easyicon);
                markerOptions.position(poiInfo.location)
                        //添加图标
                        .icon(bitmapDescriptor4);
                mBaiduMap.addOverlay(markerOptions);
            }
    
            @Override
            public void navigationPositionCallback(View view, PoiInfo poiInfo) {
                mPoiInfo = poiInfo;
                Log.d(TAG,"POI导航回调"+poiInfo.name);
                if(dialog!=null &&  dialog.getDialog()!=null
                        && dialog.getDialog().isShowing()) {
                    //dialog is showing so do something
                    dialog.onStart();
                    dialog = new MapRouteDialog(mPoiInfo,mLocation,navigationMap);
                    dialog.show(getSupportFragmentManager(),"路线");
                } else {
                    //dialog is not showing
                    dialog = new MapRouteDialog(mPoiInfo,mLocation,navigationMap);
                    dialog.show(getSupportFragmentManager(),"路线");
                }
            }
        }
    
        /**
         * 绘制导航路线
         */
        public class NavigationMap implements MapRouteDialog.RouteSelectionCallback {
            /**
             * 不行路线导航回调
             * @param walkingRouteLine
             */
            @Override
            public void walkingRoute(WalkingRouteLine walkingRouteLine) {
                clearMarker();
                WalkingRouteOverlay overlay = new WalkingRouteOverlay(mBaiduMap);
                mBaiduMap.setOnMarkerClickListener(overlay);
                overlay.setData(walkingRouteLine);
                //把搜索结果添加到百度地图里面
                overlay.addToMap();
                //把搜索结果显示在同一个屏幕
                overlay.zoomToSpan();
            }
    
            /**
             * 公交路线导航回调
             * @param transitRouteLine
             */
            @Override
            public void busRoutes(TransitRouteLine transitRouteLine) {
                clearMarker();
                TransitRouteOverlay overlay = new TransitRouteOverlay(mBaiduMap);
                mBaiduMap.setOnMarkerClickListener(overlay);
                //取出查询出来的所有路线,选择第一条
                overlay.setData(transitRouteLine);
                //把搜索结果添加到百度地图里面
                overlay.addToMap();
                //把搜索结果显示在同一个屏幕
                overlay.zoomToSpan();
            }
    
            /**
             * 行车路线导航
             * @param drivingRouteLine
             */
            @Override
            public void drivingDirections(DrivingRouteLine drivingRouteLine) {
                clearMarker();
                DrivingRouteOverlay overlay = new DrivingRouteOverlay(mBaiduMap);
                mBaiduMap.setOnMarkerClickListener(overlay);
                overlay.setData(drivingRouteLine);
                //把搜索结果添加到百度地图里面
                overlay.addToMap();
                //把搜索结果显示在同一个屏幕
                overlay.zoomToSpan();
            }
        }
    
        //创建一个热力图服务回调的函数
    }
    
    
    MapSearchDialog
    package icu.shaoyayu.android.iearnit.dialog.map;
    
    
    /**
     * @author shaoyayu
     * avatar dialog box pops up dialog
     */
    public class MapSearchDialog extends BottomDialog {
    
        private static final String  TAG = "MapSearchDialog";
        PoiSearch mPoiSearch = PoiSearch.newInstance();
        //当前的我一个位置
        private RecyclerView mShowSearchResults;
        private BDLocation location;
        private EditText mEnterLocation;
        private ImageView mCloseSession;
        private Button mFindALocation;
        //
        private POICallback poiCallback;
    
        public MapSearchDialog(BDLocation location,POICallback poiCallback){
            this.location = location;
            this.poiCallback = poiCallback;
        }
    
        @Override
        protected View createView(LayoutInflater inflater, ViewGroup container) {
            View view = inflater.inflate(R.layout.dialog_map_search,container,false);
            mEnterLocation = view.findViewById(R.id.et_map_location_search);
            mCloseSession = view.findViewById(R.id.iv_map_search_dog_close);
            mFindALocation = view.findViewById(R.id.bt_find_location);
            mShowSearchResults = view.findViewById(R.id.rv_map_search_results);
    
            mCloseSession.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    onStop();
                }
            });
            mFindALocation.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //移除输入的焦点
                    mEnterLocation.clearFocus();//取消焦点
                    InputMethodManager imm = (InputMethodManager)getActivity().getSystemService(INPUT_METHOD_SERVICE);
                    imm.hideSoftInputFromWindow(mEnterLocation.getWindowToken(), 0);
                    String findContent = mEnterLocation.getText().toString().trim();
                    Log.d(TAG,"搜索内容:"+findContent);
                    mPoiSearch.setOnGetPoiSearchResultListener(SearchMonitor);
    //                Log.d(TAG,"当前城市:"+location.getCity());
                    PoiCitySearchOption citySearchOption = new PoiCitySearchOption();
    //                citySearchOption.city(location.getCity());
                    //测试使用
                    citySearchOption.city("荆州");
                    citySearchOption.keyword(findContent);
                    citySearchOption.pageCapacity(100);
                    citySearchOption.pageNum(0);
                    mPoiSearch.searchInCity(citySearchOption);
                }
            });
            return view;
        }
    
        @Override
        public void onStop() {
            //回收资源,适配器等
            super.onStop();
            //关闭的时候释放资源
            mPoiSearch.destroy();
        }
    
        public interface SearchResultCallback{
            void showChooseALocation();
            void showReachLocation();
        }
    
        /**
         * 搜索回调的监听函数
         */
        OnGetPoiSearchResultListener SearchMonitor = new OnGetPoiSearchResultListener() {
            @Override
            public void onGetPoiResult(PoiResult poiResult) {
                if (poiResult == null
                        || poiResult.error == SearchResult.ERRORNO.RESULT_NOT_FOUND) {// 没有找到检索结果
                    Log.d(TAG,"为能找到搜索结果");
                    Toast.makeText(getContext(), "没有搜索结果", Toast.LENGTH_SHORT).show();
                    return;
                }
                if (poiResult.error == SearchResult.ERRORNO.NO_ERROR) {// 检索结果正常返回
                    List<PoiInfo> allPoi = poiResult.getAllPoi();
                    for (PoiInfo poiInfo : allPoi) {
                        Log.d(TAG,poiInfo.name);
                    }
                    //Sequence
                    mShowSearchResults.setAdapter(new ShowSearchDataAdapter(allPoi,poiCallback));
                    FullyLinearLayoutManager mLinearLayoutManager = new FullyLinearLayoutManager(getContext());
                    mShowSearchResults.setLayoutManager(mLinearLayoutManager);
                }
                //调用初始化参数显示
            }
            @Override
            public void onGetPoiDetailResult(PoiDetailSearchResult poiDetailSearchResult) {
    
            }
            @Override
            public void onGetPoiIndoorResult(PoiIndoorResult poiIndoorResult) {
    
            }
            //废弃
            @Override
            public void onGetPoiDetailResult(PoiDetailResult poiDetailResult) {
    
            }
        };
    
    
        //适配器
    
        class ShowSearchDataAdapter extends RecyclerView.Adapter<MyPolicyInfo>{
    
            List<PoiInfo> policyInfos;
            POICallback mPoiCallback;
            public ShowSearchDataAdapter(List<PoiInfo> policyInfos,POICallback poiCallback){
                this.policyInfos = policyInfos;
                this.mPoiCallback = poiCallback;
            }
    
            @Override
            public int getItemViewType(int position) {
                return position;
            }
    
            @NonNull
            @Override
            public MyPolicyInfo onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
                LayoutInflater inflater = LayoutInflater.from(getContext());
                View view = inflater.inflate(R.layout.view_search_results_item,parent,false);
                return new MyPolicyInfo(view);
            }
    
            @Override
            public void onBindViewHolder(@NonNull MyPolicyInfo holder, final int position) {
                holder.poiName.setText( policyInfos.get(position).name);
                LatLng current = new LatLng(location.getLatitude(),location.getLongitude());
                final LatLng poiPlace = policyInfos.get(position).getLocation();
                holder.poiDistance.setText(DistanceUtil.getDistance(current,poiPlace)+"米");
                holder.poiDetail.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        //设置一个新的位置,然后关闭当前的弹窗
                        onStop();
                        mPoiCallback.callbackForDetails(v,policyInfos.get(position));
                    }
                });
                holder.poiNavigate.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        //导航
                        onStop();
                        mPoiCallback.navigationPositionCallback(v,policyInfos.get(position));
                    }
                });
            }
            @Override
            public int getItemCount() {
                return policyInfos.size();
            }
        }
        class MyPolicyInfo extends RecyclerView.ViewHolder {
            //四个控件
            TextView poiName;
            TextView poiDistance;
            Button poiDetail;
            Button poiNavigate;
            public MyPolicyInfo(@NonNull View itemView) {
                super(itemView);
                //实例化参数
                poiName = itemView.findViewById(R.id.tv_poi_name);
                poiDistance = itemView.findViewById(R.id.tv_poi_distance);
                poiDetail = itemView.findViewById(R.id.bt_poi_detail);
                poiNavigate = itemView.findViewById(R.id.bt_poi_navigate);
                //注册一个点击事件
            }
        }
    
    
        public interface POICallback {
    
            /**
             * 显示搜索结果
             * @param poiInfos
             */
            void showSearchResults(List<PoiInfo> poiInfos);
    
            /**
             * 详情位置回调
             * @param view
             * @param poiInfo
             */
            void callbackForDetails(View view, PoiInfo poiInfo);
    
    
            /**
             * 导航位置回调
             * @param view
             * @param poiInfo
             */
            void navigationPositionCallback(View view, PoiInfo poiInfo);
    
        }
    
    }
    
    
    MapRouteDialog
    package icu.shaoyayu.android.iearnit.dialog.map;
    
    /**
     * @author shaoyayu
     * 路线规划类
     * 驾车
     */
    public class MapRouteDialog extends BottomDialog {
    
        private static final String TAG = "MapRouteDialog";
        private ImageView mCloseNavigation;
        private PoiInfo poiInfo;
        private BDLocation location;
        private RoutePlanSearch routePlanSearch;
        private RecyclerView mRecyclerView;
        private RouteSelectionCallback routeSelectionCallback;
        //保存三个搜索结果
        private List<WalkingRouteLine> walkingRouteLines = null; //步行 walk
        private List<TransitRouteLine> transitRouteLines = null; //公交 bus
        private List<DrivingRouteLine> drivingRouteLines = null; //自驾 self_driving
        //三个都是继承 navigation_route
    
        public MapRouteDialog(PoiInfo poiInfo,BDLocation location,RouteSelectionCallback routeSelectionCallback){
            this.poiInfo = poiInfo;
            this.location = location;
            this.routeSelectionCallback = routeSelectionCallback;
        }
    
        @Override
        protected View createView(LayoutInflater inflater, ViewGroup container) {
            if (poiInfo!=null&&location!=null){
                //自驾导航
                routePlanSearch = RoutePlanSearch.newInstance();
                routePlanSearch.setOnGetRoutePlanResultListener(new PathOnGetRoutePlanResultListener());
                routePlanSearch.drivingSearch(getDrivingRoutePlanOption());
                routePlanSearch.transitSearch(getTransitRoutePlanOption());
                routePlanSearch.walkingSearch(getWalkingRoutePlanOption());
            }
            View view = inflater.inflate(R.layout.dialog_map_route,container,false);
            mCloseNavigation = view.findViewById(R.id.iv_map_navigation_dog_close);
            mRecyclerView = view.findViewById(R.id.rv_navigation_type);
            mCloseNavigation.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    onStop();
                }
            });
            //给ViewPage注册适配器
            return view;
        }
    
        @Override
        public void onStop() {
            super.onStop();
        }
    
        private void initRecyclerViewAdapter(){
            if (walkingRouteLines!=null && transitRouteLines!=null && drivingRouteLines!=null){
                mRecyclerView.setAdapter(new NavigationAdapter());
                FullyLinearLayoutManager mLinearLayoutManager = new FullyLinearLayoutManager(getContext());
                mRecyclerView.setLayoutManager(mLinearLayoutManager);
                //更新适配器
    //            mRecyclerView.swapAdapter();
            }
        }
    
        /**
         * 驾车导航
         * @return
         */
        private DrivingRoutePlanOption getDrivingRoutePlanOption() {
            DrivingRoutePlanOption drivingRoutePlanOption = new DrivingRoutePlanOption();
            drivingRoutePlanOption.from(PlanNode.withLocation(new LatLng(location.getLatitude(),location.getLongitude())));
            drivingRoutePlanOption.to(PlanNode.withLocation(poiInfo.location));
            return drivingRoutePlanOption;
        }
    
        /**
         * 公交导航
         * @return
         */
        private TransitRoutePlanOption getTransitRoutePlanOption() {
            TransitRoutePlanOption transitRoutePlanOption = new TransitRoutePlanOption();
    //        transitRoutePlanOption.city(location.getCity());
            transitRoutePlanOption.city("荆州");
            transitRoutePlanOption.from(PlanNode.withLocation(new LatLng(location.getLatitude(),location.getLongitude())));
            transitRoutePlanOption.to(PlanNode.withLocation(poiInfo.location));
            //路线选型
            /*
            EBUS_NO_SUBWAY
                公交检索策略常量:不含地铁
                EBUS_TIME_FIRST
                公交检索策略常量:时间优先
                EBUS_TRANSFER_FIRST
                公交检索策略常量:最少换乘
                EBUS_WALK_FIRST
                公交检索策略常量:最少步行距离
             */
            transitRoutePlanOption.policy(TransitRoutePlanOption.TransitPolicy.EBUS_WALK_FIRST);
            return transitRoutePlanOption;
        }
    
        /**
         * 步行导航
         * @return
         */
        private WalkingRoutePlanOption getWalkingRoutePlanOption() {
            WalkingRoutePlanOption walkingRoutePlanOption = new WalkingRoutePlanOption();
            walkingRoutePlanOption.from(PlanNode.withLocation(new LatLng(location.getLatitude(),location.getLongitude())));
            walkingRoutePlanOption.to(PlanNode.withLocation(poiInfo.location));
            return walkingRoutePlanOption;
        }
    
        //规划路线回调
        class PathOnGetRoutePlanResultListener implements OnGetRoutePlanResultListener{
    
            /**
             * 不行路线回调
             * @param walkingRouteResult
             */
            @Override
            public void onGetWalkingRouteResult(WalkingRouteResult walkingRouteResult) {
    //            mParcelableRouteLines.add(walkingRouteResult.getRouteLines());
                walkingRouteLines = walkingRouteResult.getRouteLines();
                for (int i = 0; i < walkingRouteLines.size(); i++) {
                    Log.d(TAG,i+"步行路线耗时:"+walkingRouteLines.get(i).getDuration()/60+"分钟");
                    List<WalkingRouteLine.WalkingStep> allStep = walkingRouteLines.get(i).getAllStep();
                    for (int j = 0; j < allStep.size(); j++) {
                        Log.d(TAG,i+","+j+",步行路线:"+allStep.get(j).getInstructions());
                    }
                }
                initRecyclerViewAdapter();
            }
    
            @Override
            public void onGetTransitRouteResult(TransitRouteResult transitRouteResult) {
                transitRouteLines = transitRouteResult.getRouteLines();
                for (int i = 0; i < transitRouteLines.size(); i++) {
                    Log.d(TAG,i+"公交路线:"+transitRouteLines.get(i).getDuration()/60+"分钟");
                    List<TransitRouteLine.TransitStep> allStep = transitRouteLines.get(i).getAllStep();
                    for (int j = 0; j < allStep.size(); j++) {
                        Log.d(TAG,i+","+j+",公交路线:"+allStep.get(j).getInstructions());
                    }
                }
                initRecyclerViewAdapter();
            }
    
            @Override
            public void onGetMassTransitRouteResult(MassTransitRouteResult massTransitRouteResult) {
    
            }
    
            @Override
            public void onGetDrivingRouteResult(DrivingRouteResult drivingRouteResult) {
                //所有选择方案
                drivingRouteLines = drivingRouteResult.getRouteLines();
                for (int i = 0; i < drivingRouteLines.size(); i++) {
                    Log.d(TAG,i+"自驾:"+drivingRouteLines.get(i).getDuration()/60+"分钟");
                    DrivingRouteLine drivingRouteLine = drivingRouteLines.get(i);
                    List<DrivingRouteLine.DrivingStep> allStep = drivingRouteLine.getAllStep();
                    for (int j = 0; j < allStep.size(); j++) {
                        Log.d(TAG,i+","+j+",自驾:"+allStep.get(j).getInstructions());
                    }
                }
                initRecyclerViewAdapter();
            }
    
            @Override
            public void onGetIndoorRouteResult(IndoorRouteResult indoorRouteResult) {
    
            }
    
            @Override
            public void onGetBikingRouteResult(BikingRouteResult bikingRouteResult) {
    
            }
        }
    
    
        /**
         * 适配器,需要在填充的时候填写数据
         */
        class NavigationAdapter extends RecyclerView.Adapter<MyRouteDetails>{
    
            @Override
            public int getItemViewType(int position) {
                return position;
            }
    
            @NonNull
            @Override
            public MyRouteDetails onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
                LayoutInflater inflater = LayoutInflater.from(getContext());
                View view = inflater.inflate(R.layout.view_navigation_route,parent,false);
                return new MyRouteDetails(view);
            }
    
            @Override
            public void onBindViewHolder(@NonNull MyRouteDetails holder, int position) {
                if (position<walkingRouteLines.size()){
                    holder.routeType.setText("步行路线:"+(position+1));
                    holder.timeConsumingRoute.setText("耗时:"+walkingRouteLines.get(position).getDuration()/60+" Minute");
                    holder.startNavigation.setImageResource(R.drawable.ic_walk_foreground);
                    String content = "";
                    List<WalkingRouteLine.WalkingStep> allStep = walkingRouteLines.get(position).getAllStep();
                    for (int j = 0; j < allStep.size(); j++) {
                        content = content + allStep.get(j).getInstructions()+"\n";
                    }
                    holder.routeDetails.setText(content);
                    //设置一个点击事件,回调
                    final int finalPosition = position;
                    holder.startNavigation.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            onStop();
                            routeSelectionCallback.walkingRoute(walkingRouteLines.get(finalPosition));
                        }
                    });
                }else if (walkingRouteLines.size()<=position && position<(walkingRouteLines.size()+transitRouteLines.size())){
                    position = position - walkingRouteLines.size();
                    holder.routeType.setText("公交路线:"+(position+1));
                    holder.timeConsumingRoute.setText("耗时:"+transitRouteLines.get(position).getDuration()/60+" Minute");
                    holder.startNavigation.setImageResource(R.drawable.ic_bus_foreground);
                    String content = "";
                    List<TransitRouteLine.TransitStep> allStep = transitRouteLines.get(position).getAllStep();
                    for (int j = 0; j < allStep.size(); j++) {
                        content = content + allStep.get(j).getInstructions()+"\n";
                    }
                    holder.routeDetails.setText(content);
                    final int finalPosition = position;
                    holder.startNavigation.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            onStop();
                            routeSelectionCallback.busRoutes(transitRouteLines.get(finalPosition));
                        }
                    });
                }else{
                    position = position - (walkingRouteLines.size()+transitRouteLines.size());
                    holder.routeType.setText("驾车路线:"+(position+1));
                    holder.timeConsumingRoute.setText("耗时:"+drivingRouteLines.get(position).getDuration()/60+" Minute");
                    holder.startNavigation.setImageResource(R.drawable.ic_self_driving_foreground);
                    String content = "";
                    DrivingRouteLine drivingRouteLine = drivingRouteLines.get(position);
                    List<DrivingRouteLine.DrivingStep> allStep = drivingRouteLine.getAllStep();
                    for (int j = 0; j < allStep.size(); j++) {
                        content = content + allStep.get(j).getInstructions()+"\n";
                    }
                    holder.routeDetails.setText(content);
                    final int finalPosition = position;
                    holder.startNavigation.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            onStop();
                            routeSelectionCallback.drivingDirections(drivingRouteLines.get(finalPosition));
                        }
                    });
                }
            }
    
            @Override
            public int getItemCount() {
                int size = 0;
                if (walkingRouteLines!=null && walkingRouteLines.size()!=0){
                    size = size +walkingRouteLines.size();
                }
                if (transitRouteLines!=null && transitRouteLines.size()!=0){
                    size = size + transitRouteLines.size();
                }
                if (drivingRouteLines!=null && drivingRouteLines.size()!=0){
                    size = size +drivingRouteLines.size();
                }
                return size;
            }
        }
    
        class MyRouteDetails extends RecyclerView.ViewHolder {
            //四个控件
            TextView routeType,timeConsumingRoute,routeDetails;
            ImageView startNavigation;
            public MyRouteDetails(@NonNull View itemView) {
                super(itemView);
                routeType = itemView.findViewById(R.id.tv_route_type);
                timeConsumingRoute = itemView.findViewById(R.id.tv_time_consuming_route);
                routeDetails = itemView.findViewById(R.id.tv_details);
                startNavigation = itemView.findViewById(R.id.iv_start_navigation);
            }
        }
    
        public interface RouteSelectionCallback{
            //步行路线规划
            void walkingRoute(WalkingRouteLine walkingRouteLine);
            //换车路线规划
            void busRoutes(TransitRouteLine transitRouteLine );
            //驾车路线规划
            void drivingDirections(DrivingRouteLine drivingRouteLine);
        }
    
    }
    
    
    MapShareDialog
    package icu.shaoyayu.android.iearnit.dialog.map; 
    
    /**
     * @author shaoyayu
     * 位置共享解决方案
     */
    public class MapShareDialog extends BottomDialog {
    
        private ImageView mStopDialog;
        private Switch locationSharing,trackSharing,recordTrack;
        private Intent positioningService;
        private TextView mLocationInfo;
        private BDLocation mLocation;
    
        public MapShareDialog(BDLocation location){
            this.mLocation = location;
        }
    
        @Override
        protected View createView(LayoutInflater inflater, ViewGroup container) {
            View view = inflater.inflate(R.layout.dialog_map_share,container,false);
            initTheControl(view);
            initData();
            return view;
        }
    
    
        //初始化控件
        private void initTheControl(View view){
            positioningService = new Intent(getContext(), LocationSharingService.class);
            mStopDialog = view.findViewById(R.id.iv_map_share_dog_close);
            //监控关闭弹窗
            mStopDialog.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    onStop();
                }
            });
            //位置共享控件
            locationSharing = view.findViewById(R.id.sc_location_sharing);
            //判断当前的服务是不是正在执行
            if (isServiceRunning("icu.shaoyayu.android.iearnit.service.LocationSharingService")){
                //设置为执行状态
                locationSharing.setChecked(true);
            }
            //开关事假
            locationSharing.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    if (isChecked){
                        //开启
                        showTips("已经为你开启位置共享");
                        getActivity().startService(positioningService);
                    }else {
                        //关闭
                        showTips("已经为你关闭位置共享");
                        getActivity().stopService(positioningService);
                    }
                }
            });
            //轨迹共享
            trackSharing = view.findViewById(R.id.sc_track_sharing);
            trackSharing.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    if (isChecked){
                        //开启
                        showTips("已经为你开启轨迹共享");
                    }else {
                        //关闭
                        showTips("已经为你关闭轨迹共享");
                    }
                }
            });
            //轨迹录制
            recordTrack = view.findViewById(R.id.sc_track_record);
            recordTrack.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                @Override
                public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                    if (isChecked){
                        //开启
                        showTips("已经为你开启轨迹录制");
                    }else {
                        //关闭
                        showTips("已经为你关闭轨迹录制");
                    }
                }
            });
            mLocationInfo = view.findViewById(R.id.tv_location_info);
    
        }
    
        //初始化数据
        private void initData(){
            if (mLocation==null){
                mLocationInfo.setText("Positioning failed");
            }else {
                String province = mLocation.getProvince();    //获取省份
                String city = mLocation.getCity();           //获取城市
                String district = mLocation.getDistrict();    //获取区县
                String street = mLocation.getStreet();       //获取街道信息
                String town = mLocation.getTown();           //获取乡镇信息
                String desc = mLocation.getLocationDescribe(); //详细信息
                String locationInfo = province + city + district + street + town +"\n"+ desc;
                mLocationInfo.setText(locationInfo);
            }
        }
    
        //显示一个对话框提示共享开始,
        private void showTips(String str){
            Toast.makeText(getContext(), str, Toast.LENGTH_SHORT).show();
        }
    
        @Override
        public void onStop() {
            super.onStop();
        }
    
        /**
         * 根据服务的名称判断当前的服务是不是正在执行
         * @param serviceName
         * @return
         */
        private boolean isServiceRunning(String serviceName) {
            ActivityManager manager = (ActivityManager) getActivity().getSystemService(ACTIVITY_SERVICE);
            for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
                if (serviceName.equals(service.service.getClassName())) {
                    return true;
                }
            }
            return false;
        }
    }
    
    
    LocationSharingService
    package icu.shaoyayu.android.iearnit.service; 
    
    /**
     * @author shaoyayu
     * 实现位置实时共享的一个服务
     */
    public class LocationSharingService extends Service implements PositioningService.ContinuousPositioningCallback {
    
        private LocationSharingNetService netService = new LocationSharingNetService();
    
        private static final String TAG = "LocationSharingService";
    
        private PositioningService positioningService;
        public LocationSharingService() {
    
        }
    
        @Override
        public void onCreate() {
            super.onCreate();
            positioningService = new PositioningService(getApplicationContext(),this,1500);
        }
    
        @Override
        public IBinder onBind(Intent intent) {
            // TODO: Return the communication channel to the service.
            throw new UnsupportedOperationException("Not yet implemented");
        }
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId) {
            positioningService.startPositioning();
            return super.onStartCommand(intent, flags, startId);
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
            positioningService.stopPositioning();
        }
    
        //定位后的回调方法
        @Override
        public void getLocation(BDLocation bdLocation, long timestamp) {
            Log.d(TAG,"后台定位:"+timestamp+","+bdLocation.getLatitude()+","+bdLocation.getLongitude());
            //没一秒上传一次记录到云端,如果上传失败,整合下次一起上传到云端,删除数据。
            String country = bdLocation.getCountry();    //获取国家
            String province = bdLocation.getProvince();    //获取省份
            String city = bdLocation.getCity();           //获取城市
            String district = bdLocation.getDistrict();    //获取区县
            String street = bdLocation.getStreet();       //获取街道信息
            String adcode = bdLocation.getAdCode();        //获取adcode
            String town = bdLocation.getTown();           //获取乡镇信息
            String desc = bdLocation.getLocationDescribe(); //详细信息
            String locationInfo = timestamp+","+bdLocation.getLatitude()+","+bdLocation.getLongitude()+","+System.currentTimeMillis()+","+country+","+province+","+city+","+district+","+street+","+adcode+","+town+","+desc;
            netService.locationSharing("soxswmddl4546dsf45dsf,"+locationInfo);
            //直接上传到Redis数据库,LocationSharingService
            //写入文件系统里面去存储
        }
    }
    
    
    PositioningService
    package icu.shaoyayu.android.iearnit.service;
    /**
     * @author shaoyayu
     */
    public class PositioningService {
    
        private Context context;
        private ContinuousPositioningCallback callback;
        private int spacing = 0;
        LocationClient locationClient;
    
        public PositioningService(Context context,final ContinuousPositioningCallback callback,int spacing){
            this.context = context;
            this.callback = callback;
            this.spacing = spacing;
            locationClient = new LocationClient(context);
            initLocationOption();
        }
    
        /**
         * 联系位置定位在后台
         */
        public void initLocationOption() {
            //声明LocationClient类实例并配置定位参数
            LocationClientOption locationOption = new LocationClientOption();
            LocationSharingLocationListener myLocationListener = new LocationSharingLocationListener();
            //注册监听函数
            locationClient.registerLocationListener(myLocationListener);
            //可选,默认高精度,设置定位模式,高精度,低功耗,仅设备
            locationOption.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy);
            //可选,默认gcj02,设置返回的定位结果坐标系,如果配合百度地图使用,建议设置为bd09ll;
            locationOption.setCoorType("bd09ll");
            //可选,默认0,即仅定位一次,设置发起连续定位请求的间隔需要大于等于1000ms才是有效的
            locationOption.setScanSpan(this.spacing);
            //可选,设置是否需要地址信息,默认不需要
            locationOption.setIsNeedAddress(true);
            //可选,设置是否需要地址描述
            locationOption.setIsNeedLocationDescribe(true);
            //可选,设置是否需要设备方向结果
            locationOption.setNeedDeviceDirect(false);
            //可选,默认false,设置是否当gps有效时按照1S1次频率输出GPS结果
            locationOption.setLocationNotify(true);
            //可选,默认true,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认不杀死
            locationOption.setIgnoreKillProcess(true);
            //可选,默认false,设置是否需要位置语义化结果,可以在BDLocation.getLocationDescribe里得到,结果类似于“在北京天安门附近”
            locationOption.setIsNeedLocationDescribe(true);
            //可选,默认false,设置是否需要POI结果,可以在BDLocation.getPoiList里得到
            locationOption.setIsNeedLocationPoiList(true);
            //可选,默认false,设置是否收集CRASH信息,默认收集
            locationOption.SetIgnoreCacheException(false);
            //可选,默认false,设置是否开启Gps定位
            locationOption.setOpenGps(true);
            //可选,默认false,设置定位时是否需要海拔信息,默认不需要,除基础定位版本都可用
            locationOption.setIsNeedAltitude(false);
            //设置打开自动回调位置模式,该开关打开后,期间只要定位SDK检测到位置变化就会主动回调给开发者,该模式下开发者无需再关心定位间隔是多少,定位SDK本身发现位置变化就会及时回调给开发者
            locationOption.setOpenAutoNotifyMode();
            //设置打开自动回调位置模式,该开关打开后,期间只要定位SDK检测到位置变化就会主动回调给开发者
            locationOption.setOpenAutoNotifyMode(3000,1, LocationClientOption.LOC_SENSITIVITY_HIGHT);
            //需将配置好的LocationClientOption对象,通过setLocOption方法传递给LocationClient对象使用
            locationClient.setLocOption(locationOption);
            //核心实现代码如下,详细代码请参考官网Demo。
            //开启前台定位服务:
            Notification.Builder builder = new Notification.Builder (context);
            //获取一个Notification构造器
            Intent nfIntent = new Intent(context, LocationServiceActivity.class);
            builder.setContentIntent(PendingIntent.getActivity(context, 0, nfIntent, 0)) // 设置PendingIntent
                    .setContentTitle("正在进行后台定位") // 设置下拉列表里的标题
                    .setSmallIcon(R.mipmap.ic_launcher) // 设置状态栏内的小图标
                    .setContentText("后台定位通知") // 设置上下文内容
                    .setAutoCancel(true)
                    .setWhen(System.currentTimeMillis()); // 设置该通知发生的时间
            Notification notification = null;
            notification = builder.build();
            notification.defaults = Notification.DEFAULT_SOUND; //设置为默认的声音
            locationClient.enableLocInForeground(1001, notification);// 调起前台定位
            //停止前台定位服务:
            locationClient.disableLocInForeground(true);// 关闭前台定位,同时移除通知栏
    
    
        }
    
        /**
         * 开始定位
         */
        public void startPositioning(){
            locationClient.start();
        }
    
        /**
         * 停止定位
         */
        public void stopPositioning(){
            locationClient.stop();
        }
    
    
        /**
         *
         * 实现定位回调
         */
        public class LocationSharingLocationListener extends BDAbstractLocationListener {
            @Override
            public void onReceiveLocation(BDLocation location){
                callback.getLocation(location,System.currentTimeMillis());
            }
        }
    
        public interface ContinuousPositioningCallback{
            void getLocation(BDLocation bdLocation,long timestamp);
        }
    
    
    }
    
    

    添加的权限如下:

    <!-- 开启访问网络的权限 -->
    <!-- 访问网络,进行地图相关业务数据请求,包括地图数据,路线规划,POI检索等 -->
    <uses-permission android:name="android.permission.INTERNET" /> <!-- 日历权限 -->
    <uses-permission android:name="android.permission.READ_CALENDAR" />
    <uses-permission android:name="android.permission.WRITE_CALENDAR" />
    <!-- 获取网络状态,根据网络状态切换进行数据请求网络转换 -->
    <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.WRITE_EXTERNAL_STORAGE" />
    <!-- 这个权限用于进行网络定位 -->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <!-- 这个权限用于访问GPS定位 -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <!-- 用于访问wifi网络信息,wifi信息会用于进行网络定位 -->
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <!-- 这个权限用于获取wifi的获取权限,wifi信息会用来进行网络定位 -->
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    
    
    界面代码:
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout 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"
        android:orientation="vertical"
        tools:context=".activity.service.LocationServiceActivity">
        <!--自定义状态栏-->
        <icu.shaoyayu.android.iearnit.view.SimpleMenu
            android:id="@+id/menu_location_service"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_constraintStart_toStartOf="parent" />
    
        <androidx.constraintlayout.widget.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">
            <com.baidu.mapapi.map.MapView
                android:id="@+id/mp_location_service"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:clickable="true">
    
            </com.baidu.mapapi.map.MapView>
    
            <com.google.android.material.floatingactionbutton.FloatingActionButton
                android:id="@+id/fab_map_search"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginEnd="10dp"
                android:layout_marginBottom="240dp"
                android:clickable="true"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:srcCompat="@android:drawable/ic_menu_search" />
    
            <com.google.android.material.floatingactionbutton.FloatingActionButton
                android:id="@+id/fab_map_route"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginEnd="10dp"
                android:layout_marginBottom="160dp"
                android:clickable="true"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:srcCompat="@android:drawable/ic_menu_send" />
    
            <com.google.android.material.floatingactionbutton.FloatingActionButton
                android:id="@+id/fab_map_share"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginEnd="10dp"
                android:layout_marginBottom="80dp"
                android:clickable="true"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:srcCompat="@android:drawable/ic_menu_myplaces" />
    
            <Switch
                android:background="@drawable/recommended_album_popup"
                android:id="@+id/sc_open_heat_map"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginTop="15dp"
                android:layout_marginEnd="15dp"
                android:text="开启热力图"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintTop_toTopOf="parent" />
    
        </androidx.constraintlayout.widget.ConstraintLayout>
    
    </LinearLayout>
    
    
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="720dp"
        android:orientation="vertical">
        <LinearLayout
            android:padding="12dp"
            android:background="@drawable/recommended_album_popup"
            android:layout_width="match_parent"
            android:layout_height="720dp"
            android:orientation="vertical">
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="30dp"
                android:gravity="center"
                android:orientation="vertical">
                <ImageView
                    android:id="@+id/iv_map_search_dog_close"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:src="@drawable/ic_down_foreground"/>
            </LinearLayout>
    
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal">
    
                <EditText
                    android:id="@+id/et_map_location_search"
                    android:layout_width="wrap_content"
                    android:layout_height="match_parent"
                    android:background="@null"
                    android:layout_weight="5"
                    android:hint="请输入"/>
    
                <Button
                    android:id="@+id/bt_find_location"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:text="开始查找" />
            </LinearLayout>
            <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/rv_map_search_results"
                android:layout_width="match_parent"
                android:layout_height="match_parent"/>
        </LinearLayout>
    </LinearLayout>
    
    
    <?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="720dp"
        android:background="@drawable/recom