package com.hh.hhomc.services;

import android.app.IntentService;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;

import androidx.annotation.Nullable;
import androidx.core.content.FileProvider;

import com.blankj.utilcode.util.FileUtils;
import com.common.lib_base.CommonApplication;
import com.common.lib_base.bean.StringResultBean;
import com.common.lib_base.common.async.ThreadPoolManager;
import com.common.lib_base.common.http.rx.RxHttpResponseCompat;
import com.common.lib_base.common.local.AppLocalConfigHandler;
import com.common.lib_base.utils.LogUtils;
import com.common.lib_base.utils.StringUtils;
import com.common.lib_base.utils.log.AppLogUtils;
import com.common.lib_base.utils.ui.ToastUtils;
import com.common.lib_base.utils.ui.UIUtils;
import com.common.pos.api.util.ShellUtils;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.hh.hhomc.AppMessageBean;
import com.hh.hhomc.BuildConfig;
import com.hh.hhomc.IAidlCallBack;
import com.hh.hhomc.IAidlInterface;
import com.hh.hhomc.MainActivity;
import com.hh.hhomc.MyApplication;
import com.hh.hhomc.R;
import com.hh.hhomc.bean.AppInfoBean;
import com.hh.hhomc.bean.DeviceStatusBean;
import com.hh.hhomc.bean.LogListSendBean;
import com.hh.hhomc.bean.ServerActionAppUpdateRequestBean;
import com.hh.hhomc.bean.ServerActionAppUpdateResultBean;
import com.hh.hhomc.bean.ServerActionBean;
import com.hh.hhomc.common.ConfigData;
import com.hh.hhomc.common.Constants;
import com.hh.hhomc.common.IAppLocalConfig;
import com.hh.hhomc.deviceui.BaseDeviceUI;
import com.hh.hhomc.deviceui.IDeviceUI;
import com.hh.hhomc.deviceui.SilenceInstallSuccessListener;
import com.hh.hhomc.http.ApiService;
import com.hh.hhomc.http.HttpManager;
import com.hh.hhomc.utils.AppUtils;
import com.hh.hhomc.utils.ChunkedUploadExample;
import com.hh.hhomc.utils.DeviceUtils;
import com.hh.hhomc.utils.K8DeviceUtils;
import com.hh.hhomc.utils.ZipUtils;
import com.hjq.permissions.OnPermissionCallback;
import com.hjq.permissions.Permission;
import com.hjq.permissions.XXPermissions;
import com.yaoxiaowen.download.DownloadHelper;
import com.yaoxiaowen.download.FileInfo;

import org.java_websocket.client.WebSocketClient;
import org.java_websocket.handshake.ServerHandshake;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Type;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.channels.NotYetConnectedException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import io.reactivex.Observable;
import io.reactivex.Observer;
import io.reactivex.disposables.Disposable;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;

import static com.hh.hhomc.common.Constants.SERVER_ACTION.CANCEL_UPGRADE;
import static com.hh.hhomc.common.Constants.SERVER_ACTION.CLOSE_APP;
import static com.hh.hhomc.common.Constants.SERVER_ACTION.DOWNLOAD_LOG;
import static com.hh.hhomc.common.Constants.SERVER_ACTION.FETCH_LOG;
import static com.hh.hhomc.common.Constants.SERVER_ACTION.INSTALL_UPGRADE;
import static com.hh.hhomc.common.Constants.SERVER_ACTION.QUERY_DEVICE_BIZ_DATA;
import static com.hh.hhomc.common.Constants.SERVER_ACTION.REBOOT;
import static com.hh.hhomc.common.Constants.SERVER_ACTION.REPORT_STATUS;
import static com.hh.hhomc.common.Constants.SERVER_ACTION.UPGRADE_PROCESSING;
import static com.hh.hhomc.common.Constants.VALUE.TIME_HEARTBEAT;
import static com.hh.hhomc.common.Constants.VALUE.TIME_INSTALL_ALL;
import static com.hh.hhomc.common.Constants.VALUE.TIME_INSTALL_INTERVAL;

public class BackgroundService extends Service {

    String websocketUrl;


    IAppLocalConfig localConfig;

    String sn = "";

    // aidl消息发送者，标识收到的消息来自哪个app
    String aidlSender = "HHOMC";

    private static final String FIRST_ACTION = "download_helper_first_action";


    /**
     * 下载过程会通过发送广播, 广播通过intent携带文件数据的 信息。
     * intent 的key值就是该字段
     * eg : FileInfo fileInfo = (FileInfo) intent.getSerializableExtra(DownloadConstant.EXTRA_INTENT_DOWNLOAD);
     */
    public static final String EXTRA_INTENT_DOWNLOAD = "yaoxiaowen_download_extra";


    private TextView firstTitle;
    private ProgressBar firstProgressBar;
    private Button firstBtn;
    private String apkFileName = "k8.apk";

    long apkTaskId;

    IDeviceUI iDeviceUI;

