package com.xiaomi.smarthome.device.api; import android.app.Activity; import android.app.Application; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.Typeface; import android.location.Address; import android.location.Geocoder; import android.location.Location; import android.net.Uri; import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.os.Bundle; import android.support.annotation.Nullable; import android.text.TextUtils; import android.util.AttributeSet; import android.view.ViewGroup; import android.widget.FrameLayout; import com.tencent.mm.sdk.openapi.IWXAPI; import com.xiaomi.plugin.core.XmPluginPackage; import com.xiaomi.smarthome.bluetooth.Response; import com.xiaomi.smarthome.bluetooth.XmBluetoothRecord; import com.xiaomi.smarthome.camera.HLSDownloader; import com.xiaomi.smarthome.camera.IXmStreamClient; import com.xiaomi.smarthome.camera.XmAAcCodec; import com.xiaomi.smarthome.camera.XmCameraP2p; import com.xiaomi.smarthome.camera.XmMp4Record; import com.xiaomi.smarthome.camera.XmP2PInfo; import com.xiaomi.smarthome.camera.XmVideoViewGl; import com.xiaomi.smarthome.camera.exopackage.MJExoPlayer; import com.xiaomi.smarthome.device.api.printer.PrinterControl; import com.xiaomi.smarthome.device.api.spec.operation.ActionParam; import com.xiaomi.smarthome.device.api.spec.operation.PropertyParam; import com.xiaomi.smarthome.device.api.spec.operation.controller.DeviceController; import com.xiaomi.smarthome.plugin.devicesubscribe.PluginSubscribeCallback; import com.xiaomi.smarthome.plugin.devicesubscribe.PluginUnSubscribeCallback; import com.xiaomi.smarthome.plugin.service.HostService; import org.apache.http.NameValuePair; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; /** * 插件宿主提供给插件的接口 */ public abstract class XmPluginHostApi { public final static String METHOD_POST = "POST"; public final static String METHOD_GET = "GET"; protected static XmPluginHostApi sXmPluginHostApi = null; public static XmPluginHostApi instance() { return sXmPluginHostApi; } /** * 插件sdk版本号,插件开发如果必须要与之前api兼容,需要通过SDK_VERSION判断兼容性 */ public abstract int getApiLevel(); /** * ApiLevel: 18 主app渠道 * * @return */ public abstract String getChannel(); /** * ApiLevel:1 */ public abstract Application application(); /** * ApiLevel:1 */ public abstract Context context(); // 启动插件包内部某个activity /** * ApiLevel:1 * * @param xmPluginPackage 插件包 * @param intent 传入的参数 * @param did 设备did * @param activityClass 启动的activity */ public abstract void startActivity(Context context, XmPluginPackage xmPluginPackage, Intent intent, String did, Class activityClass); /** * ApiLevel:1 调用智能家居后台http服务 * * @param model 插件model * @param relativeUrl 服务接口url * @param params * @param callback * @param parser */ public abstract <T> void callSmartHomeApi(String model, String relativeUrl, JSONObject params, final Callback<T> callback, final Parser<T> parser); /** * ApiLevel:58 调用智能家居后台http服务 * * @param model 插件model * @param hostPrefix HOST前缀 * @param relativeUrl 服务接口url * @param method 请求方法 * @param params * @param callback * @param parser */ public abstract <T> void callSmartHomeApi(String model, String hostPrefix, String relativeUrl, String method, JSONObject params, final Callback<T> callback, final Parser<T> parser); // method POST or GET /** * ApiLevel:1 调用普通http请求 * * @param model 插件model * @param url 请求url * @param method METHOD_POST或METHOD_GET * @param params * @param callback * @param parser */ @Deprecated public abstract <T> void callHttpApi(String model, String url, String method, List<NameValuePair> params, final Callback<T> callback, final Parser<T> parser); /** * ApiLevel: 13 调用普通http请求 * * @param model * @param url * @param method * @param params * @param callback * @param parser * @param <T> */ public abstract <T> void callHttpApiV13(String model, String url, String method, List<KeyValuePair> params, final Callback<T> callback, final Parser<T> parser); /** * ApiLevel:1 设备方法调用 * * @param method 方法名 * @param params 参数,可以是一个集合Collection子类 * @param callback 回调结果 * @param parser */ public abstract <T> void callMethod(String did, String method, Object[] params, final Callback<T> callback, final Parser<T> parser); /** * ApiLevel:1 设备方法调用 * * @param method 方法名 * @param params * @param callback 回调结果 * @param parser */ public abstract <T> void callMethod(String did, String method, JSONArray params, final Callback<T> callback, final Parser<T> parser); /** * ApiLevel:59 设备方法调用,强制从云端调用,object为JSONObject或者为JSONArray * * @param method 方法名 * @param params * @param callback 回调结果 * @param parser */ public abstract <T> void callMethodFromCloud(String did, String method, Object params, final Callback<T> callback, final Parser<T> parser); /** * ApiLevel:29 设备方法调用 * * @param method 方法名 * @param params * @param callback 回调结果 * @param parser */ public abstract <T> void callMethod(String did, String method, JSONObject params, final Callback<T> callback, final Parser<T> parser); /** * ApiLevel:1 获取设备列表 * * @return */ public abstract List<DeviceStat> getDeviceList(); /** * ApiLevel:30 获取设备列表 * * @return 打印机的控制类 */ public abstract PrinterControl getPrinterControl(); /** * ApiLevel: 30 获取指定model的设备列表 * * @return */ public abstract List<DeviceStat> getDeviceListV2(List<String> modelList); /** * ApiLevel: 69 获取当前家庭所有房间 * * @return */ public abstract List<RoomStat> getRoomAll(); /** * ApiLevel: 69 删除房间 * * @param roomIds * @param callback */ public abstract void deleteRoom(final List<String> roomIds, final Callback<Void> callback); /** * ApiLevel: 69 房间重命名 * * @param roomId * @param name * @param callback */ public abstract void renameRoom(final String roomId, final String name, final Callback<Void> callback); /** * 对当前家庭增加房间 * rn sdk新增 * RnApiLevel: 10020 * * @param roomStat * @param callback */ public abstract void addRoom(RoomStat roomStat, Callback<RoomStat> callback); /** * ApiLevel:1 获取子设备 * * @param did 设备did * @return */ public abstract List<DeviceStat> getSubDeviceByParentDid(String did); /** * ApiLevel:1 获取设备信息 * * @param did * @return */ public abstract DeviceStat getDeviceByDid(String did); /** * ApiLevel:1 获取子设备 * * @param didList * @param callback */ public void getSubDevice(String model, String[] didList, final Callback<List<DeviceStat>> callback) { JSONObject dataObj = new JSONObject(); try { if (didList != null) { JSONArray array = new JSONArray(); for (String did : didList) { array.put(did); } dataObj.put("dids", array); } WifiManager wifi = (WifiManager) context().getSystemService(Context.WIFI_SERVICE); WifiInfo info = wifi.getConnectionInfo(); String bssid = info != null ? info.getBSSID() : null; if (!TextUtils.isEmpty(bssid)) { dataObj.put("uid", bssid.toUpperCase()); } } catch (JSONException e) { if (callback != null) { callback.onFailure(-1, e.toString()); return; } } // [{"uid":103434651,"did":"lumi.158d00005e90f8","mac":"","pd_id":42,"city_id":101010200,"bssid":"","token":"","access_type":3,"localip":"","name":"门窗传感器","ssid":"","longitude":116.330283,"latitude":40.028534,"parent_id":"88292"},{"uid":103434651,"did":"lumi.158d00005e9267","mac":"","pd_id":41,"city_id":0,"bssid":"","token":"","access_type":3,"localip":"","name":"无线开关","ssid":"","longitude":0,"latitude":0,"parent_id":"88292"}] callSmartHomeApi(model, "/home/sub_device_list", dataObj, callback, new Parser<List<DeviceStat>>() { @Override public List<DeviceStat> parse(String resp) throws JSONException { List<DeviceStat> subDeviceList = new ArrayList<DeviceStat>(); JSONObject response = new JSONObject(resp); JSONArray array = response.optJSONArray("list"); if (array == null) return subDeviceList; for (int i = 0; i < array.length(); i++) { JSONObject object = array.getJSONObject(i); DeviceStat result = new DeviceStat(); result.did = object.optString("did"); result.model = object.optString("model"); result.name = object.optString("name"); result.bindFlag = object.optInt("adminFlag"); result.authFlag = object.optInt("shareFlag"); result.ip = object.optString("localip"); result.mac = object.optString("mac"); result.parentModel = object.optString("parent_model"); result.parentId = object.optString("parent_id"); // // 对于子设备,一律认为在线 // if (!TextUtils.isEmpty(result.parentId)) { // result.isOnline = true; // } else { // result.isOnline = object.optBoolean("isOnline"); // } result.isOnline = object.optBoolean("isOnline"); subDeviceList.add(result); } return subDeviceList; } }); } /** * ApiLevel:1 订阅设备属性变化 变化后push消息通知 需要在IXmPluginMessageReceiver里面接收消息通知 * * @param did * @param pid * @param entryList 属性列表 属性必须加 prop. * @param expire 分钟 必须<=3 * @param callback */ public abstract void subscribeDevice(String did, int pid, List<String> entryList, int expire, Callback<Void> callback); /** * ApiLevel: 13 取消订阅 * * @param did * @param pid * @param entryList * @param callback */ public abstract void unsubscribeDevice(String did, int pid, List<String> entryList, Callback<Void> callback); /** * ApiLevel: 25 订阅设备属性变化(跟model无关) 变化后push消息通知 需要在IXmPluginMessageReceiver里面接收消息通知 * * @param did * @param pid * @param entryList 属性列表 属性必须加 prop. * @param expire 分钟 必须<=3 * @param callback */ public abstract void subscribeDeviceV2(String did, int pid, List<String> entryList, int expire, PluginSubscribeCallback callback); /** * ApiLevel: 25 取消订阅(跟model无关) * * @param did * @param pid * @param entryList * @param callback */ public abstract void unsubscribeDeviceV2(String did, int pid, List<String> entryList, String subId, PluginUnSubscribeCallback callback); // ApiLevel:1 // 统计相关接口,参考miui开放平台统计, // 不推荐使用,无法把统计数据开放到第三方 // // http://dev.xiaomi.com/doc/p%3D3995/index.html // //////////// @Deprecated public abstract void recordCountEvent(String category, String key); @Deprecated public abstract void recordCountEvent(String category, String key, Map<String, String> params); @Deprecated public abstract void recordCalculateEvent(String category, String key, long value); @Deprecated public abstract void recordCalculateEvent(String category, String key, long value, Map<String, String> params); @Deprecated public abstract void recordStringPropertyEvent(String category, String key, String value); @Deprecated public abstract void recordNumericPropertyEvent(String category, String key, long value); /** * ApiLevel:2 米家后台统计(Deprecated) * * @param appId 第三方插件开放唯一id,定义为厂商名 * @param value 为Object 可以为int或String或JsonObject * @param extra 可以为null */ @Deprecated public abstract void addRecord(String appId, String key, Object value, JSONObject extra); /** * ApiLevel: 6 米家后台统计 * * @param loadedInfo 插件上下文 * @param key * @param value * @param extra 添加打点统计新规范,必须按照下面的key value来传参数 * key: PageStart 应用页面打开,自动上报 * value: { * "name":"页面名称", * "starttime":"打开时间,时间戳格式" * } * key: Task 应用表现,例如等待时间、执行结果等 * value:{ * "name":"任务名称", * "parent":"任务所在的页面", * "duration":"任务耗时,以毫秒计,可选", * "result":"任务结果,默认0为成功,-1为失败,其它自行定义,可选", * "starttime":"操作时间,时间戳格式" * } * key: PageEnd 应用页面关闭,自动上报 * value:{ * "name":"页面名称", * "starttime":"关闭时间,时间戳格式" * } * key: FloatWindow 悬浮窗打开 * value:{ * "name":"悬浮窗名称,可使用悬浮窗标题", * "parent":"弹出框所在页面名称", * "starttime":"打开时间,时间戳格式" * } * key: RPC 手机向设备发送指令,自动上报 * value:{ * "name":"指令名称", * "parameter":"指令的参数列表,json格式", * "web":"使用的网络,0为局域网,1为外网", * "starttime":"操作时间,时间戳格式" * } * key: Operation 用户行为,例如点击按钮 * value:{ * "name":"操作名称", * "parent":"弹出框所在页面名称", * "position":"操作所在的位置,格式为x/屏幕宽度&y/屏幕高度,如0.4&0.6", * "starttime":"操作时间,时间戳格式" * } * key:WebEnd 网页关闭,自动上报 * value: { * "url":"网页连接", * "starttime":"关闭时间,时间戳格式" * } * key:WebStart 网页打开,自动上报 * value:{ * "url":"网页连接", * "starttime":"打开时间,时间戳格式" * } */ public abstract void addRecord(XmPluginPackage loadedInfo, String key, Object value, JSONObject extra); public static final String RecordTypeClick = "click"; public static final String RecordTypeResult = "result"; public void addRecordV3(XmPluginPackage loadedInfo, String type, String key, Object value, JSONObject extra) { if (type != null) { type = type.toLowerCase().trim(); if (!type.isEmpty()) { key = type + ":" + key; } } addRecord(loadedInfo, key, value, extra); } // /////////////// // scence /** * ApiLevel:2 获取场景 * * @param model * @param st_id 场景模板id * @param did * @param name * @param callback */ @Deprecated public void loadScene(String model, int st_id, String did, String name, final Callback<JSONObject> callback) { JSONObject dataObj = new JSONObject(); try { dataObj.put("st_id", st_id); dataObj.put("identify", did); if (name != null && !name.equals("")) { dataObj.put("name", name); } } catch (JSONException e) { if (callback != null) callback.onFailure(-1, e.toString()); return; } callSmartHomeApi(model, "/scene/list", dataObj, callback, new Parser<JSONObject>() { @Override public JSONObject parse(String result) throws JSONException { return new JSONObject(result); } }); } /** * ApiLevel:2 编辑场景接口 * * @param model * @param st_id 场景模板id * @param us_id 场景id * @param did * @param name * @param setting * @param authed * @param callback */ @Deprecated public void editScene(String model, int st_id, int us_id, String did, String name, JSONObject setting, JSONArray authed, final Callback<JSONObject> callback) { if (us_id < 0) { if (callback != null) { callback.onFailure(-1, "us_id is illegal"); } return; } JSONObject dataObj = new JSONObject(); try { dataObj.put("us_id", us_id + ""); dataObj.put("identify", did); dataObj.put("name", name); dataObj.put("st_id", st_id); dataObj.put("setting", setting); dataObj.put("authed", authed); } catch (JSONException e) { if (callback != null) { callback.onFailure(-1, e.toString()); return; } } callSmartHomeApi(model, "/scene/edit", dataObj, callback, new Parser<JSONObject>() { @Override public JSONObject parse(String result) throws JSONException { return new JSONObject(result); } }); } /** * ApiLevel:3 设置定时场景 * * @param model * @param did * @param us_id * @param name * @param setting * @param authed * @param callback */ @Deprecated public void editTimerScene(String model, String did, int us_id, String name, JSONObject setting, JSONArray authed, final Callback<JSONObject> callback) { if (us_id < 0) { if (callback != null) { callback.onFailure(-1, "us_id is illegal"); } return; } JSONObject dataObj = new JSONObject(); try { dataObj.put("us_id", us_id + ""); dataObj.put("identify", did); dataObj.put("name", name); dataObj.put("st_id", 8); dataObj.put("setting", setting); dataObj.put("authed", authed); } catch (JSONException e) { if (callback != null) callback.onFailure(-1, e.toString()); return; } callSmartHomeApi(model, "/scene/edit", dataObj, callback, new Parser<JSONObject>() { @Override public JSONObject parse(String result) throws JSONException { return new JSONObject(result); } }); } /** * ApiLevel:68 设置定时场景 * * @param model 设备model * @param did 设备 did * @param us_id 定时场景的唯一标识。创建时传"0" * @param name 定时器名称 * @param setting 定时器具体内容 * @param authed 可以为null * @param callback */ public void editTimerScene(String model, String did, String us_id, String name, JSONObject setting, JSONArray authed, final Callback<JSONObject> callback) { JSONObject dataObj = new JSONObject(); try { if (!TextUtils.isEmpty(us_id) && !TextUtils.equals("0", us_id)) { dataObj.put("us_id", us_id); } dataObj.put("identify", did); dataObj.put("name", name); dataObj.put("st_id", 8); dataObj.put("setting", setting); dataObj.put("authed", authed); } catch (JSONException e) { if (callback != null) callback.onFailure(-1, e.toString()); return; } callSmartHomeApi(model, "/scene/edit", dataObj, callback, new Parser<JSONObject>() { @Override public JSONObject parse(String result) throws JSONException { return new JSONObject(result); } }); } /** * ApiLevel:78 获取定时场景列表 * * @param model 设备model * @param did 设备 did * @param callback */ public void loadTimerScenes(String model, String did, final Callback<JSONObject> callback) { JSONObject dataObj = new JSONObject(); try { dataObj.put("identify", did); dataObj.put("st_id", 8); } catch (JSONException e) { if (callback != null) callback.onFailure(-1, e.toString()); return; } callSmartHomeApi(model, "/scene/list", dataObj, callback, new Parser<JSONObject>() { @Override public JSONObject parse(String result) throws JSONException { return new JSONObject(result); } }); } /** * ApiLevel:3 加载所有定时场景 * * @param model * @param did * @param name * @param callback */ @Deprecated public void loadTimerScene(String model, String did, String name, final Callback<JSONObject> callback) { JSONObject dataObj = new JSONObject(); try { dataObj.put("identify", did); if (name != null && !name.equals("")) { dataObj.put("name", name); } } catch (JSONException e) { if (callback != null) callback.onFailure(-1, e.toString()); return; } callSmartHomeApi(model, "/scene/list", dataObj, callback, new Parser<JSONObject>() { @Override public JSONObject parse(String result) throws JSONException { return new JSONObject(result); } }); } /** * ApiLevel:3 获取定时场景 * * @param model * @param did * @param us_id * @param callback */ @Deprecated public void getTimerScene(String model, String did, int us_id, final Callback<JSONObject> callback) { if (us_id < 0) { if (callback != null) { callback.onFailure(-1, "us_id is illegal"); } return; } JSONObject dataObj = new JSONObject(); try { dataObj.put("identify", did); dataObj.put("us_id", us_id + ""); } catch (JSONException e) { if (callback != null) callback.onFailure(-1, e.toString()); return; } callSmartHomeApi(model, "/scene/get", dataObj, callback, new Parser<JSONObject>() { @Override public JSONObject parse(String result) throws JSONException { return new JSONObject(result); } }); } /** * ApiLevel:68 获取定时场景 * * @param model * @param did * @param us_id * @param callback */ @Deprecated public void getTimerScene(String model, String did, String us_id, final Callback<JSONObject> callback) { JSONObject dataObj = new JSONObject(); try { dataObj.put("identify", did); if (!TextUtils.isEmpty(us_id) && !TextUtils.equals("0", us_id)) { dataObj.put("us_id", us_id); } } catch (JSONException e) { if (callback != null) callback.onFailure(-1, e.toString()); return; } callSmartHomeApi(model, "/scene/get", dataObj, callback, new Parser<JSONObject>() { @Override public JSONObject parse(String result) throws JSONException { return new JSONObject(result); } }); } /** * ApiLevel:3 删除场景 * * @param model * @param did * @param us_id * @param callback */ @Deprecated public void delScene(String model, String did, int us_id, final Callback<JSONObject> callback) { if (us_id <= 0) { if (callback != null) { callback.onFailure(-1, "us_id is illegal"); } return; } JSONObject dataObj = new JSONObject(); try { dataObj.put("identify", did); dataObj.put("us_id", us_id + ""); } catch (JSONException e) { if (callback != null) callback.onFailure(-1, e.toString()); return; } callSmartHomeApi(model, "/scene/delete", dataObj, callback, new Parser<JSONObject>() { @Override public JSONObject parse(String result) throws JSONException { return new JSONObject(result); } }); } /** * ApiLevel:3 设置场景 * * @param model * @param did * @param name * @param st_id * @param setting * @param authed * @param callback */ public void setScene(String model, String did, String name, int st_id, JSONObject setting, JSONArray authed, final Callback<Void> callback) { JSONObject dataObj = new JSONObject(); try { dataObj.put("identify", did); dataObj.put("name", name); dataObj.put("st_id", st_id); dataObj.put("setting", setting); dataObj.put("authed", authed); dataObj.put("setting", setting); } catch (JSONException e) { if (callback != null) callback.onFailure(-1, e.toString()); return; } callSmartHomeApi(model, "/scene/idfy_edit", dataObj, callback, null); } /** * ApiLevel:3 获取某个设备场景 * * @param model * @param did * @param callback */ public void getScene(String model, String did, final Callback<JSONObject> callback) { JSONObject dataObj = new JSONObject(); try { dataObj.put("identify", did); } catch (JSONException e) { if (callback != null) callback.onFailure(-1, e.toString()); return; } callSmartHomeApi(model, "/scene/idfy_get", dataObj, callback, new Parser<JSONObject>() { @Override public JSONObject parse(String result) throws JSONException { return new JSONObject(result); } }); } /** * ApiLevel:3 启动场景 * * @param model * @param did * @param key * @param callback */ public void startScene(String model, String did, String key, final Callback<JSONObject> callback) { JSONObject dataObj = new JSONObject(); try { dataObj.put("identify", did); dataObj.put("key", key); } catch (JSONException e) { if (callback != null) callback.onFailure(-1, e.toString()); return; } callSmartHomeApi(model, "/scene/idfy_start", dataObj, callback, new Parser<JSONObject>() { @Override public JSONObject parse(String result) throws JSONException { return new JSONObject(result); } }); } // /////////////// /** * ApiLevel:3 上报gps信息 * * @param model * @param did * @param lng * @param lat * @param adminArea * @param countryCode * @param locality * @param thoroughfare * @param subLocality * @param callback */ public void reportGPSInfo(String model, String did, double lng, double lat, String adminArea, String countryCode, String locality, String thoroughfare, String subLocality, Callback<Void> callback) { JSONObject dataObj = new JSONObject(); try { dataObj.put("did", did); dataObj.put("lng", lng); dataObj.put("lat", lat); dataObj.put("adminArea", adminArea); dataObj.put("countryCode", countryCode); dataObj.put("locality", locality); dataObj.put("thoroughfare", thoroughfare); dataObj.put("language", "zh_CN"); dataObj.put("subLocality", subLocality); } catch (JSONException e) { callback.onFailure(-1, e.toString()); return; } callSmartHomeApi(model, "/location/set", dataObj, callback, null); } /** * ApiLevel:3 获取天气 * * @param model * @param did * @param callback */ public void getWeatherInfo(String model, String did, Callback<WeatherInfo> callback) { JSONObject dataObj = new JSONObject(); try { dataObj.put("did", did); } catch (JSONException e) { callback.onFailure(-1, e.toString()); return; } callSmartHomeApi(model, "/location/weather", dataObj, callback, new Parser<WeatherInfo>() { @Override public WeatherInfo parse(String data) throws JSONException { JSONObject response = new JSONObject(data); WeatherInfo result = new WeatherInfo(); JSONObject aqiJsonObj = response.optJSONObject("aqi"); result.aqi.city = aqiJsonObj.optString("city"); result.aqi.city_id = aqiJsonObj.optString("city_id"); result.aqi.pub_time = aqiJsonObj.optString("pub_time"); result.aqi.aqi = aqiJsonObj.optString("aqi"); result.aqi.pm25 = aqiJsonObj.optString("pm25"); result.aqi.pm10 = aqiJsonObj.optString("pm10"); result.aqi.so2 = aqiJsonObj.optString("so2"); result.aqi.no2 = aqiJsonObj.optString("no2"); result.aqi.src = aqiJsonObj.optString("src"); result.aqi.spot = aqiJsonObj.optString("spot"); return result; } }); } /** * ApiLevel:65 设备方法调用,完全透明调用,需要自己设置参数 * * @param sid servicetoken 对应的 sid * @param callback 回调结果 */ public abstract void getServiceToken(String sid, Callback<JSONObject> callback); /** * ApiLevel:66 * * @return 红外列表 */ public abstract List<DeviceStat> getIrDevList(); /** * ApiLevel:2 设备方法调用,完全透明调用,需要自己设置参数 * * @param did * @param params 参数,JsonObject字符串 * @param callback 回调结果 * @param parser */ public abstract <T> void callMethod(String did, String params, final Callback<T> callback, final Parser<T> parser); /** * ApiLevel:2 访问路由器服务远程接口 * * @param routerId 路由器id * @param url * @param method * @param params * @param callback * @param parser */ @Deprecated public abstract <T> void callRouterRemoteApi(String routerId, String url, String method, boolean fullPath, List<NameValuePair> params, final Callback<T> callback, final Parser<T> parser); /** * ApiLevel: 13 访问路由器服务远程接口 * * @param routerId * @param url * @param method * @param fullPath * @param params * @param callback * @param parser * @param <T> */ public abstract <T> void callRouterRemoteApiV13(String routerId, String url, String method, boolean fullPath, List<KeyValuePair> params, final Callback<T> callback, final Parser<T> parser); /** * ApiLevel:2 获取当前登录的账号id * * @return */ public abstract String getAccountId(); /** * ApiLevel:2 调用本地局域网普通http请求 延时更低,超时时间为2s * * @param model 插件model * @param url 请求url * @param method METHOD_POST或METHOD_GET * @param params * @param callback * @param parser */ @Deprecated public abstract <T> void callLocalHttpApi(String model, String url, String method, List<NameValuePair> params, final Callback<T> callback, final Parser<T> parser); /** * ApiLevel: 13 调用本地局域网普通http请求 延时更低,超时时间为2s * * @param model * @param url * @param method * @param params * @param callback * @param parser * @param <T> */ public abstract <T> void callLocalHttpApiV13(String model, String url, String method, List<KeyValuePair> params, final Callback<T> callback, final Parser<T> parser); /** * ApiLevel:2 修改设备名字 * * @param did * @param newName * @param callback */ public abstract void modDeviceName(String did, String newName, final Callback<Void> callback); /** * ApiLevel:2 解绑设备 * * @param did * @param callback */ public abstract void unBindDevice(final String did, int pid, final Callback<Void> callback); /** * ApiLevel:3 获取最新位置 * * @return */ public abstract Location getLastLocation(); /** * ApiLevel:3 判断是否是网络定位 * * @return */ public abstract boolean isNetworkLocationEnabled(); /** * ApiLevel:3 判断是否gps定位 * * @return */ public abstract boolean isGPSLocationEnable(); /** * ApiLevel:3 获取位置 * * @param callback */ public abstract void requestLocation(Callback<Location> callback); /** * ApiLevel:3 获取设备固件升级信息 * * @param callback */ @Deprecated public void getUpdateInfo(String model, String did, int pid, final Callback<DeviceUpdateInfo> callback) { JSONObject dataObj = new JSONObject(); try { dataObj.put("did", did); dataObj.put("pid", pid); } catch (JSONException e) { if (callback != null) callback.onFailure(-1, e.toString()); return; } callSmartHomeApi(model, "/home/checkversion", dataObj, callback, new Parser<DeviceUpdateInfo>() { @Override public DeviceUpdateInfo parse(String result) throws JSONException { DeviceUpdateInfo updateInfo = new DeviceUpdateInfo(); JSONObject jsonObj = new JSONObject(result); if (jsonObj.optBoolean("updating")) { updateInfo.mHasNewFirmware = false; } else { updateInfo.mHasNewFirmware = !jsonObj.optBoolean("isLatest"); } updateInfo.mCurVersion = jsonObj.optString("curr"); updateInfo.mNewVersion = jsonObj.optString("latest"); updateInfo.mUpdateDes = jsonObj.optString("description"); updateInfo.mForce = jsonObj.optInt("force"); return updateInfo; } }); } /** * ApiLevel:3 加载native so * * @param libName so库名字 * @param classLoader 插件的classloader */ @Deprecated public abstract void loadLibrary(String model, String libName, ClassLoader classLoader); /** * ApiLevel:6 加载native so * <p> * 已经废弃,请使用System.loadLibrary。如果使用的话会抛出异常 * * @param loadedInfo 插件上下文 * @param libName so库名字 */ @Deprecated public abstract void loadLibrary(XmPluginPackage loadedInfo, String libName); /** * ApiLevel:3 获取app属性 * * @param model * @param name 属性名 * @return 属性值 */ public abstract String getProperty(String model, String name); /** * ApiLevel:3 刷新设备列表 * * @param callback * @return */ public abstract void updateDeviceList(Callback<Void> callback); /** * ApiLevel:4 插件中设备数据属性发生变化,同步数据到米家主app中,比如设备列表中显示某些属性状态 * * @param did * @param jsonObject * @return */ public abstract void updateDeviceProperties(String did, JSONObject jsonObject); /** * ApiLevel:4 写log文件,可以从反馈上报到统计平台 * * @param tag * @param info * @return */ public abstract void log(String tag, String info); /** * ApiLevel:6 * * @param service * @param xmPluginPackage * @param activityClass */ @Deprecated public abstract void startService(Intent service, XmPluginPackage xmPluginPackage, Class activityClass); /** * ApiLevel:6 * * @param service * @param xmPluginPackage * @param activityClass * @return */ @Deprecated public abstract boolean stopService(Intent service, XmPluginPackage xmPluginPackage, Class activityClass); /** * ApiLevel:6 * * @param service * @param xmPluginPackage * @param activityClass * @param conn * @param flags * @return */ @Deprecated public abstract boolean bindService(Intent service, XmPluginPackage xmPluginPackage, Class activityClass, ServiceConnection conn, int flags); /** * ApiLevel:6 把某个设备添加桌面快捷方式 * * @param xmPluginPackage * @param did * @param intent */ public abstract void addToLauncher(XmPluginPackage xmPluginPackage, String did, Intent intent); /** * ApiLevel:6 设置子设备是否在主设备列表显示 * * @param xmPluginPackage * @param shownInDeviceList * @param did * @param context * @param callback */ public abstract void setSubDeviceShownMode(XmPluginPackage xmPluginPackage, boolean shownInDeviceList, String did, Context context, final Callback<Void> callback); /** * ApiLevel:7 检测当前连接路由器是否是小米路由器 * * @param routerId * @param callback */ @Deprecated public abstract void checkLocalRouterInfo(String routerId, Callback<Void> callback); /** * ApiLevel:7 返回当前连接路由器是否是小米路由器 * * @return */ @Deprecated public abstract boolean isLocalMiRouter(); /** * ApiLevel:7 获取路由器文件下载地址 * * @param url * @return */ public abstract String getRouterFileDownloadUrl(String url); /** * ApiLevel:8 页面跳转 * * @param xmPluginPackage * @param uri */ public abstract void gotoPage(Context context, XmPluginPackage xmPluginPackage, Uri uri, Callback<Void> callback); /** * ApiLevel:8 获取场景 * * @param model * @param st_id 场景模板id * @param did * @param identify * @param callback */ public void loadScene(String model, int st_id, String did, String identify, String name, final Callback<JSONObject> callback) { JSONObject dataObj = new JSONObject(); try { dataObj.put("st_id", st_id); dataObj.put("did", did); dataObj.put("identify", identify); } catch (JSONException e) { if (callback != null) callback.onFailure(-1, e.toString()); return; } callSmartHomeApi(model, "/scene/list", dataObj, callback, new Parser<JSONObject>() { @Override public JSONObject parse(String result) throws JSONException { return new JSONObject(result); } }); } /** * ApiLevel:8 编辑场景接口 * * @param model * @param st_id 场景模板id * @param us_id 场景id * @param did * @param name * @param setting * @param authed * @param callback */ @Deprecated public void editScene(String model, int st_id, int us_id, String did, String identify, String name, JSONObject setting, JSONArray authed, final Callback<JSONObject> callback) { if (us_id < 0) { if (callback != null) { callback.onFailure(-1, "us_id is illegal"); } return; } JSONObject dataObj = new JSONObject(); try { dataObj.put("us_id", us_id + ""); dataObj.put("identify", identify); if (name != null) { dataObj.put("name", name); } dataObj.put("st_id", st_id); dataObj.put("setting", setting); dataObj.put("authed", authed); } catch (JSONException e) { if (callback != null) { callback.onFailure(-1, e.toString()); return; } } callSmartHomeApi(model, "/scene/edit", dataObj, callback, new Parser<JSONObject>() { @Override public JSONObject parse(String result) throws JSONException { return new JSONObject(result); } }); } /** * ApiLevel:68 编辑场景接口 * * @param model * @param st_id 场景模板id * @param us_id 场景id * @param did * @param name * @param setting * @param authed * @param callback */ public void editScene(String model, int st_id, String us_id, String did, String identify, String name, JSONObject setting, JSONArray authed, final Callback<JSONObject> callback) { if (TextUtils.isEmpty(us_id)) { if (callback != null) { callback.onFailure(-1, "us_id is illegal"); } return; } JSONObject dataObj = new JSONObject(); try { dataObj.put("us_id", us_id); dataObj.put("identify", identify); if (name != null) { dataObj.put("name", name); } dataObj.put("st_id", st_id); dataObj.put("setting", setting); dataObj.put("authed", authed); } catch (JSONException e) { if (callback != null) { callback.onFailure(-1, e.toString()); return; } } callSmartHomeApi(model, "/scene/edit", dataObj, callback, new Parser<JSONObject>() { @Override public JSONObject parse(String result) throws JSONException { return new JSONObject(result); } }); } public abstract void editSceneV2(String model, int st_id, String us_id, String did, String identify, String name, JSONObject setting, JSONArray authed, final Callback<JSONObject> callback); /** * ApiLevel:8 删除场景接口 */ @Deprecated public void delScene(String model, int us_id, final Callback<JSONObject> callback) { if (us_id <= 0) { if (callback != null) { callback.onFailure(-1, "us_id is illegal"); } return; } JSONObject dataObj = new JSONObject(); try { dataObj.put("us_id", us_id + ""); } catch (JSONException e) { if (callback != null) callback.onFailure(-1, e.toString()); return; } callSmartHomeApi(model, "/scene/delete", dataObj, callback, new Parser<JSONObject>() { @Override public JSONObject parse(String result) throws JSONException { return new JSONObject(result); } }); } /** * ApiLevel:68 删除场景接口 */ public void delScene(String model, String us_id, final Callback<JSONObject> callback) { if (TextUtils.isEmpty(us_id) || TextUtils.equals("0", us_id)) { if (callback != null) { callback.onFailure(-1, "us_id is illegal"); } return; } JSONObject dataObj = new JSONObject(); try { dataObj.put("us_id", us_id); } catch (JSONException e) { if (callback != null) callback.onFailure(-1, e.toString()); return; } callSmartHomeApi(model, "/scene/delete", dataObj, callback, new Parser<JSONObject>() { @Override public JSONObject parse(String result) throws JSONException { return new JSONObject(result); } }); } public void delScenes(String model, List<String> us_ids, final Callback<JSONObject> callback) { if (us_ids == null || us_ids.size() == 0) { if (callback != null) { callback.onFailure(-1, "us_ids is null"); } return; } JSONObject cmdObj = new JSONObject(); try { JSONArray array = new JSONArray(); for (String i : us_ids) { if (TextUtils.isEmpty(i) || TextUtils.equals("0", i)) { continue; } array.put(i); } if (array == null || array.length() == 0) { if (callback != null) { callback.onFailure(-1, "has illegal id"); } return; } cmdObj.put("us_id", array); } catch (JSONException e) { if (callback != null) { callback.onFailure(-1, "json exception"); } return; } callSmartHomeApi(model, "/scene/delete", cmdObj, callback, new Parser<JSONObject>() { @Override public JSONObject parse(String result) throws JSONException { return new JSONObject(result); } }); } /** * ApiLevel:8 调用智能家居后台http服务 * * @param model 插件model * @param relativeUrl 服务接口url * @param params * @param callback * @param parser */ public abstract <T> void callSmartHomeApi(String model, String relativeUrl, String params, final Callback<T> callback, final Parser<T> parser); /** * ApiLevel:58 调用智能家居后台http服务 * * @param model 插件model * @param hostPrefix host前缀 * @param relativeUrl 服务接口url * @param method 请求方法 * @param params * @param callback * @param parser */ public abstract <T> void callSmartHomeApi(String model, String hostPrefix, String relativeUrl, String method, String params, final Callback<T> callback, final Parser<T> parser); /** * ApiLevel:8 向某个设备的插件发送消息 * * @param did * @param msgType * @param msgArg * @param deviceStat * @param msgCallback */ public abstract void sendMessage(String did, int msgType, Intent msgArg, DeviceStat deviceStat, MessageCallback msgCallback); /** * ApiLevel:10 通知蓝牙设备已绑定 * * @param mac 绑定的设备mac * @param token 设备token */ public abstract void notifyBluetoothBinded(String mac, String token); /** * ApiLevel:10 获取小米用户信息 * * @param userid 小米账号 */ public abstract void getUserInfo(String userid, final Callback<UserInfo> callback); /** * ApiLevel:10 开始一个下载 * * @param uri download uri * @param udn can be @null * @param dirType the directory type to pass to {@link Context#getExternalFilesDir(String)} * @param subPath the path within the external directory. If subPath is a directory(ending with * "/"), destination filename will be generated. * @return download id */ @Deprecated public abstract long startDownload(Uri uri, String udn, String dirType, String subPath); /** * ApiLevel:10 pause download * * @param ids the IDs of the downloads */ @Deprecated public abstract void pauseDownload(long... ids); /** * ApiLevel:10 resume download * * @param ids the IDs of the downloads */ @Deprecated public abstract void resumeDownload(long... ids); /** * ApiLevel:10 restart download * * @param ids the IDs of the downloads */ @Deprecated public abstract void restartDownload(long... ids); /** * ApiLevel:10 remove download * * @param ids the IDs of the downloads */ @Deprecated public abstract void removeDownload(long... ids); /** * ApiLevel:10 query download * * @param onlyVisibleDownloads hide downloads exclude * @param filterIds the IDs of the downloads */ @Deprecated public abstract Cursor queryDownload(boolean onlyVisibleDownloads, long... filterIds); /** * ApiLevel:10 notify wifi download manager * * @param isConnected */ @Deprecated public abstract void notifyLocalWifiConnect(boolean isConnected); /** * ApiLevel:14 更新设备的子设备 */ public abstract void updateSubDevice(XmPluginPackage xmPluginPackage, String[] didList, Callback<List<DeviceStat>> callback); /** * ApiLevel:15 异步调用第三方云接口 需要注意,由于后台返回的数据原因,目前回调接口可能有2种数据。 * 目前异步接口通过push通知和超时重试2种方式获取数据。其中超时重试可能会比push获取的数据多封装一层 * 如push获取的数据如果如下"{\"bssid\":\"d0:ee:07:23:22:90\"}",则超时重试则可能会是{"code":0,"message":"ok","result":"{\"bssid\":\"d0:ee:07:23:22:90\"}"} * 有效载荷在result字段中。插件解析可能需要对数据做兼容处理 */ public abstract void callRemoteAsync(final String[] dids, final int appId, Object object, Callback<JSONObject> callback); /** * ApiLevel:23 异步调用第三方云接口 finalCallback: 异步请求最终结果回调,其回调表明最终结果(如果成功)或是失败 directCallback: * 异步请求中间回调,用于通知后台关于异步请求的配置.目前返回结果如下{"sid": 32323,"interval": 3,"max_retry": * 3},意思是最多重试三次,每次请求间隔3秒 如果请求提交失败,则直接调用finalCallback的回调,表明callRemoteAsync失败 */ public abstract void callRemoteAsync(final String[] dids, final int appId, Object object, Callback<JSONObject> finalCallback, Callback<JSONObject> directCallback); /** * ApiLevel:16 获取蓝牙设备固件升级信息 */ public abstract void getBluetoothFirmwareUpdateInfo(String model, final Callback<BtFirmwareUpdateInfo> callback); /** * ApiLevel:17 同步设备gps信息 */ public void reportGPSInfo(final String did, final Callback<Void> callback) { if (TextUtils.isEmpty(did)) { if (callback != null) { callback.onFailure(-1, ""); } return; } final DeviceStat deviceStat = getDeviceByDid(did); if (deviceStat == null) { if (callback != null) { callback.onFailure(-1, ""); } return; } requestLocation(new Callback<Location>() { @Override public void onSuccess(Location location) { if (location == null) { if (callback != null) { callback.onFailure(-1, ""); } return; } Address lastAddress = null; Geocoder geoCoder = new Geocoder(context()); try { List<Address> addressList = geoCoder.getFromLocation( location.getLatitude(), location.getLongitude(), 1); if (addressList != null && addressList.size() > 0) { lastAddress = addressList.get(0); } } catch (IOException e) { } if (lastAddress == null) { if (callback != null) { callback.onFailure(-1, ""); } return; } String adminArea = ""; String countryCode = ""; String locality = ""; String thoroughfare = ""; String subLocality = ""; adminArea = lastAddress.getAdminArea(); countryCode = lastAddress.getCountryCode(); locality = lastAddress.getLocality(); thoroughfare = lastAddress.getThoroughfare(); subLocality = lastAddress.getSubLocality(); reportGPSInfo(deviceStat.model, did, location.getLongitude(), location.getLatitude(), adminArea, countryCode, locality, thoroughfare, subLocality, callback); } @Override public void onFailure(int error, String errorInfo) { if (callback != null) { callback.onFailure(error, errorInfo); } } }); } /** * 针对RN插件新增 * ApiLevel: 94 * rn api level: 10020 */ public void reportDeviceGPSInfo(final String did, final Callback<JSONObject> callback) { if (TextUtils.isEmpty(did)) { if (callback != null) { callback.onFailure(-1, ""); } return; } final DeviceStat deviceStat = getDeviceByDid(did); if (deviceStat == null) { if (callback != null) { callback.onFailure(-1, ""); } return; } requestLocation(new Callback<Location>() { @Override public void onSuccess(Location location) { if (location == null) { if (callback != null) { callback.onFailure(-1, ""); } return; } Address lastAddress = null; Geocoder geoCoder = new Geocoder(context()); try { List<Address> addressList = geoCoder.getFromLocation( location.getLatitude(), location.getLongitude(), 1); if (addressList != null && addressList.size() > 0) { lastAddress = addressList.get(0); } } catch (IOException e) { } if (lastAddress == null) { if (callback != null) { callback.onFailure(-1, ""); } return; } String adminArea = ""; String countryCode = ""; String locality = ""; String thoroughfare = ""; String subLocality = ""; adminArea = lastAddress.getAdminArea(); countryCode = lastAddress.getCountryCode(); locality = lastAddress.getLocality(); thoroughfare = lastAddress.getThoroughfare(); subLocality = lastAddress.getSubLocality(); // 封装数据返回给层 final JSONObject dataObj = new JSONObject(); try { dataObj.put("longitude", "" + location.getLongitude()); dataObj.put("latitude", "" + location.getLatitude()); dataObj.put("adminArea", "" + adminArea); dataObj.put("countryCode", "" + countryCode); dataObj.put("locality", "" + locality); dataObj.put("thoroughfare", "" + thoroughfare); dataObj.put("subLocality", "" + subLocality); } catch (JSONException e) { callback.onFailure(-1, e.toString()); return; } reportGPSInfo(deviceStat.model, did, location.getLongitude(), location.getLatitude(), adminArea, countryCode, locality, thoroughfare, subLocality, new Callback<Void>() { @Override public void onSuccess(Void result) { callback.onSuccess(dataObj); } @Override public void onFailure(int error, String errorInfo) { callback.onFailure(error, errorInfo); } }); } @Override public void onFailure(int error, String errorInfo) { if (callback != null) { callback.onFailure(error, errorInfo); } } }); } /** * 在ApiLevel:25后升级了微信sdk,有用到这个接口的必须更新插件sdk适配,发布新版插件并且修改minPluginSdkApiVersion为25 ApiLevel:20 * 创建米家app注册的微信接口 */ public abstract IWXAPI createWXAPI(Context context, boolean bl); /** * ApiLevel: 20 蓝牙数据上报 */ public abstract void reportBluetoothRecords(String did, String model, List<XmBluetoothRecord> records, final Callback<List<Boolean>> callback); /** * ApiLevel: 20 下载蓝牙固件 */ public abstract void downloadBleFirmware(String url, Response.BleUpgradeResponse response); /** * ApiLevel: 28 取消下载蓝牙固件 * * @param url */ public abstract void cancelDownloadBleFirmware(String url); /** * ApiLevel: 20 设置蓝牙设备副标题 */ public abstract void setBleDeviceSubtitle(String mac, String subtitle); /** * ApiLevel: 21 设置蓝牙设备名称 */ public abstract void deviceRename(String mac, final String name); /** * ApiLevel: 22 获取当前服务器 * * @return "cn":中国大陆 "tw":台湾 "sg":新加坡 "in":印度 */ @Deprecated public abstract String getGlobalSettingServer(); /** * ApiLevel: 60 获取当前服务器 * * @param changeServer true: 获取到的不一定是用户当前选择的服务器(比如香港共用新加坡服务器),false:获取到的是用户当前选择的服务器 * @return "cn":中国大陆 "tw":台湾 "sg":新加坡 "in":印度 */ @Deprecated public abstract String getGlobalSettingServer(boolean changeServer); /** * ApiLevel: 91 获取当前服务器 * <p> * 获取当前服务器 * * @return 返回json表示 { "machineCode": "cn", "countryCode": "CN"} */ public abstract String getCurrentServer(); /** * ApiLevel: 91 获取当前服务器 * <p> * 获取当前语言下当前服务器的的名称 * * @param callback */ public abstract void getServerName(Callback<String> callback); /** * ApiLevel: 93 * 当前服务器是否为除了中国大陆外的服务器 * * @param context * @return */ public abstract boolean isInternationalServer(Context context); /** * ApiLevel: 93 * 当前服务器是否为中国大陆 * * @param context * @return */ public abstract boolean isChinaMainLand(Context context); /** * ApiLevel: 93 * 当前服务器是否为欧洲 * * @param context * @return */ public abstract boolean isEurope(Context context); /** * ApiLevel: 93 * 当前服务器是否为韩国 * * @param context * @return */ public abstract boolean isKorea(Context context); /** * ApiLevel: 93 * 当前服务器是否为台湾 * * @param context * @return */ public abstract boolean isTW(Context context); /** * ApiLevel: 93 * 当前服务器是否为印度 * * @param context * @return */ public abstract boolean isIndia(Context context); /** * ApiLevel: 93 * 当前服务器是否为美国 * * @param context * @return */ public abstract boolean isAmerica(Context context); /** * ApiLevel: 93 * 当前服务器是否为俄罗斯 * * @param context * @return */ public abstract boolean isRussia(Context context); /** * ApiLevel: 93 * 当前服务器是否为新加坡 * * @param context * @return */ public abstract boolean isSingapore(Context context); /** * ApiLevel: 22 给设备发送broadcast,会发送给IXmPluginMessageReceiver.handleMessage */ public Intent getBroadCastIntent(DeviceStat deviceStat) { Intent intent = new Intent("com.xiaomi.smarthome.RECEIVE_MESSAGE"); if (deviceStat != null) { intent.putExtra("device_id", deviceStat.did); intent.putExtra("device_mac", deviceStat.mac); intent.putExtra("user_model", deviceStat.model); } return intent; } /** * ApiLevel: 22 获取设备属性和事件历史记录 * * @param model * @param did 设备did * @param type 属性为prop,事件为event * @param key 属性名,不需要prop或者event前缀 * @param timeStart 起始时间单位为秒 * @param timeEnd 结束事件,单位为秒 * @param callback 回调 */ public void getUserDeviceData(String model, String did, String type, String key, long timeStart, long timeEnd, Callback<JSONArray> callback) { JSONObject dataObj = new JSONObject(); try { dataObj.put("did", did); dataObj.put("type", type); dataObj.put("key", key); dataObj.put("time_start", timeStart); dataObj.put("time_end", timeEnd); // dataObj.put("limit",500); } catch (JSONException e) { if (callback != null) { callback.onFailure(-1, e.toString()); return; } } callSmartHomeApi(model, "/user/get_user_device_data", dataObj, callback, new Parser<JSONArray>() { @Override public JSONArray parse(String result) throws JSONException { JSONObject response = new JSONObject(result); return response.getJSONArray("result"); } }); } /** * ApiLevel: 91 设置设备属性和事件历史记录 * * @param model * @param did 设备did * @param type 属性为prop,事件为event * @param key 属性名,不需要prop或者event前缀 * @param time 起始时间单位为秒 * @param value 值 * @param callback 回调 */ public abstract void setUserDeviceData(String model, String did, String type, String key, long time, Object value, Callback<JSONArray> callback); /** * ApiLevel: 22 创建或修改设置app/插件自由存储空间,最大4k * * @param app_id 厂商APP_ID,需要向小米申请 * @param key 索引,从0开始 * @param data key,value结构数据 */ @Deprecated public void setUserConfig(String model, String app_id, int key, Map<String, Object> data, Callback<Boolean> callback) { if (callback != null) { callback.onFailure(-1, "This API is forbidden, please use setUserConfigV2 instead"); } } /** * ApiLevel: 22 拉取设置app/插件自由存储空间 * * @param model * @param app_id 厂商APP_ID,需要向小米申请 * @param keys 索引,从0开始 * @param callback key,value结构数据 */ @Deprecated public void getUserConfig(String model, String app_id, int[] keys, Callback<Map<String, Object>> callback) { if (callback != null) { callback.onFailure(-1, "API forbidden, please use getUserConfigV2 instead!"); } } /** * ApiLevel: 24 查询水电燃气余额 * * @param type 1:水 2:电 3:燃气 * @param latitude 纬度 * @param longitude 经度 * @param callback 返回查询余额Json * //{"balance":300,"updateTime":1465781516,"rechargeItemName":"郑州市燃气费"} * 返回null时表示没有绑定机表号 */ public abstract void getRechargeBalances(int type, double latitude, double longitude, Callback<JSONObject> callback); /** * ApiLevel: 26 编码生成二维码图片 * * @param barcode 二维码信息 * @param width 图片宽度 * @param height 图片高度 * @return 返回二维码图片, 为ARGB_8888格式 */ public abstract Bitmap encodeBarcode(String barcode, int width, int height); /** * ApiLevel: 26 解码二维码图片 * * @param bitmap 二维码图片,必须为ARGB_8888格式 * @return 返回二维码信息 */ public abstract String decodeBarcode(Bitmap bitmap); /** * ApiLevel: 27 从服务器更新设备信息 * * @param didList * @param callback */ public abstract void updateDevice(List<String> didList, Callback<List<DeviceStat>> callback); /** * ApiLevel: 27 * * @param context * @param loadedInfo * @param hostService * @param startIntent * @param serviceClass * @param callback */ public abstract void startService(Context context, XmPluginPackage loadedInfo, HostService hostService, Intent startIntent, Class serviceClass, Callback<Bundle> callback); /** * ApiLevel: 27 * * @param context * @param loadedInfo * @param hostService * @param startIntent * @param serviceClass * @param callback */ public abstract void stopService(Context context, XmPluginPackage loadedInfo, HostService hostService, Intent startIntent, Class serviceClass, Callback<Bundle> callback); public abstract int getDrawableResIdByName(XmPluginPackage loadedInfo, String resName); /** * ApiLevel: 30 获取组设备中的设备信息 * * @param did 组设备id */ public void getVirtualDevicesByDid(String model, String did, final Callback<List<DeviceStat>> callback) { JSONObject dataObj = new JSONObject(); try { dataObj.put("type", "get"); dataObj.put("masterDid", did); } catch (JSONException e) { if (callback != null) callback.onFailure(-1, e.toString()); return; } callSmartHomeApi(model, "/home/virtualdevicectr", dataObj, callback, new Parser<List<DeviceStat>>() { @Override public List<DeviceStat> parse(String result) throws JSONException { JSONObject jsonObject = new JSONObject(result); ArrayList<DeviceStat> deviceStatArrayList = new ArrayList<DeviceStat>(); JSONArray membersJson = jsonObject.optJSONArray("members"); if (membersJson != null && membersJson.length() > 0) { for (int i = 0; i < membersJson.length(); i++) { deviceStatArrayList.add(getDeviceByDid(membersJson.optString(i))); } } return deviceStatArrayList; } }); } /** * ApiLevel: 30 创建或修改设置app/插件自由存储空间,最大4k * * @param xmPluginPackage 插件上下文 * @param model 设备Model * @param app_id 厂商APP_ID,需要向小米申请,0和1预留 * @param key 索引,从0开始 * @param data key,value结构数据 * @param callback */ public void setUserConfigV2(XmPluginPackage xmPluginPackage, String model, int app_id, int key, Map<String, Object> data, Callback<Boolean> callback) { if (app_id == 0 || app_id == 1) { if (callback != null) { callback.onFailure(-1, "App id invalid, value 0 and 1 are reserved."); } return; } JSONObject dataObj = new JSONObject(); try { dataObj.put("component_id", app_id); dataObj.put("key", key); JSONObject attris = new JSONObject(); Set<Map.Entry<String, Object>> entrys = data.entrySet(); for (Map.Entry<String, Object> entry : entrys) { attris.put(entry.getKey(), entry.getValue()); } dataObj.put("data", attris); } catch (JSONException e) { if (callback != null) { callback.onFailure(-1, e.toString()); } return; } callSmartHomeApi(model, "/user/set_user_config", dataObj, callback, new Parser<Boolean>() { @Override public Boolean parse(String result) throws JSONException { JSONObject response = new JSONObject(result); int res = response.optInt("result"); return res != 0; } }); } /** * ApiLevel: 41 创建或修改设置app/插件自由存储空间,最大4k * * @param xmPluginPackage 插件上下文 * @param model 设备Model * @param data 索引,从0开始 * @param callback */ public void setUserConfigV3(XmPluginPackage xmPluginPackage, String model, int key, Map<String, Object> data, Callback<Boolean> callback) { JSONObject dataObj = new JSONObject(); try { dataObj.put("key", key); dataObj.put("model", model); JSONObject attris = new JSONObject(); Set<Map.Entry<String, Object>> entrys = data.entrySet(); for (Map.Entry<String, Object> entry : entrys) { attris.put(entry.getKey(), entry.getValue()); } dataObj.put("data", attris); } catch (JSONException e) { if (callback != null) { callback.onFailure(-1, e.toString()); } return; } callSmartHomeApi(model, "/user/set_third_user_config", dataObj, callback, new Parser<Boolean>() { @Override public Boolean parse(String result) throws JSONException { JSONObject response = new JSONObject(result); int res = response.optInt("result"); return res != 0; } }); } /** * ApiLevel: 42 创建或修改设置app/插件自由存储空间。如果数据超过服务器设置的阈值,自动分段存储到云端。 * 但是分段存储会占用额外的key,比如key=100时,分出的新段会存储在101,102,103...等后续相邻的key上, * 所以:若调用者打算用到多个key,每2个key之间需要留出足够的间隔以供分段用,推荐>100,比如100,200,300... * * @param xmPluginPackage * @param model * @param key * @param data * @param callback 返回存储这条数据占用的key */ public abstract void setUserConfigV5(XmPluginPackage xmPluginPackage, String model, int key, Map<String, Object> data, Callback<int[]> callback); /** * ApiLevel: 30 拉取设置app/插件自由存储空间 * * @param xmPluginPackage 插件上下文 * @param model 设备Model * @param app_id 厂商APP_ID,需要向小米申请, 0 和 1 预留 * @param keys 索引,从0开始 * @param callback key,value结构数据 */ public void getUserConfigV2(XmPluginPackage xmPluginPackage, String model, int app_id, int[] keys, Callback<Map<String, Object>> callback) { if (app_id == 0 || app_id == 1) { if (callback != null) { callback.onFailure(-1, "App id invalid, 0 and 1 are reserved."); } return; } JSONObject dataObj = new JSONObject(); try { dataObj.put("component_id", app_id); JSONArray keysArray = new JSONArray(); for (int i = 0; i < keys.length; i++) { keysArray.put(keys[i]); } dataObj.put("keys", keysArray); } catch (JSONException e) { if (callback != null) { callback.onFailure(-1, e.toString()); return; } } callSmartHomeApi(model, "/user/get_user_config", dataObj, callback, new Parser<Map<String, Object>>() { @Override public Map<String, Object> parse(String result) throws JSONException { JSONObject response = new JSONObject(result); Map<String, Object> map = new HashMap<String, Object>(); JSONObject resultObj = response.optJSONObject("result"); if (resultObj != null) { Iterator<String> iterator = resultObj.keys(); while (iterator.hasNext()) { String key = iterator.next(); map.put(key, resultObj.get(key)); } } return map; } }); } /** * ApiLevel: 40 拉取设置app/插件自由存储空间 * * @param xmPluginPackage 插件上下文 * @param model 设备Model * @param app_id 厂商APP_ID,需要向小米申请, 0 和 1 预留 * @param keys 索引,从0开始 * @param callback key,value结构数据,key为传入的int[]的各个元素,value为对应的JSONObject,例如"3" -> "{"uid":"923000000","data":{"data":"i am test data"},"component_id":"10000","update_time":"1492657366","key":"3"}" */ public void getUserConfigV3(XmPluginPackage xmPluginPackage, String model, int app_id, int[] keys, Callback<Map<String, Object>> callback) { if (app_id == 0 || app_id == 1) { if (callback != null) { callback.onFailure(-1, "App id invalid, 0 and 1 are reserved."); } return; } JSONObject dataObj = new JSONObject(); try { dataObj.put("component_id", app_id); JSONArray keysArray = new JSONArray(); for (int i = 0; i < keys.length; i++) { keysArray.put(keys[i]); } dataObj.put("keys", keysArray); } catch (JSONException e) { if (callback != null) { callback.onFailure(-1, e.toString()); return; } } callSmartHomeApi(model, "/user/get_user_config", dataObj, callback, new Parser<Map<String, Object>>() { @Override public Map<String, Object> parse(String result) throws JSONException { JSONObject response = new JSONObject(result); Map<String, Object> map = new HashMap<String, Object>(); JSONArray resultObj = response.optJSONArray("result"); for (int i = 0; i < resultObj.length(); i++) { JSONObject jsonObject = resultObj.getJSONObject(i); String key = (String) jsonObject.get("key"); map.put(key, jsonObject); } return map; } }); } /** * ApiLevel: 41 拉取设置app/插件自由存储空间 * * @param xmPluginPackage 插件上下文 * @param model 设备Model * @param keys 索引,从0开始 * @param callback key,value结构数据,key为传入的int[]的各个元素,value为对应的JSONObject,例如"3" -> "{"uid":"923000000","data":{"data":"i am test data"},"component_id":"10000","update_time":"1492657366","key":"3"}" */ public void getUserConfigV4(XmPluginPackage xmPluginPackage, String model, int[] keys, Callback<Map<String, Object>> callback) { JSONObject dataObj = new JSONObject(); try { JSONArray keysArray = new JSONArray(); for (int i = 0; i < keys.length; i++) { keysArray.put(keys[i]); } dataObj.put("keys", keysArray); dataObj.put("model", model); } catch (JSONException e) { if (callback != null) { callback.onFailure(-1, e.toString()); return; } } callSmartHomeApi(model, "/user/get_third_user_config", dataObj, callback, new Parser<Map<String, Object>>() { @Override public Map<String, Object> parse(String result) throws JSONException { JSONObject response = new JSONObject(result); Map<String, Object> map = new HashMap<>(); JSONArray resultObj = response.optJSONArray("result"); for (int i = 0; i < resultObj.length(); i++) { JSONObject jsonObject = resultObj.getJSONObject(i); Object key = jsonObject.get("key"); if (key.equals(JSONObject.NULL)) continue; map.put((String) key, jsonObject); } return map; } }); } /** * ApiLevel: 42 * 与setUserConfigV5配套使用,会把分段的数据自动合并后返回,使得分段行为对调用者透明 * * @param xmPluginPackage * @param model * @param keys * @param callback */ public abstract void getUserConfigV5(XmPluginPackage xmPluginPackage, String model, int[] keys, Callback<Map<String, Object>> callback); /** * ApiLevel: 32 打开插件安全验证通过后,可以获取设备pincode * * @param did * @return */ public abstract String getDevicePincode(String did); /** * ApiLevel: 32,本地ping设备,查看设备是否是本地设备 * * @param did * @param callback */ public abstract void localPing(String did, Callback<Void> callback); /** * ApiLevel: 32,从服务器批量获取设备属性 * * @param jsonArray [{"did":"aaa", "props":["prop.aaa","prop.bbb"]},{"did":"123", "props":["prop.jjjj","prop.777"]}] * @param callback */ public void batchGetDeviceProps(String model, JSONArray jsonArray, Callback<String> callback) { callSmartHomeApi(model, "/device/batchdevicedatas", jsonArray.toString(), callback, new Parser<String>() { @Override public String parse(String result) throws JSONException { return result; } }); } /** * ApiLevel: 32 * 打开语音授权页面。 * 使用startActivityForResult方法,回调根据resultCode是RESULT_CANCELED或者RESULT_OK判定操作是否成功 * 返回true,说明打开了授权页面,否则不需要打开授权页面 * * @param did * @param activity: */ public abstract boolean checkAndShowVoiceCtrlAuthorizePageIfNeed(Activity activity, String did, int requestCode); /** * ApiLevel: 31 * * @param did */ public abstract void visualSecureBind(String did); /** * ApiLevel: 31 * * @param model 设备model */ public abstract void getFirmwareUpdateInfoCommon(String model, final Callback<FirmwareUpdateInfo> callback); /** * ApiLevel: 32 下载固件 */ public abstract void downloadFirmware(String url, Response.FirmwareUpgradeResponse response); /** * ApiLevel: 33 * 获取网络链接对应的图片资源 */ public abstract void loadBitmap(String imageUrl, Callback<Bitmap> callback); /** * ApiLevel:34 获取设备标签 * * @param did * @return */ public abstract DeviceTag getDeviceTagByDid(String did); /** * RN-sdk api 10023通过灯的model来获取灯组的model * @param model * @return */ public abstract String getLightDeviceGroupModel(String model); /** * ApiLevel:34 添加标签,若did不为空,则同时为此设备设置该标签 * * @param tag * @param did */ public abstract void addTag(String tag, String did); /** * ApiLevel:34 删除标签 * * @param tag */ public abstract void removeTag(String tag); /** * ApiLevel: 34 * 根据设备的model获取设备实物图 */ public abstract void getDeviceRealIconByModel(String model, Callback<Bitmap> callback); /** * ApiLevel:34 获取建议标签 * * @param did * @return */ public abstract List<String> getRecommendTags(String did); /** * ApiLevel: 36 * 初始化相机发送通道 */ public abstract void initCameraFrameSender(String did); /** * ApiLevel: 36 * 摄像机设备发送video接口 */ public abstract void sendCameraFrame(String did, byte[] data, long seq, int frameSize, long timestamp, boolean isIFrame, int width, int height); /** * ApiLevel: 57 * 摄像机设备发送video接口 * videoType 发送的video格式 * 1 - H264 * 2 - H265 */ public abstract void sendCameraFrame(String did, byte[] data, long seq, int frameSize, long timestamp, int videoType, boolean isIFrame, int width, int height); /** * ApiLevel: 36 * 关闭发送通道 */ public abstract void closeCameraFrameSender(String did); /** * ApiLevel: 36 * 开启摄像头悬浮窗(须支持发送摄像头视频数据) */ public abstract void openCameraFloatingWindow(String did); /** * ApiLevel: 36 * 关闭摄像头悬浮窗(须支持发送摄像头视频数据) */ public abstract void closeCameraFloatingWindow(String did); /** * ApiLevel: 35 */ public abstract Typeface getFont(String name); /** * ApiLevel: 37 * * @param context * @param loadedInfo * @param hostService * @param serviceClass * @param connection * @param flags * @param callback */ public abstract void bindService(Context context, XmPluginPackage loadedInfo, HostService hostService, Class serviceClass, ServiceConnection connection, int flags, Callback<Bundle> callback); /** * ApiLevel: 37 * * @param context * @param loadedInfo * @param hostService * @param serviceClass * @param connection * @param callback */ public abstract void unbindService(Context context, XmPluginPackage loadedInfo, HostService hostService, Class serviceClass, ServiceConnection connection, Callback<Bundle> callback); /** * ApiLevel: 38 * 根据did获取设备的订阅属性 */ public abstract JSONArray getDeviceProp(String did); /** * ApiLevel:39 米家后台统计.该打点同时也更新到小米开放平台上. * * @param loadedInfo 插件上下文 * @param model 当前设备model * @param value 为Object 可以为int或String或JsonObject * @param extra 可以为null */ @Deprecated public abstract void addRecordV2(XmPluginPackage loadedInfo, String model, String key, Object value, JSONObject extra); /** * ApiLevel: 41 * 设备列表过滤能控制的设备 */ public abstract void getControllableDevices(String model, Callback<JSONObject> callback); /** * ApiLevel:43 * 跳转到意见反馈页面 * * @param activity * @param model * @param did * @param pluginPackage */ public abstract void gotoFeedback(Activity activity, String model, String did, XmPluginPackage pluginPackage); /** * ApiLevel:44 * 跳转到授权管理页 * * @param activity * @param did */ public abstract void gotoAuthManagerPage(Activity activity, String did); /** * ApiLevel:45 * 获取插件notification的icon */ public abstract int getMiHomeNotificationIcon(); /** * ApiLevel:51 * 分享电子钥匙 * * @param model 设备model * @param did 分享者的did * @param shareUid 分享目标的uid * @param status 分享类别,1:暂时,2:周期,3:永久 * @param activeTime 生效时间 UTC时间戳,单位为s * @param expireTime 过期时间 UTC时间戳,单位为s * @param weekdays 生效日期(星期几,例如周一和周三对应1和3,[1, 3],星期天对应0),仅在status=2时不可为空 * @param readonly true:被分享人不可接收锁push,false:被分享人可接收锁push,(family关系用户不受这个字段影响) * @param callback */ public void shareSecurityKey(final String model, final String did, String shareUid, final int status, final long activeTime, final long expireTime, final List<Integer> weekdays, final boolean readonly, final Callback<Void> callback) { Callback<String> userInfoCallback = new Callback<String>() { @Override public void onSuccess(String userId) { if (TextUtils.isEmpty(userId) || userId.equalsIgnoreCase("-1") || userId.equalsIgnoreCase("0")) { if (callback != null) { callback.onFailure(INVALID, "shareUid is invalid"); } } else { JSONObject dataObj = new JSONObject(); try { dataObj.put("type", "bleshare"); dataObj.put("did", did); dataObj.put("userid", userId); dataObj.put("status", status); dataObj.put("active_time", activeTime); dataObj.put("expire_time", expireTime); if (weekdays != null && weekdays.size() > 0) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < weekdays.size(); i++) { if (i == 0) { sb.append(weekdays.get(i)); } else { sb.append(","); sb.append(weekdays.get(i)); } } dataObj.put("weekdays", sb.toString()); } dataObj.put("readonly", readonly); } catch (JSONException e) { if (callback != null) callback.onFailure(-1, e.toString()); return; } callSmartHomeApi(model, "/share/bluetoothkeyshare", dataObj, callback, null); } } @Override public void onFailure(int error, String errorInfo) { if (callback != null) { callback.onFailure(error, errorInfo); } } }; JSONObject userInfoObj = new JSONObject(); try { userInfoObj.put("id", shareUid); } catch (JSONException e) { } Parser<String> parser = new Parser<String>() { @Override public String parse(String response) throws JSONException { JSONObject jsonObject = new JSONObject(response); return jsonObject.optString("userid"); } }; callSmartHomeApi(model, "/home/profile", userInfoObj, userInfoCallback, parser); } /** * ApiLevel:51 * 更新分享的电子钥匙信息 * * @param model 设备的model * @param did 分享者的did * @param keyId 电子钥匙的keyId * @param status 分享类别,1:暂时,2:周期,3:永久 * @param activeTime 生效时间 UTC时间戳,单位为s * @param expireTime 过期时间 UTC时间戳,单位为s * @param weekdays 生效日期(星期几,例如周一和周三对应1和3,[1, 3]),仅在status=2时不可为空 * @param callback */ public void updateSecurityKey(String model, String did, String keyId, int status, long activeTime, long expireTime, List<Integer> weekdays, Callback<Void> callback) { JSONObject dataObj = new JSONObject(); try { dataObj.put("type", "update"); dataObj.put("did", did); dataObj.put("keyid", keyId); dataObj.put("status", status); dataObj.put("active_time", activeTime); dataObj.put("expire_time", expireTime); if (weekdays != null && weekdays.size() > 0) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < weekdays.size(); i++) { if (i == 0) { sb.append(weekdays.get(i)); } else { sb.append(","); sb.append(weekdays.get(i)); } } dataObj.put("weekdays", sb.toString()); } } catch (JSONException e) { e.printStackTrace(); } callSmartHomeApi(model, "/share/bluetoothkeyshare", dataObj, callback, null); } /** * ApiLevel:51 * 删除共享的电子钥匙 * * @param model 设备的model * @param did 分享者的did * @param keyId 分享电子钥匙的KeyId * @param callback */ public void deleteSecurityKey(String model, String did, String keyId, final Callback<Void> callback) { JSONObject dataObj = new JSONObject(); try { dataObj.put("type", "bledelete"); dataObj.put("did", did); dataObj.put("keyid", keyId); } catch (JSONException e) { e.printStackTrace(); } callSmartHomeApi(model, "/share/bluetoothkeyshare", dataObj, callback, null); } /** * ApiLevel:51 * 获取所有分享的电子钥匙信息 * * @param model 设备model * @param did 分享者的did * @param callback */ public void getSecurityKey(String model, String did, final Callback<List<SecurityKeyInfo>> callback) { final JSONObject dataObj = new JSONObject(); try { dataObj.put("type", "get"); dataObj.put("did", did); } catch (JSONException e) { e.printStackTrace(); } callSmartHomeApi(model, "/share/bluetoothkeyshare", dataObj, callback, new Parser<List<SecurityKeyInfo>>() { @Override public List<SecurityKeyInfo> parse(String result) throws JSONException { /** * result:格式{"bleshare":[{"keyid":183038048,"shareuid":"23912868","status":"3","active_time":"1499997061","expire_time":"1531446661","isoutofdate":0}]} */ List<SecurityKeyInfo> infos = new ArrayList<SecurityKeyInfo>(); try { JSONObject resultObject = new JSONObject(result); JSONArray jsonArray = resultObject.optJSONArray("bleshare"); if (jsonArray != null && jsonArray.length() > 0) { for (int i = 0; i < jsonArray.length(); i++) { JSONObject jsonObject = jsonArray.optJSONObject(i); if (jsonObject != null) { SecurityKeyInfo info = new SecurityKeyInfo(); info.keyId = jsonObject.optString("keyid"); info.shareUid = jsonObject.optString("shareuid"); info.status = jsonObject.optInt("status"); info.activeTime = jsonObject.optLong("active_time"); info.expireTime = jsonObject.optLong("expire_time"); info.isoutofdate = jsonObject.optInt("isoutofdate"); String weekdays = jsonObject.optString("weekdays"); if (!TextUtils.isEmpty(weekdays)) { String[] days = weekdays.split(","); if (days != null && days.length > 0) { info.weekdays = new ArrayList<Integer>(); for (int tmp = 0; tmp < days.length; tmp++) { info.weekdays.add(Integer.valueOf(days[tmp])); } } } infos.add(info); } } } } catch (JSONException e) { e.printStackTrace(); } return infos; } }); } /** * ApiLevel:51 * 获取UTC时间,单位为ms * 被废弃了,使用getUTCFromServer接口 */ @Deprecated public abstract long getUTCTimeInMillis(); /** * ApiLevel:51 * 从服务器获取UTC时间,单位为秒(返回-1,说明解析出现异常,当做错误处理) * * @param callback */ public void getUTCFromServer(String model, Callback<Long> callback) { JSONObject dataObj = new JSONObject(); Parser<Long> parser = new Parser<Long>() { @Override public Long parse(String response) throws JSONException { /** * {"code":0,"message":"ok","result":1502874040} */ JSONObject jsonObject = new JSONObject(response); return jsonObject.optLong("result", -1); } }; callSmartHomeApi(model, "/device/get_utc_time", dataObj, callback, parser); } /** * ApiLevel: 51 * 获取蓝牙锁绑定的时间 * * @param model * @param did * @param callback */ public void getBleLockBindInfo(String model, String did, Callback<String> callback) { JSONObject dataObj = new JSONObject(); try { dataObj.put("did", did); } catch (JSONException e) { e.printStackTrace(); } Parser<String> parser = new Parser<String>() { @Override public String parse(String response) throws JSONException { /** * {"code":0,"message":"ok","result":{"bindtime":1505180216}} * 返回数据格式:{"bindtime":1505180216} */ JSONObject jsonObject = new JSONObject(response); return jsonObject.optString("bindtime"); } }; callSmartHomeApi(model, "/device/blelockbindinfo", dataObj, callback, parser); } /** * ApiLevel: 51 * 请求app config * * @param name * @param lang * @param version */ public abstract void getAppConfig(String name, String lang, String version, Callback<String> callback); /** * ApiLevel: 51 * 获取app语言信息 */ public abstract Locale getSettingLocale(); /** * ApiLevel: 53 * 判断当前app是否支持当前model */ public abstract boolean isModelSupport(String model); /** * ApiLevel: 54 * 提供给插件记录日志保存在本地,用户反馈时可以提交到服务器, * * @param model * @param logMessage */ public abstract void logByModel(String model, String logMessage); /** * ApiLevel: 55 * 反地理解析获取经纬度信息获取位置信息 * <p> * 注意事项: * 1. 插件要缓存相应的结果,避免频繁调用该接口,每天配额是有限的,超过后当天该接口将无法工作 * 2. 目前使用Android系统和高德进行反地理解析,而高德并不支持海外反地理解析 * 3. 反地理解析结果语言一般是米家设置的语言,如果米家跟随系统,则是手机系统的语言,但是不能保证一定会有相应的语言版本 */ public abstract void reverseGeo(double latitude, double longitude, Callback<Address> callback); /** * ApiLevel: 58 * 提供给插件记录日志保存在本地,用户反馈时可以提交到服务器 * * @param model * @param logMessage */ public abstract void logForModel(String model, String logMessage); /** * ApiLevel: 64 * 创建一个播放视频流的播放视图 * * @param context * @param original 父容器 * @param useHard 是否优先使用硬解码 * @param type 视频流编码类型 1==h264 2==h265 * @return * @see com.xiaomi.smarthome.camera.VideoFrame */ public abstract XmVideoViewGl createVideoView(Context context, FrameLayout original, boolean useHard, int type); /** * ApiLevel: 88 * 创建摄像机的p2p连接 * 需要初始化的XmP2PInfo对象,如未初始化,请调用 updateP2pPwd(...)进行初始化会返回一个XmP2PInfo * * @return */ public abstract XmCameraP2p createCameraP2p(XmP2PInfo info, int type); /** * ApiLevel: 88 * 获取XmP2PInfo 对象,里面包含了一些链接需要的参数和信息 * * @param deviceStat 设备信息 * @param type P2P 连接类型 P2P_TUTK * @see XmP2PInfo 根据P2P类型来判断更新密码的接口 */ public abstract void updateP2pPwd(DeviceStat deviceStat, int type, Callback<XmP2PInfo> callback); /** * ApiLevel: 88 * 创建一个AAC实例用来编解码AAC音频文件 * * @param enCode 是否是编码,如果是编码需要传递后面三个参数,如果是解码不需要传递 * @param framerate 采样率 8000,16000 * @param channel 音频声道 单声道还是双声道 * @param bitrate 比特率 */ public abstract XmAAcCodec createAAcCodec(boolean enCode, int framerate, int channel, int bitrate); /** * ApiLevel: 64 * 创建一个用来播放本地Mp4的视图 * * @param context * @param original 父容器 * @param useHard true MediaPlayer播放mp4 // false 使用ffmpeg 播放mp4 * @return */ public abstract XmVideoViewGl createMp4View(Context context, FrameLayout original, boolean useHard); /** * ApiLevel: 64 * 创建一个可以用来合成Mp4的接口 * * @return Mp4音视频流合成器的接口 */ public abstract XmMp4Record createMp4Record(); /** * ApiLevel: 64 * 插件获取bindkey后传给设备,然后设备再传给MIOT后台,完成设备与MIOT的绑定 */ public abstract void getBindKey(String model, Callback<String> callback); /** * ApiLevel: 75 * 检查/请求权限 * 米家将targetSdkVersion升级到>=23之后,需要适配全新的权限机制。 * ps:6.0之前的安卓版本上,申请的权限在app安装时就被授予。 * 6.0之后为了更好的保护用户隐私,部分涉及隐私的权限被定义为危险权限(CAMERA、麦克风等),需要用户主动授权后才能使用。 * 针对这种情况,凡涉及到危险权限的功能,都应该在使用前动态的检查是否已被用户授权。 * 否则可能会出现java.lang.SecurityException: Permission Denial从而导致应用崩溃。 * 危险权限列表可以参考Android开发文档https://developer.android.com/guide/topics/permissions/overview#perm-groups * * @param activity * @param requestPermission 是否发起请求权限流程 * @param callback 授权结果回调 * @param permissions 申请的权限或权限组(常见危险权限已在Permission这个类中定义,可直接作为参数传入该方法使用。) * @return 权限都已经授予/功能正常,返回true,否则,返回false */ public abstract boolean checkAndRequestPermisson(Activity activity, boolean requestPermission, Callback<List<String>> callback, String... permissions); /* * ApiLevel: 65 * 插件获取云存储报警视频, mp4格式 * @param context 不能为null * @param params 包括did,fileId,stoId的json格式string * @param callback 回调函数,获取成功或者失败的结果 */ public abstract void getCloudVideoFile(Context context, String params, ICloudDataCallback callback); /* * ApiLevel: 65 * 插件获取图片url的api,只是获取url,不真正下载图片 * @param did 设备id * @param fileId 文件id * @param stoId 存储id * @return 图片url */ public abstract String getCloudImageUrl(String did, String fileId, String stoId); /* * ApiLevel: 65 * 插件获取加密的图片 * @param context 不能为null * @param imageUri 图片的uri * @return 图片数据 */ public abstract byte[] sendImageDownloadRequest(Context context, String imageUri); /** * ApiLevel: 66 * 打开创建组设备界面 * * @param groupModel */ public abstract void createDeviceGroup(Context context, String groupModel); /** * ApiLevel: 68 * 查询did对应的设备是否开启的用户体验计划 * * @param did */ public abstract boolean isUsrExpPlanEnabled(String did); /** * ApiLevel: 68 * 设置did对应的设备是否开启的用户体验计划 * 只保存本地,目前清除数据后恢复默认值 * * @param did */ public abstract void setUsrExpPlanEnabled(String did, boolean enabled); /** * ApiLevel: 69 * 获取特定Model蓝牙设备列表信息(在后台配置具体哪个model可以获取哪些设备列表) * * @param requestModel 要获取设备列表的model * @return 返回的设备列表只包含:mac地址、did、model、设备名称(用户自定义的)、产品名称、设备实物图 */ public abstract List<DeviceStat> getFilterBluetoothDeviceList(String requestModel); /** * ApiLevel: 69 * 获取model对应的产品基本信息,比如产品名称、产品icon等 * * @param model * @return */ public abstract ProductInfo getProductInfo(String model); /* * ApiLevel: 69 * @param context 不能为null * @param viewGroup parent layout * @param attrs * @param defStyleAttr * * @return MJExoPlayer 创建的一个父view为参数viewGroup中的播放器 */ public abstract MJExoPlayer createExoPlayer(Context context, ViewGroup viewGroup, AttributeSet attrs, int defStyleAttr); /* * ApiLevel: 69 * 根据参数生成请求url,会添加加密信息(segmentIv)和地区(region)等参数进url,然后将参数进行加密 * @param hostParams 请求host的前缀(prefix)和路径(path)变量,包括请求方法(post, get) * @param pathParams 请求路径后面跟的变量数据 * * @return 返回一个请求的url */ public abstract String generateRequestUrl(String model, JSONObject hostParams, JSONObject pathParams); /* * *ApiLevel: 69 *创建一个从m3u8生成mp4的类,通过这个类可以将流数据转化为mp4文件 * @param model 设备的model * * @return 返回一个HLSDownloader实例 */ public abstract HLSDownloader getHLSDownloader(String model); /** * ApiLevel: 76 * 获取当前用户设备列表所有的蓝牙网关设备 */ public abstract List<DeviceStat> getBleGatewayDeviceList(); /** * ApiLevel: 77 * 获取Spec实例 * * @param did * @return */ public abstract DeviceController getSpecDeviceController(String did); /** * ApiLevel: 77 * 获取property属性值 * * @param context * @param properties * @param callback */ public abstract void getPropertyValues(Context context, List<PropertyParam> properties, Callback<List<PropertyParam>> callback); /** * ApiLevel: 77 * 设置属性值 * * @param context * @param property * @param callback */ public abstract void setPropertyValue(Context context, PropertyParam property, Callback<PropertyParam> callback); /** * ApiLevel: 77 * 执行action * * @param context * @param action * @param callback */ public abstract void doAction(Context context, ActionParam action, Callback<ActionParam> callback); /** * ApiLevel:85 获取蓝牙设备固件升级信息 */ public abstract void getBleMeshFirmwareUpdateInfo(String model, String did, Callback<BleMeshFirmwareUpdateInfo> callback); /** * ApiLevel: 85 * 获取灯组初始化状态 * * @return success = "1" faild = "3" initializing = "0" */ public abstract String getVirtualGroupStatus(String did); /*** * ApiLevel: 86 * @param did 设备id, 用来区分文件夹 * @param fileId 文件id,用来区分文件夹 * @param m3u8Url 从m3u8Url这个位置下载片文件 * @param callback onCloudDataSuccess中第一个参数为List<String>, 存储的是ts列表, 第二个参数是该ts所在的文件夹 */ public abstract void getCloudVideoFile(String did, String fileId, String m3u8Url, ICloudDataCallback callback); /*** * ApiLevel 86 * @param model 设备的model * @param cmdLine 和ffmpeg命令行一致,如 "ffmpeg -i /绝对路径/input.ts -c copy -f mp4 /绝对路径/output.mp4" * @return 返回ffmpeg的执行结果 0=成功 -1或其它值表示失败 * * 注意!!! 1.不要在ui线程操作, 2.cmdline完全没有任何限制,可以执行任何命令,执行结果取决于输入的命令及数据是否正确,每个参数中间的空格不可少 */ public abstract int videoConverter(String model, String cmdLine); /** * ApiLevel:88 开启和关闭微信推送mijia camera报警视频 * * @param activity * @param model 设备model * @param did 设备did * @param push 开关设定值 * @param bindcode 绑定微信账号启动界面传入的code * @param callback */ public abstract void setWxPush(Activity activity, String model, String did, boolean push, int bindcode, Callback<Boolean> callback); /** * ApiLevel:88 获取微信推送mijia camera报警开关状态 * * @param model 设备model * @param did 设备did * @param callback */ public abstract void getWxPushSwitchState(String model, String did, final Callback<Boolean> callback); /** * ApiLevel 87 * * @param areaId 地区码 101010200,与(经度,纬度)必须2选1 * @param longitude 经度 * @param latitude 纬度 * @param cityId */ public abstract void getAreaPropInfo(String model, String areaId, String longitude, String latitude, @Nullable String cityId, Callback<String> callback); /*** * ApiLevel 88 根据url获取文件,请求过程会塞入serviceToken * @param model 设备model * @param requestUrl 获取文件的url * @param localFilePath 获取文件的存储地址,文件下载成功后会存在这里 * @param callback 回调,成功返回的参数里包含上面填入的localFilePath, 出错会提示错误码,没有onCloudDataProgress回调 */ public abstract void getFile(String model, String requestUrl, String localFilePath, ICloudDataCallback callback); /** * ApiLevel:90 * <p> * 获取蓝牙设备固件升级信息,这个接口会上传设备的did,插件版本号,当前app的版本号,用于服务端做更细粒度的固件下发控制逻辑 */ public abstract void getBluetoothFirmwareUpdateInfoV2(String did, String model, int pluginVersion, final Callback<BtFirmwareUpdateInfoV2> callback); /** * ApiLevel:95 * 设备定向推荐:展示推荐入口使用。 * * @param model * @param deviceId * @param callback */ public abstract void getRecommendScenes(String model, String deviceId, final Callback<JSONObject> callback); /** * 获取蓝牙网关子设备,包括mesh和普通蓝牙设备 * RnSdkApiLevel: 10020 * * @param dids * @param callback */ public abstract void getBleGatewaySubDevices(List<String> dids, Callback<List<DeviceStat>> callback); /** * ApiLevel ?? 获取miss框架的实例 * @param model * @param did * @param deviceStat */ public abstract IXmStreamClient createStreamClient(String model, String did, DeviceStat deviceStat); /** * RN apiLevel 10021 * 初始化手环SDK */ public abstract void initBandManager(String model, String did, final Callback<Boolean> callback); /** * RN apiLevel 10021 * 释放手环SDK */ public abstract void deInitBandManager(); /** * RN apiLevel 10021 * 连接手环设备 */ public abstract void connectBand(String mac, final Callback<Integer> callback); /** * RN apiLevel 10021 * 获取所有卡片 */ public abstract void getAllCards(final Callback<String> callback); /** * RN apiLevel 10021 * 手环开卡 */ public abstract void issueDoorCard(final Callback<Boolean> callback); /** * RN apiLevel 10021 * 手环删卡 */ public abstract void deleteCard(String aid, final Callback<Boolean> callback); /** * RN apiLevel 10021 * 设置默认卡 */ public abstract void setDefaultCard(String aid, final Callback<Boolean> callback); /** * RN apiLevel 10021 * 更新卡信息 */ public abstract void updateCard(String hashmap, final Callback<Boolean> callback); /** * RN apiLevel 10021 * 获取默认卡片及激活信息 */ public abstract void getDefaultCardAndActivateInfo(final Callback<String> callback); /* * ApiLevel: unknown 上传图片到服务器, MultipartFile Form-data 方式 * @param model 设备model * @param did 设备did * @param hostPrefix url前缀,可为空 * @param relativeUrl url相对路径 * @param params 参数 * @param filePaths 文件路径,可多个文件 * @param callback 回调函数 */ public abstract void uploadImageFile(String model, String did, String hostPrefix, String relativeUrl, JSONObject params, List<String> filePaths, ICloudDataCallback<JSONObject> callback); /** * RN apiLevel 10024 * 获取 设置-->开发者选项 preview appconfig 是否选中的状态 * @return 1:表示选中, preview ; 0:表示未选中, release */ public abstract int getUsePreviewConfig(); }