panlili2024
2025-02-24 9a437cca9b3d21f5081d544024ee2b3e216176f8
更新demo
7个文件已添加
7个文件已修改
2 文件已重命名
2021 ■■■■■ 已修改文件
HDLSDK/hdl-connect/build.gradle 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK_DEMO/app/build.gradle 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK_DEMO/app/libs/com.hdl.sdk-v1.2.0.aar 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK_DEMO/app/src/main/AndroidManifest.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK_DEMO/app/src/main/java/com/hdl/hdlsdk/DemoAdapter.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK_DEMO/app/src/main/java/com/hdl/hdlsdk/EthernetUtils.java 63 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK_DEMO/app/src/main/java/com/hdl/hdlsdk/MainActivity.java 589 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK_DEMO/app/src/main/java/com/hdl/hdlsdk/SourceTestActivity.java 556 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK_DEMO/app/src/main/java/com/hdl/hdlsdk/bean/FunctionBean.java 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK_DEMO/app/src/main/java/com/hdl/hdlsdk/bean/RoomFunctionBean.java 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK_DEMO/app/src/main/java/com/hdl/hdlsdk/bean/SceneBean.java 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK_DEMO/app/src/main/java/com/hdl/hdlsdk/bean/SceneDetailBean.java 86 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK_DEMO/app/src/main/java/com/hdl/hdlsdk/bean/SceneFunctionsInfo.java 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK_DEMO/app/src/main/java/com/hdl/hdlsdk/device/DevicesListActivity.java 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK_DEMO/app/src/main/java/com/hdl/hdlsdk/device/DevicesListAdapter.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK_DEMO/app/src/main/res/layout/activity_source_test.xml 508 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDLSDK/hdl-connect/build.gradle
@@ -8,8 +8,8 @@
    defaultConfig {
        minSdkVersion rootProject.minSdkVersion
        targetSdkVersion rootProject.targetSdkVersion
        versionCode 7
        versionName "1.1.9"
        versionCode 8
        versionName "1.2.0"
        consumerProguardFiles "consumer-rules.pro"
    }
@@ -32,7 +32,6 @@
    api 'com.hdl.hdlhttp:hxhttp:1.0.4'
    api 'com.squareup.okhttp3:logging-interceptor:4.9.1'
    api files('libs/hdlSDK_V1.0.7.jar')
//    embed(name: 'hdlSDK_V1.0.2',ext: 'jar')
    api 'com.google.code.gson:gson:2.8.8'
}
HDLSDK_DEMO/app/build.gradle
@@ -7,7 +7,7 @@
    defaultConfig {
        applicationId "com.hdl.hdlsdkdemo"
        minSdk 21
        minSdk 23
        targetSdk 31
        versionCode 1
        versionName "1.0"
@@ -39,5 +39,5 @@
    implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:3.0.6'
//    implementation 'com.google.code.gson:gson:2.8.8'
    implementation files('libs\\com.hdl.sdk-v1.1.9.aar')
    implementation files('libs\\com.hdl.sdk-v1.2.0.aar')
}
HDLSDK_DEMO/app/libs/com.hdl.sdk-v1.2.0.aar
Binary files differ
HDLSDK_DEMO/app/src/main/AndroidManifest.xml
@@ -10,6 +10,7 @@
        android:name="android.permission.WRITE_EXTERNAL_STORAGE"
        tools:ignore="ScopedStorage" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEM"/>
    <application
        android:name=".App"
@@ -30,6 +31,11 @@
            </intent-filter>
        </activity>
        <activity
            android:name=".SourceTestActivity"
            android:exported="false"
            android:windowSoftInputMode="adjustPan|stateHidden" />
    </application>
</manifest>
HDLSDK_DEMO/app/src/main/java/com/hdl/hdlsdk/DemoAdapter.java
@@ -16,7 +16,7 @@
    public DemoAdapter(@Nullable List<DemoBean> data) {
        super(data);
        addItemType(0, R.layout.demo_item);
        addItemType(0,R.layout.demo_item);
    }
    @Override