    private BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (null != intent) {
                switch (intent.getAction()) {
                    case FIRST_ACTION: {
                        FileInfo fileInfo = (FileInfo) intent.getSerializableExtra(EXTRA_INTENT_DOWNLOAD);

                        String filePath = fileInfo.getFilePath();
                        AppLogUtils.e("广播--filePath=" + filePath);
                        // /storage/emulated/0/Android/data/com.hh.hhomc/cache/download/hharome_v2.2.1_app.apk

                        // 可对应ServerActionAppUpdateRequestBean中的filepath
                        String downloadUrlFileInfo = fileInfo.getDownloadUrl();

                        float pro = (float) (fileInfo.getDownloadLocation() * 1.0 / fileInfo.getSize());
                        int progress = (int) (pro * 100);
                        float downSize = fileInfo.getDownloadLocation() / 1024.0f / 1024;
                        float totalSize = fileInfo.getSize() / 1024.0f / 1024;

                        AppLogUtils.e("progress--" + progress);


                        ServerActionAppUpdateResultBean sendInstallBean = new ServerActionAppUpdateResultBean();
                        sendInstallBean.setSource("app");
                        sendInstallBean.setSn(sn);
                        sendInstallBean.setOp(UPGRADE_PROCESSING);
                        sendInstallBean.setTaskId(apkTaskId);
                        sendInstallBean.setDownloadPercent(progress);
                        sendInstallBean.setSender(apkSender);

//                        apkUrlMap.get();

                        // 开始发送信息
                        if (progress < 100) {
                            // 下载中(可取消)
                            sendInstallBean.setStatus(1);
                            String resultStr = gson.toJson(sendInstallBean);
                            AppLogUtils.e("发送apk安装升级消息--resultStr: " + resultStr);

                            sendMessageByWebSocket(resultStr);


                        } else if (progress == 100) {
                            AppLogUtils.e("apkCompleteNum--" + apkCompleteNum);
                            if (apkCompleteNum < 1) {
                                // 升级类型 1:强制升级 2:静默升级
                                if (upgradeType == 1) {
                                    AppLogUtils.e("强制升级---开始安装");
                                    // 1:强制升级
                                    // 开始安装
                                    delayInstallApk();

                                    // 安装中
                                    sendInstallBean.setStatus(3);
                                    String resultStr = gson.toJson(sendInstallBean);
                                    AppLogUtils.e("发送apk安装升级消息--resultStr: " + resultStr);

                                    sendMessageByWebSocket(resultStr);

                                } else if (upgradeType == 2) {
                                    // 2:静默升级
                                    // 等待安装(静默升级 可取消)
                                    AppLogUtils.e("静默升级");

                                    // map循环
                                    for (String key : apkUrlMap.keySet()) {
                                        AppLogUtils.e("map-key:" + key);
                                        ServerActionAppUpdateRequestBean serverUpdateBean = apkUrlMap.get(key);
                                        if (serverUpdateBean.getFilePath().equals(downloadUrlFileInfo)) {
                                            AppLogUtils.e("map循环中，静默升级---有对应下载url");
                                            // 设置为静默
                                            if (serverUpdateBean.isSilentInstall()) {
                                                isSilentInstall = true;
                                            }

                                        }
                                    }


                                    if (isSilentInstall) {
                                        AppLogUtils.e("静默升级---开始安装");
                                        // 已经下载完了，启动时安装
                                        isSilentInstall = false;

                                        delayInstallApk();


                                    } else {
                                        // 第一次下载完成
                                        sendInstallBean.setStatus(2);
                                        String resultStr = gson.toJson(sendInstallBean);
                                        AppLogUtils.e("发送apk安装升级消息--resultStr: " + resultStr);

                                        sendMessageByWebSocket(resultStr);


                                        // map循环
                                        for (String key : apkUrlMap.keySet()) {
                                            AppLogUtils.e("map-key:" + key);
                                            ServerActionAppUpdateRequestBean serverUpdateBean = apkUrlMap.get(key);
                                            if (serverUpdateBean.getFilePath().equals(downloadUrlFileInfo)) {
                                                AppLogUtils.e("map循环中，静默升级---有对应下载url");
                                                // 设置为静默
                                                serverUpdateBean.setSilentInstall(true);

                                            }
                                        }

                                    }
                                }

                                // 强制时，可能点了取消。静默时，要下次启动app时
                                // 保存，供下次启动时安装
                                String mapString = gson.toJson(apkUrlMap);
                                AppLogUtils.e("下载完后apkInfoMapStr--set--" + mapString);
                                localConfig.setApkInfoMapStr(mapString);
                                String apkInfoMapStr = localConfig.getApkInfoMapStr("");
                                AppLogUtils.e("下载完后apkInfoMapStr--get--" + apkInfoMapStr);


                                apkCompleteNum = apkCompleteNum + 1;
                                AppLogUtils.e("apkCompleteNum +1后--" + apkCompleteNum);
                            }
                        }


                    }
                    break;
                    default:
                        break;

                }
            }
        }
    };


    int apkCompleteNum = 0;
    boolean isSilentInstall;


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

    @Override
    public void onCreate() {
        AppLogUtils.e("onCreate");
//        initData();
        Looper looper = getMainLooper(); // 获取主线程的Looper对象
        if (mHandler == null) {
            mHandler = new Handler(looper); // 与主线程的Looper关联
        }

        mHandler.post(new Runnable() {
            @Override
            public void run() {
                ToastUtils.showLongToast("HHOMC服务启动");
            }
        });


        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            /**
             * Oreo不用Priority了，用importance
             * IMPORTANCE_NONE 关闭通知
             * IMPORTANCE_MIN 开启通知，不会弹出，但没有提示音，状态栏中无显示
             * IMPORTANCE_LOW 开启通知，不会弹出，不发出提示音，状态栏中显示
             * IMPORTANCE_DEFAULT 开启通知，不会弹出，发出提示音，状态栏中显示
             * IMPORTANCE_HIGH 开启通知，会弹出，发出提示音，状态栏中显示
             */
            NotificationChannel channel = new NotificationChannel("101", "test", NotificationManager.IMPORTANCE_DEFAULT);
            notificationManager.createNotificationChannel(channel);
        }
        getiDeviceUI();
        startForeground(1, getNotification());

        super.onCreate();
    }


    private Notification getNotification() {
        Notification.Builder builder = new Notification.Builder(this)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle("hhomc服务")
                .setContentText("我正在运行——SN："+DeviceUtils.getDeviceSN())
                .setAutoCancel(true);

        //设置Notification的ChannelID,否则不能正常显示

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            builder.setChannelId("101");
        }
        Notification notification = builder.build();

//        notification.flags |= Notification.FLAG_NO_CLEAR;

        return notification;
    }


    @Override
    public void onStart(Intent intent, int startId) {
        AppLogUtils.e("onStart");
        super.onStart(intent, startId);
    }

    int isFiring;

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        AppLogUtils.i("onStartCommand");


        Looper looper = getMainLooper(); // 获取主线程的Looper对象
        if (mHandler == null) {
            mHandler = new Handler(looper); // 与主线程的Looper关联
        }

        if (isFiring < 1) {
            isFiring++;
            AppLogUtils.e("服务 - 首次");

            initData();


        } else {
            AppLogUtils.i("服务 - 非首次");

            if (mWebSocketClient == null || !isWebsocketConnect) {
                AppLogUtils.e("websocket重新连接");
                restartWebsocket();
            } else {
                AppLogUtils.i("websocket连接中");
            }

            // 点击图标时
//            mHandler.post(new Runnable() {
//                @Override
//                public void run() {
//                    ToastUtils.showLongToast("HHOMC服务已启动");
//                }
//            });

        }


