SDK流程详解 - yaokantv/YKCenterSDKExample_for_AS GitHub Wiki

1.初始化

1.1 配置AndroidManifest.xml

<application
    ... >
    
    <meta-data
        android:name="yk_key"
        android:value="ykxxxxx" />
    <!-- yk_key需要向我公司申请 格式为:ykxxxxxx -->
</application>

1.2 初始化YKSDK

// 初始化SDK
YkanSDKManager.init(Context ctx, InitYkanListener initYkanListener);
// 设置Log信息是否打印
YkanSDKManager.getInstance().setLogger(true);
// 设置监听回调
DeviceManager.instanceDeviceManager(this).setGizWifiCallBack();

在InitYkanListener里面设置初始化的回调
@Override
public void onInitStart() {
    //初始化开始
}

@Override
public void onInitFinish(final int status, final String errorMsg) {
    //初始化结束
}

注意:只有在初始化完成之后,App才能完成后续的操作。

2.用户管理

用户管理包含了用户的注册、登录、重置密码等功能。更换APPID后,需要重新注册用户。
用户的注册方式有多种,比如手机号、普通用户名、邮箱等,APP可以根据需要采取不同的方式。其他流程比如登录、重置修改等部分,请直接阅读下面的流程文档。

2.1 用户注册

SDK提供三种用户注册方式:手机注册、普通用户注册、邮箱注册。

2.1.1 手机注册

通过手机注册账号,需要一个有效的手机号。注册时需要两步操作:获取短信验证码、用短信验证码注册用户。

第一步:APP获取短信验证码时,SDK向云端发送短信验证码请求,如果请求成功,云端会给手机发送短信验证码。

【示例代码】

//发送验证码
DeviceManager.instanceDeviceManager(getApplicationContext()).sendPhoneSmsCode(Context context, String phone);
//用于获取验证码的回调
DeviceManager.instanceDeviceManager(getApplicationContext()).setGizWifiCallBack(new GizWifiCallBack() {
        @Override
        public void didRequestSendPhoneSMSCodeCb(GizWifiErrorCode result) {
            if (result == GizWifiErrorCode.GIZ_SDK_SUCCESS) {
                handler.sendEmptyMessage(SEND_SUCCESSFUL);
                // 请求成功
            } else {
                // 请求失败
            }
        }
    });

第二步:用短信验证码注册时,APP把手机收到的短信验证码传给SDK,填上手机号和密码就可以注册了。

【示例代码】

//手机注册
DeviceManager.instanceDeviceManager(getApplicationContext()).register(String userName, String password, String code, YKUserAccountType YKUserAccountType.YKUserPhone)
//用于用户注册的回调
DeviceManager.instanceDeviceManager(getApplicationContext()).setGizWifiCallBack(new GizWifiCallBack() {
         @Override
        public void registerUserCb(GizWifiErrorCode result, String uid, String token) {
            Logger.d(TAG, "registerUserCb result:" + result + " uid:" + uid + " token:" + token);
            dialogUtils.sendMessage(ProgressDialogUtils.DISMISS);
            if (result == GizWifiErrorCode.GIZ_SDK_SUCCESS) {
                Toast.makeText(getApplicationContext(), "注册成功", Toast.LENGTH_LONG).show();
                toDeviceList();
                finish();
            } else if (result == GizWifiErrorCode.GIZ_OPENAPI_USERNAME_UNAVALIABLE) {
                Toast.makeText(getApplicationContext(), "userName  unavaliabale", Toast.LENGTH_LONG).show();
            } else if (result == GizWifiErrorCode.GIZ_OPENAPI_CODE_INVALID) {
                Toast.makeText(getApplicationContext(), "验证码不正确", Toast.LENGTH_LONG).show();
            } else if (result == GizWifiErrorCode.GIZ_OPENAPI_EMAIL_UNAVALIABLE) {
                Toast.makeText(getApplicationContext(), "该邮箱已注册或该邮箱无效", Toast.LENGTH_LONG).show();
            } else if (result == GizWifiErrorCode.GIZ_OPENAPI_PHONE_UNAVALIABLE) {
                Toast.makeText(getApplicationContext(), "该手机已️注册或该手机号码无效", Toast.LENGTH_LONG).show();
            } else {
                Toast.makeText(getApplicationContext(), "注册失败,请重新注册", Toast.LENGTH_LONG).show();
            }
        }
    });

2.1.2 普通注册

注册普通用户,使用用户名、密码即可创建一个账号。

【示例代码】

//手机注册
DeviceManager.instanceDeviceManager(getApplicationContext()).register(String userName, String password, null, YKUserAccountType YKUserAccountType.YKUserNormal)
//注册回调与手机注册回调一致

2.1.3 邮箱注册

通过有效的电子邮箱地址,注册一个账号。注册成功后,云端会给指定邮箱发送注册成功的邮件。

