AppRepository

40 阅读7分钟
package com.alibaba.genie.panel.repository;

import android.text.TextUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.genie.panel.App;
import com.alibaba.genie.panel.BuildConfig;
import com.alibaba.genie.panel.basic.constant.KeyConstant;
import com.alibaba.genie.panel.basic.utils.SpSaveDataUtils;
import com.alibaba.genie.panel.basic.utils.NetDeviceUtils;
import com.aliyun.aligeniessp_1_0.Client;
import com.aliyun.aligeniessp_1_0.models.CreateAlarmRequest;
import com.aliyun.aligeniessp_1_0.models.CreateAlarmResponse;
import com.aliyun.aligeniessp_1_0.models.CreatePlayingListRequest;
import com.aliyun.aligeniessp_1_0.models.CreatePlayingListResponse;
import com.aliyun.aligeniessp_1_0.models.DeleteAlarmsRequest;
import com.aliyun.aligeniessp_1_0.models.DeleteAlarmsResponse;
import com.aliyun.aligeniessp_1_0.models.DeviceControlRequest;
import com.aliyun.aligeniessp_1_0.models.DeviceControlResponse;
import com.aliyun.aligeniessp_1_0.models.GetAlarmRequest;
import com.aliyun.aligeniessp_1_0.models.GetAlarmResponse;
import com.aliyun.aligeniessp_1_0.models.GetCurrentPlayingItemRequest;
import com.aliyun.aligeniessp_1_0.models.GetCurrentPlayingItemResponse;
import com.aliyun.aligeniessp_1_0.models.GetCurrentPlayingListRequest;
import com.aliyun.aligeniessp_1_0.models.GetCurrentPlayingListResponse;
import com.aliyun.aligeniessp_1_0.models.GetDeviceIdByIdentityRequest;
import com.aliyun.aligeniessp_1_0.models.GetDeviceIdByIdentityResponse;
import com.aliyun.aligeniessp_1_0.models.GetUserByDeviceIdRequest;
import com.aliyun.aligeniessp_1_0.models.GetUserByDeviceIdResponse;
import com.aliyun.aligeniessp_1_0.models.GetWeatherRequest;
import com.aliyun.aligeniessp_1_0.models.GetWeatherResponse;
import com.aliyun.aligeniessp_1_0.models.IndexControlPlayingListRequest;
import com.aliyun.aligeniessp_1_0.models.IndexControlPlayingListResponse;
import com.aliyun.aligeniessp_1_0.models.ListAlarmsRequest;
import com.aliyun.aligeniessp_1_0.models.ListAlarmsResponse;
import com.aliyun.aligeniessp_1_0.models.ListMusicRequest;
import com.aliyun.aligeniessp_1_0.models.ListMusicResponse;
import com.aliyun.aligeniessp_1_0.models.ListRecommendContentRequest;
import com.aliyun.aligeniessp_1_0.models.ListRecommendContentResponse;
import com.aliyun.aligeniessp_1_0.models.PlayAndPauseControlRequest;
import com.aliyun.aligeniessp_1_0.models.PlayAndPauseControlResponse;
import com.aliyun.aligeniessp_1_0.models.PlayModeControlRequest;
import com.aliyun.aligeniessp_1_0.models.PlayModeControlResponse;
import com.aliyun.aligeniessp_1_0.models.PreviousAndNextControlRequest;
import com.aliyun.aligeniessp_1_0.models.PreviousAndNextControlResponse;
import com.aliyun.aligeniessp_1_0.models.QueryMusicTypeRequest;
import com.aliyun.aligeniessp_1_0.models.QueryMusicTypeResponse;
import com.aliyun.aligeniessp_1_0.models.ScgSearchRequest;
import com.aliyun.aligeniessp_1_0.models.ScgSearchResponse;
import com.aliyun.aligeniessp_1_0.models.UpdateAlarmRequest;
import com.aliyun.aligeniessp_1_0.models.UpdateAlarmResponse;
import com.aliyun.alink.linksdk.tools.ALog;
import com.aliyun.tea.TeaException;
import com.aliyun.tea.TeaModel;
import com.aliyun.teaopenapi.models.Config;
import com.dnake.system.bean.ImgUpgradeBean;
import com.dnake.system.repository.network.api.ApiService;
import com.dnake.system.repository.network.callback.ObserverCallback;
import com.dnake.system.repository.network.model.BaseModel;
import com.dnake.system.repository.network.response.ApiResponse;
import com.dnake.system.utils.AesUtils;
import com.dnake.system.utils.network.HttpHelper;
import com.google.gson.Gson;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import io.reactivex.Observable;
import okhttp3.MediaType;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;

public final class AppRepository extends BaseModel {

    private static final String TAG = "AppRepository";

    private final Gson gson;

    public AppRepository() {
        gson = new Gson();
    }

    public static void saveDeviceId(String status) {
        SpSaveDataUtils.getInstance().save(App.getApplication(), "persist.api.deviceId", status);
    }

    public static String getDeviceId() {
        return SpSaveDataUtils.getInstance().get(App.getApplication(), "persist.api.deviceId");
    }

    public static void saveUserId(String status) {
        SpSaveDataUtils.getInstance().save(App.getApplication(), "persist.api.userId", status);
    }

