黄学彪
2021-03-11 7d5d552de16a149fafdc2d255ce50a86e7bef431
临时上传一个安卓蓝牙的版本
19个文件已添加
1个文件已删除
12个文件已修改
2435 ■■■■■ 已修改文件
.vs/HDL_APP_Project/xs/UserPrefs.xml 77 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
DLL/Android/AndriodBluetoothLibrary.dll 补丁 | 查看 | 原始文档 | blame | 历史
HDL-ON_Android/Assets/Language.ini 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDL-ON_Android/Assets/Phone/PersonalCenter/AddDevice/ConnectSuccess.png 补丁 | 查看 | 原始文档 | blame | 历史
HDL-ON_Android/Assets/Phone/PersonalCenter/AddDevice/ConnectSuccessSelect.png 补丁 | 查看 | 原始文档 | blame | 历史
HDL-ON_Android/Assets/Phone/PersonalCenter/AddDevice/MiniRemoteControlBigPictrue.png 补丁 | 查看 | 原始文档 | blame | 历史
HDL-ON_Android/Assets/Phone/PersonalCenter/AddDevice/MiniRemoteControlMenuIcon.png 补丁 | 查看 | 原始文档 | blame | 历史
HDL-ON_Android/Assets/Phone/PersonalCenter/AddDevice/NetConnectSelect.png 补丁 | 查看 | 原始文档 | blame | 历史
HDL-ON_Android/Assets/Phone/PersonalCenter/AddDevice/UploadToClound.png 补丁 | 查看 | 原始文档 | blame | 历史
HDL-ON_Android/Assets/Phone/PersonalCenter/AddDevice/UploadToCloundSelect.png 补丁 | 查看 | 原始文档 | blame | 历史
HDL-ON_Android/Assets/Phone/PersonalCenter/AddDevice/WifiAndPhoneConnect.png 补丁 | 查看 | 原始文档 | blame | 历史
HDL-ON_Android/Assets/Phone/Public/ProgressMsg.png 补丁 | 查看 | 原始文档 | blame | 历史
HDL_ON/Common/R.cs 110 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDL_ON/DAL/DriverLayer/A_Protocol_Common.cs 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDL_ON/DAL/Mqtt/MqttClient.cs 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDL_ON/UI/UI0-Public/UpdataSidDataDialog.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDL_ON/UI/UI0-Stan/Controls/BaseControl/TextInputBase.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDL_ON/UI/UI0-Stan/Controls/BottomControls/BottomClickButton.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDL_ON/UI/UI0-Stan/Controls/BottomControls/BottomItemSelectControl.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDL_ON/UI/UI0-Stan/Controls/CompoundControls/ProgressRowBar.cs 251 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDL_ON/UI/UI0-Stan/Controls/NormalControls/NormalViewControl.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDL_ON/UI/UI0-Stan/Form/Base/CommonFormBase.cs 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDL_ON/UI/UI0-Stan/Form/Base/EditorCommonForm.cs 111 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDL_ON/UI/UI0-Stan/Logic/HdlAndroidBluetoothLogic.cs 567 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDL_ON/UI/UI0-Stan/Logic/HdlCloudReceiveLogic.cs 138 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDL_ON/UI/UI0-Stan/Logic/HdlWifiLogic.cs 99 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDL_ON/UI/UI2/4-PersonalCenter/AddDevice/AddMiniRemoteControlDirection1Page.cs 80 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDL_ON/UI/UI2/4-PersonalCenter/AddDevice/AddMiniRemoteControlDirection2Page.cs 242 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDL_ON/UI/UI2/4-PersonalCenter/AddDevice/AddMiniRemoteControlDirection3Page.cs 173 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDL_ON/UI/UI2/4-PersonalCenter/AddDevice/AddMiniRemoteControlDirection4Page.cs 424 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDL_ON/UI/UI2/4-PersonalCenter/AddDevice/AddThirdPartyDeviceMenuListPage.cs 92 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
HDL_ON/UI/UI2/FuntionControlView/Electrical/TuyaAirCleanerPage.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
.vs/HDL_APP_Project/xs/UserPrefs.xml
File was deleted
DLL/Android/AndriodBluetoothLibrary.dll
Binary files differ
HDL-ON_Android/Assets/Language.ini
@@ -1141,6 +1141,33 @@
1047=是否重置边刷
1048=是否重置滚刷
1049=是否重置滤网
1050=添加设备
1051=mini智能遥控器
1052=添加红外遥控
1053=长按红外遥控器按钮10秒,指示灯蓝色快闪
1054=请确保您的蓝牙已开启并处于可以被搜索状态
1055=下一步
1056=设备搜索中...
1057=没有发现红外遥控器
1058=1、请检查设备是否正常通电{0}2、请检查蓝牙功能是否正常开启{0}3、请检查指示灯是否蓝色快闪状态
1059=重新搜索
1060=连接WiFi
1061=目前只支持2.4G WiFi网络{0}暂不支持带有中文字符的WiFi名称
1062=密码
1063=正在连接中...
1064=请让红外遥控尽量接近WIFI路由器
1065=网络链接中
1066=上传到云
1067=连接成功
1068=1、请检查设备是否正常通电{0}2、请开启蓝牙功能{0}3、并长按按钮10s,指示灯常亮
1069=添加失败
1070=添加成功
1071=可以开始使用红外遥控功能!
1072=开始使用
1073=请打开蓝牙
1074=位置信息(GBS)不可用
1075=网络不可用
1076=选择红外遥控器
5000=音乐
5001=组合
HDL-ON_Android/Assets/Phone/PersonalCenter/AddDevice/ConnectSuccess.png
HDL-ON_Android/Assets/Phone/PersonalCenter/AddDevice/ConnectSuccessSelect.png
HDL-ON_Android/Assets/Phone/PersonalCenter/AddDevice/MiniRemoteControlBigPictrue.png
HDL-ON_Android/Assets/Phone/PersonalCenter/AddDevice/MiniRemoteControlMenuIcon.png
HDL-ON_Android/Assets/Phone/PersonalCenter/AddDevice/NetConnectSelect.png
HDL-ON_Android/Assets/Phone/PersonalCenter/AddDevice/UploadToClound.png
HDL-ON_Android/Assets/Phone/PersonalCenter/AddDevice/UploadToCloundSelect.png
HDL-ON_Android/Assets/Phone/PersonalCenter/AddDevice/WifiAndPhoneConnect.png
HDL-ON_Android/Assets/Phone/Public/ProgressMsg.png
HDL_ON/Common/R.cs
@@ -622,7 +622,115 @@
        /// <summary>
        /// 是否重置滤网
        /// </summary>
        public const int ResetFilterScreenMsg = 1049;
        public const int ResetFilterScreenMsg = 1049;
        /// <summary>
        /// 添加设备
        /// </summary>
        public const int AddDevice = 1050;
        /// <summary>
        /// mini智能遥控器
        /// </summary>
        public const int MiniIntelligentRemoteControl = 1051;
        /// <summary>
        /// 添加红外遥控
        /// </summary>
        public const int AddInfraredRemoteControl = 1052;
        /// <summary>
        /// 长按红外遥控器按钮10秒,指示灯蓝色快闪
        /// </summary>
        public const int AddInfraredRemoteControlMsg1 = 1053;
        /// <summary>
        /// 请确保您的蓝牙已开启并处于可以被搜索状态
        /// </summary>
        public const int AddInfraredRemoteControlMsg2 = 1054;
        /// <summary>
        /// 下一步
        /// </summary>
        public const int Next = 1055;
        /// <summary>
        /// 设备搜索中...
        /// </summary>
        public const int SearchingDevice = 1056;
        /// <summary>
        /// 没有发现红外遥控器
        /// </summary>
        public const int NoInfraredRemoteControlFound = 1057;
        /// <summary>
        /// 1、请检查设备是否正常通电{0}2、请检查蓝牙功能是否正常开启{0}3、请检查指示灯是否蓝色快闪状态
        /// </summary>
        public const int AddInfraredRemoteControlMsg3 = 1058;
        /// <summary>
        /// 重新搜索
        /// </summary>
        public const int ReSearch = 1059;
        /// <summary>
        /// 连接WiFi
        /// </summary>
        public const int ConnectWiFi = 1060;
        /// <summary>
        /// 目前只支持2.4G WiFi网络{0}暂不支持带有中文字符的WiFi名称
        /// </summary>
        public const int AddInfraredRemoteControlMsg4 = 1061;
        /// <summary>
        /// 密码
        /// </summary>
        public const int Password = 1062;
        /// <summary>
        /// 正在连接中...
        /// </summary>
        public const int NowConnectting = 1063;
        /// <summary>
        /// 请让红外遥控尽量接近WIFI路由器
        /// </summary>
        public const int AddInfraredRemoteControlMsg5 = 1064;
        /// <summary>
        /// 网络链接中
        /// </summary>
        public const int InTheNetworkLink = 1065;
        /// <summary>
        /// 上传到云
        /// </summary>
        public const int UploadToCloud = 1066;
        /// <summary>
        /// 连接成功
        /// </summary>
        public const int ConnectSuccess = 1067;
        /// <summary>
        /// 1、请检查设备是否正常通电{0}2、请开启蓝牙功能{0}3、并长按按钮10s,指示灯常亮
        /// </summary>
        public const int AddInfraredRemoteControlMsg6 = 1068;
        /// <summary>
        /// 添加失败
        /// </summary>
        public const int AddFail = 1069;
        /// <summary>
        /// 添加成功
        /// </summary>
        public const int AddSuccess = 1070;
        /// <summary>
        /// 可以开始使用红外遥控功能!
        /// </summary>
        public const int AddInfraredRemoteControlMsg7 = 1071;
        /// <summary>
        /// 开始使用
        /// </summary>
        public const int StartUse = 1072;
        /// <summary>
        /// 请打开蓝牙
        /// </summary>
        public const int PleaseTurnOnBluetooth = 1073;
        /// <summary>
        /// 位置信息(GBS)不可用
        /// </summary>
        public const int GbsIsNotAvailable = 1074;
        /// <summary>
        /// 网络不可用
        /// </summary>
        public const int NetworkIsNotAvailable = 1075;
        /// <summary>
        /// 选择红外遥控器
        /// </summary>
        public const int ChooseInfraredRemoteControl = 1076;