【示例代码】

//手机注册
DeviceManager.instanceDeviceManager(getApplicationContext()).register(String userName, String password, null, YKUserAccountType YKUserAccountType.YKUserEmail)
//注册回调与手机注册回调一致

2.2 用户登录

Android SDK 提供三种登录方式:普通用户登录、手机/邮箱(手机邮箱用同一种登录方式)登录、匿名登录。

2.2.1 普通用户登录

通过普通注册成功的用户,可以通过普通用户登录来登录我们SDK。

【示例代码】

//普通用户登录
DeviceManager.instanceDeviceManager(getApplicationContext()).userLogin(String userName, String password, YKUserAccountType YKUserAccountType.YKUserNormal)
//登录回调
DeviceManager.instanceDeviceManager(getApplicationContext()).setGizWifiCallBack(new GizWifiCallBack() {
    @Override
        public void userLoginCb(GizWifiErrorCode result, String uid, String token) {
            if (result == GizWifiErrorCode.GIZ_SDK_SUCCESS) {// 登陆成功
                toDeviceList();
            } else if (result == GizWifiErrorCode.GIZ_OPENAPI_USER_NOT_EXIST) {// 用户不存在
                toast(R.string.GIZ_OPENAPI_USER_NOT_EXIST);
            } else if (result == GizWifiErrorCode.GIZ_OPENAPI_USERNAME_PASSWORD_ERROR) {//// 用户名或者密码错误
                toast(R.string.GIZ_OPENAPI_USERNAME_PASSWORD_ERROR);
            } else {
                toast("登陆失败,请重新登录");
            }
        }
});

2.2.2 手机/邮箱登录

通过手机/邮箱注册成功的用户,可以通过手机/邮箱登录来登录我们SDK。

【示例代码】

//普通用户登录
DeviceManager.instanceDeviceManager(getApplicationContext()).userLogin(String userName, String password, YKUserAccountType YKUserAccountType.YKUserPhone)
//登录回调与普通登录回调一致

2.2.3 匿名登录

用户每次匿名登录时,获取到的uid是相同的。Android SDK使用Android ID生成登录账号。每个Android系统都有一个独立的Android ID,系统刷机后将改变。因此,系统刷机后匿名登录的用户信息将无法保留。

【示例代码】

//匿名登录
DeviceManager.instanceDeviceManager(getApplicationContext()).userLoginAnonymous();

2.3重置密码

如果忘记了用户密码,可以通过手机验证码或邮箱设置新的密码。SDK支持手机号重置密码和邮箱重置密码两种,手机号重置需要接收验证码,邮箱重置需要进⼊邮箱,根据链接提示进行重置。(注意:暂时不支持普通用户重置密码!)

2.3.1 手机号重置密码

手机号重置密码时,需要先获取短信验证码再重置。获取短信验证码方式与手机注册时相同。

第一步:获取短信验证码(与注册时相同,这里不再赘述)

第二步:用短信验证码重置密码

【示例代码】

DeviceManager.instanceDeviceManager(getApplicationContext()).resetPassword(String userName, String password, String code, YKUserAccountType YKUserAccountType.YKUserPhone)
//重置密码回调
DeviceManager.instanceDeviceManager(getApplicationContext()).setGizWifiCallBack(new GizWifiCallBack() {
/** 用于重置密码的回调 */
        @Override
        public void didChangeUserPasswordCd(GizWifiErrorCode result) {
            dialogUtils.sendMessage(ProgressDialogUtils.DISMISS);
            if (result == GizWifiErrorCode.GIZ_SDK_SUCCESS) {
                // 请求成功
            } else {
                // 请求失败
            }
        }
});

2.3.2 邮箱重置密码

邮箱重置密码时,云端会给指定邮箱发送安全链接。用户需要到邮箱中查收邮件,并按邮件指示执行重置操作。重置密码邮件有可能进入用户的邮箱的垃圾箱中,需提醒用户。

邮件发送成功回调与密码修改成功回调一致,因此需要注意在回调的时候区分。

【示例代码】

DeviceManager.instanceDeviceManager(getApplicationContext()).resetPassword(String userName, String password, String code, YKUserAccountType YKUserAccountType.YKUserEmail)

3.小苹果管理

3.1 配置入网

控制设备前,需要先让设备连到路由器上。连上路由器的设备,如果路由器能接入外网,设备会自动注册到SDK。

在开始配置前,设备要先进入配置模式,然后APP调用配置接口发送要配置的路由器ssid和密码。设备配置成功后,SDK给APP返回已配置成功的设备mac地址和产品类型标识,便于APP做下一步的操作。如果设备是重置后进入的配置模式,如果配置成功时设备还来不及从云端获取到DID,则APP得到的DID为空。

