package com.sunzee.service;

import android.app.AlarmManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.os.SystemClock;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.text.TextUtils;
import android.util.Log;
import android.view.WindowManager;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.hboxs.serialport.frame.ResponseFrame;
import com.hboxs.serialport.message.Message;
import com.hboxs.serialport.util.AsciiUtils;
import com.hboxs.serialport.util.ByteUtils;
import com.hboxs.serialport.util.HexUtils;
import com.orhanobut.hawk.Hawk;
import com.sunzee.R;
import com.sunzee.base.BaseApplication;
import com.sunzee.db.WarringBeanDao;
import com.sunzee.model.Global;
import com.sunzee.model.Heartbeat;
import com.sunzee.model.HoleInformation;
import com.sunzee.model.HttpResult;
import com.sunzee.model.domain.AddAlarmRecordBean;
import com.sunzee.model.domain.ErrorBean;
import com.sunzee.model.domain.GetAdBean;
import com.sunzee.model.domain.HeartbeatBean;
import com.sunzee.model.domain.Name;
import com.sunzee.model.domain.ParameterBean;
import com.sunzee.model.domain.TimeRuleBean;
import com.sunzee.model.domain.WarringBean;
import com.sunzee.model.message.ApiMessageEvent;
import com.sunzee.model.message.DownLoadMessageEvent;
import com.sunzee.receiver.Alarmreceiver;
import com.sunzee.retrofit.ApiCallback;
import com.sunzee.retrofit.ApiClient;
import com.sunzee.retrofit.ApiStores;
import com.sunzee.thread.advanceparameter.ThreadPoolAdvanceParameter;
import com.sunzee.thread.myservice.ThreadPoolMyservice;
import com.sunzee.ui.dialog.WarringDialog;
import com.sunzee.utils.FileUtil;
import com.sunzee.utils.HexadecimalUtil;
import com.sunzee.utils.PreventSpeedClickUtil;
import com.sunzee.utils.SharedPreferencesUtils;
import com.sunzee.utils.TimeUtil;
import com.sunzee.utils.TimerUtil;
import com.sunzee.utils.ToastUtil;
import com.sunzee.utils.UiUtil;
import com.wuxiaolong.androidutils.library.LogUtil;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.observers.DisposableObserver;
import io.reactivex.schedulers.Schedulers;
import okhttp3.RequestBody;

public class MyService extends Service {
    private static final String TAG = "MyService";
    private ThreadPoolMyservice mThreadPoolMyservice = new ThreadPoolMyservice();//读取一些需要一直读取，或者属于myservice的地址
    private boolean isRead = true;
    private boolean isRegularCleaning = false;
    private ThreadPoolAdvanceParameter mPoolAdvanceParameter = new ThreadPoolAdvanceParameter();
    public final static int TOTAL_SUM = 14;

    //存储两个数据：是否上过厕所，一开始上厕所的时间是什么时候
    //CopyOnWriteArrayList并不是完全意义上的线程安全，如果涉及到remove操作，一定要谨慎处理。
    //写操作是加锁，读操作是不加锁的。多读少写时使用
    //厕所状态从0开始。
    public static final List<HoleInformation> sHoleInformationList = new LinkedList<>();
    //厕所序号从1开始。
    public static final LinkedList<Integer> sCleaningLocationList = new LinkedList<>();//存储要清洗的位置。