HDL_ON/DAL/DriverLayer/A_Protocol_Common.cs
@@ -115,5 +115,15 @@
                return $"/user/{Control.Ins.GatewayId}/custom/scene/execute";
            }
        }
        /// <summary>
        /// 添加设备上报
        /// </summary>
        public string AddDevicePush
        {
            get
            {
                return $"/base/{Control.Ins.GatewayId}/thing/topo/found_reply";
            }
        }
    }
}
HDL_ON/DAL/Mqtt/MqttClient.cs
@@ -191,9 +191,15 @@
                        Topic = $"/user/{DB_ResidenceData.Instance.CurrentRegion.RegionID}/app/thing/property/send",
                        QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce
                    };
                    //设备入网上报主题(目前只有红外宝)
                    var topicFilterPush3 = new MqttTopicFilter()
                    {
                        Topic = $"/user/{DB_ResidenceData.Instance.CurrentRegion.RegionID}/app/thing/topo/found",
                        QualityOfServiceLevel = MQTTnet.Protocol.MqttQualityOfServiceLevel.AtMostOnce
                    };
                    Utlis.WriteLine("开始订阅!");
                    var result = await RemoteMqttClient.SubscribeAsync(new MqttTopicFilter[] {  topicFilterPush2, topicAlinkStatus });
                    var result = await RemoteMqttClient.SubscribeAsync(new MqttTopicFilter[] { topicFilterPush2, topicAlinkStatus, topicFilterPush3 });
                    if (result.Items[0].ResultCode == MQTTnet.Client.Subscribing.MqttClientSubscribeResultCode.GrantedQoS0)
                    {
                        isSubscribeSuccess = true;
HDL_ON/UI/UI0-Public/UpdataSidDataDialog.cs
@@ -44,7 +44,7 @@
                    //sidObj.bus.LoopId = Convert.ToByte(sidObj.sid.Substring(20, 4),16);
                    sidObj.bus.loopId = sidObj.sid.Substring(20, 4);
                }
                FunctionList.List.AddDeviceFunction(sidObj);
                //FunctionList.List.AddDeviceFunction(sidObj);
            }
            //MainPage.GoUserPage();
        }