SDK的设备配置接口如果超时时间还未结束,无法进行下一次配置。此外,因为设备配置成功的广播包只有APP连到同一路由上才能收取,因此这个超时时间应该预留出APP连接路由器的时间。

需要注意的是,如果配置上线的设备不是APP要获取的产品类型,该设备就不会出现在设备列表中。

3.1.1 创建DeviceConfig对象

【示例代码】
public DeviceConfig(Context ctx,IDeviceConfigListener iConfig)
参数说明
ctx:上下文
IdeviceConfigListener:配置是否成功回调接口

3.1.2 设置回调函数

【示例代码】
@Override
public void didSetDeviceOnboarding(GizWifiErrorCode result, String mac,
		String did, String productKey) {
	if (GizWifiErrorCode.GIZ_SDK_DEVICE_CONFIG_IS_RUNNING == result) {
		return;
	} 
	if (result == GizWifiErrorCode.GIZ_SDK_SUCCESS) { 
	    //入网成功
	} else { 
	    //入网失败
	} 
} 

3.1.3 设置密码并开始入网

【示例代码】
deviceConfig.setPwdSSID(String workSSID, String workSSIDPsw);
deviceConfig.startAirlink(String workSSID,String  workSSIDPsw);
参数说明:
workSSID :wifi 设备的ssid
workSSIDPsw :wifi 密码

3.1.4 停止设备配网

【示例代码】
deviceConfig.stopDeviceOnboarding();  

3.2设备发现和订阅部分

3.2.1设备发现

APP设置好监听,启动SDK后,就可以收到SDK的设备列表推送。每次局域网设备或者用户绑定设备发生变化时,SDK都会主动上报最新的设备列表。设备断电再上电、有新设备上线等都会触发设备列表发生变化。用户登录后,SDK会主动把用户已绑定的设备列表上报给APP,绑定设备在不同的手机上登录帐号都可获取到。

如果APP想要刷新绑定设备列表,可以调用绑定设备列表接口,同时可以指定自己关心的产品类型标识,SDK会把筛选后的设备列表返回给APP。 SDK提供设备列表缓存,设备列表中的设备对象在整个APP生命周期中一直有效。缓存的设备列表会与当前最新的已发现设备同步更新。

【示例代码】
DeviceManager mDeviceManager = DeviceManager.instanceDeviceManager(getApplicationContext());
//设置设备发现的监听
mDeviceManager.setGizWifiCallBack(new GizWifiCallBack() {
    @Override
    public void discoveredrCb(GizWifiErrorCode result,java.util.List<GizWifiDevice> deviceList) {
        switch (result) {
            case GIZ_SDK_SUCCESS:
                //实时刷新
                update(deviceList);
                break;
            default:
                break;
        }
    }
});
//获取设备列表
mDeviceManager.getCanUseGizWifiDevice();

3.2.2 设备订阅和绑定

APP得到设备列表后,给设备设置监听后,可以订阅设备。已订阅的设备将被自动绑定和自动登录,设备登录成功后会主动上报最新状态。

自动绑定仅限于局域网设备。对于无法在局域网内发现的设备,APP可以通过手动绑定的方式完成绑定。绑定成功的设备,需要订阅后才能使用。

解除订阅的设备,连接会被断开,不能再继续下发控制指令了。

所有通过SDK得到的设备,都可以订阅,订阅结果通过回调返回。订阅成功的设备,要在其网络状态变为可控时才能查询状态和下发控制指令。

【示例代码】
// 以设备列表中的第一个设备实例为例,为其设置监听
GizWifiDevice mDevice = null;
for (int i = 0; i < deviceList.size(); i++) {
    mDevice = deviceList[0];
    mDevice.setListener(mListener);
    mDevice.setSubscribe(true);
    break;
}

3.2.3 设备解绑

已绑定的设备可以解绑,解绑需要APP调用接口完成操作,SDK不支持自动解绑。对于已订阅的设备,解绑成功时会被解除订阅,同时断开设备连接,设备状态也不会再主动上报了。设备解绑后,APP刷新绑定设备列表时就得不到该设备了。

【示例代码】
GizWifiDevice mGizWifiDevice = wifiDevices.get(position);
// 已经绑定的设备才去解绑
if (mGizWifiDevice.isBind()) {
    // 解绑该设备 
    mDeviceManager.unbindDevice(mGizWifiDevice.etDid()); update(mDeviceManager.getCanUseGizWifiDevice());
} else {
    toast("该设备未绑定");
}

4.遥控器管理

4.1 初始化

在下载遥控器数据之前,要创建遥控云接口对象,且需要在下载数据之前需要设置设备ID,用哪个设备去下载。

【示例代码】
// 遥控云数据接口分装对象对象
ykanInterface = new YkanIRInterfaceImpl(getApplicationContext());
//下载数据之前需要设置设备ID,用哪个设备去下载
YkanSDKManager.getInstance().setDeviceId(GizWifiDevice.getDid());