    public static String getUserId() {
        return SpSaveDataUtils.getInstance().get(App.getApplication(), "persist.api.userId");
    }

    /**
     * 创建请求 Client
     */
    public Client createClient() throws Exception {
        Config config = new Config()
                // AccessKey ID
                .setAccessKeyId(BuildConfig.ACCESS_KEY_ID)
                // AccessKey Secret
                .setAccessKeySecret(BuildConfig.ACCESS_KEY_SECRET);
        // 访问的域名
        config.endpoint = "openapi.aligenie.com";
        // 创建 Client
        return new Client(config);
    }

    public void execute(Runnable runnable) {
        ThreadPoolManager.getInstance().execute(runnable);
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////
    // 设备信息
    ////////////////////////////////////////////////////////////////////////////////////////////////

    /**
     * 获取设备 ID
     */
    public void loadDeviceId() {
        GetDeviceIdByIdentityRequest request = new GetDeviceIdByIdentityRequest();
        request.setProductKey(BuildConfig.PRODUCT_KEY)
                .setEncodeType(KeyConstant.PROJECT_ID)
                .setEncodeKey(BuildConfig.PROJECT_ID)
                .setIdentityId(NetDeviceUtils.getBlueToothMac(App.getApplication()))
                .setIdentityType(KeyConstant.MAC);
        execute(() -> {
            try {
                GetDeviceIdByIdentityResponse response = createClient().getDeviceIdByIdentity(request);
                String text = response.getBody().getResult().getDeviceOpenId();
                saveDeviceId(text);
                ALog.e(TAG, "DeviceId:" + text);
                if (TextUtils.isEmpty(AppRepository.getUserId())) {
                    loadUserId(text);
                }
            } catch (Exception e) {
                e.printStackTrace();
                saveDeviceId("");
                saveUserId("");
                ALog.e(TAG, "获取设备 ID 失败");
            }
        });
    }

    /**
     * 设备音量等属性控制
     *
     * @param volume 控制的音量
     * @param isMute 是否静音
     */
    public void deviceControl(Integer volume, boolean isMute, final OnResponseListener<DeviceControlResponse> listener) {

        // 控制音量入参
        DeviceControlRequest.DeviceControlRequestControlRequest controlRequest = new DeviceControlRequest.DeviceControlRequestControlRequest()
                .setVolume(volume)
                .setMuted(isMute);

        // 设备标识信息
        DeviceControlRequest.DeviceControlRequestDeviceInfo deviceInfo = new DeviceControlRequest.DeviceControlRequestDeviceInfo()
                .setId(getDeviceId())
                .setIdType(KeyConstant.OPEN_ID)
                .setEncodeType(KeyConstant.PROJECT_ID)
                .setEncodeKey(BuildConfig.PROJECT_ID);

        DeviceControlRequest request = new DeviceControlRequest()
                .setControlRequest(controlRequest)
                .setDeviceInfo(deviceInfo);

        execute(() -> {
            try {
                DeviceControlResponse response = createClient().deviceControl(request);
                listener.onSuccess(response);
            } catch (Exception e) {
                e.printStackTrace();
                TeaException err = new TeaException(e.getMessage(), e);
                listener.onError(err.code, err.message);
            }
        });
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////
    // 用户设备关系
    ////////////////////////////////////////////////////////////////////////////////////////////////

    /**
     * 获取用户 ID
     */
    public void loadUserId(String deviceId) {
        GetUserByDeviceIdRequest request = new GetUserByDeviceIdRequest();

        GetUserByDeviceIdRequest.GetUserByDeviceIdRequestDeviceInfo deviceInfo = new GetUserByDeviceIdRequest.GetUserByDeviceIdRequestDeviceInfo();
        deviceInfo.setEncodeType(KeyConstant.PROJECT_ID)
                .setEncodeKey(BuildConfig.PROJECT_ID)
                .setIdType(KeyConstant.OPEN_ID)
                .setId(deviceId);
        request.setDeviceInfo(deviceInfo);

        execute(() -> {
            try {
                GetUserByDeviceIdResponse response = createClient().getUserByDeviceId(request);
                String text = response.getBody().getResult().getUserOpenId();
                saveUserId(text);
                ALog.e(TAG, "UserId:" + text);
            } catch (Exception e) {
                e.printStackTrace();
                saveDeviceId("");
                saveUserId("");
                ALog.e(TAG, "获取用户 ID 失败");
            }
        });
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////
    // 内容点播 API
    ////////////////////////////////////////////////////////////////////////////////////////////////

    /**
     * 创建播放列表并播放指定的内容
     *
     * @param index       播放的 index (可空 默认为 0 表示从头播放)
     * @param playMode    列表循环:Repeat;随机:Shuffle;单曲循环:RepeatOne;顺序播放:Normal
     * @param contentType 内容:content;专辑:album;歌单:collect
     */
    public void createPlayingList(List<CreatePlayingListRequest.CreatePlayingListRequestOpenCreatePlayingListRequestContentList> contentList
            , int index, String playMode, String contentType
            , final OnResponseListener<CreatePlayingListResponse> listener) {

        CreatePlayingListRequest request = new CreatePlayingListRequest();

        // 用户标识信息
        CreatePlayingListRequest.CreatePlayingListRequestUserInfo userInfo = new CreatePlayingListRequest.CreatePlayingListRequestUserInfo()
                .setId(getUserId())
                .setIdType(KeyConstant.OPEN_ID)
                .setEncodeType(KeyConstant.PROJECT_ID)
                .setEncodeKey(BuildConfig.PROJECT_ID);

        // 设备标识信息
        CreatePlayingListRequest.CreatePlayingListRequestDeviceInfo deviceInfo = new CreatePlayingListRequest.CreatePlayingListRequestDeviceInfo()
                .setId(getDeviceId())
                .setIdType(KeyConstant.OPEN_ID)
                .setEncodeType(KeyConstant.PROJECT_ID)
                .setEncodeKey(BuildConfig.PROJECT_ID);

        // 业务参数
        CreatePlayingListRequest.CreatePlayingListRequestOpenCreatePlayingListRequest playingListRequest = new CreatePlayingListRequest.CreatePlayingListRequestOpenCreatePlayingListRequest()
                .setContentType(contentType)
                .setContentList(contentList)
                .setIndex(index)
                .setPlayMode(playMode);

        request.setDeviceInfo(deviceInfo)
                .setUserInfo(userInfo)
                .setOpenCreatePlayingListRequest(playingListRequest);

        execute(() -> {
            try {
                ALog.i(TAG + "-createPlayingList request", gson.toJson(request) + "\n");
                CreatePlayingListResponse response = createClient().createPlayingList(request);
                ALog.i(TAG + "-createPlayingList response", gson.toJson(response) + "\n");
                listener.onSuccess(response);
            } catch (Exception e) {
                e.printStackTrace();
                TeaException err = new TeaException(e.getMessage(), e);
                listener.onError(err.code, err.message);
            }
        });
    }

    /**
     * 获取每日推荐的音乐或者音频
     */
    public void getMusicDailySpecialList(final OnResponseListener<ListRecommendContentResponse> listener) {
        ListRecommendContentRequest request = new ListRecommendContentRequest();

        request.setRequest(new ListRecommendContentRequest.ListRecommendContentRequestRequest().setType("song").setCount(10))
                .setUserInfo(new ListRecommendContentRequest.ListRecommendContentRequestUserInfo()
                        .setId(getUserId())
                        .setIdType(KeyConstant.OPEN_ID)
                        .setEncodeType(KeyConstant.PROJECT_ID)
                        .setEncodeKey(BuildConfig.PROJECT_ID))
                .setDeviceInfo(new ListRecommendContentRequest.ListRecommendContentRequestDeviceInfo()
                                .setId(getDeviceId())
                                .setIdType(KeyConstant.OPEN_ID)
                                .setEncodeType(KeyConstant.PROJECT_ID)
                                .setEncodeKey(BuildConfig.PROJECT_ID));

        execute(() -> {
            try {
                ALog.i(TAG + "-getMusicDailySpecialList request", gson.toJson(request) + "\n");
                ListRecommendContentResponse response = createClient().listRecommendContent(request);
                ALog.i(TAG + "-getMusicDailySpecialList response", gson.toJson(response) + "\n");
                listener.onSuccess(response);
            } catch (Exception e) {
                e.printStackTrace();
                TeaException err = new TeaException(e.getMessage(), e);
                listener.onError(err.code, err.message);
            }
        });
    }

    /**
     * 获取当前播放项
     */
    public void getCurrentPlayingItem(final OnResponseListener<GetCurrentPlayingItemResponse> listener) {
        GetCurrentPlayingItemRequest request = new GetCurrentPlayingItemRequest();

        request.setDeviceInfo(
                        // 设备标识信息
                        new GetCurrentPlayingItemRequest.GetCurrentPlayingItemRequestDeviceInfo()
                                .setId(getDeviceId())
                                .setIdType(KeyConstant.OPEN_ID)
                                .setEncodeType(KeyConstant.PROJECT_ID)
                                .setEncodeKey(BuildConfig.PROJECT_ID))
                // 用户标识信息
                .setUserInfo(new GetCurrentPlayingItemRequest.GetCurrentPlayingItemRequestUserInfo()
                        .setId(getUserId())
                        .setIdType(KeyConstant.OPEN_ID)
                        .setEncodeType(KeyConstant.PROJECT_ID)
                        .setEncodeKey(BuildConfig.PROJECT_ID));

        execute(() -> {
            try {
                ALog.i(TAG + "-getCurrentPlayingItem request", gson.toJson(request) + "\n");
                GetCurrentPlayingItemResponse response = createClient().getCurrentPlayingItem(request);
                ALog.i(TAG + "-getCurrentPlayingItem response", gson.toJson(response) + "\n");
                listener.onSuccess(response);
            } catch (Exception e) {
                e.printStackTrace();
                TeaException err = new TeaException(e.getMessage(), e);
                listener.onError(err.code, err.message);
            }
        });
    }

    /**
     * 获取当前播放列表
     */
    public void getCurrentPlayingList(int pageSize, final OnResponseListener<GetCurrentPlayingListResponse> listener) {
        GetCurrentPlayingListRequest request = new GetCurrentPlayingListRequest();

        request.setDeviceInfo(
                        // 设备标识信息
                        new GetCurrentPlayingListRequest.GetCurrentPlayingListRequestDeviceInfo()
                                .setId(getDeviceId())
                                .setIdType(KeyConstant.OPEN_ID)
                                .setEncodeType(KeyConstant.PROJECT_ID)
                                .setEncodeKey(BuildConfig.PROJECT_ID))
                // 用户标识信息
                .setUserInfo(new GetCurrentPlayingListRequest.GetCurrentPlayingListRequestUserInfo()
                        .setId(getUserId())
                        .setIdType(KeyConstant.OPEN_ID)
                        .setEncodeType(KeyConstant.PROJECT_ID)
                        .setEncodeKey(BuildConfig.PROJECT_ID))
                //业务参数
                .setOpenQueryPlayListRequest(new GetCurrentPlayingListRequest.GetCurrentPlayingListRequestOpenQueryPlayListRequest()
                        //获取当前播放列表的歌曲数量
                        .setPageSize(pageSize)
                        .setPageNum(1));

        execute(() -> {
            try {
                ALog.i(TAG + "-getCurrentPlayingList", gson.toJson(request) + "\n");
                GetCurrentPlayingListResponse response = createClient().getCurrentPlayingList(request);
                listener.onSuccess(response);
            } catch (Exception e) {
                e.printStackTrace();
                TeaException err = new TeaException(e.getMessage(), e);
                listener.onError(err.code, err.message);
            }
        });
    }

    /**
     * 播放暂停控制
     */
    public void playAndPauseControl(boolean playOrPause, final OnResponseListener<PlayAndPauseControlResponse> listener) {
        PlayAndPauseControlRequest request = new PlayAndPauseControlRequest();

        request.setDeviceInfo(
                        // 设备标识信息
                        new PlayAndPauseControlRequest.PlayAndPauseControlRequestDeviceInfo()
                                .setId(getDeviceId())
                                .setIdType(KeyConstant.OPEN_ID)
                                .setEncodeType(KeyConstant.PROJECT_ID)
                                .setEncodeKey(BuildConfig.PROJECT_ID))
                // 用户标识信息
                .setUserInfo(new PlayAndPauseControlRequest.PlayAndPauseControlRequestUserInfo()
                        .setId(getUserId())
                        .setIdType(KeyConstant.OPEN_ID)
                        .setEncodeType(KeyConstant.PROJECT_ID)
                        .setEncodeKey(BuildConfig.PROJECT_ID))
                //业务参数
                .setOpenPlayAndPauseControlParam(new PlayAndPauseControlRequest.PlayAndPauseControlRequestOpenPlayAndPauseControlParam()
                        .setOpenPlayAndPauseCommand(playOrPause ? "Play" : "Pause"));

        execute(() -> {
            try {
                PlayAndPauseControlResponse response = createClient().playAndPauseControl(request);
                listener.onSuccess(response);
            } catch (Exception e) {
                e.printStackTrace();
                TeaException err = new TeaException(e.getMessage(), e);
                listener.onError(err.code, err.message);
            }
        });
    }

    /**
     * 播放模式设置
     */
    public void playModeControl(String playMode, final OnResponseListener<PlayModeControlResponse> listener) {
        PlayModeControlRequest request = new PlayModeControlRequest();

        request.setDeviceInfo(
                        // 设备标识信息
                        new PlayModeControlRequest.PlayModeControlRequestDeviceInfo()
                                .setId(getDeviceId())
                                .setIdType(KeyConstant.OPEN_ID)
                                .setEncodeType(KeyConstant.PROJECT_ID)
                                .setEncodeKey(BuildConfig.PROJECT_ID))
                // 用户标识信息
                .setUserInfo(new PlayModeControlRequest.PlayModeControlRequestUserInfo()
                        .setId(getUserId())
                        .setIdType(KeyConstant.OPEN_ID)
                        .setEncodeType(KeyConstant.PROJECT_ID)
                        .setEncodeKey(BuildConfig.PROJECT_ID))
                //业务参数
                .setOpenPlayModeControlRequest(new PlayModeControlRequest.PlayModeControlRequestOpenPlayModeControlRequest()
                        .setOpenPlayMode(playMode));

        execute(() -> {
            try {
                PlayModeControlResponse response = createClient().playModeControl(request);
                listener.onSuccess(response);
            } catch (Exception e) {
                e.printStackTrace();
                TeaException err = new TeaException(e.getMessage(), e);
                listener.onError(err.code, err.message);
            }
        });
    }

    /**
     * 对创建的播放列表中的内容进行上下一首控制
     */
    public void previousAndNextControl(boolean isNext, final OnResponseListener<PreviousAndNextControlResponse> listener) {
        PreviousAndNextControlRequest request = new PreviousAndNextControlRequest();

        request.setDeviceInfo(
                        // 设备标识信息
                        new PreviousAndNextControlRequest.PreviousAndNextControlRequestDeviceInfo()
                                .setId(getDeviceId())
                                .setIdType(KeyConstant.OPEN_ID)
                                .setEncodeType(KeyConstant.PROJECT_ID)
                                .setEncodeKey(BuildConfig.PROJECT_ID))
                // 用户标识信息
                .setUserInfo(new PreviousAndNextControlRequest.PreviousAndNextControlRequestUserInfo()
                        .setId(getUserId())
                        .setIdType(KeyConstant.OPEN_ID)
                        .setEncodeType(KeyConstant.PROJECT_ID)
                        .setEncodeKey(BuildConfig.PROJECT_ID))
                //业务参数
                .setOpenControlPlayingListRequest(new PreviousAndNextControlRequest.PreviousAndNextControlRequestOpenControlPlayingListRequest()
                        .setCmd(isNext ? "NEXT" : "PREVIOUS"));

        execute(() -> {
            try {
                PreviousAndNextControlResponse response = createClient().previousAndNextControl(request);
                listener.onSuccess(response);
            } catch (Exception e) {
                e.printStackTrace();
                TeaException err = new TeaException(e.getMessage(), e);
                listener.onError(err.code, err.message);
            }
        });
    }

    /**
     * 播放列表点击播放
     */
    public void indexControlPlayingList(int index, final OnResponseListener<IndexControlPlayingListResponse> listener) {
        IndexControlPlayingListRequest request = new IndexControlPlayingListRequest();

        // 设备标识信息
        IndexControlPlayingListRequest.IndexControlPlayingListRequestDeviceInfo requestDeviceInfo = new IndexControlPlayingListRequest.IndexControlPlayingListRequestDeviceInfo()
                .setId(getDeviceId())
                .setIdType(KeyConstant.OPEN_ID)
                .setEncodeType(KeyConstant.PROJECT_ID)
                .setEncodeKey(BuildConfig.PROJECT_ID);
        // 用户标识信息
        IndexControlPlayingListRequest.IndexControlPlayingListRequestUserInfo requestUserInfo = new IndexControlPlayingListRequest.IndexControlPlayingListRequestUserInfo().setId(getUserId())
                .setIdType(KeyConstant.OPEN_ID)
                .setEncodeType(KeyConstant.PROJECT_ID)
                .setEncodeKey(BuildConfig.PROJECT_ID);
        //业务参数
        IndexControlPlayingListRequest.IndexControlPlayingListRequestOpenIndexControlRequest indexControlRequest = new IndexControlPlayingListRequest.IndexControlPlayingListRequestOpenIndexControlRequest()
                .setIndex(index);

        request.setDeviceInfo(requestDeviceInfo)
                .setUserInfo(requestUserInfo)
                .setOpenIndexControlRequest(indexControlRequest);

        execute(() -> {
            try {
                IndexControlPlayingListResponse response = createClient().indexControlPlayingList(request);
                listener.onSuccess(response);
            } catch (Exception e) {
                e.printStackTrace();
                TeaException err = new TeaException(e.getMessage(), e);
                listener.onError(err.code, err.message);
            }
        });
    }

    /**
     * 根据选品池ID查询选品池内容
     *
     * @param topicId  选品池ID
     * @param pageSize 每页记录条数
     * @param pageNum  页数
     */
    public void getScgSearch(String topicId, int pageSize, int pageNum, final OnResponseListener<ScgSearchResponse> listener) {
        ScgSearchRequest request = new ScgSearchRequest();

        //排序参数
        ScgSearchRequest.ScgSearchRequestScgFilterSortParam scgFilterSortParam = new ScgSearchRequest.ScgSearchRequestScgFilterSortParam()
                .setSortKey("internal_id")
                .setSortOrder("ASC")
                .setSortText("“”");

        //分页类型(每页记录条数)
        ScgSearchRequest.ScgSearchRequestScgFilterPageParam scgFilterPageParam = new ScgSearchRequest.ScgSearchRequestScgFilterPageParam()
                .setPageSize(pageSize)
                .setPageNum(pageNum);

        //分页类型(跳过的条目数量)
        ScgSearchRequest.ScgSearchRequestScgFilterOffSetParam scgFilterOffSetParam = new ScgSearchRequest.ScgSearchRequestScgFilterOffSetParam()
                .setOffset(10)
                .setLimit(16);

        //查询Filter
        ScgSearchRequest.ScgSearchRequestScgFilter scgFilter = new ScgSearchRequest.ScgSearchRequestScgFilter().setSortParam(scgFilterSortParam)
                .setOffSetParam(scgFilterOffSetParam)
                .setPageParam(scgFilterPageParam)
                .setUseOffSet(false);

        request.setScgFilter(scgFilter)
                .setTopicId(topicId);

        execute(() -> {
            try {
                ALog.i(TAG + "-getScgSearch request", gson.toJson(request) + "\n");
                ScgSearchResponse response = createClient().scgSearch(request);
                ALog.i(TAG + "-getScgSearch response", gson.toJson(response) + "\n");
                listener.onSuccess(response);
            } catch (Exception e) {
                e.printStackTrace();
                TeaException err = new TeaException(e.getMessage(), e);
                listener.onError(err.code, err.message);
            }
        });
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////
    // 闹钟 API
    ////////////////////////////////////////////////////////////////////////////////////////////////

    /**
     * 创建闹钟
     *
     * @param scheduleInfo 调度信息
     * @param musicInfo    铃声信息
     * @param volume       铃声音量
     */
    public void createAlarm(CreateAlarmRequest.CreateAlarmRequestPayloadScheduleInfo scheduleInfo,
                            CreateAlarmRequest.CreateAlarmRequestPayloadMusicInfo musicInfo,
                            int volume,
                            OnResponseListener<CreateAlarmResponse> listener) {
        CreateAlarmRequest request = new CreateAlarmRequest();

        // 服务请求入参
        CreateAlarmRequest.CreateAlarmRequestPayload payload = new CreateAlarmRequest.CreateAlarmRequestPayload();
        payload.setScheduleInfo(scheduleInfo)
                .setMusicInfo(musicInfo)
                .setVolume(volume);

        // 用户标识信息
        CreateAlarmRequest.CreateAlarmRequestUserInfo userInfo = new CreateAlarmRequest.CreateAlarmRequestUserInfo();
        userInfo.setId(getUserId())
                .setIdType(KeyConstant.OPEN_ID)
                .setEncodeType(KeyConstant.PROJECT_ID)
                .setEncodeKey(BuildConfig.PROJECT_ID);

        // 设备标识信息
        CreateAlarmRequest.CreateAlarmRequestDeviceInfo deviceInfo = new CreateAlarmRequest.CreateAlarmRequestDeviceInfo();
        deviceInfo.setId(getDeviceId())
                .setIdType(KeyConstant.OPEN_ID)
                .setEncodeType(KeyConstant.PROJECT_ID)
                .setEncodeKey(BuildConfig.PROJECT_ID);

        request.setPayload(payload)
                .setUserInfo(userInfo)
                .setDeviceInfo(deviceInfo);

        execute(() -> {
            try {
                CreateAlarmResponse response = createClient().createAlarm(request);
                listener.onSuccess(response);
            } catch (Exception e) {
                e.printStackTrace();
                TeaException err = new TeaException(e.getMessage(), e);
                listener.onError(err.code, err.message);
            }
        });
    }

    /**
     * 批量删除闹钟
     *
     * @param ids 删除的闹钟 id 集合
     */
    public void deleteAlarms(List<Long> ids, OnResponseListener<DeleteAlarmsResponse> listener) {
        DeleteAlarmsRequest request = new DeleteAlarmsRequest();

        // 服务请求入参
        DeleteAlarmsRequest.DeleteAlarmsRequestPayload payload = new DeleteAlarmsRequest.DeleteAlarmsRequestPayload();
        payload.setAlarmIds(ids);

        // 用户标识信息
        DeleteAlarmsRequest.DeleteAlarmsRequestUserInfo userInfo = new DeleteAlarmsRequest.DeleteAlarmsRequestUserInfo();
        userInfo.setId(getUserId())
                .setIdType(KeyConstant.OPEN_ID)
                .setEncodeType(KeyConstant.PROJECT_ID)
                .setEncodeKey(BuildConfig.PROJECT_ID);

        // 设备标识信息
        DeleteAlarmsRequest.DeleteAlarmsRequestDeviceInfo deviceInfo = new DeleteAlarmsRequest.DeleteAlarmsRequestDeviceInfo();
        deviceInfo.setId(getDeviceId())
                .setIdType(KeyConstant.OPEN_ID)
                .setEncodeType(KeyConstant.PROJECT_ID)
                .setEncodeKey(BuildConfig.PROJECT_ID);

        request.setPayload(payload)
                .setUserInfo(userInfo)
                .setDeviceInfo(deviceInfo);

        execute(() -> {
            try {
                DeleteAlarmsResponse response = createClient().deleteAlarms(request);
                listener.onSuccess(response);
            } catch (Exception e) {
                e.printStackTrace();
                TeaException err = new TeaException(e.getMessage(), e);
                listener.onError(err.code, err.message);
            }
        });
    }

    /**
     * 获取单个闹钟详情
     *
     * @param id 闹钟 id
     */
    public void getAlarm(Long id, OnResponseListener<GetAlarmResponse> listener) {
        GetAlarmRequest request = new GetAlarmRequest();

        // 服务请求入参
        GetAlarmRequest.GetAlarmRequestPayload payload = new GetAlarmRequest.GetAlarmRequestPayload();
        payload.setAlarmId(id);

        // 用户标识信息
        GetAlarmRequest.GetAlarmRequestUserInfo userInfo = new GetAlarmRequest.GetAlarmRequestUserInfo();
        userInfo.setId(getUserId())
                .setIdType(KeyConstant.OPEN_ID)
                .setEncodeType(KeyConstant.PROJECT_ID)
                .setEncodeKey(BuildConfig.PROJECT_ID);

        // 设备标识信息
        GetAlarmRequest.GetAlarmRequestDeviceInfo deviceInfo = new GetAlarmRequest.GetAlarmRequestDeviceInfo();
        deviceInfo.setId(getDeviceId())
                .setIdType(KeyConstant.OPEN_ID)
                .setEncodeType(KeyConstant.PROJECT_ID)
                .setEncodeKey(BuildConfig.PROJECT_ID);

        request.setPayload(payload)
                .setUserInfo(userInfo)
                .setDeviceInfo(deviceInfo);

        execute(() -> {
            try {
                GetAlarmResponse response = createClient().getAlarm(request);
                listener.onSuccess(response);
            } catch (Exception e) {
                e.printStackTrace();
                TeaException err = new TeaException(e.getMessage(), e);
                listener.onError(err.code, err.message);
            }
        });
    }

    /**
     * 查询闹钟列表
     *
     * @param currentPage 当前页
     * @param pageSize    每页条数,最大 100
     */
    public void getListAlarms(final int currentPage,
                              final int pageSize,
                              final OnResponseListener<ListAlarmsResponse> listener) {
        ListAlarmsRequest request = new ListAlarmsRequest();

        // 服务请求入参
        ListAlarmsRequest.ListAlarmsRequestPayload payload = new ListAlarmsRequest.ListAlarmsRequestPayload();
        payload.setCurrentPage(currentPage)
                .setPageSize(pageSize);

        // 用户标识信息
        ListAlarmsRequest.ListAlarmsRequestUserInfo userInfo = new ListAlarmsRequest.ListAlarmsRequestUserInfo();
        userInfo.setId(getUserId())
                .setIdType(KeyConstant.OPEN_ID)
                .setEncodeType(KeyConstant.PROJECT_ID)
                .setEncodeKey(BuildConfig.PROJECT_ID);

        // 设备标识信息
        ListAlarmsRequest.ListAlarmsRequestDeviceInfo deviceInfo = new ListAlarmsRequest.ListAlarmsRequestDeviceInfo();
        deviceInfo.setId(getDeviceId())
                .setIdType(KeyConstant.OPEN_ID)
                .setEncodeType(KeyConstant.PROJECT_ID)
                .setEncodeKey(BuildConfig.PROJECT_ID);

        request.setPayload(payload)
                .setUserInfo(userInfo)
                .setDeviceInfo(deviceInfo);

        execute(() -> {
            try {
                ListAlarmsResponse response = createClient().listAlarms(request);
                listener.onSuccess(response);
            } catch (Exception e) {
                e.printStackTrace();
                TeaException err = new TeaException(e.getMessage(), e);
                listener.onError(err.code, err.message);
            }
        });
    }

    /**
     * 查询闹钟铃声分页列表
     *
     * @param musicType     铃声类别 id 通过 {@link #queryMusicType(OnResponseListener)} 获取
     * @param musicTypeName 铃声类别名称 获取方式同上
     * @param currentPage   当前页
     * @param pageSize      每页条数 最大值100
     */
    public void getMusicList(Long musicType,
                             String musicTypeName,
                             int currentPage,
                             int pageSize,
                             OnResponseListener<ListMusicResponse> listener) {
        ListMusicRequest request = new ListMusicRequest();

        // 服务请求入参
        ListMusicRequest.ListMusicRequestPayload payload = new ListMusicRequest.ListMusicRequestPayload();
        payload.setMusicType(musicType)
                .setMusicTypeName(musicTypeName)
                .setCurrentPage(currentPage)
                .setPageSize(pageSize);

        // 用户标识信息
        ListMusicRequest.ListMusicRequestUserInfo userInfo = new ListMusicRequest.ListMusicRequestUserInfo();
        userInfo.setId(getUserId())
                .setIdType(KeyConstant.OPEN_ID)
                .setEncodeType(KeyConstant.PROJECT_ID)
                .setEncodeKey(BuildConfig.PROJECT_ID);

        // 设备标识信息
        ListMusicRequest.ListMusicRequestDeviceInfo deviceInfo = new ListMusicRequest.ListMusicRequestDeviceInfo();
        deviceInfo.setId(getDeviceId())
                .setIdType(KeyConstant.OPEN_ID)
                .setEncodeType(KeyConstant.PROJECT_ID)
                .setEncodeKey(BuildConfig.PROJECT_ID);

        request.setPayload(payload)
                .setUserInfo(userInfo)
                .setDeviceInfo(deviceInfo);

        execute(() -> {
            try {
                ListMusicResponse response = createClient().listMusic(request);
                listener.onSuccess(response);
            } catch (Exception e) {
                e.printStackTrace();
                TeaException err = new TeaException(e.getMessage(), e);
                listener.onError(err.code, err.message);
            }
        });
    }

    /**
     * 获取闹钟音乐类型列表
     */
    public void queryMusicType(OnResponseListener<QueryMusicTypeResponse> listener) {
        QueryMusicTypeRequest request = new QueryMusicTypeRequest();

        // 用户标识信息
        QueryMusicTypeRequest.QueryMusicTypeRequestUserInfo userInfo = new QueryMusicTypeRequest.QueryMusicTypeRequestUserInfo();
        userInfo.setId(getUserId())
                .setIdType(KeyConstant.OPEN_ID)
                .setEncodeType(KeyConstant.PROJECT_ID)
                .setEncodeKey(BuildConfig.PROJECT_ID);

        // 设备标识信息
        QueryMusicTypeRequest.QueryMusicTypeRequestDeviceInfo deviceInfo = new QueryMusicTypeRequest.QueryMusicTypeRequestDeviceInfo();
        deviceInfo.setId(getDeviceId())
                .setIdType(KeyConstant.OPEN_ID)
                .setEncodeType(KeyConstant.PROJECT_ID)
                .setEncodeKey(BuildConfig.PROJECT_ID);

        request.setUserInfo(userInfo)
                .setDeviceInfo(deviceInfo);

        execute(() -> {
            try {
                QueryMusicTypeResponse response = createClient().queryMusicType(request);
                listener.onSuccess(response);
            } catch (Exception e) {
                e.printStackTrace();
                TeaException err = new TeaException(e.getMessage(), e);
                listener.onError(err.code, err.message);
            }
        });
    }

    /**
     * 更新闹钟
     *
     * @param id           闹钟 id
     * @param volume       铃声音量
     * @param scheduleInfo 调度信息
     * @param musicInfo    铃声信息
     */
    public void updateAlarm(Long id,
                            int volume,
                            UpdateAlarmRequest.UpdateAlarmRequestPayloadScheduleInfo scheduleInfo,
                            UpdateAlarmRequest.UpdateAlarmRequestPayloadMusicInfo musicInfo,
                            OnResponseListener<UpdateAlarmResponse> listener) {
        UpdateAlarmRequest request = new UpdateAlarmRequest();

        // 服务请求入参
        UpdateAlarmRequest.UpdateAlarmRequestPayload payload = new UpdateAlarmRequest.UpdateAlarmRequestPayload();
        payload.setAlarmId(id)
                .setVolume(volume)
                .setScheduleInfo(scheduleInfo)
                .setMusicInfo(musicInfo);

        // 用户标识信息
        UpdateAlarmRequest.UpdateAlarmRequestUserInfo userInfo = new UpdateAlarmRequest.UpdateAlarmRequestUserInfo();
        userInfo.setId(getUserId())
                .setIdType(KeyConstant.OPEN_ID)
                .setEncodeType(KeyConstant.PROJECT_ID)
                .setEncodeKey(BuildConfig.PROJECT_ID);

        // 设备标识信息
        UpdateAlarmRequest.UpdateAlarmRequestDeviceInfo deviceInfo = new UpdateAlarmRequest.UpdateAlarmRequestDeviceInfo();
        deviceInfo.setId(getDeviceId())
                .setIdType(KeyConstant.OPEN_ID)
                .setEncodeType(KeyConstant.PROJECT_ID)
                .setEncodeKey(BuildConfig.PROJECT_ID);

        request.setPayload(payload)
                .setUserInfo(userInfo)
                .setDeviceInfo(deviceInfo);

        execute(() -> {
            try {
                UpdateAlarmResponse response = createClient().updateAlarm(request);
                listener.onSuccess(response);
            } catch (Exception e) {
                e.printStackTrace();
                TeaException err = new TeaException(e.getMessage(), e);
                listener.onError(err.code, err.message);
            }
        });
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////
    // 天气请求
    ////////////////////////////////////////////////////////////////////////////////////////////////

    /**
     * 查询天气
     */
    public void getWeather(OnResponseListener<GetWeatherResponse> listener) {
        GetWeatherRequest request = new GetWeatherRequest();

        // 用户标识信息
        GetWeatherRequest.GetWeatherRequestUserInfo userInfo = new GetWeatherRequest.GetWeatherRequestUserInfo();
        userInfo.setId(getUserId())
                .setIdType(KeyConstant.OPEN_ID)
                .setEncodeType(KeyConstant.PROJECT_ID)
                .setEncodeKey(BuildConfig.PROJECT_ID);

        // 设备标识信息
        GetWeatherRequest.GetWeatherRequestDeviceInfo deviceInfo = new GetWeatherRequest.GetWeatherRequestDeviceInfo();
        deviceInfo.setId(getDeviceId())
                .setIdType(KeyConstant.OPEN_ID)
                .setEncodeType(KeyConstant.PROJECT_ID)
                .setEncodeKey(BuildConfig.PROJECT_ID);

        request.setPayload(new GetWeatherRequest.GetWeatherRequestPayload())
                .setUserInfo(userInfo)
                .setDeviceInfo(deviceInfo);

        execute(() -> {
            try {
                GetWeatherResponse response = createClient().getWeather(request);
                listener.onSuccess(response);
            } catch (Exception e) {
                e.printStackTrace();
                TeaException err = new TeaException(e.getMessage(), e);
                listener.onError(err.code, err.message);
            }
        });
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////
    // OTA升级
    ////////////////////////////////////////////////////////////////////////////////////////////////

    /**
     * 检查固件升级
     */
    public Observable<ApiResponse<ImgUpgradeBean>> checkImgVersion(String model, int versionNum) {
        Map<String, Object> map = new HashMap<>();
        map.put("model", model);
        map.put("versionNum", versionNum);
        RequestBody body = createBody(map);
        return getApiService().checkImgVersion(body);
    }

    /**
     * 创建RequestBody
     *
     * @param obj Object
     */
    public RequestBody createBody(Object obj) {
        String json = JSON.toJSONString(obj);
        ALog.i("http", "createBody: " + json);
        String cipher = AesUtils.encrypt(HttpHelper.RC4_KEY, json);
        String body = "{"cipher":"" + cipher + ""}";
        return RequestBody.create(MediaType.parse("application/json"), body);
    }

    private ApiService getApiService() {
        return HttpHelper.getInstance().create(ApiService.class);
    }

    public Observable<ResponseBody> downloadFile(String url) {
        return getApiService().downloadFile(url);
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////
    // 其他
    ////////////////////////////////////////////////////////////////////////////////////////////////

    /**
     * 添加需回收的Http请求
     *
     * @param callback ObserverCallback
     */
    public void addCallback(ObserverCallback callback) {
        callbacks.add(callback);
    }


    /**
     * 请求响应监听
     */
    public interface OnResponseListener<T extends TeaModel> {
        /**
         * 成功
         *
         * @param response 返回的信息
         */
        void onSuccess(T response);

        /**
         * 失败
         *
         * @param code    错误码
         * @param message 错误信息
         */
        void onError(String code, String message);
    }
}