HDLSDK_DEMO/app/src/main/java/com/hdl/hdlsdk/EthernetUtils.java
New file
@@ -0,0 +1,63 @@
package com.hdl.hdlsdk;
import android.text.TextUtils;
import android.util.Log;
import java.util.regex.Pattern;
public class EthernetUtils {
    public boolean checkIPValue(String ipAddr, String gateway, String netMask, String dns1, String dns2) {
        boolean enable = false;
        Pattern pattern = Pattern.compile("(^((\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])$)|^(\\d|[1-2]\\d|3[0-2])$"); /*check subnet mask*/
        if (isValidIpAddress(ipAddr) && isValidIpAddress(gateway)
                && isValidIpAddress(dns1) && (pattern.matcher(netMask).matches())) {
            if (TextUtils.isEmpty(dns2)) { // 为空可以不考虑
                enable = true;
            } else {
                if (isValidIpAddress(dns2)) {
                    enable = true;
                } else {
                    enable = false;
                }
            }
        } else {
            enable = false;
        }
        return enable;
    }
    private boolean isValidIpAddress(String value) {
        int start = 0;
        int end = value.indexOf('.');
        int numBlocks = 0;
        while (start < value.length()) {
            if (-1 == end) {
                end = value.length();
            }
            try {
                int block = Integer.parseInt(value.substring(start, end));
                if ((block > 255) || (block < 0)) {
                    Log.w("EthernetIP",
                            "isValidIpAddress() : invalid 'block', block = "
                                    + block);
                    return false;
                }
            } catch (NumberFormatException e) {
                Log.w("EthernetIP", "isValidIpAddress() : e = " + e);
                return false;
            }
            numBlocks++;
            start = end + 1;
            end = value.indexOf('.', start);
        }
        return numBlocks == 4;
    }
}
HDLSDK_DEMO/app/src/main/java/com/hdl/hdlsdk/MainActivity.java
@@ -1,8 +1,10 @@
package com.hdl.hdlsdk;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
@@ -15,7 +17,6 @@
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
@@ -23,6 +24,10 @@
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.listener.OnItemClickListener;
import com.google.gson.reflect.TypeToken;
import com.hdl.hdlsdk.bean.FunctionBean;
import com.hdl.hdlsdk.bean.RoomFunctionBean;
import com.hdl.hdlsdk.bean.SceneBean;
import com.hdl.hdlsdk.bean.SceneDetailBean;
import com.hdl.hdlsdk.device.DevicesListActivity;
import com.hdl.sdk.common.config.TopicConstant;
import com.hdl.sdk.common.event.DeleteNetworkListener;
@@ -33,14 +38,18 @@
import com.hdl.sdk.common.utils.gson.GsonConvert;
import com.hdl.sdk.connect.HDLLink;
import com.hdl.sdk.connect.bean.LinkResponse;
import com.hdl.sdk.connect.bean.request.AttributesRequest;
import com.hdl.sdk.connect.bean.request.AuthenticateRequest;
import com.hdl.sdk.connect.bean.request.DeviceControlRequest;
import com.hdl.sdk.connect.bean.request.ListSidRequest;
import com.hdl.sdk.connect.bean.request.ListUploadRequest;
import com.hdl.sdk.connect.bean.response.BaseLocalResponse;
import com.hdl.sdk.connect.bean.response.GatewaySearchBean;
import com.hdl.sdk.connect.bean.response.UpdateInfo;
import com.hdl.sdk.connect.callback.HDLLinkCallBack;
import com.hdl.sdk.connect.callback.HDLLinkResponseCallBack;
import com.hdl.sdk.connect.cloud.CallBackListener;
import com.hdl.sdk.connect.cloud.CheckAppVersionListener;
import com.hdl.sdk.connect.cloud.HDLException;
import com.hdl.sdk.connect.config.HDLLinkConfig;
import com.hdl.sdk.connect.socket.HDLAuthSocket;
@@ -51,8 +60,6 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import retrofit2.http.HEAD;
public class MainActivity extends AppCompatActivity {
@@ -65,46 +72,25 @@
    private EditText editText;
    boolean isOn;
    private EventListener allTopicsListener;
    private String testLightSid = "02010131D9C03D01020300010107";
    private String testLightSid = "020101A19B485D02020100010101";
    private String secret = "";
    @Override
    protected void onDestroy() {
        super.onDestroy();
        removeAllTopicsListener();
    }
    void initDeviceInfo() {
        AuthenticateRequest.AuthenticateDeviceInfoBean infoBean = new AuthenticateRequest.AuthenticateDeviceInfoBean();
        infoBean.setDeviceMAC("f2c5d8bad48f");
        infoBean.setIPMAC("f2c5d8bad48f");
        infoBean.setDeviceName("音乐播放器");//设备名字
        infoBean.setDeviceModel("MCLog.431");//设备型号
        infoBean.setAccessMode("WIFI");
        infoBean.setIPGateway("192.168.1.1");
        infoBean.setIPAddress("192.168.1.103");
        infoBean.setGateway_type("screen.touch");
        infoBean.setHw_version("HW2.0");
        infoBean.setFw_version("Fw1.0");
        infoBean.setOID("010105000000FE11");//每个设备oid都要不一样
        infoBean.setSid("110105000000FE08110100000011");//每个设备的sid都要不一样
        infoBean.setSupplier("JINMAOYUN");
        HDLLinkConfig.getInstance().setDeviceInfoBean(infoBean);
    }
    private List<FunctionBean> devicesList = new ArrayList<>();
    private List<FunctionBean> roomDevicesList = new ArrayList<>();
    private List<SceneBean> sceneList = new ArrayList<>();
    private List<SceneDetailBean> sceneDetailList = new ArrayList<>();
    private List<SceneDetailBean> roomSceneList = new ArrayList<>();
    void applyDeviceSecret() {
        tv.setText("开始申请设备密钥...");
        responseTv.setText("");
//        //正式服务器
        String appKey = "i8hR07jzrIS";//appkey
        String appSecret = "BmnJ8RWTtaVEBk24zPPF4UMwfYu0lAWU";//appsecret
//        String appKey = "i8hR07jzrIS";//appkey
//        String appSecret = "BmnJ8RWTtaVEBk24zPPF4UMwfYu0lAWU";//appsecret
        //测试服务器
//        String appKey ="FcRyUJlLJFF";
//        String appSecret = "wz8wn75ABidx8vXcFGUotqhwFkTaYvvJ";
        String appKey = "FcRyUJlLJFF";
        String appSecret = "wz8wn75ABidx8vXcFGUotqhwFkTaYvvJ";
//        String appKey = "L2OZliZRxHc";
//        String appSecret = "aCIWSvJDOukXfx3kivsKW11x9xdR3IbV";
@@ -136,63 +122,30 @@
    }
    /**
     * 入网认证
     */
    void sendAuthenticateRequest() {
        tv.setText("开始入网认证...");
    void checkAppVersion() {
        tv.setText("开始检测更新...");
        responseTv.setText("");
        //认证提交参数准备
//
//        //测试服务器
//        String spkStr = "music.standard";//产品spk
//        String macStr = "AA000000000000AF";//设备唯一MAC地址
//        String secret = "44b360eb74b7ba64";//通过spk和mac提交云端认证后分配的secret
//        正式服务器
        String spkStr = "screen.touch";//产品spk
//        String macStr = "AA00000000000100";//设备唯一MAC地址
        String macStr = editText.getText().toString();//设备唯一MAC地址
//        String secret = "e186beeb7974998e";//通过spk和mac提交云端认证后分配的
//        //正式服务器
        String appKey = "i8hR07jzrIS";//appkey
        String appSecret = "BmnJ8RWTtaVEBk24zPPF4UMwfYu0lAWU";//appsecret
        String mac_key = stringToMD5(stringToMD5(macStr + secret));
        String versionString = "HDL_V1.0.1";//
        String time = String.valueOf(System.currentTimeMillis());
        HDLLinkConfig.getInstance().getDeviceInfoBean().setDeviceMAC(macStr);
//        HDLLinkConfig.getInstance().setCurrentGateway(infoBean);
        String appCode = "1697150870315999233";//appCode
        //1.设置认证信息
        AuthenticateRequest.RequestBean requestBean = new AuthenticateRequest.RequestBean();
        requestBean.setMAC(macStr);
        requestBean.setSupplier("JINMAOYUN");
        requestBean.setFirmwareVersion(versionString);
        requestBean.setHardwareModel("1956F");
//        HDLLinkConfig.getInstance().setRequestBean(requestBean);
        AuthenticateRequest.AuthBean authbean = new AuthenticateRequest.AuthBean();
        authbean.setSpk(spkStr);
        authbean.setMACKey(mac_key);
        authbean.setRequest(requestBean);
        HDLLinkConfig.getInstance().setAuthBean(authbean);
        //HDLLinkConfig.getInstance().getDeviceInfoBean()这个初始化的时候要先设置好
        AuthenticateRequest request = new AuthenticateRequest(IdUtils.getUUId(), time, HDLLinkConfig.getInstance().getDeviceInfoBean(), authbean);
        HDLLink.getInstance().startAuthenticateRequest(request, new HDLLinkCallBack() {
        HDLLink.getInstance().checkAppVersion(this, appKey, appSecret, getAppVersionName(this), appCode, new CheckAppVersionListener() {
            @Override
            public void onError(HDLLinkException e) {
                tv.setText("认证失败" + e.getCode());
                responseTv.setText(e.getMsg());
                Log.e(TAG, "onError: 认证失败 " + e.getCode());
            public void onSuccess(UpdateInfo info) {
                tv.setText("有新更新");
                responseTv.setText(info.toString());
            }
            @RequiresApi(api = Build.VERSION_CODES.O)
            @Override
            public void onSuccess(String msg) {
                tv.setText("认证成功");
                responseTv.setText(msg.toString());
                localSecret.setText("密钥:" + HDLLinkConfig.getInstance().getLocalSecret());
            public void onError(HDLException e) {
                tv.setText("检测更新失败");
                responseTv.setText(e.getMsg());
            }
        });
    }
    public void UploadDeviceAuth(String mac, String result, String message, String auth_code) {
@@ -241,6 +194,8 @@
            }
        });
        UploadSidList();
        ActivityResultLauncher<String[]> launcher = registerForActivityResult(new ActivityResultContracts.RequestMultiplePermissions(), new ActivityResultCallback<Map<String, Boolean>>() {
            @Override
            public void onActivityResult(Map<String, Boolean> result) {
@@ -255,27 +210,24 @@
        beans.add(new DemoBean("入网认证"));
        beans.add(new DemoBean("搜索指定网关是否在线"));
        beans.add(new DemoBean("上报oid列表"));
        beans.add(new DemoBean("获取功能列表"));
        beans.add(new DemoBean("功能属性读取"));
        beans.add(new DemoBean("获取设备列表"));
        beans.add(new DemoBean("设备功能属性读取"));
        beans.add(new DemoBean("设备控制"));
        beans.add(new DemoBean("读取状态"));
        beans.add(new DemoBean("获取场景列表"));
        beans.add(new DemoBean("场景详情"));
        beans.add(new DemoBean("场景控制"));
        beans.add(new DemoBean("设备功能列表"));
        beans.add(new DemoBean("UDP发送"));
        beans.add(new DemoBean("TCP发送"));
        beans.add(new DemoBean("UDP发送,监听主题回复,带重发带回调"));
        beans.add(new DemoBean("TCP发送,监听主题回复,带重发带回调"));
        beans.add(new DemoBean("退网"));
        beans.add(new DemoBean("Source功能支持"));
        beans.add(new DemoBean("获取房间列表"));
        beans.add(new DemoBean("获取房间设备列表"));
        beans.add(new DemoBean("获取房间场景列表"));
        beans.add(new DemoBean("获取自动化列表"));
        beans.add(new DemoBean("⾃动化启⽤禁⽤"));
        demoAdapter = new DemoAdapter(beans);
        rv.setAdapter(demoAdapter);
//        final SocketOptions options = new SocketOptions();
//
//        MessagePipeLine pipeLine = new MessagePipeLine();
//        options.setHandleMessage(pipeLine);
//        options.setEnabledHeartbeat(false);
        demoAdapter.setOnItemClickListener(new OnItemClickListener() {
            @Override
@@ -298,11 +250,12 @@
                        UploadOidList();
                        break;
                    case 4:
                        //获取功能列表
                        //获取设备列表
                        getFunctionList();
                        //startDevicesListActivity();
                        break;
                    case 5:
                        //功能属性读取
                        //设备功能属性读取
                        getFunctionAttribute();
                        break;
                    case 6:
@@ -318,32 +271,48 @@
                        getSceneList();
                        break;
                    case 9:
                        //场景详情
                        getSceneDetail();
                        break;
                    case 10:
                        //场景控制
                        controlScene();
                        break;
                    case 10:
                        //功能列表
                        startDevicesListActivity();
                        break;
                    case 11:
                        //UDP发送
                        udpSend();
                        break;
                    case 12:
                        //TCP发送
                        tcpSend();
                        break;
                    case 13:
                        //UDP发送,监听主题回复,带重发带回调
                        udpSendWithCallback();
                        break;
                    case 14:
                    case 12:
                        //TCP发送,监听主题回复,带重发带回调
                        tcpSendWithCallback();
                        break;
                    case 15:
                    case 13:
                        //退网
                        deleteNetwork();
                        break;
                    case 14:
                        //Source功能支持
                        startSourceTestActivity();
                        break;
                    case 15:
                        //获取房间列表
                        getRoomList();
                        break;
                    case 16:
                        //获取房间设备列表
                        getRoomDeviceList();
                        break;
                    case 17:
                        //获取房间场景列表
                        getRoomSceneList();
                        break;
                    case 18:
                        //获取自动化列表
                        getLogicList();
                        break;
                    case 19:
                        //⾃动化启⽤禁⽤
                        editEnableLogic();
                        break;
                }
            }
@@ -377,8 +346,10 @@
            @Override
            public void onMessage(Object msg) {
                LinkResponse response = (LinkResponse) msg;
                if ("/user/all/custom/gateway/broadcast_reply".equals(response.getTopic())){
                Log.i("onMessage", "response.getTopic():" + response.getTopic());
                if ("/user/all/custom/gateway/broadcast_reply".equals(response.getTopic())) {
                    localSecret.setText("密钥:" + HDLLinkConfig.getInstance().getLocalSecret());
                }
            }
        };
@@ -428,6 +399,74 @@
        HDLLink.getInstance().removeAllTopicsListener(allTopicsListener);
    }
    void initDeviceInfo() {
        AuthenticateRequest.AuthenticateDeviceInfoBean infoBean = new AuthenticateRequest.AuthenticateDeviceInfoBean();
        infoBean.setDeviceMAC("f2c5d8bad48f");
        infoBean.setIPMAC("f2c5d8bad48f");
        infoBean.setDeviceName("魔镜");//设备名字
        infoBean.setDeviceModel("HDLSDK");//设备型号
        infoBean.setAccessMode("WIFI");
        infoBean.setIPGateway("192.168.31.1");
        infoBean.setIPAddress("192.168.31.103");
        infoBean.setGateway_type("screen.touch");
        infoBean.setHw_version("HW2.0");
        infoBean.setFw_version("Fw1.0");
        infoBean.setOID("010105000000FE11");//每个设备oid都要不一样
        infoBean.setSid("110105000000FE08110100000011");//每个设备的sid都要不一样
        infoBean.setSupplier("JINMAOYUN");
        HDLLinkConfig.getInstance().setDeviceInfoBean(infoBean);
    }
    /**
     * 入网认证
     */
    void sendAuthenticateRequest() {
        tv.setText("开始入网认证...");
        //认证提交参数准备
//        测试服务
//        String spkStr = "ir.module";//产品spk
//        String macStr = "AA000000000000AF";//设备唯一MAC地址
//        String secret = "44b360eb74b7ba64";//通过spk和mac提交云端认证后分配的secret
//        正式服务器
        String spkStr = "screen.mirror";//产品spk
        String macStr = "f2c5d8bad48f";//设备唯一MAC地址
//        String secret = "e186beeb7974998e";//通过spk和mac提交云端认证后分配的secret
        String mac_key = stringToMD5(stringToMD5(macStr + secret));
        String versionString = "HDL_V1.0.1";//
        String time = String.valueOf(System.currentTimeMillis());
        HDLLinkConfig.getInstance().getDeviceInfoBean().setDeviceMAC(macStr);
        //1.设置认证信息
        AuthenticateRequest.RequestBean requestBean = new AuthenticateRequest.RequestBean();
        requestBean.setMAC(macStr);
        requestBean.setSupplier("JINMAOYUN");
        requestBean.setFirmwareVersion(versionString);
        requestBean.setHardwareModel("1956F");
        AuthenticateRequest.AuthBean authbean = new AuthenticateRequest.AuthBean();
        authbean.setSpk(spkStr);
        authbean.setMACKey(mac_key);
        authbean.setRequest(requestBean);
        //HDLLinkConfig.getInstance().getDeviceInfoBean()这个初始化的时候要先设置好
        AuthenticateRequest request = new AuthenticateRequest(IdUtils.getUUId(), time, HDLLinkConfig.getInstance().getDeviceInfoBean(), authbean);
        HDLLink.getInstance().startAuthenticateRequest(request, new HDLLinkCallBack() {
            @Override
            public void onError(HDLLinkException e) {
                tv.setText("认证失败");
                responseTv.setText(e.getMsg());
                Log.i("TAG", "onError: 认证失败");
            }
            @Override
            public void onSuccess(String msg) {
                tv.setText("认证成功");
                responseTv.setText(msg.toString());
            }
        });
    }
    String stringToMD5(String text) {
        byte[] hash;
@@ -443,8 +482,7 @@
        StringBuilder hex = new StringBuilder(hash.length * 2);
        for (byte b : hash) {
            if ((b & 0xFF) < 0x10)
                hex.append("0");
            if ((b & 0xFF) < 0x10) hex.append("0");
            hex.append(Integer.toHexString(b & 0xFF));
        }
@@ -458,6 +496,7 @@
    void searchGatewayBroadcast() {
        tv.setText("搜索网关中...");
        responseTv.setText("");
        HDLLinkConfig.getInstance().getGatewayId();
        HDLLink.getInstance().searchGatewayBroadcast(new HDLAuthSocket.SearchGatewayCallBack() {
            @Override
            public void onError(HDLLinkException e) {
@@ -475,10 +514,10 @@
    }
    /**
     * 获取功能列表
     * 获取设备列表
     */
    void getFunctionList() {
        tv.setText("获取功能列表中...");
        tv.setText("获取设备列表中...");
        responseTv.setText("");
        HDLLink.getInstance().getFunctionList(new HDLLinkCallBack() {
            @Override
@@ -488,18 +527,37 @@
            @Override
            public void onSuccess(String data) {
                tv.setText("获取功能列表成功");
                tv.setText("获取设备列表成功");
                responseTv.setText(data);
                handelFunctionList(data);
            }
        });
    }
    void handelFunctionList(String data) {
        try {
            final LinkResponse linkResponse = GsonConvert.getGson().fromJson(data, new TypeToken<LinkResponse>() {
            }.getType());
            final BaseLocalResponse<List<FunctionBean>> bean = GsonConvert.getGson().fromJson(linkResponse.getData(), new TypeToken<BaseLocalResponse<List<FunctionBean>>>() {
            }.getType());
            devicesList.clear();
            devicesList.addAll(bean.getObjects());
            Log.d(TAG, "handelFunList-----> " + devicesList.toString());
        } catch (Exception e) {
            Log.e(TAG, "handelFunList: " + e.getMessage());
        }
    }
    /**
     * 功能属性读取
     * 设备功能属性读取
     * 支持批量读取
     */
    void getFunctionAttribute() {
        tv.setText("功能属性读取");
        tv.setText("设备功能属性读取");
        responseTv.setText("");
        List<String> sids = new ArrayList<>();
        sids.add(testLightSid);
@@ -558,6 +616,7 @@
        statusBeanList.add(bean);
        request.setStatus(statusBeanList);
        requestList.add(request);
        HDLLink.getInstance().propertyDown(requestList, new HDLLinkCallBack() {
            @Override
            public void onSuccess(String data) {
@@ -581,6 +640,8 @@
            @Override
            public void onSuccess(String msg) {
                responseTv.setText(msg);
                handelSceneList(msg);
            }
            @Override
@@ -590,8 +651,73 @@
        });
    }
    void handelSceneList(String data) {
        try {
            final LinkResponse linkResponse = GsonConvert.getGson().fromJson(data, new TypeToken<LinkResponse>() {
            }.getType());
            final BaseLocalResponse<List<SceneBean>> bean = GsonConvert.getGson().fromJson(linkResponse.getData(), new TypeToken<BaseLocalResponse<List<SceneBean>>>() {
            }.getType());
            sceneList.clear();
            sceneList.addAll(bean.getObjects());
            Log.d(TAG, "handelSceneList-----> " + sceneList.toString());
        } catch (Exception e) {
            Log.e(TAG, "handelSceneList: " + e.getMessage());
        }
    }
    //场景列表
    // {"id":"8a5eaa143ce943b987b577df5a66759b","time_stamp":"1637040217235","objects":[{"sid":"04010560D2C7170A0A0100000000","name":"回家模式","status":"off","group":"255","delay":"0","modify_time":"1634871490"},{"sid":"04010560D2C76E0A0A0100010000","name":"离家模式","status":"off","group":"255","delay":"0","modify_time":"1634785823"}]}
//    {"id":"98a683eca5384f2db2ca1ed688953439","time_stamp":"1740024067320","code":"0","msg":"Success","objects":[{"sid":"0201039965BF5D0A0A0100011100","name":"场景-1","status":"off","group":"255","delay":"0","modify_time":"1735293636","local":"false"},{"sid":"030105016B84AA0A0A0100020000","name":"大厅灯开","status":"off","group":"255","delay":"0","modify_time":"1740023916","local":"false"},{"sid":"030105016D14240A0A0100030000","name":"大厅灯关","status":"off","group":"255","delay":"0","modify_time":"1740023969","local":"false"},{"sid":"020103D465BF5D0A0A0100041100","name":"场景-4","status":"off","group":"255","delay":"0","modify_time":"1735200096","local":"false"}]}
    /**
     * 获取场景详情
     * 执行成功的话 响应code为200
     */
    void getSceneDetail() {
        tv.setText("场景读取");
        responseTv.setText("");
        //场景sid列表,支持批量读取
        if (sceneList != null && sceneList.size() != 0) {
            List<String> sids = new ArrayList<>();
            for (SceneBean s : sceneList) {
                sids.add(s.getSid());//遍历所有场景拿到详情信息
            }
            HDLLink.getInstance().getScene(sids, new HDLLinkCallBack() {
                @Override
                public void onSuccess(String msg) {
                    responseTv.setText(msg);
                    handelSceneDetailList(msg);
                }
                @Override
                public void onError(HDLLinkException e) {
                    responseTv.setText(e.getMsg());
                }
            });
        } else {
            Toast.makeText(MainActivity.this, "请先获取场景列表", Toast.LENGTH_SHORT).show();
        }
    }
    void handelSceneDetailList(String data) {
        try {
            final LinkResponse linkResponse = GsonConvert.getGson().fromJson(data, new TypeToken<LinkResponse>() {
            }.getType());
            final BaseLocalResponse<List<SceneDetailBean>> bean = GsonConvert.getGson().fromJson(linkResponse.getData(), new TypeToken<BaseLocalResponse<List<SceneDetailBean>>>() {
            }.getType());
            sceneDetailList.clear();
            sceneDetailList.addAll(bean.getObjects());
            Log.d(TAG, "handelSceneDetailList-----> " + sceneDetailList.toString());
        } catch (Exception e) {
            Log.e(TAG, "handelSceneDetailList: " + e.getMessage());
        }
    }
    /**
     * 控制场景
@@ -604,9 +730,9 @@
        List<String> sids = new ArrayList<>();
        isOn = !isOn;
        if (isOn) {
            sids.add("04010560D2C7170A0A0100000000");
            sids.add("030105016D14240A0A0100030000");
        } else {
            sids.add("04010560D2C76E0A0A0100010000");
            sids.add("030105016B84AA0A0A0100020000");
        }
        HDLLink.getInstance().controlScene(sids, new HDLLinkCallBack() {
            @Override
@@ -621,9 +747,161 @@
        });
    }
    /**
     * 获取房间列表
     */
    void getRoomList() {
        tv.setText("读取房间列表");
        responseTv.setText("");
        HDLLink.getInstance().getRoomList(new HDLLinkCallBack() {
            @Override
            public void onSuccess(String msg) {
                responseTv.setText(msg);
            }
            @Override
            public void onError(HDLLinkException e) {
                responseTv.setText(e.getMsg());
            }
        });
    }
    /**
     * 获取房间设备列表
     * 先获取房间绑定关系列表,通过sid和设备列表匹配筛选
     */
    void getRoomDeviceList() {
        tv.setText("获取房间设备列表");
        responseTv.setText("");
        //房间uid列表,支持批量读取
        List<String> uid = new ArrayList<>();
        uid.add("64a4fc6f-4eae-4d1d-82e4-40140c802c48");
        HDLLink.getInstance().getRoomBindList(uid, new HDLLinkCallBack() {
            @Override
            public void onSuccess(String msg) {
                if (!TextUtils.isEmpty(msg)) {
                    handelRoomFunctionList(msg);
                }
            }
            @Override
            public void onError(HDLLinkException e) {
                responseTv.setText(e.getMsg());
            }
        });
    }
    void handelRoomFunctionList(String data) {
        try {
            final LinkResponse linkResponse = GsonConvert.getGson().fromJson(data, new TypeToken<LinkResponse>() {
            }.getType());
            final BaseLocalResponse<List<RoomFunctionBean>> bean = GsonConvert.getGson().fromJson(linkResponse.getData(), new TypeToken<BaseLocalResponse<List<RoomFunctionBean>>>() {
            }.getType());
            List<RoomFunctionBean> roomFunctionBeans = bean.getObjects();
            List<RoomFunctionBean.Functions> functions = roomFunctionBeans.get(0).getFunctions();
            roomDevicesList.clear();
            if (devicesList != null && devicesList.size() != 0) {
                for (int i = 0; i < functions.size(); i++) {
                    for (int j = 0; j < devicesList.size(); j++) {
                        //与设备列表的数据匹配,sid对应
                        if (functions.get(i).getSid().equals(devicesList.get(j).getSid())) {
                            roomDevicesList.add(devicesList.get(j));
                        }
                    }
                }
                responseTv.setText(roomDevicesList.toString());
                Log.d(TAG, "handelRoomFunctionList-----> " + roomDevicesList.toString());
            } else {
                Toast.makeText(MainActivity.this, "请先获取设备列表", Toast.LENGTH_SHORT).show();
            }
        } catch (Exception e) {
            Log.e(TAG, "handelRoomFunctionList: " + e.getMessage());
        }
    }
    /**
     * 获取自动化列表
     */
    void getLogicList() {
        tv.setText("读取自动化列表");
        responseTv.setText("");
        HDLLink.getInstance().getLogicList(new HDLLinkCallBack() {
            @Override
            public void onSuccess(String msg) {
                responseTv.setText(msg);
            }
            @Override
            public void onError(HDLLinkException e) {
                responseTv.setText(e.getMsg());
            }
        });
    }
    /**
     * ⾃动化启⽤禁⽤
     */
    void editEnableLogic() {
        tv.setText("⾃动化启⽤禁⽤");
        responseTv.setText("");
        String sid = "0301050041800C161501000A0000";//自动化sid
        boolean enable = true;//true=启⽤ false=禁⽤
        HDLLink.getInstance().editEnableLogic(sid, enable, new HDLLinkCallBack() {
            @Override
            public void onSuccess(String msg) {
                responseTv.setText(msg);
            }
            @Override
            public void onError(HDLLinkException e) {
                responseTv.setText(e.getMsg());
            }
        });
    }
    /**
     * 获取房间场景列表(需要先拿到场景详情)
     */
    void getRoomSceneList() {
        tv.setText("获取房间场景列表");
        responseTv.setText("");
        String uid = "64a4fc6f-4eae-4d1d-82e4-40140c802c48";
        roomSceneList.clear();
        if (sceneDetailList != null && sceneDetailList.size() != 0) {
            for (SceneDetailBean s : sceneDetailList) {
                List<String> roomUids = s.getUids();
                if (roomUids != null && roomUids.size() != 0) {
                    for (int i = 0; i < roomUids.size(); i++) {
                        if (uid.equals(roomUids.get(i))) {
                            roomSceneList.add(s);
                        }
                    }
                }
            }
            responseTv.setText(roomSceneList.toString());
            Log.d(TAG, "getRoomSceneList-----> " + roomSceneList.toString());
        } else {
            Toast.makeText(MainActivity.this, "请先获取场景列表详情", Toast.LENGTH_SHORT).show();
        }
    }
    void startDevicesListActivity() {
        Intent intent = new Intent(this, DevicesListActivity.class);
        startActivity(intent);
    }
    void startSourceTestActivity() {
        Intent intent = new Intent(this, SourceTestActivity.class);
        startActivity(intent);
    }
@@ -764,4 +1042,73 @@
            }
        });
    }
    private void UploadSidList() {
        tv.setText("上报Sid列表...");
        responseTv.setText("");
        //1.设置设备信息
        AuthenticateRequest.AuthenticateDeviceInfoBean authenticateDeviceInfoBean = HDLLinkConfig.getInstance().getDeviceInfoBean();
        ListSidRequest request = new ListSidRequest();
        request.setOid(authenticateDeviceInfoBean.getOID());
        request.setName("sid名称");
        request.setOmodel(authenticateDeviceInfoBean.getDeviceModel());
        request.setSid("12345678");//当前sid的
        request.setSpk("light.switch");//当前spk名称,根据实际设备来定义
        request.setFrom(authenticateDeviceInfoBean.getOID());//来自哪个网关,如果时Link网络设备,则填自身oid;如果是驱动则不需要此字段
        AttributesRequest attributes = new AttributesRequest();
        attributes.setKey("on_off");
        attributes.setData_type("string");
        List<Object> valueList = new ArrayList<>();
        valueList.add("on");
        valueList.add("off");
        attributes.setValue(valueList);
        //添加支持的属性列表
        List<AttributesRequest> attributesList = new ArrayList<>();
        request.setAttributes(attributesList);
        List<ListSidRequest> sidRequestList = new ArrayList<>();
        sidRequestList.add(request);
        HDLLink.getInstance().UploadSidList(sidRequestList, new HDLLinkCallBack() {
            @Override
            public void onError(HDLLinkException error) {
                tv.setText(error.getMsg());
            }
            @Override
            public void onSuccess(String data) {
                tv.setText("上报sid列表成功");
                responseTv.setText(data);
            }
        });
    }
    /**
     * 获取APP版本
     *
     * @param context
     * @return
     */
    public static String getAppVersionName(Context context) {
        String versionName = "0";
        try {
            PackageManager packageManager = context.getPackageManager();
            PackageInfo packageInfo = packageManager.getPackageInfo(context.getPackageName(), 0);
            versionName = packageInfo.versionName;
            if (TextUtils.isEmpty(versionName)) {
                versionName = "0";
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return versionName;
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        removeAllTopicsListener();
    }
}
HDLSDK_DEMO/app/src/main/java/com/hdl/hdlsdk/SourceTestActivity.java
New file
@@ -0,0 +1,556 @@
package com.hdl.hdlsdk;
import android.Manifest;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.storage.StorageManager;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Surface;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.app.NotificationCompat;
import com.hdl.sdk.sourceos.knob.OsEventListener;
import com.hdl.sdk.sourceos.OsManager;
import com.hdl.sdk.sourceos.knob.IQuickKnobListenerAdapter;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
public class SourceTestActivity extends AppCompatActivity implements View.OnClickListener {
    private Button btnApiVersion, btnDeviceModel, btnOsVersion, btnRunningMemory, btnInnerStorage, btnFreeStorage, btnKernelVersion, btnBuilderNumber, btnFwVersion, btnShutDown, btnReboot, btnSystemConfiginfo, btnBrightness, btnRotation, notifyOpen, notifyClose, btnOpenBackLight, btnCloseBackLight, btnStatusBarShow, btnStatusBarHide, btnMicEnable, btnEthMacAddress, btnEthIpAddress, btnScardPath, btnInner, btnInstall, btnEthernetConnect, btnSubmitStaticIp, btnSleep, btnWakeUp, btnFilterPermission, btnOta, btnNetmask, btnGateway, btnDns, btnDisconnectEth, btnConnectEth, btnWwitchDhcp;
    private TextView tvContent;
    private EditText editIpAddress, editGateway, editNetmask, editDns1, editDns2, editBrightness, editRotation;
    final private int LED_NOTIFICATION_ID = 100;
    private NotificationManager notificationManager;
    private String notificationId = "leds";
    private String notificationName = "ledsTest";
    private Timer mTimer;
    private static String TAG = "SourceTestActivity";
    private IQuickKnobListenerAdapter knobListenerAdapter;
    private final int PERMISSION_REQUEST = 0xa00;
    private OsEventListener eventListener = new OsEventListener() {
        @Override
        public void onKeyEvent(int keyCode, int state) {
            try {
                if (KeyEvent.KEYCODE_MUTE == keyCode) {
                    //麦克风状态变化
                    boolean micState = OsManager.getMicEnable();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    };
    @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_source_test);
        initView();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.REBOOT, Manifest.permission.READ_PHONE_STATE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST);
        }
        //系统接口初始化
        OsManager.init(SourceTestActivity.this);
        OsManager.addEventListener(eventListener);
        OsManager.startTof(1);
        startTimerTask();
        //旋钮初始化
        initKnob();
    }
    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
            case PERMISSION_REQUEST:
                if (grantResults != null && permissions != null) {
                    for (int i = 0; i < grantResults.length; i++) {
                        Log.d(TAG, "grantResults[" + i + "]:" + grantResults[i]);
                        Log.d(TAG, "permissions[" + i + "]:" + permissions[i]);
                    }
                }
                break;
        }
    }
    // 开启任务
    private void startTimerTask() {
        mTimer = new Timer();
        mTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                int data = OsManager.readTofData();
                Log.d(TAG, "Tof data:" + data);
            }
        }, 500, 3000);
    }
    // 取消任务
    private void cancelTask() {
        if (mTimer != null) {
            mTimer.cancel();
        }
    }
    private void initView() {
        tvContent = findViewById(R.id.tv_content);
        btnApiVersion = findViewById(R.id.btn_api_version);
        btnDeviceModel = findViewById(R.id.btn_device_model);
        btnOsVersion = findViewById(R.id.btn_os_version);
        btnRunningMemory = findViewById(R.id.btn_running_memory);
        btnInnerStorage = findViewById(R.id.btn_inner_storage);
        btnFreeStorage = findViewById(R.id.btn_free_storage);
        btnKernelVersion = findViewById(R.id.btn_kernel_version);
        btnBuilderNumber = findViewById(R.id.btn_builder_number);
        btnFwVersion = findViewById(R.id.btn_fwversion);
        btnShutDown = findViewById(R.id.btn_shut_down);
        btnReboot = findViewById(R.id.btn_reboot);
        btnSystemConfiginfo = findViewById(R.id.btn_system_configinfo);
        btnBrightness = findViewById(R.id.btn_brightness);
        btnRotation = findViewById(R.id.btn_rotation);
        notifyOpen = findViewById(R.id.btn_notifyLight_open);
        notifyClose = findViewById(R.id.btn_notifyLight_close);
        btnOpenBackLight = findViewById(R.id.btn_open_back_light);
        btnCloseBackLight = findViewById(R.id.btn_close_back_light);
        btnStatusBarShow = findViewById(R.id.btn_statusBar_show);
        btnStatusBarHide = findViewById(R.id.btn_statusBar_hide);
        btnMicEnable = findViewById(R.id.btn_mic_enable);
        btnEthMacAddress = findViewById(R.id.btn_eth_mac_address);
        btnEthIpAddress = findViewById(R.id.btn_eth_ip_address);
        btnScardPath = findViewById(R.id.btn_sdcard);
        btnInner = findViewById(R.id.btn_inner);
        btnInstall = findViewById(R.id.btn_install);
        btnEthernetConnect = findViewById(R.id.btn_ethernet_connect);
        editRotation = findViewById(R.id.edit_rotation);
        editIpAddress = findViewById(R.id.edit_ip_address);
        editGateway = findViewById(R.id.edit_gateway);//网关
        editNetmask = findViewById(R.id.edit_netmask);//掩码
        editDns1 = findViewById(R.id.edit_dns1);
        editDns2 = findViewById(R.id.edit_dns2);
        btnSubmitStaticIp = findViewById(R.id.btn_submit_static_ip);
        btnSleep = findViewById(R.id.btn_sleep);
        editBrightness = findViewById(R.id.edit_brightness);
        btnWakeUp = findViewById(R.id.btn_wake_up);
        btnFilterPermission = findViewById(R.id.btn_filter_permission);
        btnOta = findViewById(R.id.btn_ota);
        btnNetmask = findViewById(R.id.btn_netmask);
        btnGateway = findViewById(R.id.btn_gateway);
        btnDns = findViewById(R.id.btn_dns);
        btnDisconnectEth = findViewById(R.id.btn_disconnect_eth);
        btnConnectEth = findViewById(R.id.btn_connect_eth);
        btnWwitchDhcp = findViewById(R.id.btn_switch_dhcp);
        btnApiVersion.setOnClickListener(this);
        btnDeviceModel.setOnClickListener(this);
        btnOsVersion.setOnClickListener(this);
        btnRunningMemory.setOnClickListener(this);
        btnInnerStorage.setOnClickListener(this);
        btnFreeStorage.setOnClickListener(this);
        btnKernelVersion.setOnClickListener(this);
        btnBuilderNumber.setOnClickListener(this);
        btnFwVersion.setOnClickListener(this);
        btnShutDown.setOnClickListener(this);
        btnReboot.setOnClickListener(this);
        btnSystemConfiginfo.setOnClickListener(this);
        btnBrightness.setOnClickListener(this);
        btnRotation.setOnClickListener(this);
        notifyOpen.setOnClickListener(this);
        notifyClose.setOnClickListener(this);
        btnOpenBackLight.setOnClickListener(this);
        btnCloseBackLight.setOnClickListener(this);
        btnStatusBarShow.setOnClickListener(this);
        btnStatusBarHide.setOnClickListener(this);
        btnMicEnable.setOnClickListener(this);
        btnEthMacAddress.setOnClickListener(this);
        btnEthIpAddress.setOnClickListener(this);
        btnScardPath.setOnClickListener(this);
        btnInner.setOnClickListener(this);
        btnInstall.setOnClickListener(this);
        btnEthernetConnect.setOnClickListener(this);
        btnSubmitStaticIp.setOnClickListener(this);
        btnSleep.setOnClickListener(this);
        btnWakeUp.setOnClickListener(this);
        btnFilterPermission.setOnClickListener(this);
        btnOta.setOnClickListener(this);
        btnNetmask.setOnClickListener(this);
        btnGateway.setOnClickListener(this);
        btnDns.setOnClickListener(this);
        btnDisconnectEth.setOnClickListener(this);
        btnConnectEth.setOnClickListener(this);
        btnWwitchDhcp.setOnClickListener(this);
    }
    private void initKnob() {
        knobListenerAdapter = new IQuickKnobListenerAdapter() {
            @Override
            public void onKnobLeftListener() {
                super.onKnobLeftListener();
                //滑动到上一个
                //scrollPre();
                tvContent.setText("旋钮滑动到上一个");
            }
            @Override
            public void onKnobRightListener() {
                super.onKnobRightListener();
                //滑动到下一个
                //scrollNext();
                tvContent.setText("旋钮滑动到下一个");
            }
        };
        OsManager.addEventListener(knobListenerAdapter);
    }
    // 判断存储卡的路径是否可用
    public static boolean getStorageState(Context context, String path) {
        try {
            StorageManager sm = (StorageManager) context.getSystemService(context.STORAGE_SERVICE);
            Method getVolumeStateMethod = StorageManager.class.getMethod("getVolumeState", new Class[]{String.class});
            String state = (String) getVolumeStateMethod.invoke(sm, path);
            if (state.equals(Environment.MEDIA_MOUNTED_READ_ONLY) || state.equals(Environment.MEDIA_MOUNTED)) {
                return true;
            }
            return false;
        } catch (Exception e) {
            Log.e(TAG, "getStorageState() failed", e);
            return false;
        }
    }
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_api_version:
                String apiVersion = OsManager.getAPIVersion();
                Log.e(TAG, "apiVersion :" + apiVersion);
                tvContent.setText(apiVersion);
                Toast.makeText(this, "aip版本 :" + apiVersion, Toast.LENGTH_SHORT).show();
                break;
            case R.id.btn_device_model:
                String deviceModel = OsManager.getDeviceModel();
                Log.e(TAG, "deviceModel :" + deviceModel);
                tvContent.setText(deviceModel);
                Toast.makeText(this, "设备model :" + deviceModel, Toast.LENGTH_SHORT).show();
                break;
            case R.id.btn_os_version:
                String androidOSVersion = OsManager.getAndroidOSVersion();
                Log.e(TAG, "androidOSVersion :" + androidOSVersion);
                tvContent.setText(androidOSVersion);
                Toast.makeText(this, "系统版本 :" + androidOSVersion, Toast.LENGTH_SHORT).show();
                break;
            case R.id.btn_running_memory:
                String runningMemory = OsManager.getRunningMemory();
                Log.e(TAG, "runningMemory :" + runningMemory);
                tvContent.setText(runningMemory);
                Toast.makeText(this, "运行内存 :" + runningMemory, Toast.LENGTH_SHORT).show();
                break;
            case R.id.btn_inner_storage:
                String internalStorageMemory = OsManager.getInternalStorageMemory();
                Log.e(TAG, "internalStorageMemory :" + internalStorageMemory);
                tvContent.setText(internalStorageMemory);
                Toast.makeText(this, "内部存储路径 :" + internalStorageMemory, Toast.LENGTH_SHORT).show();
                break;
            case R.id.btn_free_storage:
                String internalFreeStorageMemory = OsManager.getInternalFreeStorageMemory();
                Log.e(TAG, "internalFreeStorageMemory :" + internalFreeStorageMemory);
                tvContent.setText(internalFreeStorageMemory);
                Toast.makeText(this, "内部存储可用容量 :" + internalFreeStorageMemory, Toast.LENGTH_SHORT).show();
                break;
            case R.id.btn_kernel_version:
                String kernelVersion = OsManager.getKernelVersion();
                Log.e(TAG, "kernelVersion :" + kernelVersion);
                tvContent.setText(kernelVersion);
                Toast.makeText(this, "kernel版本信息 :" + kernelVersion, Toast.LENGTH_SHORT).show();
                break;
            case R.id.btn_builder_number:
                String builderNumberDisplay = OsManager.getBuilderNumberDisplay();
                Log.e(TAG, "builderNumberDisplay :" + builderNumberDisplay);
                tvContent.setText(builderNumberDisplay);
                Toast.makeText(this, "DisplayId :" + builderNumberDisplay, Toast.LENGTH_SHORT).show();
                break;
            case R.id.btn_fwversion:
                String fwVersion = OsManager.getFwVersion();
                Log.e(TAG, "fwVersion :" + fwVersion);
                tvContent.setText(fwVersion);
                Toast.makeText(this, "fwVersion :" + fwVersion, Toast.LENGTH_SHORT).show();
                break;
            case R.id.btn_shut_down:
                OsManager.shutdown();
                break;
            case R.id.btn_reboot:
                OsManager.reboot();
                break;
            case R.id.btn_system_configinfo:
                String jsondata = OsManager.readSystemConfigInfo();
                tvContent.setText(jsondata);
                break;
            case R.id.btn_brightness:
                String trim = editBrightness.getText().toString().trim();
                if (!TextUtils.isEmpty(trim)) {
                    OsManager.setBrightness(Integer.parseInt(trim));
                } else {
                    Toast.makeText(SourceTestActivity.this, "请输入亮度值", Toast.LENGTH_LONG).show();
                }
                break;
            case R.id.btn_rotation:
                String rotation = editRotation.getText().toString().trim();
                if (!TextUtils.isEmpty(rotation)) {
                    OsManager.setRotation(rotation);
                } else {
                    Toast.makeText(SourceTestActivity.this, "请输入旋转方向", Toast.LENGTH_LONG).show();
                }
                int value = Surface.ROTATION_0;
                if (rotation.equals("90")) {
                    value = Surface.ROTATION_90;
                } else if (rotation.equals("180")) {
                    value = Surface.ROTATION_180;
                } else if (rotation.equals("270")) {
                    value = Surface.ROTATION_270;
                }
                //Settings.System.putInt(getContentResolver(), Settings.System.USER_ROTATION, value);
                Toast.makeText(SourceTestActivity.this, "旋转:" + rotation, Toast.LENGTH_LONG).show();
                break;
            case R.id.btn_notifyLight_open:
//                setNotificationAndForeground();
                NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
                if (notificationManager.isNotificationPolicyAccessGranted()) {
                    Toast.makeText(SourceTestActivity.this, "通知OK:", Toast.LENGTH_LONG).show();
                }
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    NotificationChannel channel = new NotificationChannel(notificationId, notificationName, NotificationManager.IMPORTANCE_DEFAULT);
                    channel.enableLights(true);
                    channel.setLightColor(0x00ff1288);
                    notificationManager.createNotificationChannel(channel);
                }
                Notification.Builder builder = new Notification.Builder(this).setLights(0x00ff1288, 50, 50).setDefaults(NotificationCompat.DEFAULT_LIGHTS).setSound(Uri.EMPTY).setSmallIcon(R.drawable.ic_launcher_foreground).setColor(Color.RED).setAutoCancel(true).setWhen(System.currentTimeMillis()).setContentTitle("呼吸灯通知").setContentText("已成功开启");
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    builder.setChannelId(notificationId);
                }
                notificationManager.notify(LED_NOTIFICATION_ID, builder.build()); //发送通知
                break;
            case R.id.btn_notifyLight_close:
                NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
                manager.cancel(LED_NOTIFICATION_ID);             //关闭通知灯
                break;
            case R.id.btn_open_back_light:
                OsManager.setLcdBlackLight(true);
                break;
            case R.id.btn_close_back_light:
                OsManager.setLcdBlackLight(false);
                break;
            case R.id.btn_statusBar_show:
                Intent intent = new Intent();
                intent.setAction("com.android.navigation.status");
                intent.putExtra("hide", false);//auto true 为显示 ,false 为 隐藏
                sendBroadcast(intent);
                break;
            case R.id.btn_statusBar_hide:
                Intent intent1 = new Intent();
                intent1.setAction("com.android.navigation.status");
                intent1.putExtra("hide", true);//auto true 为显示 ,false 为 隐藏
                sendBroadcast(intent1);
                break;
            case R.id.btn_mic_enable:
                boolean micEnable = OsManager.getMicEnable();
                Log.e(TAG, "micEnable :" + micEnable);
                Toast.makeText(this, "麦克风状态 :" + micEnable, Toast.LENGTH_SHORT).show();
                break;
            case R.id.btn_eth_mac_address:
                String ethMacAddress = OsManager.getEthMacAddress();
                Log.e(TAG, "ethMacAddress :" + ethMacAddress);
                tvContent.setText(ethMacAddress);
                Toast.makeText(this, "Mac 地址 :" + ethMacAddress, Toast.LENGTH_SHORT).show();
                break;
            case R.id.btn_eth_ip_address:
                String ethIPAddress = OsManager.getEthIpAddress();
                Log.e(TAG, "ethIPAddress :" + ethIPAddress);
                tvContent.setText(ethIPAddress);
                Toast.makeText(this, "以太网ip地址 :" + ethIPAddress, Toast.LENGTH_SHORT).show();
                break;
            case R.id.btn_sdcard:
//                String sdcardPath = OsManager.getSdcardPath();
//                Log.e(TAG, "sdcardPath :" + sdcardPath);
//                tvContent.setText(sdcardPath);
//                Toast.makeText(this, "sdcard路径 :" + sdcardPath, Toast.LENGTH_SHORT).show();
                try {
                    List<String> sdPaths = new ArrayList<>();
                    StorageManager sm = (StorageManager) this.getSystemService(this.STORAGE_SERVICE);
                    Method getVolumePathsMethod = StorageManager.class.getMethod("getVolumePaths");
                    String[] paths = (String[]) getVolumePathsMethod.invoke(sm);//获取所有sd卡路径
                    if (paths.length >= 1) {
                        for (int i = 1; i < paths.length; i++) {
                            if (getStorageState(this, paths[i])) {
                                sdPaths.add(paths[i]);
                            }
                        }
                    }
                    Toast.makeText(this, "sdcard路径 :" + sdPaths, Toast.LENGTH_SHORT).show();
//                    return sdPaths;
                } catch (Exception e) {
                    Log.e(TAG, "getSecondaryStoragePath() failed", e);
                }
                break;
            case R.id.btn_inner: {
//                String primaryStoragePath = OsManager.getPrimaryStoragePath();
//                Log.e(TAG, "primaryStoragePath :" + primaryStoragePath);
//                tvContent.setText(primaryStoragePath);
//                Toast.makeText(this, "内部存储路径 :" + primaryStoragePath, Toast.LENGTH_SHORT).show();
                try {
                    StorageManager sm = (StorageManager) this.getSystemService(this.STORAGE_SERVICE);
                    Method getVolumePathsMethod = StorageManager.class.getMethod("getVolumePaths");
                    String[] paths = (String[]) getVolumePathsMethod.invoke(sm);
                    // first element in paths[] is primary storage path
//                    return paths[0];
                    Toast.makeText(this, "内部存储路径 :" + paths[0], Toast.LENGTH_SHORT).show();
                } catch (Exception e) {
                    Log.e(TAG, "getPrimaryStoragePath() failed", e);
                }
                break;
            }
            case R.id.btn_install:
                Intent intent3 = new Intent();
                intent3.setAction("com.hdl.os.SilentInstall");
                intent3.putExtra("com.hdl.os.SilentInstall.path", "/storage/emulated/0/FactoryTools.apk");
                intent3.putExtra("com.hdl.os.SilentInstall.packageName", "com.hdl.factory");
                intent3.putExtra("com.hdl.os.SilentInstall.activityName", "MainMobile");
                sendBroadcast(intent3);
                break;
            case R.id.btn_ethernet_connect:
                int ethernetLinkStatus = OsManager.getEthernetLinkStatus();
                Log.e(TAG, "ethernetLinkStatus :" + ethernetLinkStatus);
                Toast.makeText(this, "以太网连接状态 :" + ethernetLinkStatus, Toast.LENGTH_SHORT).show();
                break;
            case R.id.btn_submit_static_ip:
                //设置静态ip
                String ipAddress = editIpAddress.getText().toString().trim();
                String gateway = editGateway.getText().toString().trim();
                String netmask = editNetmask.getText().toString().trim();
                String dns1 = editDns1.getText().toString().trim();
                String dns2 = editDns2.getText().toString().trim();
                EthernetUtils ethernetUtils = new EthernetUtils();
                boolean b = ethernetUtils.checkIPValue(ipAddress, gateway, netmask, dns1, dns2);
                if (b) {
                    OsManager.setStaticIp(ipAddress, netmask, gateway, dns1, dns2);
                }
                break;
            case R.id.btn_sleep:
                OsManager.goToSleep("screen");
                break;
            case R.id.btn_wake_up:
                OsManager.wakeUp("screen");
                break;
            case R.id.btn_filter_permission:
                Log.d(TAG, "setFilterPermissionPackageName");
                OsManager.setFilterPermissionPackageName("com.kugou.android");
                OsManager.setFilterPermissionPackageName("com.tencent.qqmusic");
                //Settings.System.putInt(getContentResolver(), Settings.System.SCREEN_BRIGHTNESS, 0);
                break;
            case R.id.btn_ota:
                Intent intent2 = new Intent();
                intent2.setAction("com.hdl.os.OTA");
                intent2.putExtra("com.hdl.os.OTA.path", "/storage/emulated/0/rk3566-ota-115442.zip");
                sendBroadcast(intent2);
                break;
            case R.id.btn_netmask:  //子网掩码
                String netmask1 = OsManager.getEthNetmask();
                Toast.makeText(this, "子网掩码:" + netmask1, Toast.LENGTH_LONG).show();
                break;
            case R.id.btn_gateway: //网关
                String gateway1 = OsManager.getEthGateway();
                Toast.makeText(this, "网关:" + gateway1, Toast.LENGTH_LONG).show();
                break;
            case R.id.btn_dns://dns
                String ethDns1 = OsManager.getEthDns1();
                String ethDns2 = OsManager.getEthDns1();
                Toast.makeText(this, "ethDns1:" + ethDns1 + " ethDns2: " + ethDns2, Toast.LENGTH_LONG).show();
                break;
            case R.id.btn_disconnect_eth: //断开以太网
                OsManager.disconnectEthernet("eth0");
                break;
            case R.id.btn_connect_eth: //连接以太网
                OsManager.connectEthernet("eth0");
                break;
            case R.id.btn_switch_dhcp: //切换动态ip
                OsManager.switchDHCP();
                break;
        }
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        cancelTask();
        OsManager.stopTof();
        if (eventListener != null) {
            OsManager.removeEventListener(eventListener);
        }
    }
}
HDLSDK_DEMO/app/src/main/java/com/hdl/hdlsdk/bean/FunctionBean.java
File was renamed from HDLSDK_DEMO/app/src/main/java/com/hdl/hdlsdk/device/FunctionBean.java
@@ -1,6 +1,4 @@
package com.hdl.hdlsdk.device;
import com.chad.library.adapter.base.entity.MultiItemEntity;
package com.hdl.hdlsdk.bean;
import java.io.Serializable;
import java.util.List;
@@ -103,4 +101,17 @@
        }
    }
    @Override
    public String toString() {
        return "FunctionBean{" +
                "sid='" + sid + '\'' +
                ", oid='" + oid + '\'' +
                ", name='" + name + '\'' +
                ", spk='" + spk + '\'' +
                ", omodel='" + omodel + '\'' +
                ", src='" + src + '\'' +
                ", online='" + online + '\'' +
                ", status=" + status +
                '}';
    }
}
HDLSDK_DEMO/app/src/main/java/com/hdl/hdlsdk/bean/RoomFunctionBean.java
New file
@@ -0,0 +1,41 @@
package com.hdl.hdlsdk.bean;
import java.io.Serializable;
import java.util.List;
/**
 * Created by jlchen on 12/7/21.
 */