4.2 获取遥控云所有的设备类型

【示例代码】
/**
* @param mac:设备Mac地址
* @param listener:http请求回调方法
*/
ykanInterface.getDeviceType(currGizWifiDevice.getMacAddress(), new YKanHttpListener() {
    @Override
    public void onSuccess(BaseResult baseResult) {
        DeviceTypeResult deviceResult = (DeviceTypeResult) baseResult;
        ...
    }
    @Override
    public void onFail(YKError ykError) {
        Log.e(TAG, "ykError:" + ykError.toString());
    }
});

4.3 获取设备类型下面的所有品牌

【示例代码】
/**
 * @param mac:设备Mac地址
 * @param type:设备型号
 * @param listener:http请求回调方法
 */
ykanInterface.getBrandsByType(currGizWifiDevice.getMacAddress(), currDeviceType.getTid(), new YKanHttpListener() {
    @Override
    public void onSuccess(BaseResult baseResult) {
        BrandResult brandResult = (BrandResult) baseResult;
    }
    @Override
    public void onFail(YKError ykError) {
        Log.e(TAG, "ykError:" + ykError.toString());
    }
});

4.3 根据品牌id和设备类型获取匹配的遥控器对象集合

【示例代码】
/**
 * @param mac:设备Mac地址
 * @param bid:品牌ID
 * @param type:设备类型ID
 * @param listener:http请求回调方法
 */
 ykanInterface.getRemoteMatched(currGizWifiDevice.getMacAddress(),currBrand.getBid(), currDeviceType.getTid(), new YKanHttpListener() {
    @Override
    public void onSuccess(BaseResult baseResult) {
        controlResult = (MatchRemoteControlResult) baseResult;
    }
    @Override
    public void onFail(YKError ykError) {
        Log.e(TAG, "ykError:" + ykError.toString());
    }
});

4.4 根据遥控ID获取遥控器相关详细信息

【示例代码】
/**
 * @param mac:设备Mac地址
 * @param rcID:遥控器ID
 * @param listener:http请求回调方法
 */
 ykanInterface.getRemoteDetails(currGizWifiDevice.getMacAddress(), currRemoteControl.getRid(), new YKanHttpListener() {
    @Override
    public void onSuccess(BaseResult baseResult) {
        if (baseResult != null) {
            remoteControl = (RemoteControl) baseResult;
        }
    }
    @Override
    public void onFail(YKError ykError) {
        Log.e(TAG, "ykError:" + ykError.toString());
    }
});

5.遥控码库管理

5.1 码库的使用

5.1.1 创建设备的控制器

【示例代码】
参数说明
ctx  :上下文
GizWifiDevice:当前使用的小苹果
IdeviceControllerListener:需要回调监听
DeviceController driverControl = new DeviceController(Context ctx, GizWifiDevice device, IDeviceControllerListener listener);

public interface IDeviceControllerListener {
    public void didUpdateNetStatus(GizWifiDevice device, GizWifiDeviceNetStatus netStatus) {
        switch (device.getNetStatus()) {
            case GizDeviceOffline:
                Logger.d(TAG, "设备下线");
                break;
            case GizDeviceOnline:
                Logger.d(TAG, "设备上线");
                break;
            default:
                break;
        }
    }

    public void didGetHardwareInfo(GizWifiErrorCode result, GizWifiDevice device, ConcurrentHashMap<String, String> hardwareInfo) {
        Logger.d(TAG, "获取设备信息 :");
        if (GizWifiErrorCode.GIZ_SDK_SUCCESS == result) {
            Logger.d(TAG, "获取设备信息 : hardwareInfo :" + hardwareInfo);
        } else {
        }
    }

    public void didSetCustomInfo(GizWifiErrorCode result, GizWifiDevice device) {
        Logger.d(TAG, "自定义设备信息回调");
        if (GizWifiErrorCode.GIZ_SDK_SUCCESS == result) {
            Logger.d(TAG, "自定义设备信息成功");
        }
    }
}

5.1.2 发送红外码

根据之前下载的红外遥控码,通过设备控制器就能将红外码发送到小苹果。

【示例代码】
driverControl.sendCMD(code, SendType.Infrared);
备注:SendType为枚举类型
SendType.Infrared 为红外
SendType.RadioFrequency 为433/315射频
SendType.RadioFrequencySP 为特殊433/315射频
SendType.Trunk 为透传

5.2 红外码学习

5.2.1 设置回调函数

在学习之前需要初始化,把监听接口传入,在回调函数里面,如果学习成功,会有相应的数据返回,用户可以把学习到的红外码保存下来。

【示例代码】
//设置回调函数
DeviceController. initLearn(LearnCodeListener);