//        AlarmManagerUtils.getInstance(getApplicationContext()).getUpAlarmManagerWorkOnOthers(TIME_HEARTBEAT);


        return START_STICKY; // 这个返回值表示服务被系统杀死后会尝试重新启动
    }


    private void initData() {

        AppLogUtils.e("initData--");

        localConfig = AppLocalConfigHandler.create(MyApplication.getContext(), IAppLocalConfig.class);

        sn = DeviceUtils.getDeviceSN();

        websocketUrl = BuildConfig.BASE_URL_WEBSOCKET + "websocket?sn=" + sn;

        AppLogUtils.e("onCreate--initSockect--websocketUrl--" + websocketUrl);
        initSockect(websocketUrl);


        String appPackageName = DeviceUtils.getAppPackageName(MyApplication.getContext());
        LogUtils.e("当前appPackageName = " + appPackageName);

        // 绑定aidl服务
        bindService();

        initDownloadApk();

        localMapSendWebsocketInfo();
    }


    private void localMapSendWebsocketInfo() {

//        localConfig.setApkInfoMapStr("");

        String apkInfoMapStr = localConfig.getApkInfoMapStr("");
        AppLogUtils.e("apkInfoMapStr--" + apkInfoMapStr);
        if (StringUtils.isNotNull(apkInfoMapStr)) {

            // 转换之前保存的本地map
            Type type = new TypeToken<HashMap<String, ServerActionAppUpdateRequestBean>>() {
            }.getType();
            HashMap<String, ServerActionAppUpdateRequestBean> localHashMap = new Gson().fromJson(apkInfoMapStr, type);


            apkUrlMap.clear();
            apkUrlMap.putAll(localHashMap);

            if (apkUrlMap.size() == 0) {
                AppLogUtils.e("map无数据，无安装任务");
                return;
            }

            // 获取设备已安装app列表
            ArrayList<AppInfoBean> appList = AppUtils.getAppList(getApplicationContext());
            if (appList != null && appList.size() > 0) {
                int k = 0;
                // 循环apkUrlMap
                for (int i = 0; i < appList.size(); i++) {
                    for (String key : apkUrlMap.keySet()) {
//                        AppLogUtils.e("map-key:" + key);
                        ServerActionAppUpdateRequestBean serverUpdateBean = apkUrlMap.get(key);
                        if (key.equals(appList.get(i).getPackageName())) {
                            AppLogUtils.e("map循环中，有包名");
                            // 已有
                            // 并且apk已有
                            File apkFile = new File(getDir(), serverUpdateBean.getFileName());
                            if (apkFile != null && apkFile.exists()) {
                                AppLogUtils.e("map循环中，有包名，有apk");
                                AppLogUtils.e("map循环中，有包名，有apk--apkFile.length()---" + apkFile.length());
                                AppLogUtils.e("map循环中，有包名，有apk--mBean.getFileSize()--" + serverUpdateBean.getFileSize());
                                if (apkFile.length() == serverUpdateBean.getFileSize()) {
                                    AppLogUtils.e("map循环中，有包名，有完整的apk");
                                    if (appList.get(i).getVersionName().equals(serverUpdateBean.getVersionName())) {
                                        AppLogUtils.e("map循环中，有包名，有完整的apk，版本号一致，安装成功");


                                        ServerActionAppUpdateResultBean resultBean = new ServerActionAppUpdateResultBean();
                                        resultBean.setSource("app");
                                        resultBean.setSn(DeviceUtils.getDeviceSN());
                                        resultBean.setOp(UPGRADE_PROCESSING);
                                        resultBean.setTaskId(serverUpdateBean.getTaskId());
                                        resultBean.setDownloadPercent(100);
                                        resultBean.setSender(serverUpdateBean.getSender());
                                        resultBean.setStatus(4);

                                        if (mWebSocketClient == null) {
                                            AppLogUtils.e("刚启动--根据本地保存的map--websocketUrl--" + websocketUrl);
                                            initSockect(websocketUrl);
                                        }
                                        String resultStr = gson.toJson(resultBean);
                                        AppLogUtils.e("根据本地保存的map--安装成功---发送apk安装升级消息--resultStr: " + resultStr);

                                        sendMessageByWebSocket(resultStr);

                                        pauseTaskAndDelete(serverUpdateBean);
                                    } else {
                                        AppLogUtils.e("map循环中，有包名，有完整的apk，开始安装");
                                        startDownloadApk(serverUpdateBean);
                                    }
                                } else {
                                    AppLogUtils.e("map循环中，有包名，不是完整的apk，接着下载");
                                    startDownloadApk(serverUpdateBean);
                                }

                            } else {
                                AppLogUtils.e("map循环中，有包名，没有apk，开始下载");
                                startDownloadApk(serverUpdateBean);
                            }
                        }
                    }
                    k++;
                }

                if (k == apkUrlMap.size()) {
                    // map循环完了，还没有
                    // 下载
                    AppLogUtils.e("map循环完了，还没有，下载");
//                    startDownloadApk(localHashMap.get(0));

                    Iterator<HashMap.Entry<String, ServerActionAppUpdateRequestBean>> iterator = localHashMap.entrySet().iterator();
                    if (iterator.hasNext()) {
                        HashMap.Entry<String, ServerActionAppUpdateRequestBean> entry = iterator.next();
                        AppLogUtils.e("第一个值为：" + entry.getValue().toString());
//                        System.out.println("第一个值为：" + entry.getValue());
                        startDownloadApk(entry.getValue());
                    }

                } else {
                    AppLogUtils.e("map中有，不下载");

                    // 情况：静默下载，新应用（之前没有安装过）
                    for (String key : apkUrlMap.keySet()) {
                        ServerActionAppUpdateRequestBean requestBean = apkUrlMap.get(key);
                        startDownloadApk(requestBean);
                    }

                }
            }


        }
    }


    DownloadHelper mDownloadHelper;
    File apkFile;

    boolean isRegisterDownload;

    /**
     * 断点续传用到的库
     * https://github.com/yaowen369/DownloadHelper
     * 后台下载了，但没有进度条。查看服务端apk下载路径
     */
    private void initDownloadApk() {
        AppLogUtils.e("initDownloadApk");

        mDownloadHelper = DownloadHelper.getInstance();
        mDownloadHelper.setDebug(true);

        IntentFilter filter = new IntentFilter();
        filter.addAction(FIRST_ACTION);

        registerReceiver(receiver, filter);

        isRegisterDownload = true;


    }

    File dir;

    private File getDir() {
        if (dir != null && dir.exists()) {
            return dir;
        }

        dir = new File(getExternalCacheDir(), "download");
        if (!dir.exists()) {
            dir.mkdirs();
        }
        return dir;
    }


    @Override
    public void onDestroy() {
        // 在服务销毁时执行一些清理操作


        // 解绑广播
        if (isRegisterDownload && receiver != null) {
            unregisterReceiver(receiver);
        }


        //解除注册
        if (null != iAidlInterface && iAidlInterface.asBinder().isBinderAlive()) {
            try {
                iAidlInterface.unregisterCallBack(iAidlCallBack);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
        //解除绑定服务
        if (isServiceConnection && serviceConnection != null) {
            unbindService(serviceConnection);
        }

        super.onDestroy();

        if (mHandler != null) {
            mHandler.removeCallbacksAndMessages(null);
            mHandler = null;
        }

    }


    URI uri;
    WebSocketClient mWebSocketClient;

    Gson gson = new Gson();


    boolean isWebsocketConnect;

    public void initSockect(String url) {
        try {
            uri = new URI(url);
            AppLogUtils.e("WBSOCKETURL: " + url);
        } catch (URISyntaxException e) {
            // 异常也重连
            isWebsocketConnect = false;
            e.printStackTrace();
        }
        if (null == mWebSocketClient) {
            mWebSocketClient = new WebSocketClient(uri) {
                @Override
                public void onOpen(ServerHandshake serverHandshake) {
                    AppLogUtils.e("onOpen: ");
                    isWebsocketConnect = true;

                    uploadDeviceStatus();

//                    queryServerAppInfo();

//                    isWebsocketConnect = false;

                }

                @Override
                public void onMessage(String serverResultStr) {
                    AppLogUtils.e("onMessage: " + serverResultStr);

                    if (StringUtils.isNull(serverResultStr)) {
                        AppLogUtils.e("onMessage数据空");
                        return;
                    }

                    // 转换服务端返回的数据
                    ServerActionBean serverActionBean = gson.fromJson(serverResultStr, ServerActionBean.class);
                    AppLogUtils.e("serverActionBean--" + serverActionBean.toString());

                    if (serverActionBean != null) {
                        String serverSn = serverActionBean.getSn();
                        AppLogUtils.i("local-sn--" + sn);
                        AppLogUtils.i("server-sn--" + serverSn);
                        if (!sn.equals(serverSn)) {
                            // 如果sn号不相等，就不操作
                            AppLogUtils.i("sn号不相等--");
                            return;
                        }

                        AppLogUtils.i("sn号相等--接着执行");

                        // 服务端要干的操作
                        String op = serverActionBean.getOp();
                        AppLogUtils.e("op--" + op);
                        if (FETCH_LOG.equals(op)) {
                            AppLogUtils.e(FETCH_LOG + "  拉取日志列表，上传日志文件名列表供展示下载");

                            returnLogNameList(serverActionBean);

                        } else if (DOWNLOAD_LOG.equals(op)) {
                            AppLogUtils.e(DOWNLOAD_LOG + "  后台返回选中要下载日志列表，进行日志文件上传");

                            uploadLogFileList(serverActionBean);

                        } else if (INSTALL_UPGRADE.equals(op)) {
                            AppLogUtils.e(INSTALL_UPGRADE + "  apk安装升级");

                            installApkByServer(serverResultStr);


                        } else if (CANCEL_UPGRADE.equals(op)) {
                            AppLogUtils.e(CANCEL_UPGRADE + "  apk取消安装升级");

                            cancelApkByServer(serverResultStr);


                        } else if (CLOSE_APP.equals(op)) {
                            AppLogUtils.e(CLOSE_APP + "  应⽤关闭");

                            closeAppByServer(serverActionBean);

                        } else if (REBOOT.equals(op)) {
                            AppLogUtils.e(REBOOT + "  应⽤设备重启");

                            restartDevice();

                        } else if (QUERY_DEVICE_BIZ_DATA.equals(op)) {
                            AppLogUtils.e(REBOOT + "  获取设备业务参数");

                            queryDeviceAppInfo(serverResultStr);

                        }

                    }


                }

                @Override
                public void onClose(int i, String s, boolean b) {
                    // 检查在OTA平台设备列表是否已经添加设备
                    AppLogUtils.e("onClose: ");
                    isWebsocketConnect = false;
                }

                @Override
                public void onError(Exception e) {
                    AppLogUtils.e("onError--e = " + e.toString());
                    // java.net.UnknownHostException: hhomc.hz-hanghui.com
                    isWebsocketConnect = false;
                }
            };
            mWebSocketClient.connect();

//            if (heartBeatRunnable != null) {
//                mHandler.removeCallbacks(heartBeatRunnable);
//            }
            mHandler.postDelayed(heartBeatRunnable, 5 * 1000);//开启心跳检测

//            mHandler.post(new Runnable() {
//                @Override
//                public void run() {
//                    ToastUtils.showLongToast("HHOMC服务启动");
//                }
//            });

        }
    }


    private void queryDeviceAppInfo(String serverResultStr) {
        // 转换服务端返回的数据
        // 此数据是业务app上次在线发送的数据
        ServerActionAppUpdateRequestBean mBean = gson.fromJson(serverResultStr, ServerActionAppUpdateRequestBean.class);
        String packageNameServer = mBean.getPackageName();
        // 此版本号是业务app在线时上传的，不一定是要升级的版本号，可能是老的
        String versionNameServer = mBean.getVersionName();

        // 本地保存的信息
        ServerActionAppUpdateRequestBean serverUpdateBean = apkUrlMap.get(packageNameServer);

        if (apkUrlMap.size() == 0) {
            AppLogUtils.e("apkUrlMap无数据");
            return;
        }


        if (serverUpdateBean != null) {
            String packageNameLocal = serverUpdateBean.getPackageName();
            // 更新apk任务时的版本号
            String versionNameLocal = serverUpdateBean.getVersionName();
            if (packageNameLocal.equals(packageNameServer)) {

                // 安装成功与否发送给服务端的消息
                ServerActionAppUpdateResultBean resultBean = new ServerActionAppUpdateResultBean();
                resultBean.setSource("app");
                resultBean.setSn(DeviceUtils.getDeviceSN());
                resultBean.setOp(UPGRADE_PROCESSING);
                resultBean.setTaskId(serverUpdateBean.getTaskId());
                resultBean.setDownloadPercent(100);
                resultBean.setSender(serverUpdateBean.getSender());

                if (mWebSocketClient == null) {
                    AppLogUtils.e("iAidlCallBack--websocketUrl--" + websocketUrl);
                    initSockect(websocketUrl);
                }

                if (versionNameServer.equals(versionNameLocal)) {
                    // 相等就是安装成功
                    // 4:安装成功
                    resultBean.setStatus(4);
                    String resultStr = gson.toJson(resultBean);
                    AppLogUtils.e("主动查询设备业务--安装成功---发送apk安装升级消息--resultStr: " + resultStr);
                    sendMessageByWebSocket(resultStr);

                } else {
                    // 5:安装失败
                    resultBean.setStatus(5);
                    String resultStr = gson.toJson(resultBean);
                    AppLogUtils.e("主动查询设备业务--安装失败---发送apk安装升级消息--resultStr: " + resultStr);
                    sendMessageByWebSocket(resultStr);

                }

                pauseTaskAndDelete(serverUpdateBean);

            }


        }
    }

    private void closeAppByServer(ServerActionBean serverActionBean) {
        if (null != iAidlInterface) {
            AppLogUtils.e("iAidlInterface!-null");
            try {
                AppMessageBean bean = new AppMessageBean();
                bean.setOp(CLOSE_APP);
                bean.setBusinessAppPackageName(serverActionBean.getPackageName());
                bean.setSender(aidlSender);
                iAidlInterface.setAppMessageBean(bean);
                AppLogUtils.e("iAidlInterface发送  应⽤关闭");
            } catch (RemoteException e) {
                AppLogUtils.e("RemoteException--e---" + e.toString());
                e.printStackTrace();
            }
        } else {
            AppLogUtils.e("iAidlInterface--null");
        }
    }

    private void cancelApkByServer(String serverResultStr) {
        // 转换服务端返回的数据
        ServerActionAppUpdateRequestBean mBean = gson.fromJson(serverResultStr, ServerActionAppUpdateRequestBean.class);

        apkSender = mBean.getSender();

        ServerActionAppUpdateRequestBean serverBean = apkUrlMap.get(mBean.getPackageName());

        pauseTaskAndDelete(serverBean);
    }

    private void installApkByServer(String serverResultStr) {
        // 转换服务端返回的数据
        ServerActionAppUpdateRequestBean mBean = gson.fromJson(serverResultStr, ServerActionAppUpdateRequestBean.class);

        lastServerUpdateBean = mBean;

        // 会有同一个下载url多次发送消息过来的情况，故判断是否已有下载
        AppLogUtils.e("apkUrlMap.size()--" + apkUrlMap.size());
        if (apkUrlMap.size() > 0) {
            int k = 0;
            boolean canInstall = false;
            // 循环apkUrlMap
            for (String key : apkUrlMap.keySet()) {
                AppLogUtils.e("map-key:" + key);
                if (key.equals(mBean.getPackageName())) {
                    AppLogUtils.e("map循环中，有包名");
                    // 已有
                    // 并且apk已有
                    File apkFile = new File(getDir(), mBean.getFileName());
                    if (apkFile != null && apkFile.exists()) {
                        AppLogUtils.e("map循环中，有包名，有apk");
                        AppLogUtils.e("map循环中，有包名，有apk--apkFile.length()---" + apkFile.length());
                        AppLogUtils.e("map循环中，有包名，有apk--mBean.getFileSize()--" + mBean.getFileSize());
                        if (apkFile.length() == mBean.getFileSize()) {
                            AppLogUtils.e("map循环中，有包名，有完整的apk");
                            canInstall = true;
                            break;
                        } else {
                            AppLogUtils.e("map循环中，有包名，不是完整的apk");
                        }

                    } else {
                        AppLogUtils.e("map循环中，有包名，没有apk");
                    }
                }
                k++;
            }
            if (k == apkUrlMap.size()) {
                // map循环完了，还没有
                // 下载
                AppLogUtils.e("map循环完了，还没有，下载");
                startDownloadApk(mBean);
            } else {
                AppLogUtils.e("map中有，不下载");
            }

            if (canInstall) {
                delayInstallApk();
            }


        } else {
            // 没有map，直接下载
            AppLogUtils.e("没有map，直接下载");
            startDownloadApk(mBean);
        }
    }

    private void uploadLogFileList(ServerActionBean serverActionBean) {
        List<String> waitUploadLogPaths = serverActionBean.getPaths();
        if (waitUploadLogPaths == null || waitUploadLogPaths.size() == 0) {
            AppLogUtils.e("waitUploadLogPaths == null");
            return;
        }
        // 等待上传路径
        logAllNum = waitUploadLogPaths.size();
        // 注意重置
        logSuccessPath.clear();
        logSuccessNum = 0;

        String logType = serverActionBean.getLogType();
        String sender = serverActionBean.getSender();
        ThreadPoolManager.getInstance().executeIOTask(new Runnable() {
            @Override
            public void run() {
                try {
                    synchronized (BackgroundService.class) {
                        String zipPath = ZipUtils.createZipFolder(MyApplication.getContext(), waitUploadLogPaths);
                        String downloadUrl = ChunkedUploadExample.uploadFile(MyApplication.getContext(), zipPath);
                        ArrayList<String> downLoadUrls = new ArrayList<>();
                        downLoadUrls.add(downloadUrl);
                        // 返回已上传的日志文件http列表
                        reportLogList(DOWNLOAD_LOG, downLoadUrls, logType, sender);
                    }
                }catch (IOException e){

                }catch (OutOfMemoryError e2){

                }catch (Exception e3){

                }

            }
        });
        // 循环上传，成功+1判断是否等于总数，都上传完后再发送消息
   /*     for (String path : waitUploadLogPaths) {
            uploadLogFile(path, logType, sender);
        }*/
    }

    public void returnLogNameList(ServerActionBean serverActionBean) {
        String logType = serverActionBean.getLogType();
        AppLogUtils.e("logType:" + logType);
        String logPath = serverActionBean.getLogDirPath();
        AppLogUtils.e("logPath:" + logPath);

//        if(StringUtils.isNull(logType)){
//            logType = "logcat";
//        }

        List<String> logTypeList = printLogPath(logPath, Constants.VALUE.TIME_LOG_DAY);

        // 返回日志文件名列表
        reportLogList(FETCH_LOG, logTypeList, logType, serverActionBean.getSender());
    }


    // 重启设备
    private void restartDevice() {

        getiDeviceUI().reboot();
       /* try {
            // posutil
            ShellUtils.execCommand("reboot", true);
        } catch (Exception e) {
            e.printStackTrace();
        }*/
    }

    public IDeviceUI getiDeviceUI() {
        if(iDeviceUI==null){
            synchronized (BackgroundService.class){
                if(iDeviceUI==null){
                    iDeviceUI = BaseDeviceUI.getInstance().getDeviceUI();
                }
            }
        }
        return iDeviceUI;
    }

    public void queryServerAppInfo() {

        ServerActionBean requestBean = new ServerActionBean();
        requestBean.setSn(DeviceUtils.getDeviceSN());
        requestBean.setSource("app");
        requestBean.setOp(QUERY_DEVICE_BIZ_DATA);
        requestBean.setMsg("获取设备业务参数");

        String requestStr = gson.toJson(requestBean);
        AppLogUtils.e("requestStr = " + requestStr);

        sendMessageByWebSocket(requestStr);

    }


    // 30秒上报一次  60秒未上报视为设备离线状态
    private void uploadDeviceStatus() {
        DeviceStatusBean bean = new DeviceStatusBean();
        bean.setSn(DeviceUtils.getDeviceSN());
        bean.setSource("app");
        bean.setOp(REPORT_STATUS);
        bean.setMsg("上报设备状态（sn、在离线、软硬件版本、包名、ip地址等）");
        // 业务应⽤包名
//        bean.setBizAppApkName(businessAppPackageName);
        // 业务应⽤在线状态 0:离线 1：在线
//        bean.setBizAppOnline("1");
        // 业务应⽤版本"
//        bean.setBizAppVersion(businessAppVersionName);
        // 设备型号
        bean.setDeviceModel(DeviceUtils.getDeviceModel());
        // ota应⽤包名-omc
        bean.setOtaAppApkName(DeviceUtils.getAppPackageName(this));
        // ota应⽤版本号-omc
        bean.setOtaAppVersion(BuildConfig.VERSION_NAME);
        // 系统版本
        bean.setSysVersion(DeviceUtils.getAndroidVersion());
//        bean.setHhVersion(DeviceUtils.getAppVersionName(this));
        bean.setApkName(DeviceUtils.getAppPackageName(this));
        bean.setFirmwareVersion(DeviceUtils.getDeviceDisplay());
        bean.setIpAddress(DeviceUtils.getDeviceIP());

        String s = gson.toJson(bean);
        AppLogUtils.e("心跳-----上报设备状态: " + s);

        // 上报设备状态
        sendMessageByWebSocket(s);

//        mHandler.postDelayed(heartBeatRunnable, 1 * 1000);//开启心跳检测
    }


    // 0000
    public void sendMessageByWebSocket(String message) {

        if (mWebSocketClient == null || !isWebsocketConnect) {
            restartWebsocket();
        }

        try {
            mWebSocketClient.send(message);
        } catch (NotYetConnectedException e) {

            restartWebsocket();

            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    mWebSocketClient.send(message);
                }
            }, 2 * 1000); //延时执行run内代码

        } catch (RuntimeException e) {
            AppLogUtils.e("sendMessageByWebSocket--RuntimeException: ");
            e.printStackTrace();
        }


    }


    private void restartWebsocket() {
        mHandler.removeCallbacks(heartBeatRunnable);
        if (mWebSocketClient != null) {
            mWebSocketClient.close();//取消掉以前的长连接
            mWebSocketClient = null;
        }

        new InitSocketThread().start();//创建一个新的连接
    }

    class InitSocketThread extends Thread {
        @Override
        public void run() {
            super.run();
            AppLogUtils.e("InitSocketThread--websocketUrl--" + websocketUrl);
            initSockect(websocketUrl);
        }
    }


    private long sendTime = 0L;
    // 定时任务，发送心跳包
    private Handler mHandler;

    private Runnable heartBeatRunnable = new Runnable() {
        @Override
        public void run() {
            AppLogUtils.e("开始发送心跳包检测-------------");
            if (System.currentTimeMillis() - sendTime >= TIME_HEARTBEAT) {
                if (mWebSocketClient != null) {
                    if (!isWebsocketConnect) {//长连接已断开，
                        AppLogUtils.e("发送心跳包-------------长连接已断开");
                        restartWebsocket();
                    } else {//长连接处于连接状态---
                        AppLogUtils.e("发送心跳包-------------长连接处于连接状态");
                        // 上报设备状态
                        uploadDeviceStatus();
                    }
                } else {
                    AppLogUtils.e("开始发送心跳包检测-----mWebSocketClient = null------restartWebsocket");
                    restartWebsocket();
                }

                sendTime = System.currentTimeMillis();
            }

            mHandler.postDelayed(heartBeatRunnable, TIME_HEARTBEAT);//每隔一定的时间，对长连接进行一次心跳检测

//            AlarmManagerUtils.getInstance(getApplicationContext()).getUpAlarmManagerWorkOnOthers(TIME_HEARTBEAT);
        }
    };


    String apkSender;


    // key是包名，value是更新信息的bean
    HashMap<String, ServerActionAppUpdateRequestBean> apkUrlMap = new HashMap<>();

    // 升级类型 1:强制升级 2:静默升级"
    int upgradeType;

    private void startDownloadApk(ServerActionAppUpdateRequestBean mBean) {
        AppLogUtils.e("startDownloadApk---------");


        String apkUrl = mBean.getFilePath();
        AppLogUtils.e("apkUrl = " + apkUrl);
//        apkUrl = testurl;

//        String apkName = apkUrl.substring(apkUrl.lastIndexOf("/") + 1);
//        AppLogUtils.e("apkName--" + apkName);
//        apkFileName = apkName;

        apkFileName = mBean.getFileName() + "";

        // 根据文件名创建对应文件
        apkFile = new File(getDir(), apkFileName);

        AppLogUtils.e("apkFile---" + apkFile.getAbsolutePath());

        apkTaskId = mBean.getTaskId();
        apkSender = mBean.getSender();
        upgradeType = mBean.getUpgradeType();
        AppLogUtils.e("升级方式upgradeType---" + upgradeType);

        mDownloadHelper.addTask(apkUrl, apkFile, FIRST_ACTION).submit(MyApplication.getContext());

        apkUrlMap.put(mBean.getPackageName() + "", mBean);

        apkCompleteNum = 0;

    }


    private void delayInstallApk() {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                startInstallApk();
            }
        }, 2 * 1000); //延时执行run内代码
    }

    // 开始安装
    private void startInstallApk() {
//        AppLogUtils.e("startInstallApk--开始安装，filePath=" + filePath);
        getiDeviceUI().silenceInstall(apkFile.getAbsolutePath(), new SilenceInstallSuccessListener() {
            @Override
            public void success(boolean isSucceeded) {
                if(!isSucceeded){
                    defaultInstallApp() ;
                }
            }
        });
    }

    private void defaultInstallApp(){
        AppLogUtils.e("startInstallApk--开始安装，apkFile=" + apkFile.getName());

        mHandler.postDelayed(apkInstallRunnable, TIME_INSTALL_INTERVAL);//开启定时任务
        AppLogUtils.e("startInstallApk--开始安装，启动定时检测任务");
        apkInstallTime = System.currentTimeMillis();

        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { // 7.0+以上版本
            AppLogUtils.e("fileprovider----" + BuildConfig.APPLICATION_ID + ".provider");
            // 注意与清单文件中authorities值对应，不然就是Couldn't find meta-data for provider with authority
            Uri apkUri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".provider", apkFile);
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
        } else {
            intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
        }
        this.startActivity(intent);

    }


    List<String> logSuccessPath = new ArrayList<>();
    int logSuccessNum;
    int logAllNum;


    private void uploadLogFile(String path, String logType, String sender) {

        AppLogUtils.e("uploadLogFile---path:" + path + "   logType--" + logType);

        File file = new File(path);
        RequestBody requestFile = RequestBody.create(MediaType.parse("file/txt"), file);
        MultipartBody.Part filePart = MultipartBody.Part.createFormData("file", file.getName(), requestFile);


        ApiService ApiService = HttpManager.getInstance(CommonApplication.getContext()).create(ApiService.class);
        Observable observable = ApiService.uploadFile(filePart);
        observable.compose(RxHttpResponseCompat.<StringResultBean>compatResult())
                .subscribe(new Observer<StringResultBean>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        AppLogUtils.e("uploadLogFile---onSubscribe:");
                    }

                    @Override
                    public void onNext(StringResultBean resultBean) {

                        AppLogUtils.e("uploadLogFile---onNext--toString:" + resultBean.toString());
                        // 上传成功
                        logSuccessPath.add(resultBean.getString());

                        logSuccessNum++;

//                        LogUtils.e(mTag + "onSuccess--number:" + number);
                        AppLogUtils.e("uploadLogFile---onSuccess--paths.size():" + logSuccessNum);
                        if (logSuccessNum == logAllNum) {
                            // 都上传完后，开始发送消息

                            // 返回已上传的日志文件http列表
                            reportLogList(DOWNLOAD_LOG, logSuccessPath, logType, sender);

                        } else {
                            AppLogUtils.e("uploadLogFile---noSuccess----number:" + logSuccessNum);
                        }
                    }


                    @Override
                    public void onError(Throwable e) {
                        AppLogUtils.e("uploadLogFile---onError:");
                        //上传失败
//                        if (callback != null) {
//                            callback.onFailure(new ClientException(), new ServiceException(-1,"上传失败","-1","-1","-1","-1"));
//                        }
                    }

                    @Override
                    public void onComplete() {
                        AppLogUtils.e("uploadLogFile---onComplete:");
                    }
                });
    }


    /**
     * 上传日志列表和已上传的http日志列表都用这个
     * path和op不一样
     */
    private void reportLogList(String op, List<String> logTypeList, String logType, String sender) {
        LogListSendBean logListSendBean = new LogListSendBean();
        logListSendBean.setOp(op);
        logListSendBean.setSn(sn);
        logListSendBean.setSource("app");
        logListSendBean.setSender(sender);

        LogListSendBean.LogsDTO logsDTO = new LogListSendBean.LogsDTO();

        List<String> logList = new ArrayList<>();
        logList.addAll(logTypeList);

        logsDTO.setPaths(logList);
        logsDTO.setLogType(logType);

        List<LogListSendBean.LogsDTO> logsDTOList = new ArrayList<>();
        logsDTOList.add(logsDTO);

        logListSendBean.setLogs(logsDTOList);


        String resultStr = gson.toJson(logListSendBean);
        AppLogUtils.e("reportLogList--resultStr: " + resultStr);

        // 开始发送信息
        sendMessageByWebSocket(resultStr);

    }


    /**
     * @param logPath 日志类型
     * @param day     几天内
     * @return
     */
    private List<String> printLogPath(String logPath, int day) {
        List<String> pathList = new ArrayList<>();
        String logDir = getLogcatDir(logPath);
        if (TextUtils.isEmpty(logDir)) {
            AppLogUtils.e("未查询到日志");
            return pathList;
        }
        int base = day * 86400000;//day 天毫秒数
        Calendar calendar = Calendar.getInstance();
        File file = new File(logDir);
        File[] files = file.listFiles();
        if (files != null) {
            for (File logFile : files) {
                long lastModified = logFile.lastModified();
                long time = calendar.getTime().getTime();
                long dif = time - lastModified;
                if (dif <= base) {
                    String absolutePath = logFile.getAbsolutePath();
                    pathList.add(absolutePath);
                }

            }
            AppLogUtils.e("文件FilePath = " + pathList.toString());
//            ToastUtils.showShort("读取" + logType + "日志成功");
        } else {
//            ToastUtils.showLong("未查询到日志");
            AppLogUtils.e("未查询到日志");
        }
        return pathList;
    }


    public static String getLogcatDir(String logPath) {
        //获取外存路径
//        String externalStoragePath = BuildConfig.LOG_FILE_AROME;
//        String externalStoragePath = "/storage/emulated/0/Android/data/com.telpo.facesongcheng/files";
        //命名存储目录
//        String logPath = externalStoragePath + File.separator + logType;
        //判断目录是否存在
        boolean fileExists = FileUtils.isFileExists(logPath);
        if (fileExists) {
            return logPath;
        } else {
            return null;
        }
    }

    boolean hasPermission;

    /**
     * 请求权限
     */
    private void requestPermissionsMethod() {
        XXPermissions.with(this)
                // 申请多个权限
                .permission(Permission.MANAGE_EXTERNAL_STORAGE)
                // 设置权限请求拦截器（局部设置）
                //.interceptor(new PermissionInterceptor())
                // 设置不触发错误检测机制（局部设置）
                //.unchecked()
                .request(new OnPermissionCallback() {

                    @Override
                    public void onGranted(List<String> permissions, boolean all) {
                        hasPermission = true;
                    }

                    @Override
                    public void onDenied(List<String> permissions, boolean never) {
                    }
                });
    }


    ServerActionAppUpdateRequestBean lastServerUpdateBean;


    private long apkInstallTime = 0L;
    // 定时任务，是否安装成功的循环
    private Runnable apkInstallRunnable = new Runnable() {
        @Override
        public void run() {
            AppLogUtils.e("开始apkInstallRunnable检测-------------");
//            AppLogUtils.e("开始apkInstallRunnable检测-------System.currentTimeMillis() =" + System.currentTimeMillis());
//            AppLogUtils.e("开始apkInstallRunnable检测-------apkInstallTime =" + apkInstallTime);
//            AppLogUtils.e("开始apkInstallRunnable检测-------相减 =" + (System.currentTimeMillis() - apkInstallTime));

            if (System.currentTimeMillis() - apkInstallTime >= TIME_INSTALL_ALL) {
                // 现在时间-开始安装时间，超过了安装总时长，算安装失败
//                AppLogUtils.e("超过了安装总时长");
                AppLogUtils.e("超过了安装总时长，主动查询服务器");

                queryServerAppInfo();


//                ArrayList<AppInfoBean> appList = AppUtils.getAppList(MyApplication.getContext());
//
//                if (appList != null && appList.size() > 0) {
//                    // 循环apkUrlMap
//                    for (int i = 0; i < appList.size(); i++) {
//                        for (String key : apkUrlMap.keySet()) {
////                        AppLogUtils.e("map-key:" + key);
//                            ServerActionAppUpdateRequestBean serverUpdateBean = apkUrlMap.get(key);
//
//                            AppInfoBean appInfoBean = appList.get(i);
//
//                            if (key.equals(appInfoBean.getPackageName())) {
//                                AppLogUtils.e("map循环中，有包名");
//
//                                // 安装成功与否发送给服务端的消息
//                                ServerActionAppUpdateResultBean resultBean = new ServerActionAppUpdateResultBean();
//                                resultBean.setSource("app");
//                                resultBean.setSn(DeviceUtils.getDeviceSN());
//                                resultBean.setOp(UPGRADE_PROCESSING);
//                                resultBean.setTaskId(serverUpdateBean.getTaskId());
//                                resultBean.setDownloadPercent(100);
//                                resultBean.setSender(serverUpdateBean.getSender());
//
//                                if (mWebSocketClient == null) {
//                                    initSockect(websocketUrl);
//                                }
//
//                                // 5:安装失败
//                                resultBean.setStatus(5);
//                                String resultStr = gson.toJson(resultBean);
//                                AppLogUtils.e("定时任务--安装失败---发送apk安装升级消息--resultStr: " + resultStr);
//                                mWebSocketClient.send(resultStr);
//
//                            }
//                        }
//                    }
//
//                }


            } else {


                ArrayList<AppInfoBean> appList = AppUtils.getAppList(MyApplication.getContext());

                if (appList != null && appList.size() > 0) {
                    // 循环apkUrlMap
                    for (int i = 0; i < appList.size(); i++) {
                        for (String key : apkUrlMap.keySet()) {
//                        AppLogUtils.e("map-key:" + key);
                            ServerActionAppUpdateRequestBean serverUpdateBean = apkUrlMap.get(key);

                            AppInfoBean appInfoBean = appList.get(i);

                            if (key.equals(appInfoBean.getPackageName())) {
                                AppLogUtils.e("map循环中，有包名");
                                // 已有
                                if (appInfoBean.getVersionName().equals(serverUpdateBean.getVersionName())) {
                                    // 相等就是安装成功
                                    AppLogUtils.e("map循环中，有包名，版本号一致");
                                    // 安装成功与否发送给服务端的消息
                                    ServerActionAppUpdateResultBean resultBean = new ServerActionAppUpdateResultBean();
                                    resultBean.setSource("app");
                                    resultBean.setSn(DeviceUtils.getDeviceSN());
                                    resultBean.setOp(UPGRADE_PROCESSING);
                                    resultBean.setTaskId(serverUpdateBean.getTaskId());
                                    resultBean.setDownloadPercent(100);
                                    resultBean.setSender(serverUpdateBean.getSender());

                                    if (mWebSocketClient == null) {
                                        initSockect(websocketUrl);
                                    }

                                    // 4:安装成功
                                    resultBean.setStatus(4);
                                    String resultStr = gson.toJson(resultBean);
                                    AppLogUtils.e("定时任务--安装成功---发送apk安装升级消息--resultStr: " + resultStr);

                                    sendMessageByWebSocket(resultStr);

                                    pauseTaskAndDelete(serverUpdateBean);

                                } else {
                                    AppLogUtils.e("map循环中，有包名，但版本号还不一致");
                                }

                            }
                        }
                    }

                }


                mHandler.postDelayed(this, TIME_INSTALL_INTERVAL); //每隔一定的时间，进行一次检测
            }
        }
    };


    // ----------aidl 消息互通-----------
    private void bindService() {
        AppLogUtils.e("bindService");
        Intent intent = new Intent(getApplicationContext(), AidlService.class);
        bindService(intent, serviceConnection, BIND_AUTO_CREATE);
    }

    IAidlInterface iAidlInterface;

    boolean isServiceConnection;

    private ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            AppLogUtils.e("onServiceConnected");
            iAidlInterface = IAidlInterface.Stub.asInterface(iBinder);
            isServiceConnection = true;
            AppLogUtils.e("onServiceConnected--iAidlInterface--" + iAidlInterface);
            try {
                iAidlInterface.asBinder().linkToDeath(mDeathRecipient, 0);//监听进程是否消失
                iAidlInterface.registerCallBack(iAidlCallBack);//注册消息回调


            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {

        }
    };

    private IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {
        //当承载IBinder的进程消失时接收回调的接口
        @Override
        public void binderDied() {
            if (null == iAidlInterface) {
                return;
            }
            try {
                iAidlInterface.unregisterCallBack(iAidlCallBack);//注销
            } catch (RemoteException e) {
                e.printStackTrace();
            }
            iAidlInterface.asBinder().unlinkToDeath(mDeathRecipient, 0);
            iAidlInterface = null;
        }
    };


    String businessAppPackageName;
    String businessAppVersionName;

    private IAidlCallBack iAidlCallBack = new IAidlCallBack.Stub() {
        @Override
        public void onMessageSuccess(AppMessageBean appMessageBean) throws RemoteException {
            AppLogUtils.e("IAidlCallBack---getAppMessageBean" + appMessageBean.toString());


            // 接受消息
            if (null != appMessageBean) {
                AppLogUtils.e("接受消息");

                String sender = appMessageBean.getSender();
                AppLogUtils.e("接受消息----sender  " + sender);
                if (!sender.equals(aidlSender)) {
                    // 非自己发出的消息

                    businessAppPackageName = appMessageBean.getBusinessAppPackageName();
                    businessAppVersionName = appMessageBean.getBusinessAppVersionName();
                    String sn = appMessageBean.getSn();

                    AppLogUtils.e("接受消息----businessAppPackageName  " + businessAppPackageName);
                    AppLogUtils.e("接受消息----businessAppVersionName  " + businessAppVersionName);
                    AppLogUtils.e("接受消息----sn  " + sn);

                    if (StringUtils.isNotNull(businessAppPackageName)) {
                        if (apkUrlMap.size() > 0) {
                            ServerActionAppUpdateRequestBean serverUpdateBean = apkUrlMap.get(businessAppPackageName);

                            if (serverUpdateBean == null) {
                                // 可能是包名不是业务app，是新的包
                                AppLogUtils.e("接受消息----上次保存的bean  null");
                            } else {
                                AppLogUtils.e("接受消息----上次保存的bean  " + serverUpdateBean.toString());
                            }
                            String serverVersionName = serverUpdateBean.getVersionName();

                            if (StringUtils.isNotNull(serverVersionName)) {

                                ServerActionAppUpdateResultBean resultBean = new ServerActionAppUpdateResultBean();
                                resultBean.setSource("app");
                                resultBean.setSn(DeviceUtils.getDeviceSN());
                                resultBean.setOp(UPGRADE_PROCESSING);
                                resultBean.setTaskId(serverUpdateBean.getTaskId());
                                resultBean.setDownloadPercent(100);
                                resultBean.setSender(serverUpdateBean.getSender());

                                if (mWebSocketClient == null) {
                                    AppLogUtils.e("iAidlCallBack--websocketUrl--" + websocketUrl);
                                    initSockect(websocketUrl);
                                }

                                if (serverVersionName.equals(businessAppVersionName)) {
                                    // 相等就是安装成功
                                    // 4:安装成功
                                    resultBean.setStatus(4);
                                    String resultStr = gson.toJson(resultBean);
                                    AppLogUtils.e("接受消息--安装成功---发送apk安装升级消息--resultStr: " + resultStr);

                                    sendMessageByWebSocket(resultStr);

                                } else {
                                    // 5:安装失败
                                    resultBean.setStatus(5);
                                    String resultStr = gson.toJson(resultBean);
                                    AppLogUtils.e("接受消息--安装失败---发送apk安装升级消息--resultStr: " + resultStr);

                                    sendMessageByWebSocket(resultStr);
                                }

                                pauseTaskAndDelete(serverUpdateBean);

                            }

                        } else {
                            AppLogUtils.e("apkUrlMap.size()--0");
                        }


                    } else {
                        AppLogUtils.e("businessAppPackageName--null");

                    }

                }


            }

        }


    };

    private void pauseTaskAndDelete(ServerActionAppUpdateRequestBean serverUpdateBean) {
        // 停止下载任务
        mDownloadHelper.pauseTask(serverUpdateBean.getFilePath(), apkFile, FIRST_ACTION).submit(MyApplication.getContext());
        // 删除对应文件
        apkFile = new File(getDir(), serverUpdateBean.getFileName());
        if (apkFile != null && apkFile.exists()) {
            AppLogUtils.e("有对应文件，删除");
            apkFile.delete();
        } else {
            AppLogUtils.e("无对应文件");
        }
        // map移除该key-value
        Iterator<String> iterator = apkUrlMap.keySet().iterator();
        while (iterator.hasNext()) {
            String next = iterator.next();
            if (next.equals(serverUpdateBean.getPackageName())) {
                // 删除
                iterator.remove();
            }
        }


        AppLogUtils.e("newApkUrlMap--set--" + apkUrlMap);
        // 保存到本地
        localConfig.setApkInfoMapStr(gson.toJson(apkUrlMap));
        String apkInfoMapStr = localConfig.getApkInfoMapStr("");
        AppLogUtils.e("newApkUrlMap--get--" + apkInfoMapStr);

        // 移除定时任务
        if (apkInstallRunnable != null) {
            mHandler.removeCallbacks(apkInstallRunnable);
        }
        AppLogUtils.e("移除定时任务");

    }


}