HDL_ON/UI/UI0-Stan/Controls/BaseControl/TextInputBase.cs
@@ -7,7 +7,7 @@
namespace HDL_ON.Stan
{
    /// <summary>
    /// 输入框控件的最初原型(不建议修改和直接使用):标准字体颜色,文字向左靠齐,14号字
    /// 输入框控件的最初原型(不建议修改和直接使用):标准字体颜色(0xFF798394),文字向左靠齐,14号字
    /// </summary>
    public class TextInputBase : EditText
    {
HDL_ON/UI/UI0-Stan/Controls/BottomControls/BottomClickButton.cs
@@ -22,7 +22,7 @@
        /// <param name="i_width">有些界面很特殊,不统一按键宽度,所以预留此参数</param>
        public BottomClickButton(int i_width = 188)
        {
            this.Yaxis = Application.GetRealHeight(539);
            this.Yaxis = Application.GetRealHeight(543);
            //这个是一般位置
            this.Y = this.Yaxis;
@@ -33,6 +33,7 @@
            this.Gravity = Gravity.CenterHorizontal;
            this.Radius = (uint)Application.GetRealHeight(44) / 2;
            this.TextSize = CSS_FontSize.SubheadingFontSize;
            this.BackgroundColor = CSS_Color.MainColor;
            this.IsBold = true;
        }
    }
HDL_ON/UI/UI0-Stan/Controls/BottomControls/BottomItemSelectControl.cs
@@ -100,7 +100,7 @@
        /// 添加菜单行
        /// </summary>
        /// <param name="i_listText">显示的列表文字</param>
        /// <param name="i_listSelect">默认选择</param>
        /// <param name="i_listSelect">默认选择(请勿设置为null)</param>
        public void AddRowMenu(List<string> i_listText, List<int> i_listSelect)
        {
            foreach (var index in i_listSelect)
HDL_ON/UI/UI0-Stan/Controls/CompoundControls/ProgressRowBar.cs
New file
@@ -0,0 +1,251 @@
using HDL_ON.Stan;
using Shared;
using System;
using System.Collections.Generic;
using System.Text;
namespace HDL_ON.UI
{
    /// <summary>
    /// 行条类型的进度条控件
    /// </summary>
    public class ProgressRowBar : FrameLayout
    {
        #region ■ 变量声明___________________________
        /// <summary>
        /// 进度条能否往回走(默认不可以)
        /// </summary>
        public bool ProgressBarGoback = false;
        /// <summary>
        /// 会移动的进度条
        /// </summary>
        private FrameLayout btnProgressBar = null;
        /// <summary>
        /// 显示数值百分比的控件
        /// </summary>
        private NormalViewControl btnProgressTextView = null;
        /// <summary>
        /// 线程是否运行
        /// </summary>
        private bool isThreadAction = false;
        /// <summary>
        /// 模式区分
        /// </summary>
        private int m_ModeDiv = -1;
        /// <summary>
        /// 进度条是否可视
        /// </summary>
        public new bool Visible
        {
            get { return base.Visible; }
            set
            {
                if (this.btnProgressTextView != null)
                {
                    this.btnProgressTextView.Visible = value;
                }
                base.Visible = value;
            }
        }
        #endregion
        #region ■ 初始化_____________________________
        /// <summary>
        /// 行条类型的进度条控件
        /// </summary>
        /// <param name="width">
        /// <para>模式1:会动的那个进度条的宽度(非真实值)</para>
        /// <para>模式2:进度条在持续无限的来回移动的区域宽度(非真实值)</para>
        /// </param>
        /// <param name="height">
        /// <para>模式1:会动的那个进度条的高度(非真实值)</para>
        /// <para>模式2:进度条在持续无限的来回移动的高度(非真实值)</para>
        /// </param>
        public ProgressRowBar(int width, int height)
        {
            this.Height = Application.GetRealHeight(height);
            this.Width = Application.GetRealWidth(width);
            this.BackgroundColor = UI.CSS.CSS_Color.BackgroundColor;
            this.Radius = (uint)Application.GetRealHeight(height) / 2;
        }
        #endregion
        #region ■ 模式1______________________________
        /// <summary>
        /// 模式1  该模式为:手动填写进度值
        /// </summary>
        /// <param name="showText">
        /// <para>是否在进度条上方显示数值百分比</para>
        /// <para>请确保控件的上方有足够的区域(注:请不要扩大此控件的高度)</para>
        /// </param>
        public void StartMode1(bool showText = false)
        {
            if (m_ModeDiv != -1) { return; }
            this.m_ModeDiv = 1;
            //会移动的进度条
            this.btnProgressBar = new FrameLayout();
            btnProgressBar.Width = 0;
            btnProgressBar.Height = this.Height;
            btnProgressBar.BackgroundColor = UI.CSS.CSS_Color.MainColor;
            btnProgressBar.Radius = (uint)this.Height / 2;
            this.AddChidren(btnProgressBar);
            if (showText == true)
            {
                //进度值文本
                this.btnProgressTextView = new NormalViewControl(32, 22, true);
                btnProgressTextView.Y = this.Y - Application.GetRealHeight(22 + 10);//10:它与进度条的间距
                btnProgressTextView.X = this.X - Application.GetRealWidth(32) / 2;
                btnProgressTextView.UnSelectedImagePath = "Public/ProgressMsg.png";
                btnProgressTextView.TextSize = CSS.CSS_FontSize.PromptFontSize_SecondaryLevel;
                btnProgressTextView.TextColor= CSS.CSS_Color.FirstLevelTitleColor;
                btnProgressTextView.TextAlignment = TextAlignment.Center;
                btnProgressTextView.Text = "0%";
                this.Parent.AddChidren(btnProgressTextView);
            }
        }
        /// <summary>
        /// 重置进度条(只对模式1有效)
        /// </summary>
        public void ResetProgressBar()
        {
            if (this.m_ModeDiv == 1 && this.btnProgressBar != null)
            {
                this.btnProgressBar.Width = 0;
            }
        }
        /// <summary>
        /// 设置进度值
        /// </summary>
        /// <param name="value">此值为百分比值(也就是小于或者等于1的)</param>
        public void SetValue(decimal value)
        {
            this.SetValueEx(value);
        }
        /// <summary>
        /// 设置进度值
        /// </summary>
        /// <param name="value">进度值,内部会除以maxValue</param>
        /// <param name="maxValue">最大值</param>
        public void SetValue(decimal value, decimal maxValue)
        {
            decimal result = value / maxValue;
            this.SetValueEx(result);
        }
        /// <summary>
        /// 设置进度值
        /// </summary>
        /// <param name="value"></param>
        private void SetValueEx(decimal value)
        {
            if (btnProgressBar == null || this.m_ModeDiv != 1)
            {
                return;
            }
            if (value > 1) { value = 1; }
            HdlThreadLogic.Current.RunMain(() =>
            {
                int width = (int)(value * this.Width);
                if (this.ProgressBarGoback == false && btnProgressBar.Width >= width)
                {
                    //不能让进度条往回走
                    return;
                }
                btnProgressBar.Width = width;
                if (this.btnProgressTextView != null)
                {
                    //文本显示
                    btnProgressTextView.Text = ((int)(value * 100)) + "%";
                    //文本显示的那个图片框移动
                    this.btnProgressTextView.X = this.X + btnProgressBar.Right - btnProgressTextView.Width / 2;
                }
            });
        }
        #endregion
        #region ■ 模式2______________________________
        /// <summary>
        /// 模式2  该模式为:不能手动指定进度值,由内部线程处理,进度条在持续无限的来回移动
        /// </summary>
        /// <param name="proWidth">持续无限的来回移动的进度条的宽度(非真实值)</param>
        public void StartMode2(int proWidth = 100)
        {
            if (m_ModeDiv != -1) { return; }
            this.m_ModeDiv = 2;
            //会移动的进度条
            this.btnProgressBar = new FrameLayout();
            btnProgressBar.Width = Application.GetRealWidth(proWidth);
            btnProgressBar.Height = this.Height;
            btnProgressBar.BackgroundColor = 0xfffb744a;
            btnProgressBar.Radius = (uint)this.Height / 2;
            this.AddChidren(btnProgressBar);
            //开启模式2的线程
            this.StartMode2Thread();
        }
        /// <summary>
        /// 重新开启模式2
        /// </summary>
        public void ReStartMode2()
        {
            //开启模式2的线程
            this.StartMode2Thread();
        }
        /// <summary>
        /// 暂停模式2
        /// </summary>
        public void StopMode2()
        {
            this.isThreadAction = false;
        }
        /// <summary>
        /// 开启模式2的线程
        /// </summary>
        private void StartMode2Thread()
        {
            if (this.isThreadAction == true)
            {
                return;
            }
            this.isThreadAction = true;
            int moveLength = Application.GetRealWidth(30);
            HdlThreadLogic.Current.RunThread(() =>
            {
                while (this.Parent != null && isThreadAction == true)
                {
                    HdlThreadLogic.Current.RunMain(() =>
                    {
                        if (this.btnProgressBar.X >= this.Width)
                        {
                            //超出右边之后,再次从左边循环
                            this.btnProgressBar.X = -this.btnProgressBar.Width;
                            return;
                        }
                        this.btnProgressBar.X += moveLength;
                    }, ShowErrorMode.NO);
                    System.Threading.Thread.Sleep(150);
                }
            });
        }
        #endregion
    }
}
HDL_ON/UI/UI0-Stan/Controls/NormalControls/NormalViewControl.cs
@@ -11,7 +11,7 @@
    public class NormalViewControl : ButtonCtrBase
    {
        /// <summary>
        /// 平凡普通的控件,基本只是用来显示(正常文本字体颜色,文字向左靠齐)
        /// 平凡普通的控件,基本只是用来显示(正常文本字体颜色(0xFF798394),文字向左靠齐)
        /// </summary>
        /// <param name="i_Width">宽度</param>
        /// <param name="i_Height">高度</param>
HDL_ON/UI/UI0-Stan/Form/Base/CommonFormBase.cs
@@ -53,19 +53,6 @@
            return;
        }
        /// <summary>
        /// 添加指定画面,并移除当前画面,启动参数由指定画面的ShowForm函数所指定
        /// </summary>
        /// <param name="form">目标界面</param>
        /// <param name="parameter">启动参数:参数由指定画面的ShowForm函数所指定</param>
        public void AddFormAndCloseNowForm(CommonFormBase form, params object[] parameter)
        {
            //移除当前画面
            this.CloseForm();
            //添加画面
            form.AddForm(parameter);
        }
        #endregion
        #region ■ 关闭界面___________________________
HDL_ON/UI/UI0-Stan/Form/Base/EditorCommonForm.cs
@@ -287,6 +287,117 @@
        #endregion
        #region ■ 添加列表消息显示控件_______________
        /// <summary>
        /// 添加列表消息显示控件,返回的是最后一个控件的底部坐标
        /// </summary>
        /// <param name="frameTable">桌布容器控件</param>
        /// <param name="i_msg">显示的消息(换行请使用【{0}】进行分割)</param>
        /// <param name="i_fontSize">字体大小</param>
        /// <param name="i_fontColor">字体颜色</param>
        /// <param name="i_height">控件高度(真实值)</param>
        /// <param name="i_yy">Y轴初始坐标(真实值)</param>
        /// <param name="alignment">文字对齐方式</param>
        /// <param name="special">
        /// <para>注:除了新建这个函数的开发者以外,都不建议把这个值不设置为true</para>
        /// <para>说明:以最长的控件的X轴为基准,所有控件的X轴都变成一致</para>
        /// </param>
        /// <returns></returns>
        public int AddListMsgControls(FrameLayout frameTable, string i_msg, int i_fontSize, uint i_fontColor, int i_height,
            int i_yy, TextAlignment alignment = TextAlignment.Center, bool special = false)
        {
            var listMsg = i_msg.Split(new string[] { "{0}" }, StringSplitOptions.RemoveEmptyEntries);
            int defultWidth = this.bodyFrameLayout.Width - HdlControlResourse.XXLeft * 2;
            var listContr = new List<NormalViewControl>();
            int minXX = 10086;//控件集合最小的X轴
            foreach (var strMsg in listMsg)
            {
                //消息显示控件
                var btnMsg = new NormalViewControl(defultWidth, i_height, false);
                btnMsg.Y = i_yy;
                btnMsg.Gravity = Gravity.CenterHorizontal;
                btnMsg.TextAlignment = alignment;
                btnMsg.TextColor = i_fontColor;
                btnMsg.TextSize = i_fontSize;
                btnMsg.Text = strMsg;
                //特殊处理
                if (special == true && alignment == TextAlignment.Center)
                {
                    //设置它的真实宽度(对special变量有用)
                    int realWidth = btnMsg.GetRealWidthByText();
                    btnMsg.Width = realWidth > defultWidth ? defultWidth : realWidth;
                }
                frameTable.AddChidren(btnMsg);
                //收集控件
                listContr.Add(btnMsg);
                //记录控件集合X轴最小的值
                if (btnMsg.X < minXX) { minXX = btnMsg.X; }
                //两行之间的间距为4
                i_yy = btnMsg.Bottom + Application.GetRealHeight(4);
            }
            //特殊处理
            if (special == true && alignment == TextAlignment.Center)
            {
                foreach (var contr in listContr)
                {
                    //以最长的控件的X轴为基准,所有控件的X轴都变成一致
                    contr.X = minXX;
                }
            }
            return i_yy - Application.GetRealHeight(4);
        }
        #endregion
        #region ■ 添加底部点击按钮控件_______________
        /// <summary>
        /// 添加底部点击按钮控件
        /// </summary>
        /// <param name="i_text">显示的文本</param>
        /// <returns></returns>
        public BottomClickButton AddBottomClickButton(string i_text)
        {
            //容器控件
            var frameBack = new FrameLayout();
            frameBack.Height = Application.GetRealHeight(76);
            frameBack.Gravity = Gravity.BottomCenter;
            bodyFrameLayout.AddChidren(frameBack);
            //然后在顶部添加一个有边框的东西
            var frameLine = new FrameLayout();
            frameLine.Height = Application.GetRealHeight(50);
            frameLine.BorderWidth = 1;
            frameLine.BackgroundColor = UI.CSS.CSS_Color.MainBackgroundColor;
            frameLine.BorderColor = UI.CSS.CSS_Color.DividingLineColor;
            frameLine.SetCornerWithSameRadius(Application.GetRealHeight(24), HDLUtils.RectCornerTopLeft | HDLUtils.RectCornerTopRight);
            frameBack.AddChidren(frameLine);
            //最后再整个白色的东西遮住它的下部
            var frameWite = new FrameLayout();
            frameWite.Height = frameBack.Height - Application.GetRealHeight(24 - 10);//需要超过它
            frameWite.Width = frameBack.Width + Application.GetRealWidth(6);
            frameWite.X = -Application.GetRealWidth(3);
            frameWite.Y = Application.GetRealHeight(24);
            frameWite.BackgroundColor = UI.CSS.CSS_Color.MainBackgroundColor;
            frameBack.AddChidren(frameWite);
            //按钮
            var btnOk = new BottomClickButton(220);
            btnOk.Gravity = Gravity.Center;
            btnOk.Text = i_text;
            frameBack.AddChidren(btnOk);
            return btnOk;
        }
        #endregion
        #region ■ 一般的方法_________________________
        /// <summary>
HDL_ON/UI/UI0-Stan/Logic/HdlAndroidBluetoothLogic.cs
New file
@@ -0,0 +1,567 @@
using Shared;
using System;
using System.Collections.Generic;
using System.Text;
namespace HDL_ON.Stan
{
#if __Android__
    public class HdlAndroidBluetoothLogic
    {
        #region ■ 变量声明___________________________
        /// <summary>
        /// 安卓蓝牙的逻辑
        /// </summary>
        private static HdlAndroidBluetoothLogic m_Current = null;
        /// <summary>
        /// 安卓蓝牙的逻辑
        /// </summary>
        public static HdlAndroidBluetoothLogic Current
        {
            get
            {
                if (m_Current == null)
                {
                    m_Current = new HdlAndroidBluetoothLogic();
                }
                return m_Current;
            }
        }
        /// <summary>
        /// 当前蓝牙客户端
        /// </summary>
        private Blufi.Espressif.BlufiClient nowBlufiClient = null;
        /// <summary>
        /// 接收事件
        /// </summary>
        private Action<string> ReceiveEvent = null;
        /// <summary>
        /// 发送状态(0:发送失败 1:发送成功)
        /// </summary>
        private int sendStatuValue = -1;
        #endregion
        #region ■ 蓝牙所需功能检测___________________
        /// <summary>
        /// 检测是否能够搜索蓝牙(内部会弹出Msg框,因为内部需要检测系统权限,所以参数采用回调的方式)
        /// </summary>
        /// <param name="resultEvent">检测结果事件</param>
        public void CheckCanScanBluetooth(Action<bool> resultEvent)
        {
            var adapter = Android.Bluetooth.BluetoothAdapter.DefaultAdapter;
            var scanner = adapter.BluetoothLeScanner;
            if (adapter.IsEnabled == false || scanner == null)
            {
                HdlMessageLogic.Current.ShowMassage(ShowMsgType.Tip, Language.StringByID(StringId.PleaseTurnOnBluetooth));
                resultEvent?.Invoke(false);
                return;
            }
            //检测是否打开了系统功能
            if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.M)
            {
                var locationManager = (Android.Locations.LocationManager)Application.Activity.GetSystemService(Android.Content.Context.LocationService);
                if (locationManager == null)
                {
                    //位置信息(GBS)不可用
                    HdlMessageLogic.Current.ShowMassage(ShowMsgType.Tip, Language.StringByID(StringId.GbsIsNotAvailable));
                    resultEvent?.Invoke(false);
                    return;
                }
                if (locationManager.IsProviderEnabled("network") == false)
                {
                    HdlMessageLogic.Current.ShowMassage(ShowMsgType.Tip, Language.StringByID(StringId.NetworkIsNotAvailable));
                    resultEvent?.Invoke(false);
                    return;
                }
                if (locationManager.IsProviderEnabled("gps") == false)
                {
                    //位置信息(GBS)不可用
                    HdlMessageLogic.Current.ShowMassage(ShowMsgType.Tip, Language.StringByID(StringId.GbsIsNotAvailable));
                    resultEvent?.Invoke(false);
                    return;
                }
            }
            //检测蓝牙需要的权限
            ((BaseActivity)Application.Activity).SetPermission((result1) =>
            {
                if (result1 == false)
                {
                    resultEvent?.Invoke(false);
                    return;
                }
                ((BaseActivity)Application.Activity).SetPermission((result2) =>
                {
                    if (result2 == false)
                    {
                        resultEvent?.Invoke(false);
                        return;
                    }
                    //全部通过
                    resultEvent?.Invoke(true);
                }, "android.permission.ACCESS_FINE_LOCATION");
            }, "android.permission.ACCESS_COARSE_LOCATION");
        }
        #endregion
        #region ■ 蓝牙扫描___________________________
        /// <summary>
        /// 搜索蓝牙
        /// </summary>
        /// <param name="waitTime">搜索时间(秒)</param>
        /// <param name="FinishEvent">搜索结束的事件</param>
        public void ScanBluetooth(int waitTime, Action<List<BluetoothInfo>> FinishEvent)
        {
            //再次检测是否能够搜索蓝牙
            this.CheckCanScanBluetooth((result) =>
            {
                if (result == true)
                {
                    HdlThreadLogic.Current.RunThread(() =>
                    {
                        //开始搜索蓝牙
                        this.DoScanBluetooth(waitTime, FinishEvent);
                    });
                }
            });
        }
        /// <summary>
        /// 开始搜索蓝牙
        /// </summary>
        /// <param name="waitTime">搜索时间(秒)</param>
        /// <param name="FinishEvent">搜索结束的事件</param>
        private void DoScanBluetooth(int waitTime, Action<List<BluetoothInfo>> FinishEvent)
        {
            var listBluetoothInfo = new List<BluetoothInfo>();
            var adapter = Android.Bluetooth.BluetoothAdapter.DefaultAdapter;
            var scanner = adapter.BluetoothLeScanner;
            var scanCallback = new BluetoothScanCallback();
            scanner.StartScan(null, new Android.Bluetooth.LE.ScanSettings.Builder().SetScanMode(Android.Bluetooth.LE.ScanMode.LowLatency).Build(), scanCallback);
            System.Threading.Thread.Sleep(waitTime * 1000);
            scanner.StopScan(scanCallback);
            adapter.Dispose();
            foreach (var data in scanCallback.listData)
            {
                listBluetoothInfo.Add(data);
            }
            scanCallback.listData.Clear();
            FinishEvent?.Invoke(listBluetoothInfo);
        }
        /// <summary>
        /// 蓝牙的回调对象
        /// </summary>
        private class BluetoothScanCallback : Android.Bluetooth.LE.ScanCallback
        {
            /// <summary>
            /// 蓝牙列表
            /// </summary>
            public List<BluetoothInfo> listData = new List<BluetoothInfo>();
            /// <summary>
            /// 重复检测
            /// </summary>
            private List<string> listCheck = new List<string>();
            /// <summary>
            /// 蓝牙结果接收
            /// </summary>
            /// <param name="listResult"></param>
            public override void OnBatchScanResults(IList<Android.Bluetooth.LE.ScanResult> listResult)
            {
                foreach (var result in listResult)
                {
                    this.AddBluetoothResult(result);
                }
            }
            /// <summary>
            /// 蓝牙结果接收
            /// </summary>
            /// <param name="callbackType"></param>
            /// <param name="result"></param>
            public override void OnScanResult(Android.Bluetooth.LE.ScanCallbackType callbackType, Android.Bluetooth.LE.ScanResult result)
            {
                this.AddBluetoothResult(result);
            }
            /// <summary>
            /// 添加蓝牙缓存
            /// </summary>
            /// <param name="result"></param>
            private void AddBluetoothResult(Android.Bluetooth.LE.ScanResult result)
            {
                var device = result.Device;
                if (device == null || listCheck.Contains(device.Address) == true)
                {
                    return;
                }
                listCheck.Add(device.Address);
                var data = new BluetoothInfo();
                data.Name = device.Name;
                if (data.Name == null) { data.Name = string.Empty; }
                data.Address = device.Address;
                data.Device = device;
                listData.Add(data);
            }
        }
        #endregion
        #region ■ 蓝牙链接___________________________
        /// <summary>
        /// 蓝牙链接(false:连接失败 true:连接成功)
        /// </summary>
        /// <param name="bluetooth">需要链接的蓝牙对象</param>
        /// <param name="connectEvent">因为需要对方反馈,所以使用回调(链接结果 false:连接失败 true:连接成功)</param>
        public void ContectBluetooth(BluetoothInfo bluetooth, Action<bool> connectEvent)
        {
            try
            {
                this.nowBlufiClient = new Blufi.Espressif.BlufiClient(Application.Activity, bluetooth.Device);
                //一个回调事件
                var callback = new InnerGattCallback();
                callback.ConnectionStateEvent += (div, newState) =>
                {
                    if (div == 1)
                    {
                        if (newState == Android.Bluetooth.ProfileState.Connected)
                        {
                            //链接建立成功
                            connectEvent?.Invoke(true);
                            //只通知一次
                            connectEvent = null;
                        }
                        else if (newState == Android.Bluetooth.ProfileState.Disconnected)
                        {
                            //关闭链接
                            this.DisContectBluetooth();
                            connectEvent?.Invoke(false);
                            //只通知一次
                            connectEvent = null;
                        }
                    }
                    else if (div == -1)
                    {
                        //关闭链接
                        this.DisContectBluetooth();
                        connectEvent?.Invoke(false);
                        //只通知一次
                        connectEvent = null;
                    }
                };
                nowBlufiClient.SetGattCallback(callback);
                //另外一个回调事件
                var blufiCall = new BlufiCallbackMain();
                blufiCall.StateEvent += (div, data) =>
                {
                    //-1:异常 1:正常 2:发送数据成功 3:发送数据失败
                    if (div == StatuEnum.A异常)
                    {
                        //关闭链接
                        this.DisContectBluetooth();
                        connectEvent?.Invoke(false);
                        //只通知一次
                        connectEvent = null;
                    }
                    else if (div == StatuEnum.A发送成功 || div == StatuEnum.A发送失败)
                    {
                        sendStatuValue = div == StatuEnum.A发送成功 ? 1 : 0;
                    }
                    else if (div == StatuEnum.A蓝牙反馈)
                    {
                        //蓝牙返回的结果
                        this.ReceiveEvent?.Invoke(data);
                    }
                };
                nowBlufiClient.SetBlufiCallback(blufiCall);
                //执行链接
                nowBlufiClient.Connect();
            }
            catch
            {
                connectEvent?.Invoke(false);
                connectEvent = null;
            }
        }
        /// <summary>
        /// 先这么定义一个空的继承
        /// </summary>
        private class InnerGattCallback : Android.Bluetooth.BluetoothGattCallback
        {
            /// <summary>
            /// 状态事件回调(-1:异常 1:OnConnectionStateChange)
            /// </summary>
            public Action<int,Android.Bluetooth.ProfileState> ConnectionStateEvent = null;
            /// <summary>
            /// 链接状态改变
            /// </summary>
            /// <param name="gatt"></param>
            /// <param name="status"></param>
            /// <param name="newState"></param>
            public override void OnConnectionStateChange(Android.Bluetooth.BluetoothGatt gatt, Android.Bluetooth.GattStatus status, Android.Bluetooth.ProfileState newState)
            {
                if (status == Android.Bluetooth.GattStatus.Success)
                {
                    //回调事件
                    this.ConnectionStateEvent?.Invoke(1, newState);
                }
                else
                {
                    //回调事件
                    this.ConnectionStateEvent?.Invoke(-1, 0);
                }
            }
            /// <summary>
            /// 成功发现设备的services时,调用此方法
            /// </summary>
            /// <param name="gatt"></param>
            /// <param name="status"></param>
            public override void OnServicesDiscovered(Android.Bluetooth.BluetoothGatt gatt, Android.Bluetooth.GattStatus status)
            {
                if (status != Android.Bluetooth.GattStatus.Success)
                {
                    //回调事件
                    this.ConnectionStateEvent?.Invoke(-1, 0);
                }
            }
            /// <summary>
            /// 应该是写入事件吧
            /// </summary>
            /// <param name="gatt"></param>
            /// <param name="characteristic"></param>
            /// <param name="status"></param>
            public override void OnCharacteristicWrite(Android.Bluetooth.BluetoothGatt gatt, Android.Bluetooth.BluetoothGattCharacteristic characteristic, Android.Bluetooth.GattStatus status)
            {
                if (status != Android.Bluetooth.GattStatus.Success)
                {
                    //回调事件
                    this.ConnectionStateEvent?.Invoke(-1, 0);
                }
            }
        }
        /// <summary>
        /// 抄SDK的,我也不知道这个是什么
        /// </summary>
        private class BlufiCallbackMain : Blufi.Espressif.BlufiCallback
        {
            /// <summary>
            /// 状态事件回调 当第一个参数为"A蓝牙反馈"时,第二个参数为蓝牙返回的信息
            /// </summary>
            public Action<StatuEnum, string> StateEvent = null;
            /// <summary>
            /// 抄SDK的,我也不知道这个是什么
            /// </summary>
            /// <param name="client"></param>
            /// <param name="gatt"></param>
            /// <param name="service"></param>
            /// <param name="writeChar"></param>
            /// <param name="notifyChar"></param>
            public override void OnGattPrepared(Blufi.Espressif.BlufiClient client, Android.Bluetooth.BluetoothGatt gatt, Android.Bluetooth.BluetoothGattService service,
                Android.Bluetooth.BluetoothGattCharacteristic writeChar, Android.Bluetooth.BluetoothGattCharacteristic notifyChar)
            {
                if (service == null || writeChar == null || notifyChar == null)
                {
                    StateEvent?.Invoke(StatuEnum.A异常, null);
                    return;
                }
                try
                {
                    int mtu = 128;
                    if ((int)Android.OS.Build.VERSION.SdkInt == 29
                      && Android.OS.Build.Manufacturer.ToLower().StartsWith("samsung") == true)
                    {
                        mtu = 23;
                    }
                    var requestMtu = gatt.RequestMtu(mtu);
                    if (!requestMtu)
                    {
                        //Request mtu failed
                        client.SetPostPackageLengthLimit(20);
                    }
                    StateEvent?.Invoke(StatuEnum.A正常, null); ;
                }
                catch
                {
                    StateEvent?.Invoke(StatuEnum.A异常, null);
                    return;
                }
            }
            /// <summary>
            /// 手机端发送数据到蓝牙的结果
            /// </summary>
            /// <param name="client"></param>
            /// <param name="status">0:成功 其他都是失败</param>
            /// <param name="data">手机端发送的数据</param>
            public override void OnPostCustomDataResult(Blufi.Espressif.BlufiClient client, int status, byte[] data)
            {
                StateEvent?.Invoke(status == 0 ? StatuEnum.A发送成功 : StatuEnum.A发送失败, null);
            }
            /// <summary>
            /// 蓝牙回复的结果
            /// </summary>
            /// <param name="client"></param>
            /// <param name="status">0:成功 其他都是失败</param>
            /// <param name="data">蓝牙回复的数据</param>
            public override void OnReceiveCustomData(Blufi.Espressif.BlufiClient client, int status, byte[] data)
            {
                if (status == 0)
                {
                    var receiveData = System.Text.Encoding.UTF8.GetString(data);
                    StateEvent?.Invoke(StatuEnum.A蓝牙反馈, receiveData);
                }
            }
        }
        #endregion
        #region ■ 蓝牙关闭___________________________
        /// <summary>
        ///  关闭蓝牙链接
        /// </summary>
        public void DisContectBluetooth()
        {
            HdlThreadLogic.Current.RunMain(() =>
            {
                this.nowBlufiClient?.RequestCloseConnection();
                this.nowBlufiClient = null;
                m_Current = null;
            }, ShowErrorMode.NO);
        }
        /// <summary>
        /// 摧毁
        /// </summary>
        public void Dispone()
        {
            //关闭蓝牙链接
            this.DisContectBluetooth();
            this.ReceiveEvent = null;
            m_Current = null;
        }
        #endregion
        #region ■ 发送数据___________________________
        /// <summary>
        /// 发送数据给蓝牙
        /// </summary>
        /// <param name="i_data">发送的数据</param>
        /// <param name="waiTime">等待时间(秒),如果设置为0,则只要发送不出现异常,直接判定为成功</param>
        public bool SendData(string i_data, int waiTime = 0)
        {
            if (this.nowBlufiClient == null)
            {
                return false;
            }
            try
            {
                this.sendStatuValue = -1;
                //发送数据
                var byteData = System.Text.Encoding.UTF8.GetBytes(i_data);
                this.nowBlufiClient.PostCustomData(byteData);
                if (waiTime == 0) { return true; }
                waiTime *= 5;
                while (this.sendStatuValue == -1 && waiTime > 0)
                {
                    System.Threading.Thread.Sleep(200);
                    waiTime--;
                }
                return this.sendStatuValue == 1;
            }
            catch { return false; }
        }
        #endregion
        #region ■ 一般方法___________________________
        /// <summary>
        /// 添加蓝牙的接收事件
        /// </summary>
        /// <param name="i_ReceiveEvent">蓝牙接收事件</param>
        public void AddReceiveEvent(Action<string> i_ReceiveEvent)
        {
            this.ReceiveEvent = i_ReceiveEvent;
        }
        /// <summary>
        /// 移除蓝牙的接收事件
        /// </summary>
        public void RemoveReceiveEvent()
        {
            this.ReceiveEvent = null;
        }
        #endregion
        #region ■ 结构体_____________________________
        /// <summary>
        /// 蓝牙返回的信息
        /// </summary>
        public class BluetoothInfo
        {
            /// <summary>
            /// 名字(此名字不会null,如果它本身是null,只会是string.empty)
            /// </summary>
            public string Name = string.Empty;
            /// <summary>
            /// 地址
            /// </summary>
            public string Address = string.Empty;
            /// <summary>
            /// 蓝牙设备
            /// </summary>
            public Android.Bluetooth.BluetoothDevice Device = null;
        }
        /// <summary>
        /// 状态枚举
        /// </summary>
        private enum StatuEnum
        {
            A异常 = -1,
            A正常 = 1,
            A发送成功 = 2,
            A发送失败 = 3,
            A蓝牙反馈 = 4
        }
        #endregion
    }
#endif
}
HDL_ON/UI/UI0-Stan/Logic/HdlCloudReceiveLogic.cs
New file
@@ -0,0 +1,138 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace HDL_ON.Stan
{
    //应该也不多,就写在这里了
    /// <summary>
    /// 云端推送枚举
    /// </summary>
    public enum CloudPushEnum
    {
        A新设备上报 = 1,
    }
    /// <summary>
    /// 全局接收云端推送的的逻辑(为了执行速度,尽可能的别加耗时的操作)
    /// </summary>
    public class HdlCloudReceiveLogic
    {
        #region ■ 变量声明___________________________
        /// <summary>
        /// 全局接收云端推送的的逻辑
        /// </summary>
        private static HdlCloudReceiveLogic m_Current = null;
        /// <summary>
        /// 全局接收云端推送的的逻辑
        /// </summary>
        public static HdlCloudReceiveLogic Current
        {
            get
            {
                if (m_Current == null)
                {
                    m_Current = new HdlCloudReceiveLogic();
                }
                return m_Current;
            }
        }
        /// <summary>
        /// 云端接收事件集合
        /// </summary>
        private List<CloudReceiveEventClass> ListCloudEvent = new List<CloudReceiveEventClass>();
        #endregion
        #region ■ 全局接收___________________________
        /// <summary>
        /// 全局接收云端推送的的逻辑(为了执行速度,尽可能的别加耗时的操作)
        /// </summary>
        /// <param name="topic">整个主题</param>
        /// <param name="msgData">接收的数据</param>
        public void CloudOverallMsgReceive(string topic, string msgData)
        {
            //没有任何监听
            if (ListCloudEvent.Count == 0) { return; }
            //设备入网上报主题(目前只有红外宝)
            if (topic == DriverLayer.CommunicationTopic.ct.AddDevicePush)
            {
                for (int i = 0; i < this.ListCloudEvent.Count; i++)
                {
                    //回调事件
                    this.ListCloudEvent[i].CloudReceiveEvent(CloudPushEnum.A新设备上报, msgData);
                }
            }
        }
        #endregion
        #region ■ 添加云端监听_______________________
        /// <summary>
        /// 添加云端接收事件
        /// </summary>
        /// <param name="i_mainKey">标识事件的主键(可以随便填,主要是针对多个界面一起使用的情况)</param>
        /// <param name="action">(参数1:枚举 参数2:推送消息)</param>
        public void AddCloudReceiveEvent(string i_mainKey, Action<CloudPushEnum, string> action)
        {
            try
            {
                var eventClass = new CloudReceiveEventClass();
                eventClass.MainKey = i_mainKey;
                eventClass.CloudReceiveEvent = action;
                this.ListCloudEvent.Add(eventClass);
            }
            catch { }
        }
        #endregion
        #region ■ 移除云端监听_______________________
        /// <summary>
        /// 移除云端接收事件
        /// </summary>
        /// <param name="i_mainKey">标识事件的主键(可以随便填,主要是针对多个界面一起使用的情况)</param>
        public void RemoveCloudReceiveEvent(string i_mainKey)
        {
            try
            {
                for (int i = 0; i < this.ListCloudEvent.Count; i++)
                {
                    if (this.ListCloudEvent[i].MainKey == i_mainKey)
                    {
                        this.ListCloudEvent.RemoveAt(i);
                        i--;
                    }
                }
            }
            catch { }
        }
        #endregion
        #region ■ 结构体_____________________________
        /// <summary>
        /// 云端接收事件类
        /// </summary>
        private class CloudReceiveEventClass
        {
            /// <summary>
            /// 标识事件的主键(可以随便填,主要是针对多个界面一起使用的情况)
            /// </summary>
            public string MainKey = string.Empty;
            /// <summary>
            /// 云端接收事件(参数1:枚举 参数2:推送消息)
            /// </summary>
            public Action<CloudPushEnum, string> CloudReceiveEvent = null;
        }
        #endregion
    }
}
HDL_ON/UI/UI0-Stan/Logic/HdlWifiLogic.cs
New file
@@ -0,0 +1,99 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace HDL_ON.Stan
{
    /// <summary>
    /// WiFi的逻辑
    /// </summary>
    public class HdlWifiLogic
    {
        #region ■ 变量声明___________________________
        /// <summary>
        /// WiFi的逻辑
        /// </summary>
        private static HdlWifiLogic m_Current = null;
        /// <summary>
        /// WiFi的逻辑
        /// </summary>
        public static HdlWifiLogic Current
        {
            get
            {
                if (m_Current == null)
                {
                    m_Current = new HdlWifiLogic();
                }
                return m_Current;
            }
        }
        /// <summary>
        /// 当前wifi的SSID,也叫Wifi的名字(取不到时,会返回null)
        /// </summary>
        public string SSID
        {
            get
            {
#if __IOS__
                string ssiD = Shared.WiimuUPnP.SSID;
                if (string.IsNullOrEmpty(ssiD) == false && ssiD.StartsWith("\"") && ssiD.EndsWith("\""))
                {
                    ssiD = ssiD.Substring(1, ssiD.Length - 2);
                }
                return ssiD;
#endif
#if __Android__
                string ssiD = null;
                HdlThreadLogic.Current.RunThread(() =>
                {
                    Shared.Net.NetWiFi.GetWIFISSID((strId) =>
                    {
                        ssiD = strId;
                    });
                }, ShowErrorMode.NO);
                int count = 0;
                while (ssiD == null)
                {
                    System.Threading.Thread.Sleep(50);
                    count++;
                    if (count == 20)
                    {
                        //1秒超时
                        return null;
                    }
                }
                if (string.IsNullOrEmpty(ssiD) == false && ssiD.StartsWith("\"") && ssiD.EndsWith("\""))
                {
                    ssiD = ssiD.Substring(1, ssiD.Length - 2);
                }
                return ssiD;
#endif
            }
        }
        #endregion
        #region ■ 一般方法___________________________
        /// <summary>
        /// 打开手机wifi设置界面
        /// </summary>
        public void OpenAppWifiSettion()
        {
            if (Shared.Application.DeviceType == Shared.Device.Android)
            {
                ///打开WI-IF界面
                Shared.CommonClass.OpenAction("android.settings.WIFI_SETTINGS");
            }
            else
            {
                Shared.CommonClass.OpenAction("App-Prefs:root=WIFI");
            }
        }
        #endregion
    }
}
HDL_ON/UI/UI2/4-PersonalCenter/AddDevice/AddMiniRemoteControlDirection1Page.cs
New file
@@ -0,0 +1,80 @@
using HDL_ON.Stan;
using Shared;
using System;
using System.Collections.Generic;
using System.Text;
namespace HDL_ON.UI
{
    /// <summary>
    /// 添加Evoyo的Mini智能遥控器步骤1界面
    /// </summary>
    public class AddMiniRemoteControlDirection1Page : EditorCommonForm
    {
        #region ■ 变量声明___________________________
        #endregion
        #region ■ 初始化_____________________________
        /// <summary>
        /// 画面显示(底层会固定调用此方法,借以完成画面创建)
        /// </summary>
        public void ShowForm()
        {
            //设置头部信息
            base.SetTitleText(Language.StringByID(StringId.AddInfraredRemoteControl));
            //这个界面的背景需要白色
            bodyFrameLayout.BackgroundColor = UI.CSS.CSS_Color.MainBackgroundColor;
            //初始化中部信息
            this.InitMiddleFrame();
        }
        /// <summary>
        /// 初始化中部信息
        /// </summary>
        private void InitMiddleFrame()
        {
            //图片
            var btnPic = new PicViewControl(149, 95);
            btnPic.Y = Application.GetRealHeight(99);
            btnPic.Gravity = Gravity.CenterHorizontal;
            btnPic.UnSelectedImagePath = "PersonalCenter/AddDevice/MiniRemoteControlBigPictrue.png";
            bodyFrameLayout.AddChidren(btnPic);
            //长按红外遥控器按钮10秒,指示灯蓝色快闪
            var strMsg = Language.StringByID(StringId.AddInfraredRemoteControlMsg1);
            var intYY = this.AddListMsgControls(bodyFrameLayout, strMsg, CSS.CSS_FontSize.TextFontSize,
                CSS.CSS_Color.FirstLevelTitleColor, Application.GetRealHeight(20), Application.GetRealHeight(408));
            //请确保您的蓝牙已开启并处于可以被搜索状态
            strMsg = Language.StringByID(StringId.AddInfraredRemoteControlMsg2);
            this.AddListMsgControls(bodyFrameLayout, strMsg, CSS.CSS_FontSize.PromptFontSize_FirstLevel,
                CSS.CSS_Color.PromptingColor1, Application.GetRealHeight(18), intYY + Application.GetRealHeight(4));
            //下一步
            var btnNext = this.AddBottomClickButton(Language.StringByID(StringId.Next));
            btnNext.ButtonClickEvent += (sender, e) =>
            {
#if __IOS__
#endif
#if __Android__
                //检测蓝牙需要的东西
                HdlAndroidBluetoothLogic.Current.CheckCanScanBluetooth((result) =>
                {
                    if (result == true)
                    {
                        this.CloseForm();
                        var form = new AddMiniRemoteControlDirection2Page();
                        //wifi和密码都为空
                        form.AddForm();
                    }
                });
#endif
            };
        }
        #endregion
    }
}
HDL_ON/UI/UI2/4-PersonalCenter/AddDevice/AddMiniRemoteControlDirection2Page.cs
New file
@@ -0,0 +1,242 @@
using HDL_ON.Stan;
using Shared;
using System;
using System.Collections.Generic;
using System.Text;
namespace HDL_ON.UI
{
    /// <summary>
    /// 添加Evoyo的Mini智能遥控器步骤2界面
    /// </summary>
    public class AddMiniRemoteControlDirection2Page : EditorCommonForm
    {
        #region ■ 变量声明___________________________
        #endregion
        #region ■ 初始化_____________________________
        /// <summary>
        /// 画面显示(底层会固定调用此方法,借以完成画面创建)
        /// </summary>
        public void ShowForm()
        {
            //设置头部信息
            base.SetTitleText(Language.StringByID(StringId.AddInfraredRemoteControl));
            //这个界面的背景需要白色
            bodyFrameLayout.BackgroundColor = UI.CSS.CSS_Color.MainBackgroundColor;
            //初始化中部信息
            this.InitMiddleFrame();
        }
        /// <summary>
        /// 初始化中部信息
        /// </summary>
        private void InitMiddleFrame()
        {
            //清空body
            this.ClearBodyFrame();
            //进度条
            var btnProgress = new ProgressRowBar(180, 6);
            btnProgress.Y = Application.GetRealHeight(218);
            btnProgress.Gravity = Gravity.CenterHorizontal;
            bodyFrameLayout.AddChidren(btnProgress);
            btnProgress.StartMode1(true);
            //设备搜索中...
            var btnSearch = new NormalViewControl(bodyFrameLayout.Width, Application.GetRealHeight(20), false);
            btnSearch.Y = btnProgress.Bottom + Application.GetRealHeight(40);
            btnSearch.TextColor = CSS.CSS_Color.FirstLevelTitleColor;
            btnSearch.TextID = StringId.SearchingDevice;
            btnSearch.TextAlignment = TextAlignment.Center;
            bodyFrameLayout.AddChidren(btnSearch);
            //请确保您的蓝牙已开启并处于可以被搜索状态
            var strMsg = Language.StringByID(StringId.AddInfraredRemoteControlMsg2);
            this.AddListMsgControls(bodyFrameLayout, strMsg, CSS.CSS_FontSize.TextFontSize,
                CSS.CSS_Color.FirstLevelTitleColor, Application.GetRealHeight(20), btnSearch.Bottom + Application.GetRealHeight(4));
            //搜索时间(秒)
            int searchTime = 5;
#if __IOS__
#endif
#if __Android__
            //安卓搜索蓝牙(特效问题,加1秒)
            this.StartSearchBluetoothOnAndriod(searchTime + 1);
#endif
            HdlThreadLogic.Current.RunThread(() =>
            {
                //进度条特效
                for (int i = 0; i <= searchTime; i++)
                {
                    HdlThreadLogic.Current.RunMain(() =>
                    {
                        btnProgress.SetValue(i + 1, searchTime);
                    });
                    System.Threading.Thread.Sleep(1000);
                }
            });
        }
        #endregion
        #region ■ 安卓搜索蓝牙_______________________
#if __Android__
        /// <summary>
        /// 安卓搜索蓝牙
        /// </summary>
        /// <param name="i_searchTime">搜索时间(秒)</param>
        private void StartSearchBluetoothOnAndriod(int i_searchTime)
        {
            //开始搜索蓝牙
            HdlAndroidBluetoothLogic.Current.ScanBluetooth(i_searchTime, (listBluetooth) =>
            {
                var listDevice = new List<HdlAndroidBluetoothLogic.BluetoothInfo>();
                foreach (var device in listBluetooth)
                {
                    //只有这个标识,才是红外宝
                    if (device.Name.StartsWith("MIR01R-LK.10") == true)
                    {
                        //是指定的红外宝设备
                        listDevice.Add(device);
                    }
                }
                if (listDevice.Count == 0)
                {
                    //摧毁蓝牙缓存
                    HdlAndroidBluetoothLogic.Current.Dispone();
                    //显示失败界面
                    HdlThreadLogic.Current.RunMain(() =>
                    {
                        this.ShowFailView();
                    });
                }
                else if (listDevice.Count == 1)
                {
                    //如果只检测到一个,则直接连接
                    HdlAndroidBluetoothLogic.Current.ContectBluetooth(listDevice[0], (result) =>
                    {
                        if (result == true)
                        {
                            //连接成功,则跳转到下一个界面
                            HdlThreadLogic.Current.RunMain(() =>
                            {
                                this.CloseForm();
                                var form = new AddMiniRemoteControlDirection3Page();
                                form.AddForm();
                            });
                        }
                    });
                }
                else
                {
                    var listName = new List<string>();
                    foreach (var device in listDevice)
                    {
                        listName.Add(device.Name);
                    }
                    //显示选择蓝牙列表的界面(当匹配到多个蓝牙的时候使用)
                    this.ShowBluetoothListView(listName, (index) =>
                    {
                        //如果只检测到一个,则直接连接
                        HdlAndroidBluetoothLogic.Current.ContectBluetooth(listDevice[index], (result) =>
                        {
                            if (result == true)
                            {
                                //连接成功,则跳转到下一个界面
                                HdlThreadLogic.Current.RunMain(() =>
                                {
                                    this.CloseForm();
                                    var form = new AddMiniRemoteControlDirection3Page();
                                    form.AddForm();
                                });
                            }
                        });
                    });
                }
            });
        }
#endif
        #endregion
        #region ■ 显示选择蓝牙列表的界面_____________
        /// <summary>
        /// 显示选择蓝牙列表的界面(当匹配到多个蓝牙的时候使用)
        /// </summary>
        /// <param name="listName">蓝牙名字列表</param>
        /// <param name="selectEvent">选择事件(考虑到Ios和安卓,所以这样定参数)</param>
        private void ShowBluetoothListView(List<string> listName, Action<int> selectEvent)
        {
            HdlThreadLogic.Current.RunMain(() =>
            {
                var contr = new BottomItemSelectControl(listName.Count, Language.StringByID(StringId.ChooseInfraredRemoteControl), false);
                //初始化
                contr.AddRowMenu(listName, new List<int>());
                contr.FinishOnlyEvent += (div, value) =>
                {
                    if (div == 0)
                    {
                        //如果点击了取消,则关闭这个界面,不管了
                        this.CloseForm();
                    }
                    else
                    {
                        //调用回调函数
                        selectEvent?.Invoke(value);
                    }
                };
            });
        }
        #endregion
        #region ■ 显示失败界面_______________________
        /// <summary>
        /// 显示失败界面
        /// </summary>
        private void ShowFailView()
        {
            //清空body
            this.ClearBodyFrame();
            //图片
            var btnPic = new PicViewControl(180, 180);
            btnPic.Y = Application.GetRealHeight(48);
            btnPic.Gravity = Gravity.CenterHorizontal;
            btnPic.UnSelectedImagePath = "Public/TipIcon_Failed.png";
            bodyFrameLayout.AddChidren(btnPic);
            //没有发现红外遥控器
            var btnMsgNot = new NormalViewControl(bodyFrameLayout.Width, Application.GetRealHeight(22), false);
            btnMsgNot.Y = btnPic.Bottom + Application.GetRealHeight(16);
            btnMsgNot.TextAlignment = TextAlignment.Center;
            btnMsgNot.TextColor = CSS.CSS_Color.AuxiliaryColor2;
            btnMsgNot.TextSize = CSS.CSS_FontSize.SubheadingFontSize;
            btnMsgNot.TextID = StringId.NoInfraredRemoteControlFound;
            bodyFrameLayout.AddChidren(btnMsgNot);
            //1、请检查设备是否正常通电
            //2、请检查蓝牙功能是否正常开启
            //3、请检查指示灯是否蓝色快闪状态
            var strMsg = Language.StringByID(StringId.AddInfraredRemoteControlMsg3);
            this.AddListMsgControls(bodyFrameLayout, strMsg, CSS.CSS_FontSize.TextFontSize,
                CSS.CSS_Color.TextualColor, Application.GetRealHeight(20), btnMsgNot.Bottom + Application.GetRealHeight(8),
                 TextAlignment.Center, true);
            //重新搜索
            var btnReSearch = this.AddBottomClickButton(Language.StringByID(StringId.ReSearch));
            btnReSearch.ButtonClickEvent += (sender, e) =>
            {
                //初始化中部信息
                this.InitMiddleFrame();
            };
        }
        #endregion
    }
}
HDL_ON/UI/UI2/4-PersonalCenter/AddDevice/AddMiniRemoteControlDirection3Page.cs
New file
@@ -0,0 +1,173 @@
using HDL_ON.Stan;
using Shared;
using System;
using System.Collections.Generic;
using System.Text;
namespace HDL_ON.UI
{
    /// <summary>
    /// 添加Evoyo的Mini智能遥控器步骤3界面
    /// </summary>
    public class AddMiniRemoteControlDirection3Page : EditorCommonForm
    {
        #region ■ 变量声明___________________________
        /// <summary>
        /// 当前wifi的名字
        /// </summary>
        private string NowWifiName = string.Empty;
        /// <summary>
        /// wifi的线程是否启动
        /// </summary>
        private bool WifiThreadAction = false;
        #endregion
        #region ■ 初始化_____________________________
        /// <summary>
        /// 画面显示(底层会固定调用此方法,借以完成画面创建)
        /// </summary>
        public void ShowForm()
        {
            //设置头部信息
            base.SetTitleText(Language.StringByID(StringId.AddInfraredRemoteControl));
            //这个界面的背景需要白色
            bodyFrameLayout.BackgroundColor = UI.CSS.CSS_Color.MainBackgroundColor;
            //初始化中部信息
            this.InitMiddleFrame();
        }
        /// <summary>
        /// 初始化中部信息
        /// </summary>
        private void InitMiddleFrame()
        {
            //连接WiFi
            var btnWifi = new NormalViewControl(200, 28, true);
            btnWifi.X = HdlControlResourse.XXLeft;
            btnWifi.Y = Application.GetRealHeight(16);
            btnWifi.IsBold = true;
            btnWifi.TextColor = CSS.CSS_Color.FirstLevelTitleColor;
            btnWifi.TextSize = CSS.CSS_FontSize.EmphasisFontSize_Secondary;
            btnWifi.TextID = StringId.ConnectWiFi;
            bodyFrameLayout.AddChidren(btnWifi);
            //目前只支持2.4G WiFi网络
            //暂不支持带有中文字符的WiFi名称
            var strMsg = Language.StringByID(StringId.AddInfraredRemoteControlMsg4);
            int yy = this.AddListMsgControls(bodyFrameLayout, strMsg, CSS.CSS_FontSize.TextFontSize, CSS.CSS_Color.TextualColor,
                Application.GetRealHeight(20), btnWifi.Bottom + Application.GetRealHeight(16), TextAlignment.CenterLeft);
            //wifi行
            var rowWifi = new RowLayoutControl();
            rowWifi.Y = yy + Application.GetRealHeight(32);
            bodyFrameLayout.AddChidren(rowWifi);
            //wifi名字
            var txtWifi = rowWifi.frameTable.AddLeftInput("", 200);
            txtWifi.TextColor = CSS.CSS_Color.FirstLevelTitleColor;
            //底线
            rowWifi.frameTable.AddBottomLine();
            //向右图标
            var btnRight = rowWifi.frameTable.AddMostRightEmptyIcon(24, 24);
            btnRight.UnSelectedImagePath = "Public/Right.png";
            btnRight.ButtonClickEvent += (sender, e) =>
            {
                //打开手机wifi设置界面
                HdlWifiLogic.Current.OpenAppWifiSettion();
                //刷新wifi名字
                this.RefreshWifiName(txtWifi);
            };
            //密码行
            var rowPsw = new RowLayoutControl();
            rowPsw.Y = rowWifi.Bottom;
            bodyFrameLayout.AddChidren(rowPsw);
            //密码
            var txtPsw = rowPsw.frameTable.AddLeftInput("551775569", 200);
            txtPsw.TextColor = CSS.CSS_Color.FirstLevelTitleColor;
            txtPsw.PlaceholderText = Language.StringByID(StringId.Password);
            txtPsw.SecureTextEntry = true;
            //底线
            rowPsw.frameTable.AddBottomLine();
            //眼睛图标
            var btnView = rowPsw.frameTable.AddMostRightEmptyIcon(24, 24);
            btnView.UnSelectedImagePath = "LoginIcon/HidePasswordIcon.png";
            btnView.SelectedImagePath = "LoginIcon/ShowPasswordIcon.png";
            btnView.ButtonClickEvent += (sender, e) =>
            {
                btnView.IsSelected = !btnView.IsSelected;
                txtPsw.SecureTextEntry = !btnView.IsSelected;
            };
            //下一步
            var btnNext = this.AddBottomClickButton(Language.StringByID(StringId.Next));
            btnNext.ButtonClickEvent += (sender, e) =>
            {
                if (txtWifi.Text.Trim() == string.Empty || txtPsw.Text.Trim() == string.Empty)
                {
                    return;
                }
                //进入下一个界面
                this.CloseForm();
                var form = new AddMiniRemoteControlDirection4Page();
                form.AddForm(txtWifi.Text.Trim(), txtPsw.Text);
            };
            HdlThreadLogic.Current.RunThread(() =>
            {
                //打开进度条,卡它一下
                this.ShowProgressBar();
                //获取当前wifi名字(里面可能会卡)
                this.NowWifiName = HdlWifiLogic.Current.SSID;
                HdlThreadLogic.Current.RunMain(() =>
                {
                    txtWifi.Text = NowWifiName;
                });
                this.CloseProgressBar();
            });
        }
        #endregion
        #region ■ 一般方法___________________________
        /// <summary>
        /// 刷新wifi名字
        /// </summary>
        private void RefreshWifiName(TextInputControl textInput)
        {
            if (this.WifiThreadAction == true) { return; }
            this.WifiThreadAction = true;
            HdlThreadLogic.Current.RunThread(() =>
            {
                //这个线程不会被中断
                while (this.Parent != null)
                {
                    System.Threading.Thread.Sleep(1500);
                    string wifiName = string.Empty;
                    try
                    {
                        //获取当前wifi名字(里面可能会卡)
                        wifiName = HdlWifiLogic.Current.SSID;
                    }
                    catch { continue; }
                    if (wifiName != this.NowWifiName)
                    {
                        this.NowWifiName = wifiName;
                        HdlThreadLogic.Current.RunMain(() =>
                        {
                            textInput.Text = this.NowWifiName;
                        });
                    }
                }
            });
        }
        #endregion
    }
}
HDL_ON/UI/UI2/4-PersonalCenter/AddDevice/AddMiniRemoteControlDirection4Page.cs
New file
@@ -0,0 +1,424 @@
using HDL_ON.Stan;
using Shared;
using System;
using System.Collections.Generic;
using System.Text;
namespace HDL_ON.UI
{
    /// <summary>
    /// 添加Evoyo的Mini智能遥控器步骤4界面
    /// </summary>
    public class AddMiniRemoteControlDirection4Page : EditorCommonForm
    {
        #region ■ 变量声明___________________________
        /// <summary>
        /// wifi名字
        /// </summary>
        private string wifiName = string.Empty;
        /// <summary>
        /// wifi密码
        /// </summary>
        private string wifiPsw = string.Empty;
        /// <summary>
        /// 超时线程是否运行
        /// </summary>
        private bool timeoutThreadActivity = false;
        /// <summary>
        /// 上传到云的图标
        /// </summary>
        private IconViewControl btnClound = null;
        /// <summary>
        /// 上传到云
        /// </summary>
        private NormalViewControl btnCloundView = null;
        /// <summary>
        /// 连接成功的图标
        /// </summary>
        private IconViewControl btnConnect = null;
        /// <summary>
        /// 连接成功
        /// </summary>
        private NormalViewControl btnConnetView = null;
        #endregion
        #region ■ 初始化_____________________________
        /// <summary>
        /// 画面显示(底层会固定调用此方法,借以完成画面创建)
        /// </summary>
        /// <param name="i_wifiName">wifi名字</param>
        /// <param name="i_wifiPsw">wifi密码</param>
        public void ShowForm(string i_wifiName, string i_wifiPsw)
        {
            this.wifiName = i_wifiName;
            this.wifiPsw = i_wifiPsw;
            //设置头部信息
            base.SetTitleText(Language.StringByID(StringId.AddInfraredRemoteControl));
            //这个界面的背景需要白色
            bodyFrameLayout.BackgroundColor = UI.CSS.CSS_Color.MainBackgroundColor;
            //添加接收蓝牙反馈的事件
            HdlAndroidBluetoothLogic.Current.AddReceiveEvent(this.BluetoothReceiveEvent);
            //添加云端反馈事件
            HdlCloudReceiveLogic.Current.AddCloudReceiveEvent("AddMiniRemoteControlDirection4Page", this.CloudReceiveEvent);
            //初始化中部信息
            this.InitMiddleFrame();
        }
        /// <summary>
        /// 初始化中部信息
        /// </summary>
        private void InitMiddleFrame()
        {
            //清空body
            this.ClearBodyFrame();
            //图片
            var btnPic = new PicViewControl(282, 121);
            btnPic.Y = Application.GetRealHeight(122);
            btnPic.Gravity = Gravity.CenterHorizontal;
            btnPic.UnSelectedImagePath = "PersonalCenter/AddDevice/WifiAndPhoneConnect.png";
            bodyFrameLayout.AddChidren(btnPic);
            //正在连接中...
            var btnSearch = new NormalViewControl(bodyFrameLayout.Width, Application.GetRealHeight(20), false);
            btnSearch.Y = btnPic.Bottom + Application.GetRealHeight(40);
            btnSearch.TextColor = CSS.CSS_Color.FirstLevelTitleColor;
            btnSearch.TextID = StringId.NowConnectting;
            btnSearch.TextAlignment = TextAlignment.Center;
            bodyFrameLayout.AddChidren(btnSearch);
            //请让红外遥控尽量接近WIFI路由器
            var strMsg = Language.StringByID(StringId.AddInfraredRemoteControlMsg5);
            this.AddListMsgControls(bodyFrameLayout, strMsg, CSS.CSS_FontSize.TextFontSize,
                CSS.CSS_Color.PromptingColor1, Application.GetRealHeight(20), btnSearch.Bottom + Application.GetRealHeight(4));
            //网络连接中
            var btnNetIcon = new IconViewControl(20);
            btnNetIcon.X = Application.GetRealWidth(60);
            btnNetIcon.Y = btnPic.Bottom + Application.GetRealHeight(265);
            btnNetIcon.UnSelectedImagePath = "PersonalCenter/AddDevice/NetConnectSelect.png";
            bodyFrameLayout.AddChidren(btnNetIcon);
            var btnNetView = new NormalViewControl(140, 18, true);//左右间距40再加文本60
            btnNetView.Y = btnNetIcon.Bottom + Application.GetRealHeight(16);
            btnNetView.TextSize = CSS.CSS_FontSize.PromptFontSize_FirstLevel;
            btnNetView.TextColor = CSS.CSS_Color.FirstLevelTitleColor;
            btnNetView.TextAlignment = TextAlignment.Center;
            btnNetView.TextID = StringId.InTheNetworkLink;
            bodyFrameLayout.AddChidren(btnNetView);
            //一条横线
            var btnLine1 = new NormalViewControl(Application.GetRealWidth(92), 2, false);
            btnLine1.X = btnNetIcon.Right + Application.GetRealWidth(3);
            btnLine1.Y = btnNetIcon.Y + (btnNetIcon.Height + 2) / 2;
            btnLine1.BackgroundColor = CSS.CSS_Color.PromptingColor1;
            bodyFrameLayout.AddChidren(btnLine1);
            //上传到云
            this.btnClound = new IconViewControl(20);
            btnClound.Gravity = Gravity.CenterHorizontal;
            btnClound.Y = btnNetIcon.Y;
            btnClound.UnSelectedImagePath = "PersonalCenter/AddDevice/UploadToClound.png";
            btnClound.SelectedImagePath = "PersonalCenter/AddDevice/UploadToCloundSelect.png";
            bodyFrameLayout.AddChidren(btnClound);
            this.btnCloundView = new NormalViewControl(btnNetView.Width, btnNetView.Height, false);
            btnCloundView.Y = btnNetView.Y;
            btnCloundView.Gravity = Gravity.CenterHorizontal;
            btnCloundView.TextSize = CSS.CSS_FontSize.PromptFontSize_FirstLevel;
            btnCloundView.TextColor = CSS.CSS_Color.PromptingColor1;
            btnCloundView.TextAlignment = TextAlignment.Center;
            btnCloundView.TextID = StringId.UploadToCloud;
            bodyFrameLayout.AddChidren(btnCloundView);
            //一条横线
            var btnLine2 = new NormalViewControl(btnLine1.Width, btnLine1.Height, false);
            btnLine2.X = btnClound.Right + Application.GetRealWidth(3);
            btnLine2.Y = btnLine1.Y;
            btnLine2.BackgroundColor = CSS.CSS_Color.PromptingColor1;
            bodyFrameLayout.AddChidren(btnLine2);
            //连接成功
            this.btnConnect = new IconViewControl(20);
            btnConnect.X = bodyFrameLayout.Width - btnNetIcon.X - btnConnect.IconSize;
            btnConnect.Y = btnNetIcon.Y;
            btnConnect.UnSelectedImagePath = "PersonalCenter/AddDevice/ConnectSuccess.png";
            btnConnect.SelectedImagePath = "PersonalCenter/AddDevice/ConnectSuccessSelect.png";
            bodyFrameLayout.AddChidren(btnConnect);
            this.btnConnetView = new NormalViewControl(btnNetView.Width, btnNetView.Height, false);
            btnConnetView.X = bodyFrameLayout.Width - btnNetView.Width - btnNetView.X;
            btnConnetView.Y = btnNetView.Y;
            btnConnetView.TextSize = CSS.CSS_FontSize.PromptFontSize_FirstLevel;
            btnConnetView.TextColor = CSS.CSS_Color.PromptingColor1;
            btnConnetView.TextAlignment = TextAlignment.Center;
            btnConnetView.TextID = StringId.ConnectSuccess;
            bodyFrameLayout.AddChidren(btnConnetView);
            HdlThreadLogic.Current.RunThread(() =>
            {
                System.Threading.Thread.Sleep(2000);
                HdlThreadLogic.Current.RunMain(() =>
                {
                    //发送账号和密码给蓝牙
                    this.SendAccountAndPswToBluetooth();
                });
                //启动超时线程
                this.StartTimeoutThread();
            });
        }
        #endregion
        #region ■ 显示成功界面_______________________
        /// <summary>
        /// 显示成功界面
        /// </summary>
        private void ShowSuccessView()
        {
            //清空body
            this.ClearBodyFrame();
            //图片
            var btnPic = new PicViewControl(180, 180);
            btnPic.Y = Application.GetRealHeight(48);
            btnPic.Gravity = Gravity.CenterHorizontal;
            btnPic.UnSelectedImagePath = "Public/TipIcon_Successfully.png";
            bodyFrameLayout.AddChidren(btnPic);
            //添加成功
            var btnFail = new NormalViewControl(bodyFrameLayout.Width, Application.GetRealHeight(22), false);
            btnFail.Y = btnPic.Bottom + Application.GetRealHeight(16);
            btnFail.TextSize = CSS.CSS_FontSize.SubheadingFontSize;
            btnFail.TextColor = CSS.CSS_Color.MainColor;
            btnFail.TextAlignment = TextAlignment.Center;
            btnFail.TextID = StringId.AddSuccess;
            bodyFrameLayout.AddChidren(btnFail);
            //可以开始使用红外遥控功能!
            var strMsg = Language.StringByID(StringId.AddInfraredRemoteControlMsg7);
            int yy = this.AddListMsgControls(bodyFrameLayout, strMsg, CSS.CSS_FontSize.TextFontSize, CSS.CSS_Color.TextualColor,
                Application.GetRealHeight(20), btnFail.Bottom + Application.GetRealHeight(8));
            //开始使用
            var btnUse = new BottomClickButton(220);
            btnUse.Y = yy + Application.GetRealHeight(60);
            btnUse.TextID = StringId.StartUse;
            bodyFrameLayout.AddChidren(btnUse);
            btnUse.ButtonClickEvent += (sender, e) =>
            {
            };
        }
        #endregion
        #region ■ 显示失败界面_______________________
        /// <summary>
        /// 显示失败界面
        /// </summary>
        private void ShowFailView()
        {
            //清空body
            this.ClearBodyFrame();
            //图片
            var btnPic = new PicViewControl(180, 180);
            btnPic.Y = Application.GetRealHeight(48);
            btnPic.Gravity = Gravity.CenterHorizontal;
            btnPic.UnSelectedImagePath = "Public/TipIcon_Failed.png";
            bodyFrameLayout.AddChidren(btnPic);
            //添加失败
            var btnFail = new NormalViewControl(bodyFrameLayout.Width, Application.GetRealHeight(22), false);
            btnFail.Y = btnPic.Bottom + Application.GetRealHeight(16);
            btnFail.TextSize = CSS.CSS_FontSize.SubheadingFontSize;
            btnFail.TextColor = CSS.CSS_Color.AuxiliaryColor2;
            btnFail.TextAlignment = TextAlignment.Center;
            btnFail.TextID = StringId.AddFail;
            bodyFrameLayout.AddChidren(btnFail);
            //1、请检查设备是否正常通电
            //2、请开启蓝牙功能
            //3、并长按按钮10s,指示灯常亮
            var strMsg = Language.StringByID(StringId.AddInfraredRemoteControlMsg6);
            this.AddListMsgControls(bodyFrameLayout, strMsg, CSS.CSS_FontSize.TextFontSize, CSS.CSS_Color.TextualColor,
                Application.GetRealHeight(20), btnFail.Bottom + Application.GetRealHeight(8),
                 TextAlignment.Center, true);
            //重试
            var btnReDo = this.AddBottomClickButton(Language.StringByID(StringId.Retry));
            btnReDo.ButtonClickEvent += (sender, e) =>
            {
                //重新初始化中部信息
                this.InitMiddleFrame();
            };
        }
        #endregion
        #region ■ 发送账号和密码给蓝牙_______________
#if __IOS__
#endif
#if __Android__
        /// <summary>
        /// 发送账号和密码给蓝牙
        /// </summary>
        private void SendAccountAndPswToBluetooth()
        {
            //获取发送到蓝牙的数据
            var sendData = this.GetSendToBluetoothData();
            //不等待
            HdlAndroidBluetoothLogic.Current.SendData(sendData);
        }
#endif
        #endregion
        #region ■ 云端反馈___________________________
        /// <summary>
        /// 云端反馈
        /// </summary>
        /// <param name="pushEnum">枚举</param>
        /// <param name="i_data">推送的内容</param>
        private void CloudReceiveEvent(CloudPushEnum pushEnum, string i_data)
        {
            if (pushEnum != CloudPushEnum.A新设备上报) { return; }
            //接收到就移除这个事件
            HdlCloudReceiveLogic.Current.RemoveCloudReceiveEvent("AddMiniRemoteControlDirection4Page");
            //停止线程
            this.timeoutThreadActivity = false;
            //添加设备成功之后,处理一些东西
            this.DoSomethingAfterAddDeviceSuccess();
        }
        /// <summary>
        /// 添加设备成功之后,处理一些东西
        /// </summary>
        private void DoSomethingAfterAddDeviceSuccess()
        {
            HdlThreadLogic.Current.RunThread(() =>
            {
                //整点特效而已
                for (int i = 1; i <= 6; i++)
                {
                    System.Threading.Thread.Sleep(1000);
                    if (i == 1)
                    {
                        HdlThreadLogic.Current.RunMain(() =>
                        {
                            //整点特效而已
                            this.btnClound.IsSelected = true;
                            this.btnCloundView.TextColor = CSS.CSS_Color.FirstLevelTitleColor;
                        });
                    }
                    else if (i == 4)
                    {
                        HdlThreadLogic.Current.RunMain(() =>
                        {
                            //整点特效而已
                            this.btnConnect.IsSelected = true;
                            this.btnConnetView.TextColor = CSS.CSS_Color.FirstLevelTitleColor;
                        });
                    }
                    else if (i == 6)
                    {
                        HdlThreadLogic.Current.RunMain(() =>
                        {
                            //显示成功界面
                            this.ShowSuccessView();
                        });
                    }
                }
            });
        }
        #endregion
        #region ■ 蓝牙反馈___________________________
        /// <summary>
        /// 蓝牙反馈
        /// </summary>
        /// <param name="i_receviceData">蓝牙反馈的数据</param>
        private void BluetoothReceiveEvent(string i_receviceData)
        {
#if DEBUG
            System.Console.WriteLine("蓝牙返回:" + i_receviceData);
#endif
        }
        #endregion
        #region ■ 超时线程___________________________
        /// <summary>
        /// 启动超时线程
        /// </summary>
        private void StartTimeoutThread()
        {
            HdlThreadLogic.Current.RunThread(() =>
            {
                //300秒超时
                int timeout = 300;
                while (this.timeoutThreadActivity == false && this.Parent != null)
                {
                    System.Threading.Thread.Sleep(1000);
                    timeout--;
                    if (timeout == 0)
                    {
                        break;
                    }
                }
                if (timeout <= 0)
                {
                    //显示失败界面
                    HdlThreadLogic.Current.RunMain(() =>
                    {
                        this.ShowFailView();
                    });
                }
            });
        }
        #endregion
        #region ■ 界面关闭___________________________
        /// <summary>
        /// 界面关闭
        /// </summary>
        public override void CloseFormBefore()
        {
            //摧毁蓝牙
            HdlAndroidBluetoothLogic.Current.Dispone();
            HdlCloudReceiveLogic.Current.RemoveCloudReceiveEvent("AddMiniRemoteControlDirection4Page");
            base.CloseFormBefore();
        }
        #endregion
        #region ■ 一般方法___________________________
        /// <summary>
        /// 获取发送到蓝牙的数据
        /// </summary>
        /// <returns></returns>
        private string GetSendToBluetoothData()
        {
            var pra = new { id = "id010203", ssid = this.wifiName, password = this.wifiPsw };
            var praData = Newtonsoft.Json.JsonConvert.SerializeObject(pra);
            var sendData = "Topic:/user/id/custom/wifi/set\r\n";
            sendData += "Length:" + praData.Length + "\r\n\r\n";
            sendData += praData;
            return sendData;
        }
        #endregion
    }
}
HDL_ON/UI/UI2/4-PersonalCenter/AddDevice/AddThirdPartyDeviceMenuListPage.cs
New file
@@ -0,0 +1,92 @@
using HDL_ON.Stan;
using Shared;
using System;
using System.Collections.Generic;
using System.Text;
namespace HDL_ON.UI
{
    /// <summary>
    /// 添加第三方设备的菜单列表界面
    /// </summary>
    public class AddThirdPartyDeviceMenuListPage : EditorCommonForm
    {
        #region ■ 变量声明___________________________
        #endregion
        #region ■ 初始化_____________________________
        /// <summary>
        /// 画面显示(底层会固定调用此方法,借以完成画面创建)
        /// </summary>
        /// <param name="i_div">
        /// <para>Evoyo:Evoyo的设备</para>
        /// <para>Yingshi:萤石设备</para>
        /// <para>Tuya:涂鸦设备</para></param>
        public void ShowForm(string i_div)
        {
            //设置头部信息
            base.SetTitleText(Language.StringByID(StringId.AddDevice));
            //初始化中部信息
            this.InitMiddleFrame(i_div);
        }
        /// <summary>
        /// 初始化中部信息
        /// </summary>
        private void InitMiddleFrame(string i_div)
        {
            //列表容器
            var listView = new VerticalListControl();
            listView.BackgroundColor = CSS.CSS_Color.MainBackgroundColor;
            listView.Height = bodyFrameLayout.Height;
            bodyFrameLayout.AddChidren(listView);
            //Evoyo的设备
            if (i_div == "Evoyo")
            {
                //初始化Evoyo设备菜单
                this.InitEvoyoDeviceListMenu(listView);
            }
            //萤石设备
            else if (i_div == "Yingshi")
            {
            }
            //涂鸦设备
            else if (i_div == "Tuya")
            {
            }
        }
        #endregion
        #region ■ 初始化Evoyo设备菜单________________
        /// <summary>
        /// 初始化Evoyo设备菜单
        /// </summary>
        /// <param name="listView"></param>
        private void InitEvoyoDeviceListMenu(VerticalListControl listView)
        {
            //mini智能遥控器
            var rowMini = new RowLayoutControl();
            listView.AddChidren(rowMini);
            rowMini.frameTable.AddLeftIcon(32, "PersonalCenter/AddDevice/MiniRemoteControlMenuIcon.png");
            var btnMiniView = rowMini.frameTable.AddLeftCaption(Language.StringByID(StringId.MiniIntelligentRemoteControl), 200);
            btnMiniView.TextColor = CSS.CSS_Color.FirstLevelTitleColor;
            rowMini.frameTable.AddRightArrow();
            rowMini.frameTable.ButtonClickEvent += (sender, e) =>
            {
                var form = new AddMiniRemoteControlDirection1Page();
                form.AddForm();
            };
            //调整桌布真实高度
            listView.AdjustRealHeight(0);
        }
        #endregion
    }
}
HDL_ON/UI/UI2/FuntionControlView/Electrical/TuyaAirCleanerPage.cs
@@ -328,7 +328,7 @@
            rowReset.Height = Application.GetRealHeight(50);
            rowReset.Width = FrameWhiteCentet2.Width;
            rowReset.Y = rowAnion.Bottom;
            FrameWhiteCentet2.AddChidren(rowReset);
            //FrameWhiteCentet2.AddChidren(rowReset);
            rowReset.AddLeftCaption(Language.StringByID(StringId.FilterElementReset), 200);
            rowReset.AddBottomLine();
            rowReset.AddRightArrow();