public interface LearnCodeListener {
    /**
     * 接收数据
     */
    public void didReceiveData(DeviceDataStatus dataStatus, String data) {
        // TODO Auto-generated method stub
        switch (dataStatus) {
            case DATA_LEARNING_SUCCESS://学习成功
                String studyValue = data;//data 表示学习接收到的数据
                break;
            case DATA_LEARNING_FAILED://学习失败
                break;
            case DATA_SEND_OK:
                if (data != null && data.startsWith("YK")) {
                    Logger.d(TAG, "发送成功 " + data);
                } else {
                }
                break;
            default:
                break;
        }
    }
}

5.2.2 发送学习指令

小苹果接收到App发送过来的学习指令后会进入慢闪状态,学习成功后小苹果会停止闪烁。

【示例代码】
//开始学习。
driverControl.startLearn();    

5.3 小夜灯(LED灯)控制

小夜灯既是小苹果LED 灯,可以通过设备控制器打开或关闭小夜灯,但是不能获取小夜灯的开关状态,如果小夜灯是开的,发送命令之后,小夜灯就会关闭。

【示例代码】
//小苹果 小夜灯
DeviceController driverControl = new DeviceController(getApplicationContext(), currGizWifiDevice, null);
findViewById(R.id.night).setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        driverControl.sendNightLight();
    }
});

5.4 数据透传(小苹果2代)

数据发送

发送的数据为Byte数组,且数据长度不能大于844.
【示例代码】
DeviceController driverControl = new DeviceController(getApplicationContext(), currGizWifiDevice, null);
findViewById(R.id.trunk).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            String data = etTrunk.getText().toString();
            if (!TextUtils.isEmpty(data)) {
                tvTrunkSend.setText(data);
                //关键接口
                driverControl.sendCMD(data , SendType.Trunk);
            }

        }
    });

数据接收

接收的数据也为Byte数组,在接收数据之前需要设置一个接收数据的回调接口
【示例代码】
DeviceController driverControl = new DeviceController(getApplicationContext(), currGizWifiDevice, null);
driverControl.setOnTrunkReceiveListener(new OnTrunkReceiveListener() {
        @Override
        public void onTrunkReceive(byte[] data) {
            if (data != null && data.length > 0) {
                tvTrunkReceive.setText(Utility.bytesToHexString(data));
            }
        }
    });

5.5 315/433模块学习(小苹果2代)

5.5.1 设置回调函数

在学习之前需要初始化,把监听接口传入,在回调函数里面,如果学习成功,会有相应的数据返回,用户可以把学习到的红外码保存下来。

【示例代码】
//设置回调函数
DeviceController. initLearn(LearnCodeListener);

public interface LearnCodeListener {
    /**
     * 接收数据
     */
    public void didReceiveData(DeviceDataStatus dataStatus, String data) {
        // TODO Auto-generated method stub
        switch (dataStatus) {
            case DATA_LEARNING_SUCCESS_315://315学习成功
            case DATA_LEARNING_SUCCESS_433://433学习成功
                String studyValue = data;//data 表示学习接收到的数据
                break;
            case DATA_LEARNING_FAILED://学习失败
                break; 
            default:
                break;
        }
    }
}

5.5.2 发送学习315/433指令

小苹果接收到App发送过来的学习指令后会进入慢闪状态,学习成功后小苹果会停止闪烁。

【示例代码】
//开始学习。
driverControl.startLearn433or315();

5.5.3 发送学习到315/433的遥控码

根据之前下载的红外遥控码,通过设备控制器就能将红外码发送到小苹果。

【示例代码】
driverControl.sendCMD(studyValue,SendType.RadioFrequency);

5.6 获取小苹果的版本

【示例代码】
  public static int getLittleAppleVersion(Context context, GizWifiDevice gizWifiDevice)

5.7 一键匹配

遥控器一键匹配的本质是一个将学习到的红外码上传到云端服务器匹配的过程,该过程分为一下几个步骤:

step1:第一次调用一键匹配接口时,先确认匹配遥控器的类型

 if(遥控器是空调或者汽车多媒体(SDK暂未提供)){
    key="ok";
}else{
    key="power";
}

step2:学习成功后,调用一键匹配接口将红外码值上传到云端

ykanInterface.oneKeyMatched(gizWifiDevice.getMacAddress(), studyValue, tid + "", bid + "", key, OneKeyMatchActivity.this);

step3:解析回调

 @Override