    private static volatile boolean isCleanOK = false;
    private static volatile boolean isToiletClean = true;
    private volatile Integer last;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "MyServiceonCreate: ");
        synchronized (sCleaningLocationList){
            sHoleInformationList.clear();
            for (int i = 0; i < TOTAL_SUM; i++) {
                sHoleInformationList.add(new HoleInformation(2, 0));//初始化
            }
        }
        EventBus.getDefault().register(this);
        startRefreshime();
    }

    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e(TAG, "onStartCommand: 开始心跳3");
        Bundle extras = null;
        if (intent != null) {
            extras = intent.getExtras();
        }

        if (extras != null) {

            int heartbeat = extras.getInt("heartbeat");
            if (heartbeat == 3) {
                stopHeartbeat();
                Log.w(TAG, "onStartCommand: 开始心跳" + heartbeat);
                Log.e(TAG, "onStartCommand: 开始心跳1");
                startHeartbeat();
            }
            int first = extras.getInt("first");
            if (first == 4) {
                //第一次启动心跳
                checkHeartData();
                mPoolAdvanceParameter.stopAll();
                mPoolAdvanceParameter.startALLRead();
            }
        }
        //进程保活相关
        flags = START_STICKY;

        //启用前台服务，主要是startForeground()
        String ns = Context.NOTIFICATION_SERVICE;

        //获得通知管理器
        NotificationManager manager1 = (NotificationManager) getSystemService(ns);

        Notification.Builder builder = new Notification.Builder(getApplicationContext());
        builder.setSmallIcon(R.drawable.login_logo);
        builder.setTicker("服务正在运行");
        builder.setContentTitle("服务正在运行");
        builder.setContentText("服务正在运行");
        builder.setWhen(System.currentTimeMillis()); //设置时间
        Notification notification = builder.build();

        //定义通知行为
        manager1.notify(0, notification);

        AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE);
        //读者可以修改此处的Minutes从而改变提醒间隔时间
        //此处是设置每隔55分钟启动一次
        //这是55分钟的毫秒数
        int Minutes = 55 * 60 * 1000;
        //SystemClock.elapsedRealtime()表示1970年1月1日0点至今所经历的时间
        long triggerAtTime = SystemClock.elapsedRealtime() + Minutes;
        //此处设置开启AlarmReceiver这个Service
        Intent i = new Intent(this, Alarmreceiver.class);
        PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0);
        //ELAPSED_REALTIME_WAKEUP表示让定时任务的出发时间从系统开机算起，并且会唤醒CPU。
        manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pi);
        if (warringDialog == null) {
            warringBeanDao = BaseApplication.getInstances().getDaoSession().getWarringBeanDao();
        }
        if (isRead) {
            isRead = !isRead;
            mThreadPoolMyservice.stopReadM600();
            mThreadPoolMyservice.stopReadD2();
            mThreadPoolMyservice.startALLRead();
        }
        //startRead();
        return super.onStartCommand(intent, flags, startId);
        //进程保活相关
        //return START_STICKY ;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mThreadPoolMyservice.stopALLRead();
        EventBus.getDefault().unregister(this);
    }

    //------------------------------------------------------------------------心跳 start---------------------------------
    private Timer timerHeartbeat;
    private TimerTask taskHeartbeat;

    /**
     * 开始心跳
     */
    private void startHeartbeat() {
        Log.e(TAG, "startHeartbeat: 开始心跳");
        timerHeartbeat = new Timer();
        taskHeartbeat = new TimerTask() {
            @Override
            public void run() {
                //经纬度不为0
                //系统管理不为空
                String managerId = (String) SharedPreferencesUtils.getParam(Name.SYSTEM_ID, "");
                if (managerId != null && !TextUtils.isEmpty(managerId)) {
                    sendHeart();
                }
            }
        };
        timerHeartbeat.schedule(taskHeartbeat, 1000, 1000 * 60 * 5);
    }

    /**
     * 发送心跳
     */
    private void sendHeart() {
        Heartbeat.managerId = (String) SharedPreferencesUtils.getParam(Name.SYSTEM_ID, "");
        Heartbeat.lastUpdateTime = TimeUtil.getStrCurTime();
        HeartbeatBean heartbeatBean = new HeartbeatBean();
        heartbeatBean.setCabinetHd(Heartbeat.cabinetHd);
        heartbeatBean.setCabinetTm(Heartbeat.cabinetTm);
        heartbeatBean.setFurnaceSp("0");
        heartbeatBean.setFurnaceTm(Heartbeat.furnaceTm);
        heartbeatBean.setLastUpdateTime(Heartbeat.lastUpdateTime);
        heartbeatBean.setLatitude(Heartbeat.latitude);
        heartbeatBean.setLongitude(Heartbeat.longitude);
        heartbeatBean.setManagerId(Heartbeat.managerId);
        heartbeatBean.setOdorConcentration(Heartbeat.odorConcentration);
        heartbeatBean.setCleaner(Heartbeat.cleaner);
        heartbeatBean.setDisinfectant(Heartbeat.disinfectant);
        heartbeatBean.setPeopleCounting(Heartbeat.peopleCounting);
        int netType = (int) SharedPreferencesUtils.getParam(Name.NET_TYPE, -1);
        if (netType == 0) {
            Heartbeat.netWorkingMode = "4g";
        } else if (netType == 1) {
            Heartbeat.netWorkingMode = "wifi";
        } else {
            Heartbeat.netWorkingMode = "no";
        }
        heartbeatBean.setNetWorkingMode(Heartbeat.netWorkingMode);
        heartbeatBean.setGtClientId(Heartbeat.clientId);
        heartbeatBean.setClientId(Heartbeat.deviceId);
        Gson gson = new Gson();
        String json = gson.toJson(heartbeatBean);
        RequestBody body = RequestBody.create(okhttp3.MediaType.parse("application/json;charset=utf-8"), json);
        addSubscription(apiStores.heart(body), new ApiCallback<HttpResult<String>>() {
            @Override
            public void onSuccess(HttpResult<String> model) {
                Log.d(TAG, "heartonSuccess: " + model);
            }

            @Override
            public void onFailure(String msg) {
                Log.d(TAG, "heartononFailure: " + msg);
            }

            @Override
            public void onFinish() {

            }
        });
    }


    /**
     * 检测心跳数据以及开始心跳
     */
    private void checkHeartData() {
        //系统管理不为空
        Heartbeat.managerId = (String) SharedPreferencesUtils.getParam(Name.SYSTEM_ID, "");
        if (Heartbeat.managerId != null && !TextUtils.isEmpty(Heartbeat.managerId)) {
            Log.e(TAG, "checkHeartData: 开始心跳2");
            startHeartbeat();
            LogUtil.i(TAG + "系统管理id为" + Heartbeat.managerId);
        } else {
            LogUtil.i(TAG + "系统管理id为空");
        }
    }

    /**
     * 停止心跳
     */
    private void stopHeartbeat() {
        if (timerHeartbeat != null) {
            taskHeartbeat.cancel();
            timerHeartbeat.cancel();
            timerHeartbeat = null;
        }
    }
    //------------------------------------------------------------------------心跳 end---------------------------------

    //——-----------------------------------------------------------------------请求 start------------------------------
    @Subscribe(threadMode = ThreadMode.MAIN)
    public void event(ApiMessageEvent messageEvent) {
        switch (messageEvent.getName()) {
            case "statusType1":
                //同步数据
                //showSyncDialog();
                break;
            case "DOWNKOADADCID":
                //上传设备id,返回该id的的广告资源
                Log.d(TAG, "event: DOWNKOADADCID");
                downAdvertising((String) messageEvent.getData());
                break;
            case "startClean":
                Log.d(TAG, "onReceive:闹钟响了26 " + messageEvent.getData());
                //开始清洗。全蹲位。
                /**
                 * 1.首先检查是否过期了，是否有次数
                 */
                isCleaned();
                break;
            case "updataParamSet":
                if (!PreventSpeedClickUtil.isFastClick()) {
                    return;
                }
                isRegularCleaning = false;
                startSet(messageEvent.getData());
                break;
            case "updataParamRst":
                if (!PreventSpeedClickUtil.isFastClick()) {
                    return;
                }
                isRegularCleaning = false;
                startRst(messageEvent.getData());
                break;
            case "updataParamWrite":
                if (!PreventSpeedClickUtil.isFastClick()) {
                    return;
                }
                startWrite(messageEvent.getData());
            case "clientid":
                stopHeartbeat();
                startHeartbeat();
                Log.d(TAG, "GTevent clientid:" + messageEvent.getData());
                break;

            case "cleanPositionNum":
                if (!PreventSpeedClickUtil.isFastClick()) {
                    return;
                }
                //开始清洗 随机清洗，会给要清洗的蹲位是
                cleanPositionNum(messageEvent.getData());
                break;
            default:
                break;

        }
    }

    private void cleanPositionNum(Object data) {
        mThreadPoolMyservice.stopWriteD120();
        mThreadPoolMyservice.startWriteD120("D120", "000" + data);
    }

    private void startWrite(Object kindData) {
        String[] split = (String[]) kindData;
        String address = split[0];
        String data = split[1].trim();
        String text = ByteUtils.decimal2fitHex(Integer.valueOf(data));
        mThreadPoolMyservice.stopWrite();
        mThreadPoolMyservice.startWrite(address, HexUtils.hexStr2BinStr(text));
    }

    private void startRst(Object data) {
        mThreadPoolMyservice.stopRst();
        mThreadPoolMyservice.startRst((String) data);
    }

    private void startSet(Object data) {
        mThreadPoolMyservice.stopSet();
        mThreadPoolMyservice.startSet((String) data);
    }

    private void isCleaned() {
        addSubscription(apiStores.getBackgroundTime(), new ApiCallback<HttpResult<String>>() {
            @Override
            public void onSuccess(HttpResult<String> model) {
                try {
                    String timedata = model.getData();
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(timedata));
                    //第一次就会出现报错。
                    Long overdueDate = (Long) Hawk.get(Name.OVERDUE_DATE);//购买的到期的时间
                    Long timeInMillis = calendar.getTimeInMillis();//当前时间
                    String data = (String) Hawk.get(Name.REMAINING);
                    long remaining = Long.valueOf(data);
                    Log.d(TAG, "onSuccess: 时间过期remaining" + remaining);
                    //如果时间没过期，那么可以继续制作
                    if (overdueDate > timeInMillis) {
                        Log.d(TAG, "onSuccess: 没有过期");
                        //发送开始清洗的订单。
                        getCleanReport(0);
                        //如果还有次那么就开始购买。
                    } else if (remaining > 0) {
                        Log.d(TAG, "onSuccess: 时间过期，按次数计算");
                        Hawk.put(Name.REMAINING, String.valueOf(remaining - 1));
                        //发送开始清洗的订单。
                        getCleanReport(0);
                    } else {
                        Log.d(TAG, "onSuccess: 全部过期，全部不能清洗");
                    }
                } catch (Exception e) {
                }
            }

            @Override
            public void onFailure(String msg) {

            }

            @Override
            public void onFinish() {

            }
        });

    }

    private void getCleanReport(int i) {
        Map<String, String> params = new HashMap<>();
        params.put("clientId", Heartbeat.deviceId);
        params.put("type", i + "");
        params.put("water", 1 + "");
        params.put("electricity", 1 + "");
        addSubscription(apiStores.getCleanReport(params), new ApiCallback<HttpResult<String>>() {

            @Override
            public void onSuccess(HttpResult<String> model) {
                Log.d(TAG, "getCleanReportonSuccess: " + model);
                if ("success".equals(model.getData())) {
                    startClean();
                } else {
                }
            }

            @Override
            public void onFailure(String msg) {

            }

            @Override
            public void onFinish() {

            }
        });
    }

    private void startClean() {
        isRegularCleaning = true;
        mThreadPoolMyservice.startSetM17();
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void event(DownLoadMessageEvent messageEvent) {
        switch (messageEvent.getType()) {
            case success:
                //先下载B屏广告 再下载A屏广告 然后窗口消失
                //下载成功
                ToastUtil.showToast("下载成功");
                Log.e(TAG, "event: 下载成功" + messageEvent.getData() + "index=" + currentIndex + " size-1=" + (getAdBeansBackup.size() - 1) + "  size" + getAdBeansBackup.size());
                //只下载公司宣传视频
                if (messageEvent.getScreenType() == 0) {
                    if (currentIndex == corporationAdBeans.size() - 1) {
                        Log.e(TAG, "event: A屏下载完成");
                        //B屏广告下完
//                        if (syncDialog != null) {
//                            syncDialog.setAdState(R.string.sync_success);
////                            syncDialog.dismiss();
//                        }
//不同的 删除本地文件(旧广告)
                        for (int i = 0; i < allFileA.size(); i++) {
                            File file = allFileA.get(i);
                            if (file != null && file.exists()) {
                                Log.e(TAG, "onNext:删除的A屏广告 " + file.getName());
                                file.delete();

                            }
                        }
                        getAdRuleId("1");
                        Hawk.put("showAdA", getAdBeansA);
                        Log.d(TAG, "GTIntentService:getAdBeansA2 " + getAdBeansA);
                        //推送给购买页和制作页更新
                        EventBus.getDefault().post(new DownLoadMessageEvent(DownLoadMessageEvent.Type.downloadAll, "", -1));
                        return;
                    }


                } else if (messageEvent.getScreenType() == 1) {
                    //B屏最后一个下载完 保存数据
                    if (currentIndex == getAdBeansBackup.size() - 1) {
                        currentIndex = 0;
                        Hawk.put("showAd", getAdBeans);
                        //全部默认显示 添加数据
                        for (int i = 0; i < getAdBeans.size(); i++) {
                            GetAdBean getAdBean = getAdBeans.get(i);
                            if (getAdBean.getLocationType().equals("棉花糖宣传广告")) {
                                showSugar.put(i, getAdBean);
                            }
                            if (getAdBean.getLocationType().equals("外接广告")) {
                                showOut.put(i, getAdBean);
                            }
                        }
                        Log.d(TAG, "event: " + getAdBeans);
                        Hawk.put("show_sugar", showSugar);
                        Hawk.put("show_out", showOut);
                        Log.d(TAG, "synAdSuccess:保存完成广告数据4" + getAdBeans.size());
                        SharedPreferencesUtils.setParam(Name.SYSTEM_ID, Heartbeat.managerId);
                        SharedPreferencesUtils.setParam(Name.CONNECT_STATE, 2);
                        //不同的 删除本地文件(旧广告)
                        for (int i = 0; i < allFile.size(); i++) {
                            File file = allFile.get(i);
                            if (file != null && file.exists()) {
                                Log.e(TAG, "onNext:删除的B屏广告 " + file.getName());
                                file.delete();

                            }
                        }
                        //开始下载公司宣传视频
                        currentIndex = 0;
                        downLoadFile(currentIndex, "", corporationAdBeans);
                        getAdBeansBackup.clear();
                        return;
                    }

                }
                if (messageEvent.getScreenType() == 1) {
                    //开始下载B屏广告
                    Log.e(TAG, "event: 开始下载B屏广告");
                    currentIndex++;//下载成功一个
                    if (currentIndex < getAdBeansBackup.size()) {
                        downLoadFile(currentIndex, getAdBeansBackup.get(currentIndex).getAdType(), getAdBeansBackup);
                    }
                } else if (messageEvent.getScreenType() == 0) {
                    //开始下载A屏广告
                    Log.e(TAG, "event: 开始下载A屏广告");
                    currentIndex++;//下载成功一个
                    if (currentIndex < corporationAdBeans.size()) {
                        downLoadFile(currentIndex, corporationAdBeans.get(currentIndex).getAdType(), corporationAdBeans);
                    }
                }

                break;
            case failed:
                //下载失败
                ToastUtil.showToast("下载失败" + messageEvent.getData());
                Log.d(TAG, "event: 下载失败" + messageEvent.getData());
                String strCurTime = TimeUtil.getStrCurTime();
                Map<String, String> parms = new HashMap();
                parms.put("clientId", Heartbeat.deviceId);
                parms.put("pushUpdateTime", strCurTime);
                addSubscription(apiStores.pushTimeUpdate(parms), new ApiCallback<HttpResult<String>>() {
                    @Override
                    public void onSuccess(HttpResult<String> model) {
                        Log.e(TAG, "onNext: 上传失败成功 ");
                    }

                    @Override
                    public void onFailure(String msg) {

                    }

                    @Override
                    public void onFinish() {

                    }
                });
                break;
            default:
                break;

        }
    }
    //——-----------------------------------------------------------------------请求 end------------------------------

    //_------------------------------------------------------------------------广告 start---------------------------------
    //要显示的棉花糖广告<index,name>
    private Map<Integer, GetAdBean> showSugar;
    //要显示的外接广告<index,name>
    private Map<Integer, GetAdBean> showOut;
    //显示的数据
    private ArrayList<GetAdBean> getAdBeans;
    private ArrayList<GetAdBean> getAdBeansA;
    //用于下载
    private ArrayList<GetAdBean> getAdBeansBackup;
    //公司宣传广告
    private ArrayList<GetAdBean> corporationAdBeans;
    //当前下载的索引
    private static int currentIndex;
    //下载成功后要删除的文件
    private ArrayList<File> allFile;
    private ArrayList<File> allFileA;

    /**
     * 上传设备id,返回该id的的广告资源
     *
     * @param s 要播放的数据
     */
    private void downAdvertising(String s) {
        showSugar = Hawk.get("show_sugar", new HashMap<Integer, GetAdBean>());
        showOut = Hawk.get("show_out", new HashMap<Integer, GetAdBean>());
        getAdBeans = new ArrayList<>();
        getAdBeansA = new ArrayList<>();
        getAdBeansBackup = new ArrayList<>();
        Gson gson = new Gson();
        //广告实体
        getAdBeans = gson.fromJson(s, new TypeToken<List<GetAdBean>>() {
        }.getType());
        getAdBeansBackup.addAll(getAdBeans);
        //只有公司宣传广告
        corporationAdBeans = new ArrayList<>();
        List<GetAdBean> indexList = new ArrayList<>();
        for (int i = 0; i < getAdBeansBackup.size(); i++) {
            if (getAdBeansBackup.get(i).getScreenType() == 0) {
                corporationAdBeans.add(getAdBeansBackup.get(i));
                indexList.add(getAdBeansBackup.get(i));
            }
        }
        for (int i = 0; i < indexList.size(); i++) {
            getAdBeansBackup.remove(indexList.get(i));
            getAdBeans.remove(indexList.get(i));
        }
        getAdBeansA.addAll(corporationAdBeans);
        currentIndex = 0;
        //全部默认显示 添加数据
        for (int i = 0; i < getAdBeansBackup.size(); i++) {
            showSugar.put(i, getAdBeansBackup.get(i));
            showOut.put(i, getAdBeansBackup.get(i));
        }
//        Hawk.put("show_sugar", showSugar);
//        Hawk.put("show_out", showOut);

        getFilesDir();
        LogUtil.d(TAG, "initView: " + getFilesDir().getName());
        //本地的所有广告数据

        File externalFilesDir = BaseApplication.getContext().getExternalFilesDir("");
        if (externalFilesDir == null) {
            externalFilesDir.mkdir();
        }
        if (!externalFilesDir.exists()) {
            externalFilesDir.mkdirs();
        }
        //1 本地的所有广告数据
        File[] allFiles = FileUtil.getAllFiles(Environment.getExternalStorageDirectory().getPath() + "/rightvideoimg/", "");
        //A屏
        File[] allFilesA = FileUtil.getAllFiles(Environment.getExternalStorageDirectory().getPath() + "/leftvideoimg/", "");
        allFile = new ArrayList<>();
        allFileA = new ArrayList<>();
        List<File> files = Arrays.asList(allFilesA);
        allFileA.addAll(files);
        if (allFiles != null && allFiles.length >= 0) {

            for (int i = 0; i < allFiles.length; i++) {
                allFile.add(allFiles[i]);
            }
        }

        //备份一个list用于删除
        //另外一个用于显示
        //相同 不下载（删除一个实体） 不删除本地文件

        ArrayList<File> unDeleteFiles = new ArrayList<>();
        if (allFiles != null) {
            for (int i = 0; i < allFiles.length; i++) {
                File file = allFiles[i];
                String name = allFiles[i].getName();
                LogUtil.d(TAG, "onNext: 本地的所有文件：" + name);
                for (int j = 0; j < getAdBeansBackup.size(); j++) {
                    GetAdBean getAdBean = getAdBeansBackup.get(j);
                    String id = getAdBean.getId();
                    //前缀名
                    String caselsh = name.substring(0, name.lastIndexOf("."));
                    if (id.equals(caselsh)) {
                        //相同的删除url 不下载
                        LogUtil.e(TAG, "onNext不下载的文件: " + name);
//                                        timeDatas.remove(j);
                        getAdBeansBackup.remove(j);
                        //记住不删除的文件
                        unDeleteFiles.add(file);
                    }
                }

            }

            for (int i = 0; i < unDeleteFiles.size(); i++) {
                LogUtil.e(TAG, "onNext: unDeleteFiles name=" + unDeleteFiles.get(i).getName());
            }


            //只剩下删除的文件
            allFile.removeAll(unDeleteFiles);
        }

        ArrayList<File> unDeleteFilesA = new ArrayList<>();
        if (allFilesA != null) {
            for (int i = 0; i < allFilesA.length; i++) {
                File file = allFilesA[i];
                String name = allFilesA[i].getName();
                LogUtil.e(TAG, "onNext: A屏本地的所有文件：" + name);
                //时间，用于判断唯一
                //跟网络数据进行对比 如果id一样的不进行下载
                for (int j = 0; j < corporationAdBeans.size(); j++) {
                    GetAdBean getAdBean = corporationAdBeans.get(j);
                    String id = getAdBean.getId();
                    //前缀名
                    String caselsh = name.substring(0, name.lastIndexOf("."));
                    if (id.equals(caselsh)) {
                        //相同的删除url 不下载
                        LogUtil.e(TAG, "onNext不下载的文件: " + name);
                        corporationAdBeans.remove(j);
                        //记住不删除的文件
                        unDeleteFilesA.add(file);
                    }
                }
            }
            //只剩下删除的文件
            allFileA.removeAll(unDeleteFilesA);
        }

        //3 下载数据
        if (getAdBeansBackup.size() <= 0) {
            LogUtil.e(TAG, "onNext: 推送过来的B屏数据相同，不下载");
            Hawk.put("showAd", getAdBeans);
            //全部默认显示 添加数据
            for (int i = 0; i < getAdBeans.size(); i++) {
                showSugar.put(i, getAdBeans.get(i));
                showOut.put(i, getAdBeans.get(i));
            }
            Log.d(TAG, "event: " + getAdBeans);
            Hawk.put("show_sugar", showSugar);
            Hawk.put("show_out", showOut);
            EventBus.getDefault().post(new ApiMessageEvent("pushTimeRule", null));
            LogUtil.d(TAG, "synAdSuccess:保存完成广告数据3" + getAdBeans.size());
            SharedPreferencesUtils.setParam(Name.SYSTEM_ID, Heartbeat.managerId);
            SharedPreferencesUtils.setParam(Name.CONNECT_STATE, 2);
            //todo
//                            if (syncDialog != null) {
//                                syncDiaLogUtil.setAdState(R.string.sync_success);
//                                syncDiaLogUtil.dismiss();
//                            }
            if (corporationAdBeans.size() <= 0) {
                LogUtil.e(TAG, "onNext: 推送过来的A屏数据相同，不下载");
                Hawk.put("showAdA", getAdBeansA);
                Log.d(TAG, "GTIntentService:getAdBeansA 1" + getAdBeansA);
                //todo
//                if (syncDialog != null) {
//                    syncDiaLogUtil.setAdState(R.string.sync_success);
//                    getAdRuleId("1");
//                }
            } else {
                downLoadFile(0, "", corporationAdBeans);
            }
            return;
        }
        downLoadFile(currentIndex, "", getAdBeansBackup);
        //开始下载
        LogUtil.e(TAG, "synProductSuccess:同步广告管理成功 ");
        LogUtil.e(TAG, "synProductSuccess:全部同步成功 ");
    }

    private CompositeDisposable mDisposables;
    protected ApiStores apiStores = ApiClient.retrofit().create(ApiStores.class);

    protected void addSubscription(Observable observable, DisposableObserver observer) {
        if (mDisposables == null) {
            mDisposables = new CompositeDisposable();
        }
        observable
                .unsubscribeOn(Schedulers.io())
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(observer);
        mDisposables.add(observer);
    }

    /**
     * 保存广告id
     */
    private void getAdRuleId(String id) {
        Map<String, String> params = new HashMap<>();
        params.put("clientId", Heartbeat.deviceId);

        addSubscription(apiStores.synTimeRule(params), new ApiCallback<HttpResult<String>>() {
            @Override
            public void onSuccess(HttpResult<String> model) {
                saveAdRules(model.getData());
            }

            @Override
            public void onFailure(String msg) {

            }

            @Override
            public void onFinish() {

            }
        });


    }

    /**
     * 保存广告id
     */
    private void saveAdRules(String id) {
        LogUtil.d(TAG, "ad_id ->" + id);
        Long lid = Long.valueOf(id);
        Map<String, Long> params = new HashMap<>();
        params.put("id", lid);
        addSubscription(apiStores.getTimeRule(params), new ApiCallback<HttpResult<String>>() {

            @Override
            public void onSuccess(HttpResult<String> rule) {
                //广告数据
                ArrayList<GetAdBean> adBeans = Hawk.get("showAd", new ArrayList<GetAdBean>());
                Gson gson = new Gson();
                List<TimeRuleBean> list = gson.fromJson(rule.getData(), new TypeToken<List<TimeRuleBean>>() {
                }.getType());
                //每个id对应的时间数
                Map<String, String> adRulesMap = new HashMap<>();
                for (int i = 0; i < adBeans.size(); i++) {
                    GetAdBean getAdBean = adBeans.get(i);
                    StringBuilder sb = new StringBuilder();
                    for (int j = 0; j < list.size(); j++) {
                        //每个规则里对应的广告
                        List<String> ad = list.get(j).getAd();
                        for (int k = 0; k < ad.size(); k++) {
                            if (ad.get(k).equals(getAdBean.getId())) {
                                sb.append(list.get(j).getTime() + "、");
                            }
                        }
                    }
                    if (sb.length() > 0) {
                        sb.deleteCharAt(sb.length() - 1);
                    }

                    Log.e(TAG, "onNext: " + "ad_id=" + getAdBean.getId() + " rules=" + sb.toString());
                    adRulesMap.put(getAdBean.getId(), sb.toString());
                }
                //保存对应的id对应的广告规则
                Hawk.put("ad_rules_map", adRulesMap);
                EventBus.getDefault().post(new ApiMessageEvent("pushTimeRule", null));// todo
//                if (syncDialog != null) {
//                    syncDialog.setAdRuleState(R.string.sync_success);
//                    syncDialog.dismiss();
//                }
            }

            @Override
            public void onFailure(String msg) {

            }

            @Override
            public void onFinish() {

            }
        });
    }

    /**
     * 下载文件
     *
     * @param index 下载索引 第几个
     * @param type  没有
     * @param datas 要下载数据列表
     */
    private void downLoadFile(int index, String type, ArrayList<GetAdBean> datas) {
        //开始下载
        Intent downloadApkIntent = new Intent(getApplicationContext(), DownServer.class);
        Bundle bundle = new Bundle();
        if (datas.size() <= 0) {
            return;
        }
        GetAdBean getAdBean = datas.get(index);
        String url = getAdBean.getUrl();
        if (TextUtils.isEmpty(url)) {
            //todo
//            if (syncDialog != null) {
//                syncDialog.setAdState(R.string.synchroniz_fail);
//                syncDialog.dismiss();
//            }
            ToastUtil.showToast(UiUtil.getStringRes(R.string.synchroniz_fail));
            return;
        }
        String type1 = url.substring(url.lastIndexOf(".") + 1);
        bundle.putString("downloadUrl", url);
        bundle.putString("download_name", getAdBean.getName());
        String time = TimeUtil.getNoTime(getAdBean.getCreateDate());
        Log.d(TAG, "downLoadFile: time=" + time);
        bundle.putString("title", getAdBean.getId());
        Log.d(TAG, "downLoadFile: 开始下载" + getAdBean.getId());
        bundle.putString("downloadtype", type1);
        bundle.putInt("scrrentype", getAdBean.getScreenType());
        downloadApkIntent.putExtra("download", bundle);
        getApplicationContext().startService(downloadApkIntent);

    }

    //------------------------------------------------------------------------广告 end---------------------------------
    private boolean isAwait = true;

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void event(Message messageEvent) {
        switch (messageEvent.getType()) {
            case connected:
                break;
            case sendError:
                break;
            case ack:
                Log.d(TAG, "Mevent: " + messageEvent.getName());
                mThreadPoolMyservice.stopSet();
                mThreadPoolMyservice.stopRst();
                mThreadPoolMyservice.stopWrite();
                if (messageEvent.getName().equals("D120")) {
                    mThreadPoolMyservice.stopWriteD120();
                    mThreadPoolMyservice.stopSetM8();
                    mThreadPoolMyservice.startSetM8();

                } else if (messageEvent.getName().equals("DD120")) {
                    mThreadPoolMyservice.stopWriteDD120();
                    mThreadPoolMyservice.stopSetM8();
                    mThreadPoolMyservice.startSetM8();
                } else if (messageEvent.getName().equals("M17")) {
                    mThreadPoolMyservice.stopSetM17();
                    if (isRegularCleaning) {
                        isRegularCleaning = false;
                        mThreadPoolMyservice.stopSetM8();
                        mThreadPoolMyservice.startSetM8();
                    }
                } else if (messageEvent.getName().equals("M8")) {

                    mThreadPoolMyservice.stopSetM8();
                    Log.d(TAG, "addCleanTime120event: 開始清洗");
                } else if (messageEvent.getName().equals("MM3")) {
                    mThreadPoolMyservice.stopWriteMM3();
                    last = 0;
                    cleanCount = 0;
                    Log.d(TAG, "addCleanTime120event: 開始复位");
                } else if (messageEvent.getName().equals("MM10")) {
                    mThreadPoolMyservice.stopSetMM10();
                    mThreadPoolMyservice.stopRstRM10();
                    mThreadPoolMyservice.startRstRM10("M10");
                } else if (messageEvent.getName().equals("RM10")) {
                    //急停复位两次的原因是因为这里会执行两次。
                    mThreadPoolMyservice.stopRstRM10();
                    new Handler().postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            Log.d(TAG, "stopSetMMM3run: ");
                            if (mThreadPoolMyservice != null) {
                                mThreadPoolMyservice.stopSetMMM3();
                                mThreadPoolMyservice.startSetMMM3("M3");
                                Log.d(TAG, "isClean: 開始清洗3");
                            }
                        }
                    }, 2000);
                } else if (messageEvent.getName().equals("MMM3")) {
                    Log.d(TAG, "stopSetMMM3runevent: ");
                    mThreadPoolMyservice.stopSetMMM3();
                    last = 0;
                    cleanCount = 0;
                }
                mPoolAdvanceParameter.stopAll();
                mPoolAdvanceParameter.startALLRead();
                break;
            case nak:
                break;
            case disconnected:
                ToastUtil.showToast(messageEvent.getContent().toString());
                break;
            case response:
                ResponseFrame responseFrame = (ResponseFrame) messageEvent.getContent();
                String name = messageEvent.getName();
                if (responseFrame.isValidSum()) {
                    //通过校验
                    //1 获取本地存储的报警记录
                    //2 将本地的报警记录进行对比
                    //3 若没有的进行添加以及上传 没有的不管他
                    //4 最好走完将他覆盖
                    if (name.equals("M600")) {
                        try {
                            String result = AsciiUtils.asciiByteArray2HexStr(responseFrame.getData());
                            List<String> strList = HexadecimalUtil.getStrList(result, 4);
                            if (result.length() != 16) {
                                return;
                            }
                            StringBuilder sb = new StringBuilder();
                            for (int i = 0, len = strList.size(); i < len; i++) {
                                String list = strList.get(i);
                                String s1 = HexadecimalUtil.hexStringToByte(list);
                                String s2 = HexadecimalUtil.flipString(s1, 8);
                                sb.append(s2);
                            }
                            String s1 = sb.toString();
                            List<String> lis = Arrays.asList(s1.split(""));
                            ArrayList<String> list = new ArrayList(lis);
                            list.remove(0);
                            showErrorDialog(list);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }/* else if (name.equals("X12")) {
                        String results = HexadecimalUtil.hexStringToByte(AsciiUtils.asciiByteArray2HexStr(responseFrame.getData()));
                        String s1 = HexadecimalUtil.flipString(results, 6).substring(0, TOTAL_SUM);//6个厕所蹲位
                        List<String> lis = Arrays.asList(s1.split(""));//第0位会是空字符串
                        ArrayList<String> result = new ArrayList(lis);//
                        result.remove(0);
                        String s = Arrays.toString(result.toArray());
                        Log.d(TAG, "X12event: "+result.size()+";s:"+s);
                        //  Log.d(TAG, "result event: " + result.get(0) + result.get(1));

                        //todo 是否监听
                        //监控1号厕所
                        monitoring(result.get(0), 1);
                        //监控2号厕所
                        monitoring(result.get(1), 2);
                        //监控3号厕所
                        monitoring(result.get(2), 3);
                        //监控4号厕所
                        monitoring(result.get(3), 4);
                        //监控5号厕所
                        monitoring(result.get(4), 5);
                        //监控6号厕所
                        monitoring(result.get(5), 6);
                    }*/else if(name.equals("X12")){
                        String result = AsciiUtils.asciiByteArray2HexStr(responseFrame.getData());
                        List<String> strList = HexadecimalUtil.getStrList(result, 4);
                        StringBuilder sb = new StringBuilder();
                        for (int i = 0, len = strList.size(); i < len; i++) {
                            String str = strList.get(i);
                            //2进制
                            String s3 = HexadecimalUtil.hexStringToByte(str);
                            //2进制翻转
                            String s2 = HexadecimalUtil.flipString(s3, 8);
                            sb.append(s2);
                        }
                        List<String> list1 = Arrays.asList(sb.toString().split(""));
                        ArrayList<String> list2 = new ArrayList(list1);
                        list2.remove(0);

                        String s = Arrays.toString(list2.toArray());
                        Log.d(TAG, "X12event1: "+s);


                        //监控1号厕所
                        monitoring(list2.get(2), 1,list2.get(8));
                        //监控2号厕所
                        monitoring(list2.get(3), 2,list2.get(9));
                        //监控3号厕所
                        monitoring(list2.get(4), 3,list2.get(10));
                        //监控4号厕所
                        monitoring(list2.get(5), 4,"0"/*list2.get(11)*/);
                        //监控5号厕所
                        monitoring(list2.get(6), 5,"0"/*list2.get(12)*/);
                        //监控6号厕所
                        monitoring(list2.get(7), 6,"0"/*list2.get(13)*/);

                    } else if (name.equals("D2")) {
                        String data = String.valueOf(HexadecimalUtil.hex2dec(HexadecimalUtil.flipString(AsciiUtils.asciiByteArray2HexStr(responseFrame.getData())).get(0)));
                        // Log.d(TAG, "addCleanTimeD2event: " + data);
                        switch (data) {
                            case "0"://复位中
                                synchronized (sCleaningLocationList) {
                                    if (!isAwait) {
                                        isAwait = true;
                                    }
                                    if (!isToiletClean) {
                                        isToiletClean = true;
                                    }
                                }
                                break;
                            case "1": //第一次待机中,开机完毕
                                //复位了，那么就需要判断是否还需要清洗
                                //todo 这里的代码会一直执行，如果不等于0，那么这里会一直执行。
                                synchronized (sCleaningLocationList) {//多线程操作需要加上同步锁
                                    if (isAwait) {
                                        isAwait = false;
                                        new Handler().postDelayed(new Runnable() {
                                            @Override
                                            public void run() {
                                                synchronized (sCleaningLocationList) {
                                                    while (sCleaningLocationList.size() > 0) {
                                                        Integer first = sCleaningLocationList.getFirst();
                                                        HoleInformation holeInformation = sHoleInformationList.get(first - 1);
                                                        if (holeInformation.getState() != 0 && holeInformation.getState() != 2 && "1".equals(holeInformation.getBodySensor())) {
                                                            //被移除了
                                                            Log.d(TAG, "被移除了1: " + first);
                                                            sCleaningLocationList.removeFirst();
                                                        } else if (holeInformation.getState() != 0 && holeInformation.getState() != 2) {
                                                            Log.d(TAG, "被移除了3: " + first);
                                                            sCleaningLocationList.removeFirst();
                                                        }else {
                                                            cleanPositionNumX20(first);
                                                            Log.d(TAG, "isClean開始清洗add: " + first);
                                                            cleanCount++;
                                                            return;
                                                        }
                                                    }
                                                }
                                            }
                                        },6000);
                                    }
                                }
                                break;
                            case "5":
                                //todo 清洗中，需要各个10秒再开始
                                synchronized (sCleaningLocationList) {
                                    //todo 必须sCleaningLocationList和sHoleInformationList不为空。才能执行里面的代码。
                                    if (sCleaningLocationList.size()>0 &&sHoleInformationList.size()>0) {
                                        if (isToiletClean) {
                                            isCleanOK = true;
                                            //多线程，我们需要控制只执行一次？
                                            Integer first = sCleaningLocationList.getFirst();//sCleaningLocationList取出来的数据从1开始。
                                            HoleInformation holeInformation = sHoleInformationList.get(first - 1);
                                            Log.d(TAG, "isClean開始清洗add急停: " + holeInformation.getState());
                                            if (holeInformation.getState() != 2) {
                                                //如果在清洗中，那么就急停
                                                isToiletClean = false;
                                                mThreadPoolMyservice.stopSetMM10();
                                                mThreadPoolMyservice.startSetMM10("M10");
                                                Log.d(TAG, "sCleaningLocationList: 紧急停止");
                                            }
                                        }
                                    }


                                }
                                break;
                            case "7"://清洗完毕----清洗過程中還是清洗完畢
                                synchronized (sCleaningLocationList) {//多线程操作需要加上同步锁
                                    if (isCleanOK) {
                                        isCleanOK = false;

                                        //准备清洗下一个厕所，如果为10次，那么就需要复位。
                                        if (cleanCount >= 10) {
                                            cleanCount = 0;
                                            mThreadPoolMyservice.stopWriteMM3();
                                            mThreadPoolMyservice.startWriteMM3("M3");
                                            return;
                                        }
                                        new Handler().postDelayed(new Runnable() {
                                            @Override
                                            public void run() {
                                                synchronized (sCleaningLocationList) {//移除这里出现了问题。
                                                    if (sCleaningLocationList.size() != 0) {
                                                        Integer first = null;
                                                        //上一个清洗的厕所123
                                                        Log.d(TAG, "被移除了2: " + first);
                                                        last = sCleaningLocationList.removeFirst();
                                                        //如果集合大于0，那么我就取出第一个位置，进行判断是否正在上厕所，如果是，那么就需要移除，继续下一个，
                                                        while (sCleaningLocationList.size() > 0) {
                                                            first = sCleaningLocationList.getFirst();//现在要清洗的厕所。456
//                                                if (sHoleInformationList.get(first-1).getState()==3) {
                                                            StringBuilder sb = new StringBuilder();
                                                            for (Integer integer1 : sCleaningLocationList) {
                                                                sb.append(integer1);
                                                            }

                                                            HoleInformation holeInformation = sHoleInformationList.get(first - 1);
                                                            if (holeInformation.getState() != 0 && holeInformation.getState() != 2 && "1".equals(holeInformation.getBodySensor())) {
                                                                Log.d(TAG, "被移除了3: " + first);
                                                                sCleaningLocationList.removeFirst();
                                                                //如果没有人在里面，但是人体传感器检测到有人，那么移除
                                                                //如果有人在里面，即使人体创奇检测到有人或者没人，都移除。
                                                            } else if (holeInformation.getState() != 0 && holeInformation.getState() != 2) {
                                                                Log.d(TAG, "被移除了3: " + first);
                                                                sCleaningLocationList.removeFirst();
                                                            } else  {
                                                                if ((last == 1 || last == 2 || last == 3) && (first == 4 || first == 5 || first == 6)) {
                                                                    mThreadPoolMyservice.stopWriteMM3();
                                                                    mThreadPoolMyservice.startWriteMM3("M3");
                                                                    Log.d(TAG, "isClean: 开始复位4");
                                                                    return;
                                                                }
                                                                cleanPositionNumX20(first);
                                                                Log.d(TAG, "isClean開始清洗add: " + first);
                                                                cleanCount++;
                                                                return;
                                                            }
                                                        }

                                                    }
                                                }
                                            }
                                        },6000);
                                    }
                                }
                                break;
                        }

                    } else {
                        //通过校验
                        Log.d(TAG, "event: " + name);
                        String result = AsciiUtils.asciiByteArray2HexStr(responseFrame.getData());
                        ArrayList<String> results = HexadecimalUtil.flipString(result);
                        setAdvanced(name, results, mPoolAdvanceParameter);
                    }

                    break;
                }
        }
    }


    private void monitoring(String number, int position, String isSomeone1) {
        //   Log.d(TAG, "monitoring: " + number + position);
        synchronized (sCleaningLocationList) {//多线程操作需要加上同步锁
            if ("0".equals(number)) {//
                //是否加入清洗
                isClean(position,isSomeone1);
            } else if ("1".equals(number)) {
                //记录
                addCleanTime(position,isSomeone1);
            }
            Log.d(TAG, "isClean開始清洗add信号: 厕所"+position+",信号为：" + number);

        }
//        }
    }

    private void addCleanTime(int number, String isSomeone) {
        /**
         * 1：
         *     将标志位变为0.，如果我为0 就不执行了。避免时间一直更新。
         *     存储当前的时间，到指定的集合中【标志位，0time】
         */
//        Log.d(TAG, "addCleanTime: 为零isCleanaddCleanTime1");
        HoleInformation holeInformation = sHoleInformationList.get(number - 1);
        holeInformation.setBodySensor(isSomeone);
//        Log.d(TAG, "为零isCleanaddCleanTime11: " + sHoleInformationList.size() + holeInformation.getState());
//        Log.d(TAG, "为零isCleanaddCleanTime12: " + (number - 1));
        if (holeInformation.getState() != 1 && holeInformation.getState() != 3) {
            holeInformation.setState(1);//上厕所
            holeInformation.setTimeDuration(System.currentTimeMillis());//存储他上厕所的时间
        } else if (holeInformation.getState() == 1) {
            if (System.currentTimeMillis() - holeInformation.getTimeDuration() > 10000) {
                //將其標誌位上過廁所。
                holeInformation.setState(3);
                // Log.d(TAG, "addCleanTime: 上厕所超过20秒");
            } else {
                //  Log.d(TAG, "addCleanTime: 上厕所没超过20秒");
            }
        }
    }

    //记录清洗次数
    private volatile int cleanCount = 0;

    private void isClean(int number, String isSomeone) {

        //为什么在60秒后复位会出现两次复位呢？因为复位过程中有的厕所写入清洗了。所以就会出现问题。【问题不大，就是多复位一次。不影响。】
        /**
         * 0：
         *    如果标志位为0，表示上一次是被上过厕所，根据存储的时间和现在的时间进行对比：
         *         超过20秒：【如果为1不判断是否超过20秒】
         *             表示没人在上厕所，那么判断是否上次为0，如果为0，那么就存储到集合里面开始清洗。
         *                                                    如果为1，那么就什么都不做。
         *         没超过20秒：
         *             表示重新厕所了。
         *         设置一个变量存储为1，表示一直为1，没人。
         *     如果标志位为1，表示一直没上厕所
         *         什么都不做。
         */
        HoleInformation holeInformation = sHoleInformationList.get(number - 1);
        holeInformation.setBodySensor(isSomeone);
        int state = holeInformation.getState();
        if (state == 3) {
            holeInformation.setState(4);
            holeInformation.setOutTimeDuration(System.currentTimeMillis());//存储他上厕所的时间
        } else if (holeInformation.getState() == 4) {
            if (System.currentTimeMillis() - holeInformation.getOutTimeDuration() > 10000) {
                //上廁所超過20秒，那麼將狀態改為上廁所狀態。
                Log.d(TAG, "为零isClean: " + sCleaningLocationList.size());
                if (sCleaningLocationList.size() == 0) {
                    //如果不包含，那么就走这里
                    sCleaningLocationList.addLast(number);
                    Log.d(TAG, "为零isCleannumber4: " + number);
                    if (last != null) {
                        if ((last == 1 || last == 2 || last == 3) && (number == 4 || number == 5 || number == 6)) {
                            Log.d(TAG, "isClean: 開始复位1");
                            mThreadPoolMyservice.stopWriteMM3();
                            mThreadPoolMyservice.startWriteMM3("M3");
                            return;
                        }
                    }
                    cleanCount++;//
                    if ("1".equals(holeInformation.getBodySensor())) {
                        sCleaningLocationList.removeFirst();
                        Log.d(TAG, "holeInformation被移除了。: ");
                    }else{
                        cleanPositionNumX20(number);
                    }
                    Log.d(TAG, "isClean開始清洗add: " + number);
                    Log.d(TAG, "addCleanTimeisClean: " + "開始清洗");
                } else {
                    //那么我们就需要判断是否在清洗，通过一个标志位。清洗中，清洗完毕
                    int index = 100;
                    for (int i = 0; i < sCleaningLocationList.size(); i++) {
                        Log.d(TAG, "isClean111: " + (sCleaningLocationList.get(i) == (number)) + "" + sCleaningLocationList.get(i) + (number));
                        if (sCleaningLocationList.get(i) == (number)) {
                            index = i;
                            Log.d(TAG, "为零isCleannumber2: " + index);
                            break;
                        }
                    }
                    if (index != 100) {
                        Log.d(TAG, "被移除了4: " + index);
                        sCleaningLocationList.remove(index);//如果移除后等于0，集合大小等于0，那么开始清洗。
                        sCleaningLocationList.addLast(number);
                    } else {
                        sCleaningLocationList.addLast(number);
                    }
                    Log.d(TAG, "addCleanTime: 清洗集合個數大於0：");
                }
                holeInformation.setState(2);//改为2或者0都可以。
            } else {
                Log.d(TAG, "addCleanTime进厕所没超过20秒 ");
            }
        } else if (holeInformation.getState() == 1) {
            if (holeInformation.getState() != 2) {
                holeInformation.setState(2);
                Log.d(TAG, "为零isCleanaddCleanTime1 addCleanTime重置狀態");
            }
        }
    }

    private void cleanPositionNumX20(int data) {
        mThreadPoolMyservice.stopWriteDD120();
        mThreadPoolMyservice.startWriteDD120("D120", "000" + data);
    }

    private boolean isOpenReadWarring = true;
    private List<String> errorListM600;
    //前进阻碍
    private boolean isadvance;
    //下降阻碍
    private boolean isdecline;

    private void showErrorDialog(ArrayList<String> list) {
        String json = (String) SharedPreferencesUtils.getParam("error_list_M600", "");
        Gson gson = new Gson();
        errorListM600 = gson.fromJson(json, new TypeToken<List<String>>() {
        }.getType());
        if (errorListM600 == null) {
            errorListM600 = new ArrayList<>();
        }

        ArrayList<String> errorList1 = new ArrayList<>();
        if (list.get(0).equals("1")) {
            //M600
            if (!isadvance) {
                showDialog(R.string.warring_forward_obstaclesM600);
                setError(0, UiUtil.getStringRes(R.string.warring_forward_obstaclesM600), errorList1, errorListM600, true);
                isadvance = true;
            }
        } else if (list.get(0).equals("0")) {
            //警告解除 弹窗消失
            if (isadvance) {
                if (warringDialog != null) {
                    warringDialog.dismiss();
                    isadvance = false;
                    //延迟三秒再设置。
                    new Handler().postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            SharedPreferencesUtils.setParam("isOpenReadWarring", true);
                        }
                    }, 3000);
                }
            }
        }
        if (list.get(1).equals("1")) {
            if (!isdecline) {
                //M601
                showDialog(R.string.warring_falling_blockM601);
                setError(1, UiUtil.getStringRes(R.string.warring_falling_blockM601), errorList1, errorListM600, true);
                isdecline = true;
            }
        } else if (list.get(1).equals("0")) {
            //警告解除 弹窗消失
            if (isdecline) {
                if (warringDialog != null) {
                    warringDialog.dismiss();
                    isdecline = false;
                    //延迟三秒再设置。
                    new Handler().postDelayed(new Runnable() {
                        @Override
                        public void run() {
                            SharedPreferencesUtils.setParam("isOpenReadWarring", true);
                        }
                    }, 3000);

                }
            }
        }

        if (list.get(2).equals("1")) {
            //M602
            boolean isOpenReadWarring = (boolean) SharedPreferencesUtils.getParam("isOpenReadWarring", true);
            if (isOpenReadWarring) {
                showDialog(R.string.warring_x_axis_stepM602);
                setError(2, UiUtil.getStringRes(R.string.warring_x_axis_stepM602), errorList1, errorListM600, false);
            }
        }
        if (list.get(3).equals("1")) {
            //M603
            boolean isOpenReadWarring = (boolean) SharedPreferencesUtils.getParam("isOpenReadWarring", true);
            if (isOpenReadWarring) {
                showDialog(R.string.warring_y_axis_stepM603);
                setError(3, UiUtil.getStringRes(R.string.warring_y_axis_stepM603), errorList1, errorListM600, false);
            }
        }

        String s = gson.toJson(errorList1);
        SharedPreferencesUtils.setParam("error_list_M600", s);
    }

    private WarringDialog warringDialog;

    private void showDialog(int strId) {
        SharedPreferencesUtils.setParam("isOpenReadWarring", false);
        isOpenReadWarring = (boolean) SharedPreferencesUtils.getParam("isOpenReadWarring", true);
        if (warringDialog == null) {
            warringDialog = new WarringDialog(this);
        }
        warringDialog.setTvContent(strId);
        warringDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
        if (!warringDialog.isShowing()) {
            warringDialog.show();
        }


    }

    private WarringBeanDao warringBeanDao;

    /**
     * @param key
     * @param reason
     * @param errorList1 新建的
     * @param errorListM 存在本地的
     */
    public void setError(int key, String reason, ArrayList<String> errorList1, List<String> errorListM, boolean isM660) {
        long date = System.currentTimeMillis();
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date curDate = new Date(date);
        String time = formatter.format(curDate);
        ErrorBean errorBean = new ErrorBean();
        errorBean.setTime(time);
        errorBean.setThingError(reason);
        errorBean.setRemark("");

        AddAlarmRecordBean addAlarmRecordBean = new AddAlarmRecordBean(reason, Heartbeat.deviceId, time, "");
        WarringBean warringBean = new WarringBean();
        warringBean.setTime(date);
        warringBean.setThingError(reason);
        warringBeanDao.insert(warringBean);
        errorList1.add(key + "");
        if (errorListM == null) {
            //只用于上传M666
            Log.d(TAG + "22", "setError: 上传");
            Gson gson = new Gson();
            String json = gson.toJson(addAlarmRecordBean);
            RequestBody body = RequestBody.create(okhttp3.MediaType.parse("application/json; charset=utf-8"), json);
//            //上传到服务器
            addSubscription(apiStores.addAlarmRecord(body), new ApiCallback<HttpResult<String>>() {
                @Override
                public void onSuccess(HttpResult<String> model) {
                    if (model.getData() != null) {
                        Log.d(TAG, "onSuccess: " + model);
                        Log.d("AddAlarmRecordApi", "onNext: " + model.getData());
                    }
                }

                @Override
                public void onFailure(String msg) {

                }

                @Override
                public void onFinish() {

                }
            });
            return;
        }
        if (!errorListM.contains(key + "")) {
            //不包含，上传
            Log.d(TAG + "22", "setError: 上传");

            Gson gson = new Gson();
            String json = gson.toJson(addAlarmRecordBean);

            RequestBody body = RequestBody.create(okhttp3.MediaType.parse("application/json; charset=utf-8"), json);

            //上传到服务器
            addSubscription(apiStores.addAlarmRecord(body), new ApiCallback<HttpResult<String>>() {
                @Override
                public void onSuccess(HttpResult<String> model) {
                    Log.d(TAG, "onSuccess: " + model);
                    if (model.getData() != null) {
                        Log.d("AddAlarmRecordApi", "onNext: " + model.getData());
                    }
                }

                @Override
                public void onFailure(String msg) {

                }

                @Override
                public void onFinish() {

                }
            });
        } else {
            Log.d(TAG + "22", "setError: 不上传");
        }
    }

    //-----------------------------------------------------------------------报警 end---------------------------------
    public void setAdvanced(String name, ArrayList<String> results, ThreadPoolAdvanceParameter threadGetParameter1) {
        if (name.equals("D418")) {
            if (!threadGetParameter1.isReceive2()) {
                threadGetParameter1.setReceive2(true);
                threadGetParameter1.stopReadD418();
                threadGetParameter1.getValues()[6] = String.valueOf(get177Data(HexadecimalUtil.hex2dec(results.get(0))));
                threadGetParameter1.getValues()[7] = String.valueOf(get177Data(HexadecimalUtil.hex2dec(results.get(1))));
                threadGetParameter1.getValues()[0] = String.valueOf(get177Data(HexadecimalUtil.hex2dec(results.get(2))));
                threadGetParameter1.getValues()[1] = String.valueOf(get177Data(HexadecimalUtil.hex2dec(results.get(3))));
                threadGetParameter1.getValues()[2] = String.valueOf(get177Data(HexadecimalUtil.hex2dec(results.get(4))));
                threadGetParameter1.getValues()[3] = String.valueOf(get177Data(HexadecimalUtil.hex2dec(results.get(5))));
                threadGetParameter1.getValues()[4] = String.valueOf(get177Data(HexadecimalUtil.hex2dec(results.get(6))));
                threadGetParameter1.getValues()[5] = String.valueOf(get177Data(HexadecimalUtil.hex2dec(results.get(7))));

                Log.d(TAG, "D418setAdvanced: " + results.size());
            }
        } else if (name.equals("D426")) {
            if (!threadGetParameter1.isReceive1()) {
                threadGetParameter1.setReceive1(true);
                threadGetParameter1.stopReadD426();
                threadGetParameter1.getValues()[7] = String.valueOf(HexadecimalUtil.hex2dec(results.get(0)));
                threadGetParameter1.getValues()[8] = String.valueOf(HexadecimalUtil.hex2dec(results.get(1)));
                threadGetParameter1.getValues()[9] = String.valueOf(HexadecimalUtil.hex2dec(results.get(2)));
                threadGetParameter1.getValues()[10] = String.valueOf(HexadecimalUtil.hex2dec(results.get(3)));
                threadGetParameter1.getValues()[11] = String.valueOf(HexadecimalUtil.hex2dec(results.get(4)));
                threadGetParameter1.getValues()[12] = String.valueOf(HexadecimalUtil.hex2dec(results.get(5)));
                threadGetParameter1.getValues()[13] = String.valueOf(HexadecimalUtil.hex2dec(results.get(6)));
                threadGetParameter1.getValues()[14] = String.valueOf(HexadecimalUtil.hex2dec(results.get(7)));
                threadGetParameter1.getValues()[15] = String.valueOf(HexadecimalUtil.hex2dec(results.get(8)));
                Log.d(TAG, "D426setAdvanced: " + results.size());
            }
        }
    }

    private String get177Data(long l) {
        return String.valueOf(Math.round((l / Global.num) * 10));
    }

    public void getDataSuccess() {
        String[] values = mPoolAdvanceParameter.getValues();
        ArrayList<ParameterBean> parameterBeans = new ArrayList<>();
        String[] paraAddress = {
                "D426", "D427", "D428", "D429",
                "D430", "D431"};
        for (int i = 0; i < values.length; i++) {
            parameterBeans.add(new ParameterBean(paraAddress[i], values[i]));
        }
        updateAdvanced(parameterBeans);
    }

    public void updateAdvanced(ArrayList<ParameterBean> parameterBeans) {
        String url = "/api/app_equipment/index/updateParam/1/" + Heartbeat.deviceId + ".htm";
        Gson gson = new Gson();
        String json = gson.toJson(parameterBeans);
        RequestBody body = RequestBody.create(okhttp3.MediaType.parse("application/json; charset=utf-8"), json);
        addSubscription(apiStores.updateParamApi(url, body), new ApiCallback<HttpResult<String>>() {
            @Override
            public void onSuccess(HttpResult<String> model) {
                Log.d(TAG, "onSuccess: " + model);
            }

            @Override
            public void onFailure(String msg) {
            }

            @Override
            public void onFinish() {
            }
        });
    }

    private Timer timerGetTime;
    private TimerTask timerTaskGetTime;
    private int resetTime = 60;
    private boolean isReset = false;

    private void startRefreshime() {
        timerGetTime = new Timer();
        timerTaskGetTime = new TimerTask() {
            @Override
            public void run() {
                synchronized (sCleaningLocationList) {//多线程操作需要加上同步锁
                    if (sCleaningLocationList.size() <= 0) {
                        //如果复位了，清洗一个后，移除了。那么就为小于等于0，那么就会有一个没有复位。
                        if (isReset) {//会导致不复位。
                            if (resetTime <= 0) {
                                //不能一直复位，因为如果一直厕所呢？所以我们复位后就需要停止继续执行这里面的内容，等到大于0的时候再进行里面的内容
                                //在集合移除最后一个的时候我们来一个标志位来解决这个问题。
                                isReset = false;
                                resetTime = 60;
                                //等于0 的时候我们就需要进行复位
                                mThreadPoolMyservice.stopWriteMM3();
                                mThreadPoolMyservice.startWriteMM3("M3");
                                Log.d(TAG, "isClean: 開始清洗2");
                                return;
                            }
                            resetTime--;
                        }
                    } else {
                        //有清洗的时候就要走这里面。
                        resetTime = 60;
                        isReset = true;
                    }
                }
            }
        };
        timerGetTime.schedule(timerTaskGetTime, 0, 1000);
    }

    private void stopRefreshTime() {
        TimerUtil.stopTimerAndTimerTask(timerGetTime, timerTaskGetTime);
    }
}

//todo 重启触摸屏后回出现问题：有的已经在清洗了，但是安卓屏幕不认。所以就会开始清洗。
/**
 * 如何优化呢？
 * 1.就需要
 */