public class RoomFunctionBean implements Serializable {
    private String uid;
    private List<Functions> functions;
    public String getUid() {
        return uid;
    }
    public void setUid(String uid) {
        this.uid = uid;
    }
    public List<Functions> getFunctions() {
        return functions;
    }
    public void setFunctions(List<Functions> functions) {
        this.functions = functions;
    }
    public class Functions implements Serializable {
        private String sid;
        public String getSid() {
            return sid;
        }
        public void setSid(String sid) {
            this.sid = sid;
        }
    }
}
HDLSDK_DEMO/app/src/main/java/com/hdl/hdlsdk/bean/SceneBean.java
New file
@@ -0,0 +1,45 @@
package com.hdl.hdlsdk.bean;
import java.io.Serializable;
/**
 * Created by panlili on 25/2/21.
 */
public class SceneBean implements Serializable {
    private String sid;
    private String status;
    private String name;
    public String getSid() {
        return sid;
    }
    public void setSid(String sid) {
        this.sid = sid;
    }
    public String getStatus() {
        return status;
    }
    public void setStatus(String status) {
        this.status = status;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "SceneBean{" +
                "sid='" + sid + '\'' +
                ", status='" + status + '\'' +
                ", name='" + name + '\'' +
                '}';
    }
}
HDLSDK_DEMO/app/src/main/java/com/hdl/hdlsdk/bean/SceneDetailBean.java
New file
@@ -0,0 +1,86 @@
package com.hdl.hdlsdk.bean;
import java.io.Serializable;
import java.util.List;
/**
 * Created by panlili on 25/2/21.
 */