public void onSuccess(BaseResult baseResult) {
    if (isFinishing()) {
        return;
    }
    dialogUtils.sendMessage(ProgressDialogUtils.DISMISS);
    if (baseResult instanceof OneKeyMatchKey) {
        key = ((OneKeyMatchKey) baseResult).getNext_cmp_key();
        showDlg();
    } else if (baseResult instanceof RemoteControl) {
        remoteControl = (RemoteControl) baseResult;
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                new AlertDialog.Builder(OneKeyMatchActivity.this).setMessage("匹配成功,进入测试").setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        toYKWifiDeviceControlActivity();
                    }
                }).create().show();
            }
        });
    } else if (baseResult instanceof MatchRemoteControlResult) {
        final MatchRemoteControlResult result = (MatchRemoteControlResult) baseResult;
        Log.e("tttt", result.toString());
        if (result != null && result.getRs() != null && result.getRs().size() > 0) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    list.clear();
                    list.addAll(result.getRs());
                    controlAdapter.notifyDataSetChanged();
                }
            });
        }
    }
}
 @Override
public void onFail(final YKError ykError) {
    dialogUtils.sendMessage(ProgressDialogUtils.DISMISS);
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            new AlertDialog.Builder(OneKeyMatchActivity.this).setMessage(ykError.getError()).setPositiveButton("确定", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                }
            }).create().show();
        }
    });
}

回调有四种情况,我们逐一分析。

当回调成功时

1.如果结果属于OneKeyMatchKey时,则说明要继续匹配下一个键,键值包含在对象里,将全局对象key替换后,重复step2操作。 (这里返回的key为英文,需要翻译成中文的请戳这里)

2.如果结果属于RemoteControl时,则说明匹配成功,这时你只需要把匹配成功的遥控器保存下来就可以了

3.如果结果属于MatchRemoteControlResult时,则说明匹配回来的是空调遥控器数组(一般匹配空调都会以数组的形式返回),数组里面包含遥控器的几个按键,这时你可以用来测试实体家电,测试成功之后再下载完整的遥控器数据。 如下图所示image

4.除以上3中情况,其他情况均为匹配失败。

5.7 全键匹配

全键匹配是比逐个匹配更为智能的匹配遥控器的方法,主要分为以下几个步骤。

  • 1.获取匹配数据 MatchHelper.STEP_GET_ALL_CTRL;
  • 2.测试红外码 MatchHelper.STEP_TEST_CODE;
  • 3.获取非空调数据匹配 MatchHelper.STEP_ALL_KEY_MATCH;
  • 4.获取空调数据匹配 MatchHelper.STEP_ALL_KEY_MATCH_AIR;
  • 5.下载匹配成功的码库 MatchHelper.STEP_DOWNLOAD_CTRL;

5.7.1 获取匹配数据

1.用户首先要根据设备的类型和品牌ID来获取该品牌下的所有匹配数据

MatchHelper helper = new MatchHelper(AllKeyMatchActivity.this).mac(gizWifiDevice.getMacAddress()).type(String.valueOf(tid)).bid(String.valueOf(bid)).control(driverControl).listener(this);
helper.start();

设置回调接口

/**
 * 数据加载开始的回调
 * @param step 当前的步骤
 */
void onLoadData(int step);
/**
 * 数据加载结果的回调
 * @param step    当前的步骤
 * @param s       是否加载成功
 * @param ykError 错误的原因
 */
void loadResult(int step, boolean s, YKError ykError);
/**
 * 根据返回的步骤和对象刷新UI和数据的回调
 * @param step 当前的步骤
 * @param o    消息对象
 */
void updateMsg(int step, Object o);

5.7.2 测试红外码

//匹配当前按键
helper.test();
如果匹配不成功,调用下面方法换下一组码,继续调用test()方法
helper.next();
next()方法会过滤掉含有相同码值的遥控器
在updateMsg()回调中有当前测试的遥控设备名称、型号等信息
如果匹配成功,调用helper.startAllKeyMatch()方法进入全键匹配,SDK会判断是进入非空调数据匹配还是进入空调数据匹配。
如果想重新匹配,可调用helper.reset()方法

5.7.3 获取非空调数据匹配

在调用helper.startAllKeyMatch()方法成功后,会在updateMsg()回调中返回非空调设备所有的按键名称、键值,用户根据键值调用test(String key)方法进行全键匹配,如果匹配不成功,调用next()找下一组码

gv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        String key = codeKeys.get(position).getKey();
        helper.test(key);
    }
});
helper.next();

5.7.4 获取空调数据匹配

在调用helper.startAllKeyMatch()方法成功后,调用test(AirConCatogery,boolean)方法测试空调按键,AirConCatogery为枚举类型,包含开关、模式、风量等,

//开关
helper.test(AirConCatogery.Power, true);
//模式
helper.test(AirConCatogery.Mode, true);
//风量
helper.test(AirConCatogery.Speed, true);
//上下扫风
helper.test(AirConCatogery.WindUp, true);
//左右扫风
helper.test(AirConCatogery.WindLeft, true);
//温度加
helper.test(AirConCatogery.Temp, true);
//温度减
helper.test(AirConCatogery.Temp, false);

5.7.5 下载匹配成功的码库

