欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Android 百度地图定时器轨迹回放,进度条和播放顺序

程序员文章站 2022-07-13 15:18:11
...

目前需要做这样一个需求,后台返回一堆打点数据,要求Android端实现轨迹回放功能,带动画的那种,还需要进度条,支持前进后退,先上图,看是否是你需要的功能。

Android 百度地图定时器轨迹回放,进度条和播放顺序

不多说直接上代码,目前的经纬度先使用类写死

TrackRecordActivity.class

public class TrackRecordActivity extends BaseFatherFragmentActivity implements
        BaiduMap.OnMapLoadedCallback,
        BaiduMap.OnMapStatusChangeListener,
        BaiduMap.OnMarkerClickListener,
        BaiduMap.OnMapClickListener {
    @BindView(R.id.tvTextTitle)
    TextView tvTextTitle;
    @BindView(R.id.btnTitleBack)
    ImageButton btnTitleBack;
    @BindView(R.id.baiduMap)
    MapView baiduMapView;
    @BindView(R.id.layoutBaidu)
    FrameLayout layoutBaidu;
    @BindView(R.id.view_control)
    View view_control;
    @BindView(R.id.iv_forward)
    ImageView iv_forward;
    @BindView(R.id.iv_play)
    ImageView iv_play;
    @BindView(R.id.iv_next)
    ImageView iv_next;

    @BindView(R.id.seekbar_play)
    SeekBar seekbar_play;
    @BindView(R.id.tv_mark_time)
    TextView tv_mark_time;
    private int playProgress;

    private BaiduMap baiduMap;
    private MyLocationListenner myListener = new MyLocationListenner();
    private LocationClient mLocClient;

    private BDLocation myLocation;
    private int mapFitZoom = 10;

    private String mDevCode;
    private String trackRecodeId;
    private List<Marker> markers;

    private boolean isPlayTrack = false;
    private LatLng playPosition = null;
    private List<HistoryLocationBean> historyLocationBeans = new ArrayList<>();
    private List<LatLng> routeList = new ArrayList<>();// 路线点的集合

    private int routeIndex;
    private boolean routeFlag;
    private final int ROUTE = 0;

    private Marker routeMarker;
    private int ROUTETIME = 500;
    private Handler mHandler = new Handler() {
        public void handleMessage(Message msg) {
            if (msg.what == ROUTE) {
                mHandler.sendEmptyMessage(PROGRESS);
                if (routeIndex == routeList.size() - 1) {
                    isPlayTrack = false;
                    routeFlag = false;
                    iv_play.setImageResource(R.drawable.ic_player_start);
                    AppLog.Loge("播放完毕");
                    routeIndex = 0;
                    if (routeMarker != null) {
                        routeMarker.remove();
                        routeMarker = null;
                    }
//                    addRouteLine(routeList);
                    //画路线
                    if (routeList.size() > 0) {
                        addMarker(routeList);
                    }
//                    drawMyRoute(routeList);
                    return;
                }
                if (routeIndex != 0) {
                    isPlayTrack = true;
                    //画路线
                    drawMyRoute(routeList.subList(0,
                            routeIndex+1));
                    //描点
                    playPosition = routeList.get(routeList.size()-1);
                    drawMapMarkView();
//                    //描起点
                    needAddMapMark(routeList.get(0),0);
                }
                // 页面跟随移动,注掉这行就是在原图上绘制
//                 moveToLocation(routeList.get(routeIndex), false);
                if (routeMarker == null) {

                    Bitmap bitmap1= BitmapFactory.decodeResource(getResources(),R.drawable.track_run);
                    BitmapDescriptor bitmap = BitmapDescriptorFactory.fromBitmap(AppUtils.imageScale(bitmap1,AppUtils.dp2Px(TrackRecordActivity.this,27),
                            AppUtils.dp2Px(TrackRecordActivity.this,38)));

                    //构建MarkerOption,用于在地图上添加Marker
                    OverlayOptions option = new MarkerOptions()
                            .position(routeList.get(routeIndex++))
                            .icon(bitmap);
                    //在地图上添加Marker,并显示
                    routeMarker = (Marker) baiduMap.addOverlay(option);

                } else {
                    routeMarker.setPosition(routeList.get(routeIndex++));
                }

                routeMarker.setToTop();
                routeMarker.setDraggable(false);//设置 marker 是否允许拖拽,默认不可拖拽
                routeMarker.setPerspective(false);//设置是否开启 Marker 覆盖物近大远小效果,默认开启
//                setUserMapCenter(routeList.get(routeIndex), mapFitZoom);

                mHandler.sendEmptyMessageDelayed(ROUTE, ROUTETIME);
            }

            if (msg.what == PROGRESS) {
                if (routeIndex == 0) {// 因为播放完毕时routeIndex被赋值成了0,不写进度条会直接跳到0的位置
                    setProgss(100);
                } else {
                    setProgss((routeIndex + 1) * 100 / routeList.size());
                }
            }
        };
    };


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.ac_track_record);
        ButterKnife.bind(this);
        initVariable();
        setViews();
        setClick();
        initSeekBar();

        updatePlayMarkUi(false);

        getData();
    }

    @Override
    protected void onStart() {
        super.onStart();
        if (!mLocClient.isStarted()) {
            mLocClient.start();
        }
    }

    @Override
    protected void onStop() {
        super.onStop();
        mLocClient.stop();
    }

    private void initSeekBar() {
        seekbar_play.setMax(100);
        seekbar_play.setProgress(0);
        playProgress = seekbar_play.getProgress();
        seekbar_play.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean b) {
                playProgress = progress ;
                AppLog.Loge("移动的进度为:"+progress);
                if (!isPlayTrack){//播放过程中无效
                    int selectIndex = 0;
                    if(routeList!=null && routeList.size()>0){
                        float seachPoi = (float) ((progress*routeList.size())/100.0);
                        if((seachPoi-(int)seachPoi)>0.5){
                            selectIndex = (int)seachPoi+1;
                        }else{
                            selectIndex = (int)seachPoi;
                        }
                        //防止溢出
                        if(selectIndex >= routeList.size()-1){
                            selectIndex = routeList.size()-1;
                        }
                    }
                    routeIndex = selectIndex;
                    AppLog.Loge("实际选择的下标为:"+routeIndex);
                    //描点
                    playPosition = routeList.get(selectIndex);
                    drawMapMarkView();
                }
            }
            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
            }
            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
            }
        });
    }

    private void initVariable() {
        markers = new ArrayList<>();
        Intent intent = getIntent();
        if (null != intent) {
            mDevCode = intent.getStringExtra("device_code");
            trackRecodeId  = intent.getStringExtra("trackRecodeId");
        }
    }

    private void setViews() {
        tvTextTitle.setText(LangComm.getString("track_record"));

        setMapView();
    }

    private void setMapView() {
        //显示控制放大缩小图标
        baiduMapView.showZoomControls(false);
        baiduMap = baiduMapView.getMap();
        // 开启定位图层
        baiduMap.setMyLocationEnabled(true);

        //设置事件
        baiduMap.setOnMapLoadedCallback(this);
        baiduMap.setOnMapClickListener(this);
        baiduMap.setOnMarkerClickListener(this);
        baiduMap.setOnMapStatusChangeListener(this);

        //百度个性化地图
        if(AppUtils.getDarkModeStatus(mContext)){
            MapCustomType.setMapType(mContext,baiduMapView,true);
        }else{
            MapCustomType.setMapType(mContext,baiduMapView,false);
        }

        // 定位初始化
        mLocClient = new LocationClient(this.getApplicationContext());
        mLocClient.registerLocationListener(myListener);
        checkPermission();
        double[] doubles = GPSUtil.gps84_To_bd09(DataCenter.locationLat, DataCenter.locationLon);
        LatLng cenpt = new LatLng(doubles[0], doubles[1]);
        setUserMapCenter(cenpt, mapFitZoom);
    }

    private void setClick() {
        //返回
        btnTitleBack.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });

        //前进
        iv_forward.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isPlayTrack){
                 return;
                }
                forwardMark();
            }
        });

        //后退
        iv_next.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isPlayTrack){
                    return;
                }
                nextMark();
            }
        });

        //播放
        iv_play.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                playMark();
            }
        });
    }


    private void forwardMark() {
        if(routeList.size()>0){
            LatLng info = null;
            if(routeIndex>0){
                routeIndex --;
            }else{
                routeIndex = routeList.size()-1;
            }
            info = routeList.get(routeIndex);
            playPosition = new LatLng(info.latitude,info.longitude);
        }

        drawMapMarkView();
    }

    private void nextMark() {
        if(routeList.size()>0){
            LatLng info = null;
            if(routeIndex < routeList.size()-1){
                routeIndex ++;
            }else{//重新回到第一个
                routeIndex = 0;
            }
            info = routeList.get(routeIndex);
            playPosition = new LatLng(info.latitude,info.longitude);
        }
        AppLog.Loge("绘制的点下标为:"+routeIndex);
        drawMapMarkView();
    }


    private void playMark() {
        if (routeList == null || routeList.size() <= 0) {
            return;
        }

        routeFlag = !routeFlag;
        iv_play.setImageResource(routeFlag ? R.drawable.ic_player_pause
                : R.drawable.ic_player_start);

        isPlayTrack = routeFlag;
        if (routeFlag) {
            if (routeIndex == 0) {
                baiduMap.clear();
                routeMarker = null;
            }
            mHandler.sendEmptyMessageDelayed(ROUTE, 0);
        } else {
            mHandler.removeMessages(0);
        }
    }

    private void updatePlayMarkUi(boolean playStatus) {
        if(playStatus){
            iv_play.setImageResource(R.drawable.ic_player_pause);
        }else{
            iv_play.setImageResource(R.drawable.ic_player_start);
        }
    }

    //显示或者是隐藏地图操作选项
    private void showOrHideControl() {
        if (view_control.getVisibility() == View.VISIBLE) {
            AnimationUtils.showAndHiddenAnimation(view_control, AnimationUtils.AnimationState.STATE_HIDDEN_UP, 300);
        } else {
            AnimationUtils.showAndHiddenAnimation(view_control, AnimationUtils.AnimationState.STATE_SHOW_UP, 300);
        }
        baiduMap.hideInfoWindow();
    }

    /**
     * 设置中心点
     */
    private void setUserMapCenter(LatLng cenpt, int levle) {
//定义地图状态
        MapStatus mMapStatus = new MapStatus.Builder()
                .target(cenpt)
                .zoom(levle)
                .build();
//定义MapStatusUpdate对象,以便描述地图状态将要发生的变化
        MapStatusUpdate mMapStatusUpdate = MapStatusUpdateFactory.newMapStatus(mMapStatus);
//改变地图状态
        baiduMap.setMapStatus(mMapStatusUpdate);
    }

    @Override
    public void onMapClick(LatLng latLng) {
        showOrHideControl();
    }

    @Override
    public void onMapPoiClick(MapPoi mapPoi) {

    }

    @Override
    public void onMapLoaded() {

    }

    @Override
    public void onMapStatusChangeStart(MapStatus mapStatus) {

    }

    @Override
    public void onMapStatusChangeStart(MapStatus mapStatus, int i) {

    }

    @Override
    public void onMapStatusChange(MapStatus mapStatus) {

    }

    @Override
    public void onMapStatusChangeFinish(MapStatus mapStatus) {

    }

    @Override
    public boolean onMarkerClick(Marker marker) {
        //正在播放轨迹,不能点击
        if (isPlayTrack){
            showInfoWindow(marker);
        }
        return false;
    }

    private void showInfoWindow(Marker marker) {
        View view = View.inflate(this, R.layout.lay_map_info_window, null);
        TextView textView = view.findViewById(R.id.item_history_time);
        Bundle bundle = marker.getExtraInfo();
        String time = bundle.getString("time");
        if (null != bundle && !StringUtils.isEmpty(time)) {
            textView.setVisibility(View.VISIBLE);
            textView.setText(time);
        }
        final InfoWindow mInfoWindow = new InfoWindow(view, marker.getPosition(), -47);
        baiduMap.showInfoWindow(mInfoWindow);

        //记录,当前点击的下标
        if(historyLocationBeans.size()>0){
            for (int i = 0; i < historyLocationBeans.size(); i++) {
                if(!StringUtils.isEmpty(time) && time.equals(historyLocationBeans.get(i).getTime())){
                    routeIndex = i;
                    break;
                }
            }
        }
    }

    /**
     * @author 陈希
     * @description 定位SDK监听函数
     * @remark
     */
    public class MyLocationListenner implements BDLocationListener {

        /**
         * @param location  定位位置
         * @author 陈希
         * @description 收到定位后处理
         * @remark
         */
        @Override
        public void onReceiveLocation(BDLocation location) {
            // map view 销毁后不在处理新接收的位置
            if (location == null || baiduMap == null) {
                return;
            }
            switch (location.getLocType()) {
                case BDLocation.TypeCriteriaException:
                case BDLocation.TypeNetWorkException:
                case BDLocation.TypeNone:
                case BDLocation.TypeOffLineLocationFail:
                case BDLocation.TypeServerError:
                case BDLocation.TypeServerCheckKeyError:
                case BDLocation.TypeOffLineLocationNetworkFail:
                case BDLocation.TypeServerDecryptError:
                    break;
                default://定位方式正确的时候

                    AppLog.Loge("当前我的位置,纬度:" + location.getLatitude() + "--经度:" + location.getLongitude() + "---定位方式:" + location.getLocType());
                    myLocation = location;

                    double[] doubles = GPSUtil.bd09_To_gps84(location.getLatitude(), location.getLongitude());
                    DataCenter.locationLat = doubles[0];
                    DataCenter.locationLon = doubles[1];

                    break;
            }
        }

        public void onReceivePoi(BDLocation poiLocation) {
        }
    }

    /**
     * @author 陈希
     * @description 查询是否已有定位和存储权限
     * @remark
     */
    private int grantedCount = 0;

    private void checkPermission() {

        final String strPer[] = {
                Manifest.permission.ACCESS_COARSE_LOCATION
        };
        grantedCount = 0;
        final RxPermissions rxPermissions = new RxPermissions(this);
        rxPermissions.requestEach(strPer)
                .subscribe(new Consumer<Permission>() {
                    @Override
                    public void accept(Permission permission) {
                        if (permission.granted) {
                            grantedCount++;
                            if (grantedCount == strPer.length) {
                                //请求成功操作
                                LocationClientOption option = new LocationClientOption();
                                option.setOpenGps(true); // 打开gps
                                option.setCoorType("bd09ll"); // 设置坐标类型
                                option.setScanSpan(120 * 1000);
                                option.setNeedDeviceDirect(true);//在网络定位时,是否需要设备方向- true:需要 ; false:不需要。默认为false
                                mLocClient.setLocOption(option);
                                mLocClient.start();
                            }
                        } else if (permission.shouldShowRequestPermissionRationale) {
                            ShowPermissionDialog(LangComm.getString("location_author"));
                        } else {
                            ShowPermissionDialog(LangComm.getString("android_check_permissions"));
                        }
                    }
                });


    }

    private PermissionDialog mPermissionDialog = null;

    private void ShowPermissionDialog(String strMsg) {
        if (mPermissionDialog == null) {
            mPermissionDialog = new PermissionDialog(this);
        }
        if (mPermissionDialog.mDialog != null && !mPermissionDialog.mDialog.isShowing()) {
            mPermissionDialog.showPermissDialog(LangComm.getString("tips"), strMsg,
                    LangComm.getString("confirm"), null);
        }
    }

    private void getData() {
//        mProgressDialog.showProgress(LangComm.getString("loading"));
//        CollarBiz.getLocationHistory(device_code, startTime + "", endTime + "",
//                AppUtils.getUserToken(TrackRecordActivity.this),
//                new MyNetBack() {
//                    @Override
//                    public boolean onFail(int iStatus, String msg) {
//                        HttpToast.ToastDefault(TrackRecordActivity.this, iStatus, msg);
//                        mProgressDialog.dismiss();
//                        return false;
//                    }
//
//                    @Override
//                    public void onSuccess(Object object) {
//                        mProgressDialog.dismiss();
//                        List<HistoryLocationBean> historyLocationBeans = (List<HistoryLocationBean>) object;
//                        setDataToMap(historyLocationBeans);
//                    }
//                });

        if(historyLocationBeans!=null){
            historyLocationBeans.clear();
        }
        historyLocationBeans.add(new HistoryLocationBean(mDevCode,113.11245,22.896382,AppUtils.getNowTime()+1));
        historyLocationBeans.add(new HistoryLocationBean(mDevCode,113.22245,22.836382,AppUtils.getNowTime()+2));
        historyLocationBeans.add(new HistoryLocationBean(mDevCode,113.33245,22.796382,AppUtils.getNowTime()+3));
        historyLocationBeans.add(new HistoryLocationBean(mDevCode,113.41245,22.696382,AppUtils.getNowTime()+4));
        historyLocationBeans.add(new HistoryLocationBean(mDevCode,113.51245,22.546382,AppUtils.getNowTime()+5));
        historyLocationBeans.add(new HistoryLocationBean(mDevCode,113.61245,22.556382,AppUtils.getNowTime()+6));
        historyLocationBeans.add(new HistoryLocationBean(mDevCode,113.71245,23.696382,AppUtils.getNowTime()+7));
        historyLocationBeans.add(new HistoryLocationBean(mDevCode,113.87245,24.756382,AppUtils.getNowTime()+8));
        historyLocationBeans.add(new HistoryLocationBean(mDevCode,113.91245,22.866382,AppUtils.getNowTime()+9));
        historyLocationBeans.add(new HistoryLocationBean(mDevCode,113.11245,21.986382,AppUtils.getNowTime()+10));

        //先移除地图所有的标注
        baiduMap.clear();
        setDataToMap(historyLocationBeans);

        if(historyLocationBeans!=null && historyLocationBeans.size()>0){
            //如果有轨迹设置地图中心点为第一个坐标
            double lat = (historyLocationBeans.get(historyLocationBeans.size()-1).getLat()+historyLocationBeans.get(0).getLat())/2;
            double log = (historyLocationBeans.get(historyLocationBeans.size()-1).getLon()+historyLocationBeans.get(0).getLon())/2;
            double dbLoction[] = GPSUtil.gps84_To_bd09(lat, log);
            LatLng point_center = new LatLng(dbLoction[0], dbLoction[1]);
            setUserMapCenter(point_center, mapFitZoom);
        }
    }


    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");

    private void setDataToMap(List<HistoryLocationBean> historyLocationBeans) {
        /**
         * 添加marker
         */
        if (routeList!=null){
            routeList.clear();
        }

        if (null != historyLocationBeans && historyLocationBeans.size() > 0) {
            for (int i = 0; i < historyLocationBeans.size(); i++) {
                double lat = historyLocationBeans.get(i).getLat();
                double log = historyLocationBeans.get(i).getLon();
                double dbLoction[] = GPSUtil.gps84_To_bd09(lat, log);
                String time = dateFormat.format(historyLocationBeans.get(i).getTime());
                LatLng latLng = new LatLng(dbLoction[0], dbLoction[1]);
                routeList.add(latLng);
            }
        }else {
            ToastView.bottomShow(TrackRecordActivity.this,LangComm.getString("no_data"), Toast.LENGTH_SHORT);
        }
        if (routeList.size() > 0) {
          addMarker(routeList);
        }
    }


    private void addMarker(List<LatLng> list_line) {
        new Thread(
                new Runnable() {
                    @Override
                    public void run() {
                        AppLog.Loge("points", list_line.size() + "");
                        markers.clear();
                        //画路线
                        drawMyRoute(list_line);

                        routeList = list_line;

                        boolean isFactory=false;
                        BitmapDescriptor bitmap = null;


                        //描绘轨迹上的点
                        for (int i = 0; i < list_line.size(); i++) {
                            //定义Maker坐标点
                            LatLng point = list_line.get(i);
                            //构建Marker图标
                            if (i == 0) {
                                isFactory=false;
                                //起点
                                needAddMapMark(point,0);
                            } else if (i == list_line.size() - 1) {
                                //终点
                                needAddMapMark(point,1);
                            } else {
                                if(!isFactory){
                                    bitmap = BitmapDescriptorFactory
                                            .fromResource(R.drawable.mark_record1);
                                }
                            }

                        }
                    }
                }
        ).start();
    }

    private void needAddMapMark(LatLng point,int position) {
        BitmapDescriptor bitmap = null;
        if(position == 0){
            Bitmap bitmap1= BitmapFactory.decodeResource(getResources(),R.drawable.track_start);
            bitmap =BitmapDescriptorFactory
                    .fromBitmap(AppUtils.imageScale(bitmap1,AppUtils.dp2Px(TrackRecordActivity.this,20),
                            AppUtils.dp2Px(TrackRecordActivity.this,32)));
        }else{
            Bitmap bitmap1= BitmapFactory.decodeResource(getResources(),R.drawable.track_end);
            bitmap = BitmapDescriptorFactory
                    .fromBitmap(AppUtils.imageScale(bitmap1,AppUtils.dp2Px(TrackRecordActivity.this,20),
                            AppUtils.dp2Px(TrackRecordActivity.this,32)));
        }

        Bundle bundleInfo = new Bundle();
//        bundleInfo.putString("time", list.get(i).getTime());
        //构建MarkerOption,用于在地图上添加Marker
        OverlayOptions option = new MarkerOptions()
                .position(point)
                .extraInfo(bundleInfo)
                .icon(bitmap);
        //在地图上添加Marker,并显示
        Marker marker = (Marker) baiduMap.addOverlay(option);
        markers.add(marker);
        marker.setDraggable(false);//设置 marker 是否允许拖拽,默认不可拖拽
        marker.setPerspective(false);//设置是否开启 Marker 覆盖物近大远小效果,默认开启
    }

    private Overlay overlay;
    //4.画轨迹方法
    /**
     * 添加路线
     *
     * @param points2
     */
    protected void drawMyRoute(List<LatLng> points2) {
        if (points2.size() == 0) {
            return;
        }
        if (null != overlay) {
            overlay.remove();
        }
        //添加纹理图片
        List<BitmapDescriptor> textureList = new ArrayList<BitmapDescriptor>();
        BitmapDescriptor mRedTexture = BitmapDescriptorFactory
                .fromAsset("icon_red_road.png");//箭头图片
        textureList.add(mRedTexture);
        // 添加纹理图片对应的顺序
        List<Integer> textureIndexs = new ArrayList<Integer>();
        for (int i = 0; i < points2.size() - 1; i++) {
            textureIndexs.add(0);
        }
        OverlayOptions options = new PolylineOptions()
                .textureIndex(textureIndexs)//设置分段纹理index数组
                .customTextureList(textureList)//设置线段的纹理,建议纹理资源长宽均为2的n次方
                .dottedLine(true)
                .color(getResources().getColor(R.color.app_khaki))
                .width(15)
                .points(points2);
        overlay = baiduMap.addOverlay(options);
    }

    private void drawMapMarkView(){
        if(playPosition!=null){
            if(routeMarker == null){
                Bitmap bitmap1= BitmapFactory.decodeResource(getResources(),R.drawable.track_run);
                BitmapDescriptor bitmap = BitmapDescriptorFactory.fromBitmap(AppUtils.imageScale(bitmap1,AppUtils.dp2Px(TrackRecordActivity.this,27),
                        AppUtils.dp2Px(TrackRecordActivity.this,38)));

                //构建MarkerOption,用于在地图上添加Marker
                OverlayOptions option = new MarkerOptions()
                        .position(playPosition)
                        .icon(bitmap);
                //在地图上添加Marker,并显示
                routeMarker = (Marker) baiduMap.addOverlay(option);
            }else{
                routeMarker.setPosition(playPosition);
                routeMarker.startAnimation();
            }

            routeMarker.setToTop();
            routeMarker.setDraggable(false);//设置 marker 是否允许拖拽,默认不可拖拽
            routeMarker.setPerspective(false);//设置是否开启 Marker 覆盖物近大远小效果,默认开启
        }

        setUserMapCenter(playPosition, mapFitZoom);

        //时间变化
        if(historyLocationBeans!=null && historyLocationBeans.size()>0){
            tv_mark_time.setText(AppUtils.timeDate(historyLocationBeans.get(routeIndex).getTime()));
        }

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }
    private void setProgss(int index) {
        seekbar_play.setProgress(index);
    }

    private final static int PROGRESS = 1234;

    /**
     * 移动到指定位置 并缩放
     *
     * @param latlng
     */
    private void moveToLocation(LatLng latlng, boolean flag) {
        MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(latlng);// 设置新的中心点
        baiduMap.animateMapStatus(u);
        if (flag && baiduMap.getMapStatus().zoom < 12.0f) {
            // 加个延时播放的效果,就可以有先平移 ,再缩放的效果
            mTimer.start();
        }
    }

    private CountDownTimer mTimer = new CountDownTimer(2000, 2000) {
        @Override
        public void onTick(long millisUntilFinished) {

        }
        @Override
        public void onFinish() {
            if (baiduMap != null) {
                MapStatusUpdate u1 = MapStatusUpdateFactory.zoomTo(12.0f);
                baiduMap.animateMapStatus(u1);
            }
        }
    };

}
HistoryLocationBean.class
public class HistoryLocationBean {
    /**
     *  "data":[{
     "deviceCode": "xxxx",
     "lon": 113.11111,
     "lat": 23.11111,
     "time": 1231231231, //时间戳毫秒数
     "type": "gps"
     },{
     "deviceCode": "xxxx",
     "lon": 113.11111,
     "lat": 23.11111,
     "time": 1231231231, //时间戳毫秒数
     "type": "gps"
     },{
     "deviceCode": "xxxx",
     "lon": 113.11111,
     "lat": 23.11111,
     "time": 1231231231, //时间戳毫秒数
     "type": "gps"
     }]
     */
    private String deviceCode;
    private double lon;
    private double lat;
    private long   time;
    private String gps;