public class SceneDetailBean implements Serializable {
    private String sid;
    private String status;
    private String name;
    private List<String> uids;
    private String delay;
    private String group;
    private List<SceneFunctionsInfo> functions;
    public String getSid() {
        return sid;
    }
    public void setSid(String sid) {
        this.sid = sid;
    }
    public String getStatus() {
        return status;
    }
    public void setStatus(String status) {
        this.status = status;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public List<String> getUids() {
        return uids;
    }
    public void setUids(List<String> uids) {
        this.uids = uids;
    }
    public String getDelay() {
        return delay;
    }
    public void setDelay(String delay) {
        this.delay = delay;
    }
    public String getGroup() {
        return group;
    }
    public void setGroup(String group) {
        this.group = group;
    }
    public List<SceneFunctionsInfo> getFunctions() {
        return functions;
    }
    public void setFunctions(List<SceneFunctionsInfo> functions) {
        this.functions = functions;
    }
    @Override
    public String toString() {
        return "SceneDetailBean{" +
                "sid='" + sid + '\'' +
                ", status='" + status + '\'' +
                ", name='" + name + '\'' +
                ", uids=" + uids +
                ", delay='" + delay + '\'' +
                ", group='" + group + '\'' +
                ", functions=" + functions +
                '}';
    }
}
HDLSDK_DEMO/app/src/main/java/com/hdl/hdlsdk/bean/SceneFunctionsInfo.java
New file
@@ -0,0 +1,75 @@
package com.hdl.hdlsdk.bean;
import java.io.Serializable;
import java.util.List;
/**
 * Created by panlili on 25/2/21.
 */
public class SceneFunctionsInfo implements Serializable {
    private String sid;
    private List<SceneStatusInfo> status;
    private String delay;
    public String getSid() {
        return sid;
    }
    public void setSid(String sid) {
        this.sid = sid;
    }
    public List<SceneStatusInfo> getStatus() {
        return status;
    }
    public void setStatus(List<SceneStatusInfo> status) {
        this.status = status;
    }
    public String getDelay() {
        return delay;
    }
    public void setDelay(String delay) {
        this.delay = delay;
    }
    public class SceneStatusInfo implements Serializable {
        private String key;
        private String value;
        public String getKey() {
            return key;
        }
        public void setKey(String key) {
            this.key = key;
        }
        public String getValue() {
            return value;
        }
        public void setValue(String value) {
            this.value = value;
        }
        @Override
        public String toString() {
            return "SceneStatusInfo{" +
                    "key='" + key + '\'' +
                    ", value='" + value + '\'' +
                    '}';
        }
    }
    @Override
    public String toString() {
        return "SceneFunctionsInfo{" +
                "sid='" + sid + '\'' +
                ", status=" + status +
                ", delay='" + delay + '\'' +
                '}';
    }
}
HDLSDK_DEMO/app/src/main/java/com/hdl/hdlsdk/device/DevicesListActivity.java
@@ -1,16 +1,16 @@
package com.hdl.hdlsdk.device;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.OrientationHelper;
import androidx.recyclerview.widget.RecyclerView;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.util.Log;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.google.gson.reflect.TypeToken;
import com.hdl.hdlsdk.R;
import com.hdl.hdlsdk.bean.FunctionBean;
import com.hdl.sdk.common.exception.HDLLinkException;
import com.hdl.sdk.common.utils.gson.GsonConvert;
import com.hdl.sdk.connect.HDLLink;
@@ -50,7 +50,7 @@
    }
    /**
     * 获取功能列表
     * 获取设备列表
     */
    void getFunctionList(){
HDLSDK_DEMO/app/src/main/java/com/hdl/hdlsdk/device/DevicesListAdapter.java
@@ -9,24 +9,14 @@
import android.widget.Switch;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;
import com.chad.library.adapter.base.BaseMultiItemQuickAdapter;
import com.chad.library.adapter.base.viewholder.BaseViewHolder;
import com.hdl.hdlsdk.DemoBean;
import com.hdl.hdlsdk.R;
import com.hdl.sdk.common.config.TopicConstant;
import com.hdl.hdlsdk.bean.FunctionBean;
import com.hdl.sdk.common.exception.HDLLinkException;
import com.hdl.sdk.common.utils.IdUtils;
import com.hdl.sdk.common.utils.LogUtils;
import com.hdl.sdk.common.utils.gson.GsonConvert;
import com.hdl.sdk.connect.HDLLink;
import com.hdl.sdk.connect.bean.request.DeviceControlRequest;
import com.hdl.sdk.connect.bean.response.BaseLocalResponse;
import com.hdl.sdk.connect.callback.HDLLinkCallBack;
import com.hdl.sdk.connect.config.HDLLinkConfig;
import java.util.ArrayList;
import java.util.List;
HDLSDK_DEMO/app/src/main/res/layout/activity_source_test.xml
New file
@@ -0,0 +1,508 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <TextView
            android:id="@+id/tv_content"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="10dp" />
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <Button
                android:id="@+id/btn_api_version"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="当前API版本" />
            <Button
                android:id="@+id/btn_device_model"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="10dp"
                android:layout_weight="1"
                android:text="设备model" />
            <Button
                android:id="@+id/btn_os_version"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="10dp"
                android:layout_weight="1"
                android:text="android系统版本" />
            <Button
                android:id="@+id/btn_running_memory"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_marginStart="10dp"
                android:layout_weight="1"
                android:text="运行内存" />
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <Button
                android:id="@+id/btn_inner_storage"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="内部存储空间" />
            <Button
                android:id="@+id/btn_free_storage"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="10dp"
                android:text="内部存储可用容量" />
            <Button
                android:id="@+id/btn_kernel_version"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="10dp"
                android:text="获取当前Kernel版本" />
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <Button
                android:id="@+id/btn_builder_number"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="获取设备的固件系统版本和编译日期" />
            <Button
                android:id="@+id/btn_fwversion"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="10dp"
                android:text="获取系统版本" />
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <Button
                android:id="@+id/btn_shut_down"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="关机" />
            <Button
                android:id="@+id/btn_reboot"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="10dp"
                android:text="重启" />
            <Button
                android:id="@+id/btn_system_configinfo"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="10dp"
                android:text="获取系统配置信息" />
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <EditText
                android:id="@+id/edit_brightness"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:hint="取值0~255"
                android:inputType="number" />
            <Button
                android:id="@+id/btn_brightness"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="设置屏幕亮度" />
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <EditText
                android:id="@+id/edit_rotation"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:hint="输入方向 0、90、180、270 "
                android:inputType="number" />
            <Button
                android:id="@+id/btn_rotation"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="设置屏幕方向" />
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <Button
                android:id="@+id/btn_notifyLight_open"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="呼吸灯" />
            <Button
                android:id="@+id/btn_notifyLight_close"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="10dp"
                android:layout_weight="1"
                android:text="关闭呼吸灯" />
            <Button
                android:id="@+id/btn_open_back_light"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="10dp"
                android:layout_weight="1"
                android:text="打开背光" />
            <Button
                android:id="@+id/btn_close_back_light"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="10dp"
                android:layout_weight="1"
                android:text="关闭背光" />
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <Button
                android:id="@+id/btn_statusBar_show"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="状态栏显示" />
            <Button
                android:id="@+id/btn_statusBar_hide"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="10dp"
                android:text="状态栏隐藏" />
            <Button
                android:id="@+id/btn_mic_enable"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="10dp"
                android:text="获取麦克风状态" />
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <Button
                android:id="@+id/btn_eth_mac_address"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="以太网 mac地址" />
            <Button
                android:id="@+id/btn_eth_ip_address"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="10dp"
                android:layout_weight="1"
                android:text="以太网 ip地址" />
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <Button
                android:id="@+id/btn_sdcard"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="sdcard 路径" />
            <Button
                android:id="@+id/btn_inner"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="10dp"
                android:layout_weight="1"
                android:text="内部存储 路径" />
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <Button
                android:id="@+id/btn_install"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="静默安装" />
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <Button
                android:id="@+id/btn_ethernet_connect"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="以太网连接状态" />
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="ip地址:" />
            <EditText
                android:id="@+id/edit_ip_address"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="192.168.0.123" />
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="网关:" />
            <EditText
                android:id="@+id/edit_gateway"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="192.168.0.1" />
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="netmask:" />
            <EditText
                android:id="@+id/edit_netmask"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="255.255.225.0" />
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="dns1:" />
            <EditText
                android:id="@+id/edit_dns1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="192.168.0.1" />
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="dns2:" />
            <EditText
                android:id="@+id/edit_dns2"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="0.0.0.0" />
        </LinearLayout>
        <Button
            android:id="@+id/btn_submit_static_ip"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="设置以太网静态IP" />
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <Button
                android:id="@+id/btn_netmask"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="子网掩码" />
            <Button
                android:id="@+id/btn_gateway"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="10dp"
                android:layout_weight="1"
                android:text="网关" />
            <Button
                android:id="@+id/btn_dns"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="10dp"
                android:layout_weight="1"
                android:text="DNS" />
            <Button
                android:id="@+id/btn_disconnect_eth"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="10dp"
                android:layout_weight="1"
                android:text="断开以太网" />
            <Button
                android:id="@+id/btn_connect_eth"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="10dp"
                android:layout_weight="1"
                android:text="连接以太网" />
            <Button
                android:id="@+id/btn_switch_dhcp"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="10dp"
                android:layout_weight="1"
                android:text="切换DHCP" />
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <Button
                android:id="@+id/btn_sleep"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="休眠" />
            <Button
                android:id="@+id/btn_wake_up"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="10dp"
                android:layout_weight="1"
                android:text="唤醒" />
            <Button
                android:id="@+id/btn_filter_permission"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="10dp"
                android:layout_weight="1"
                android:text="过滤权限" />
        </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
            <Button
                android:id="@+id/btn_ota"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="ota升级" />
        </LinearLayout>
    </LinearLayout>
</ScrollView>