helper.downloadCtrl();

5.7.6 全键匹配流程图

image

6.设备定时任务

通过给设备设置定时任务,可以让设备在预定的日期和时间执行某些操作。这些操作可以在一个月内的某几天重复,也可以在一周内的某几天重复。 定时任务可以先设定好,然后在任何时候开始执行或停止执行。定时任务创建时默认开启。

6.1 创建定时任务

定时任务可以重复执行,也可以只执行一次,重复执行分为按月重复和按周重复。但同时只能指定一种重复方式,即或者不重复或者按周重复或者按月重复。 使用SDK接口时,按周重复时给变量weekDays传值,按月重复时给monthDays传值,但如果两个变量都传值则只会处理weekDays。 下面分别以这三种情况举例说明。

6.1.1 创建一次性定时任务

假设我们需要在2017年10月16日早上6点30分开灯。如下代码中,日期和时间想要设置为几月几日几时几分,就设定为对应的值。 比如我们希望设定的是2017年1月16日早上6点30分,那么date为2017-01-16,time为06:30,其中time是24小时制,date按照示例代码格式传值即可。

【示例代码】
GizDeviceScheduler scheduler = new GizDeviceScheduler(null, "2017-10-16", "06:30", true, "任务名称");   
//UID和TOKEN在用户登录时可以获得,code为从Api获得的遥控码
YKSchedulerCenter.createScheduler(Constant.UID, Constant.TOKEN, device, scheduler, null, code);

//设置回调函数
YKSchedulerCenter.setListener(ykDeviceSchedulerCenterListener);
//回调函数
YKDeviceSchedulerCenterListener ykDeviceSchedulerCenterListener = new YKDeviceSchedulerCenterListener() {
    @Override
    public void didUpdateSchedulers(GizWifiErrorCode result, GizWifiDevice schedulerOwner, List<GizDeviceScheduler> schedulerList) {
        if (result == GizWifiErrorCode.GIZ_SDK_SUCCESS) {
            // 定时任务创建成功
            Logger.e(TAG, "定时任务创建成功");
        } else {
            // 创建失败
            Logger.e(TAG, "创建失败" + result.name() + " --" + result.getResult());
        }
    }
};

6.1.2 创建按周重复的定时任务

我们现在让定时任务按周重复执行,现在要每周的周一至周五早上6点30分都开灯。

【示例代码】
List<GizScheduleWeekday> weekDays = new ArrayList<GizScheduleWeekday>();
weekDays.add(GizScheduleWeekday.GizScheduleMonday);
weekDays.add(GizScheduleWeekday.GizScheduleTuesday);
weekDays.add(GizScheduleWeekday.GizScheduleWednesday);
weekDays.add(GizScheduleWeekday.GizScheduleThursday);
weekDays.add(GizScheduleWeekday.GizScheduleFriday);
GizDeviceScheduler scheduler = new GizDeviceScheduler(null, "06:30", weekDays, true, "任务名称");
YKSchedulerCenter.createScheduler(Constant.UID, Constant.TOKEN, device, scheduler, null, code);

6.1.3 创建按月重复的定时任务

我们现在让定时任务按周重复执行,现在要每个月的1号、15号早上6点30分都开灯。 注意不要同时设置按周重复,如果同时设置了按周重复,按月重复会被忽略。

【示例代码】
List<Integer> monthDays = new ArrayList<>();
monthDays.add(1);
monthDays.add(15);
GizDeviceScheduler scheduler =  scheduler = new GizDeviceScheduler("06:30", null, monthDays, true, "任务名称");
YKSchedulerCenter.createScheduler(Constant.UID, Constant.TOKEN, device, scheduler, null, code);

6.2 获取定时任务列表

创建好定时任务后,可以通过查询得到已经创建好的所有定时任务列表。得到定时任务列表后,可以对已经创建好的定时任务做修改或删除。

【示例代码】
 @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_scheduler_list);
    listView = (ListView) findViewById(R.id.list_view);
    schedulerAdapter = new SchedulerAdapter();
    listView.setAdapter(schedulerAdapter);
    //从设备列表里获取的设备
    currGizWifiDevice = (GizWifiDevice) getIntent().getParcelableExtra(
            "GizWifiDevice");
    // 设置定时任务监听
    GizDeviceSchedulerCenter.setListener(mListener);
    // 同步更新设备的定时任务列表,mDevice为在设备列表中得到的设备对象
    GizDeviceSchedulerCenter.updateSchedulers(Constant.UID, Constant.TOKEN, currGizWifiDevice);
}