    public HistoryLocationBean() { }

    public HistoryLocationBean(String deviceCode, double lon, double lat, long time) {
        this.deviceCode = deviceCode;
        this.lon = lon;
        this.lat = lat;
        this.time = time;
    }

    public String getDeviceCode() {
        return deviceCode;
    }

    public void setDeviceCode(String deviceCode) {
        this.deviceCode = deviceCode;
    }

    public double getLon() {
        return lon;
    }

    public void setLon(double lon) {
        this.lon = lon;
    }

    public double getLat() {
        return lat;
    }

    public void setLat(double lat) {
        this.lat = lat;
    }

    public long getTime() {
        return time;
    }

    public void setTime(long time) {
        this.time = time;
    }

    public String getGps() {
        return gps;
    }

    public void setGps(String gps) {
        this.gps = gps;
    }
}

布局文件ac_track_record.xml

<?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:id="@+id/linear_mark"
    android:orientation="vertical">

    <include layout="@layout/layout_title_bar" />

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <FrameLayout
            android:id="@+id/layoutGoogle"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:visibility="gone">


            <fragment
                android:id="@+id/googleMap"
                class="com.google.android.gms.maps.SupportMapFragment"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />

        </FrameLayout>

        <FrameLayout
            android:id="@+id/layoutBaidu"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            >

            <com.baidu.mapapi.map.MapView
                android:id="@+id/baiduMap"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:clickable="true" />

        </FrameLayout>

        <LinearLayout
            android:id="@+id/view_control"
            android:layout_width="match_parent"
            android:layout_height="90dp"
            android:gravity="center_vertical"
            android:background="@color/normal_color"
            android:layout_alignParentBottom="true">
            <ImageView
                android:id="@+id/iv_forward"
                android:layout_width="45dp"
                android:layout_height="45dp"
                android:padding="10dp"
                android:layout_marginStart="@dimen/margin15"
                android:src="@drawable/ic_track_forward"/>
            <RelativeLayout
                android:layout_width="0dp"
                android:layout_weight="1"
                android:gravity="center_vertical"
                android:layout_height="match_parent">

                <LinearLayout
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:layout_centerInParent="true"
                    android:gravity="center_vertical"
                    android:orientation="vertical">
                <SeekBar
                    android:id="@+id/seekbar_play"
                    android:layout_width="match_parent"
                    android:layout_height="30dp"
                    android:layout_centerHorizontal="true"
                    android:layout_marginEnd="10dp"
                    android:layout_marginStart="10dp"
                    android:paddingEnd="10dp"
                    android:paddingBottom="5dp"
                    android:paddingStart="10dp"
                    android:paddingTop="3dp"
                    android:progress="0"
                    android:progressDrawable="@drawable/track_bg_bar_thumb"
                    android:thumb="@drawable/badge_blue_small"
                    android:thumbOffset="0dip" />
                <TextView
                    android:id="@+id/tv_mark_time"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textSize="@dimen/text16"
                    android:layout_marginTop="5dp"
                    android:layout_gravity="center_horizontal"
                    android:textColor="@color/app_black_color"
                    android:text="@string/test"/>
                </LinearLayout>
                <ImageView
                    android:id="@+id/iv_play"
                    android:layout_width="45dp"
                    android:layout_height="45dp"
                    android:padding="10dp"
                    android:layout_alignParentBottom="true"
                    android:layout_marginStart="@dimen/margin15"
                    android:background="@drawable/corners_gray"
                    android:src="@drawable/ic_player_start"/>
            </RelativeLayout>
            <ImageView
                android:id="@+id/iv_next"
                android:layout_width="45dp"
                android:layout_height="45dp"
                android:padding="10dp"
                android:layout_marginEnd="@dimen/margin15"
                android:src="@drawable/ic_track_next"/>

        </LinearLayout>


    </RelativeLayout>


</LinearLayout>
ic_track_forward

ic_track_next

ic_player_start

Android 百度地图定时器轨迹回放,进度条和播放顺序

ic_player_pause

 Android 百度地图定时器轨迹回放,进度条和播放顺序

track_end

track_run

track_start
 

里面项目的一些样式和方法没有的话,不影响核心使用,更换你需要的代码方法即可