GizDeviceSchedulerCenterListener mListener = new GizDeviceSchedulerCenterListener() {
    @Override
    public void didUpdateSchedulers(GizWifiErrorCode result, GizWifiDevice schedulerOwner, List<GizDeviceScheduler> schedulerList) {
        if (result == GizWifiErrorCode.GIZ_SDK_SUCCESS) {
            if (schedulerList != null) {
                list.clear();
                list.addAll(schedulerList);
                schedulerAdapter.notifyDataSetChanged();
                Log.e(TAG, schedulerList.toString());
            }
        } else {
        }
    }
};

6.3 修改定时任务

可以修改已经创建好的定时任务。修改时,从获取到的定时任务列表中取出定时任务对象,编辑好要修改的内容。 注意,一旦定时任务创建好之后,就被分配了一个ID,这个ID是不能被修改的。

【示例代码】
//从任务列表里面获取任务对象
GizDeviceScheduler mScheduler = list.get(position);
mScheduler.setListener(schedulerListener);
mScheduler.setDate("2018-01-16");
mScheduler.setTime("09:40");
mScheduler.setRemark("任务" + System.currentTimeMillis());
// 创建设备的定时任务,mDevice为在设备列表中得到的设备对象
switch (which) {
    case 0:
        //一次性定时任务
        break;
    case 1:
        //周重复的定时任务
        List<GizScheduleWeekday> weekDays = new ArrayList<GizScheduleWeekday>();
        weekDays.add(GizScheduleWeekday.GizScheduleMonday);
        weekDays.add(GizScheduleWeekday.GizScheduleTuesday);
        weekDays.add(GizScheduleWeekday.GizScheduleWednesday);
        weekDays.add(GizScheduleWeekday.GizScheduleThursday);
        weekDays.add(GizScheduleWeekday.GizScheduleFriday);
        mScheduler.setWeekdays(weekDays);
        break;
    case 2:
        //我们现在让定时任务按周重复执行,现在要每个月的1号、15号早上6点30分都执行任务。
        //注意不要同时设置按周重复,如果同时设置了按周重复,按月重复会被忽略。
        List<Integer> monthDays = new ArrayList<>();
        monthDays.add(1);
        monthDays.add(15);
        mScheduler.setMonthDays(monthDays);
        break;
}
//此code为遥控码,需要从API里获取,或者用户将遥控数据存储到本地在获取
String code = "019CR9Q+zdAFhasaQ7sPQuzCgZg7GGZHHZzRtQpqkd6KlDR0lK8FOaJdPXqk63EnLFnHLAB//9lDpaPeWJK9nuRg==";
YKSchedulerCenter.editScheduler(Constant.UID, Constant.TOKEN, mScheduler, code);

//设置回调函数
GizDeviceSchedulerListener schedulerListener = new GizDeviceSchedulerListener() {
    @Override
    public void didUpdateSchedulerInfo(GizDeviceScheduler scheduler, GizWifiErrorCode result) {
        if (result == GizWifiErrorCode.GIZ_SDK_SUCCESS) { // 接收变更的定时任务信息
            Log.e(TAG, "修改成功");
        } else {
            // 失败处理
            Log.e(TAG, "修改失败" + result.toString());
        }
    }
};

6.4 删除定时任务

在得到的定时任务列表中,找到要删除的定时任务ID,删除定时任务。

【示例代码】
GizDeviceScheduler scheduler = list.get(position);
YKSchedulerCenter.deleteScheduler(Constant.UID, Constant.TOKEN, currGizWifiDevice, scheduler);

7.场景

7.1场景设置

【示例代码】
findViewById(R.id.download_code_to_device).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            ArrayList<String> codes = new ArrayList<>();
            codes.add("01ym+kFqcNrDziSw3UquVVHUwsc96CupJTtjLuODnem6EQrqZafOd6mnkT7W4o0PBT");
            codes.add(studyKey);
            int room = 0;
            int position = 0;
            for (String code : codes) {
                Message message = sendHandler.obtainMessage();
                Bundle bundle = new Bundle();
                bundle.putInt("size", codes.size());//遥控码数组的大小
                bundle.putInt("room", room);//下载到第几个场景0-8之间
                bundle.putInt("position", position);//场景中的第几位0-9之间
                bundle.putString("code", code);//码值
                message.what = 1;
                message.setData(bundle);
                sendHandler.sendMessageDelayed(message, position * 500);
                position++;
            }
        }
    });
    
    Handler sendHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);
        if (msg.what == 1) {
            Bundle bundle = msg.getData();
            driverControl.saveCodeInDevice(bundle.getInt("size"), bundle.getInt("room"), bundle.getInt("position"), bundle.getString("code"));
        }
    }
};

7.2删除场景

【示例代码】
findViewById(R.id.delete_device_code).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //删除第几个场景0-8之间
            driverControl.deleteScene(0);
        }
    });

7.3发送场景

【示例代码】
findViewById(R.id.send_scene).setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            //发送第几个场景0-8之间
            driverControl.sendScene(0);
        }
    });
⚠️ **GitHub.com Fallback** ⚠️