《第一个程序》记UDP Sender 2.0

本文介绍了如何在Android应用中防止软键盘弹出时界面整体上移的方法,并提供了一个简单的Intent返回机制,使得从Activity B返回Activity A后,再次按下返回键不会重新进入Activity B。

1.防止弹出软键盘后界面整体上移:

在AndroidManifest.xml中的activity中加入:android:windowSoftInputMode="adjustResize|stateHidden"

如下:

<activity
            android:name=".MainActivity"
            <span style="background-color: rgb(255, 0, 0);">android:windowSoftInputMode="adjustResize|stateHidden"></span>
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

2.从activity A中Intent到B,结束activityB返回A时,直接调用activityB.this.finish(),返回A后按返回键就不会再返回B了。不需要再B中IntentA
在MainWindow.xaml.cs里面有如下代码:namespace OmniTool { public partial class MainWindow : Window {private void MainWindow_Loaded(object sender, RoutedEventArgs e) { InitializeData(); SetupListViewDragDrop(); InitializeSimulatedData(); // 初始化模拟数据 // _a2lEngine = new A2LEngine.A2LEngine(); // 初始化 A2L 引擎 }}} 在该工程的UDPByteParsing.cs中有如下代码:using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace OmniTool.UDPByte { public class UDPByteParsing { private List<byte[]> _simulatedDataList = new List<byte[]>(); private void InitializeSimSulatedData() { // 这里添加多组模拟字节数据 // 示例数据1 - 包含4个Value byte[] data1 = { 0x12, 0x34, // MagicNumber 0x11, // Ver(0x1) + BlockCount(0x1) 0x01, // FrameType 0x00, // Flags 0x00, 0x01, // GlobalSequence 0x00, 0x00, 0x00, 0x01, // GlobalTimestamp // Block 1 0x01, // BlockId 0x0A, // Period 0x84, // EndFlag(1) + VarCount(4) 0x00, 0x00, 0x00, 0x0A, // BlockTimestamp 0x3F, 0x80, 0x00, 0x00, // Value 1 (1.0f as IEEE754) 0x40, 0x00, 0x00, 0x00, // Value 2 (2.0f as IEEE754) 0x40, 0x40, 0x00, 0x00, // Value 3 (3.0f as IEEE754) 0x40, 0x80, 0x00, 0x00, // Value 4 (4.0f as IEEE754) // CRC32 (这里需要计算正确的CRC,此处为示例) 0x12, 0x34, 0x56, 0x78 }; // 示例数据2 - 包含3个Value byte[] data2 = { 0x12, 0x34, // MagicNumber 0x11, // Ver(0x1) + BlockCount(0x1) 0x01, // FrameType 0x00, // Flags 0x00, 0x02, // GlobalSequence 0x00, 0x00, 0x00, 0x02, // GlobalTimestamp // Block 1 0x01, // BlockId 0x0A, // Period 0x83, // EndFlag(1) + VarCount(3) 0x00, 0x00, 0x00, 0x14, // BlockTimestamp 0x3F, 0xC0, 0x00, 0x00, // Value 1 (1.5f as IEEE754) 0x40, 0x20, 0x00, 0x00, // Value 2 (2.5f as IEEE754) 0x40, 0x60, 0x00, 0x00, // Value 3 (3.5f as IEEE754) // CRC32 0x12, 0x34, 0x56, 0x79 }; // 示例数据3 - 包含5个Value byte[] data3 = { 0x12, 0x34, // MagicNumber 0x11, // Ver(0x1) + BlockCount(0x1) 0x01, // FrameType 0x00, // Flags 0x00, 0x03, // GlobalSequence 0x00, 0x00, 0x00, 0x03, // GlobalTimestamp // Block 1 0x01, // BlockId 0x0A, // Period 0x85, // EndFlag(1) + VarCount(5) 0x00, 0x00, 0x00, 0x1E, // BlockTimestamp 0x3F, 0x80, 0x00, 0x00, // Value 1 (1.0f as IEEE754) 0x40, 0x00, 0x00, 0x00, // Value 2 (2.0f as IEEE754) 0x40, 0x40, 0x00, 0x00, // Value 3 (3.0f as IEEE754) 0x40, 0x80, 0x00, 0x00, // Value 4 (4.0f as IEEE754) 0x40, 0xA0, 0x00, 0x00, // Value 5 (5.0f as IEEE754) // CRC32 0x12, 0x34, 0x56, 0x7A }; _simulatedDataList.Add(data1); _simulatedDataList.Add(data2); _simulatedDataList.Add(data3); // 可以添加更多模拟数据... } /// <summary> /// UDP帧字节解析结果(包含整个帧的信息和多个Block) /// </summary> // CRC32 计算方法 static uint CalculateCrc32(byte[] data, int offset, int length) { uint crc = 0xFFFFFFFF; for (int i = offset; i < offset + length; i++) { crc ^= data[i]; for (int j = 0; j < 8; j++) { if ((crc & 1) != 0) crc = (crc >> 1) ^ 0xEDB88320; else crc >>= 1; } } return crc ^ 0xFFFFFFFF; } /// <summary> /// 带CRC验证的完整帧解析(支持多Block和多Value) /// </summary> static UdpFrameResult ParseUdpFrameWithCrcCheck(byte[] udpData) { if (udpData == null) throw new ArgumentNullException(nameof(udpData), "UDP数据不能为空"); // 帧头固定11字节 + 至少1个Block(最小7字节) + CRC4字节 = 最小22字节 if (udpData.Length < 22) throw new ArgumentException("UDP数据长度不足,至少需要22字节", nameof(udpData)); // 计算CRC(整个帧数据除去最后4字节CRC) uint calculatedCrc = CalculateCrc32(udpData, 0, udpData.Length - 4); uint receivedCrc = (uint)( (udpData[udpData.Length - 4] << 24) | (udpData[udpData.Length - 3] << 16) | (udpData[udpData.Length - 2] << 8) | udpData[udpData.Length - 1] ); //if (calculatedCrc != receivedCrc) // throw new InvalidDataException($"CRC校验失败(计算值:0x{calculatedCrc:X8},接收值:0x{receivedCrc:X8})"); return ParseUdpFrame(udpData); } /// <summary> /// 核心帧解析逻辑(解析多Block和多Value) /// </summary> static UdpFrameResult ParseUdpFrame(byte[] udpData) { var frame = new UdpFrameResult(); int offset = 0; // 字节偏移量(跟踪当前解析位置) // 1. 解析帧头(固定11字节) frame.MagicNumber = (ushort)((udpData[offset] << 8) | udpData[offset + 1]); offset += 2; byte verAndBlockCount = udpData[offset]; frame.Ver = (byte)((verAndBlockCount >> 4) & 0x0F); // 高4位为Ver frame.BlockCount = (byte)(verAndBlockCount & 0x0F); // 低4位为BlockCount offset += 1; frame.FrameType = udpData[offset]; offset += 1; frame.Flags = udpData[offset]; offset += 1; frame.GlobalSequence = (ushort)((udpData[offset] << 8) | udpData[offset + 1]); offset += 2; frame.GlobalTimestamp = (uint)((udpData[offset] << 24) | (udpData[offset + 1] << 16) | (udpData[offset + 2] << 8) | udpData[offset + 3]); offset += 4; // 2. 解析多个Block(数量由BlockCount决定) for (byte i = 0; i < frame.BlockCount; i++) { // 检查剩余字节是否足够解析一个Block的基础信息(7字节) if (offset + 7 > udpData.Length - 4) // 预留4字节CRC throw new InvalidDataException($"第{i + 1}个Block数据不完整(基础信息不足)"); var block = new UdpBlock(); // 解析Block基础信息(7字节) block.BlockId = udpData[offset]; offset += 1; // 验证BlockId连续性(从1开始,依次+1) if (block.BlockId != i + 1) throw new InvalidDataException($"BlockId不连续(预期:{i + 1},实际:{block.BlockId})"); block.Period = udpData[offset]; offset += 1; byte endFlagAndVarCount = udpData[offset]; block.EndFlag = (byte)((endFlagAndVarCount >> 7) & 0x01); // 最高位为EndFlag block.VarCount = (byte)(endFlagAndVarCount & 0x7F); // 低7位为VarCount offset += 1; block.BlockTimestamp = (uint)((udpData[offset] << 24) | (udpData[offset + 1] << 16) | (udpData[offset + 2] << 8) | udpData[offset + 3]); offset += 4; // 3. 解析当前Block的多个Value(数量由VarCount决定,每个Value占4字节) int valueTotalBytes = block.VarCount * 4; if (offset + valueTotalBytes > udpData.Length - 4) // 预留4字节CRC throw new InvalidDataException($"第{i + 1}个Block的Value数据不完整(预期{block.VarCount}个,实际不足)"); for (byte v = 0; v < block.VarCount; v++) { uint value = (uint)((udpData[offset] << 24) | (udpData[offset + 1] << 16) | (udpData[offset + 2] << 8) | udpData[offset + 3]); block.Values.Add(value); offset += 4; } frame.Blocks.Add(block); } // 4. 解析CRC(最后4字节) frame.Crc = (uint)( (udpData[udpData.Length - 4] << 24) | (udpData[udpData.Length - 3] << 16) | (udpData[udpData.Length - 2] << 8) | udpData[udpData.Length - 1] ); return frame; } /// <summary> /// 生成解析结果的字符串(包含多Block和多Value信息) /// </summary> private string GetFrameResultString(UdpFrameResult frame, int dataLength) { var result = new StringBuilder(); result.AppendLine($"===== UDP帧解析结果(总长度:{dataLength}字节) ====="); result.AppendLine($"1. 帧头信息:"); result.AppendLine($" - Magic Number(前2字节):0x{frame.MagicNumber:X4}"); result.AppendLine($" - Ver(第3字节高4位):0x{frame.Ver:X1}(二进制:{Convert.ToString(frame.Ver, 2).PadLeft(4, '0')})"); result.AppendLine($" - BlockCount(第3字节低4位):0x{frame.BlockCount:X1}(共{frame.BlockCount}个Block)"); result.AppendLine($" - FrameType(第4字节):0x{frame.FrameType:X2}"); result.AppendLine($" - Flags(第5字节):0x{frame.Flags:X2}"); result.AppendLine($" - GlobalSequence(第6-7字节):0x{frame.GlobalSequence:X4}"); result.AppendLine($" - GlobalTimestamp(第8-11字节):0x{frame.GlobalTimestamp:X8}"); result.AppendLine($"\n2. Block详情(共{frame.BlockCount}个):"); foreach (var block in frame.Blocks) { result.AppendLine($" ===== Block {block.BlockId} ====="); result.AppendLine($" - BlockId(第{12 + frame.Blocks.IndexOf(block) * (7 + block.VarCount * 4)}字节):0x{block.BlockId:X2}"); result.AppendLine($" - Period:0x{block.Period:X2}"); result.AppendLine($" - EndFlag(第{12 + frame.Blocks.IndexOf(block) * (7 + block.VarCount * 4) + 2}字节最高位):{block.EndFlag}(1=最后一个Block,0=非最后)"); result.AppendLine($" - VarCount(第{12 + frame.Blocks.IndexOf(block) * (7 + block.VarCount * 4) + 2}字节低7位):{block.VarCount}(共{block.VarCount}个Value)"); result.AppendLine($" - BlockTimestamp(4字节):0x{block.BlockTimestamp:X8}"); // 输出当前Block的所有Value result.AppendLine($" - Values(每个4字节,共{block.VarCount}个):"); for (int i = 0; i < block.Values.Count; i++) { result.AppendLine($" - Value{i + 1}:0x{block.Values[i]:X8}"); } } result.AppendLine($"\n3. CRC校验(最后4字节):0x{frame.Crc:X8}"); return result.ToString(); } } } 在MainWindow.xaml.cs里面的代码InitializeSimulatedData(); 报错说:当前上下文中不存在“InitializeSimulatedData”,我应该如何修改
最新发布
09-02
UDPByteParsing.cs中代码如下:using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; namespace OmniTool.UDPByte { public class UDPByteParsing { private List<byte[]> _simulatedDataList = new List<byte[]>(); private void InitializeSimSulatedData() { // 这里添加多组模拟字节数据 // 示例数据1 - 包含4个Value byte[] data1 = { 0x12, 0x34, // MagicNumber 0x11, // Ver(0x1) + BlockCount(0x1) 0x01, // FrameType 0x00, // Flags 0x00, 0x01, // GlobalSequence 0x00, 0x00, 0x00, 0x01, // GlobalTimestamp // Block 1 0x01, // BlockId 0x0A, // Period 0x84, // EndFlag(1) + VarCount(4) 0x00, 0x00, 0x00, 0x0A, // BlockTimestamp 0x3F, 0x80, 0x00, 0x00, // Value 1 (1.0f as IEEE754) 0x40, 0x00, 0x00, 0x00, // Value 2 (2.0f as IEEE754) 0x40, 0x40, 0x00, 0x00, // Value 3 (3.0f as IEEE754) 0x40, 0x80, 0x00, 0x00, // Value 4 (4.0f as IEEE754) // CRC32 (这里需要计算正确的CRC,此处为示例) 0x12, 0x34, 0x56, 0x78 }; // 示例数据2 - 包含3个Value byte[] data2 = { 0x12, 0x34, // MagicNumber 0x11, // Ver(0x1) + BlockCount(0x1) 0x01, // FrameType 0x00, // Flags 0x00, 0x02, // GlobalSequence 0x00, 0x00, 0x00, 0x02, // GlobalTimestamp // Block 1 0x01, // BlockId 0x0A, // Period 0x83, // EndFlag(1) + VarCount(3) 0x00, 0x00, 0x00, 0x14, // BlockTimestamp 0x3F, 0xC0, 0x00, 0x00, // Value 1 (1.5f as IEEE754) 0x40, 0x20, 0x00, 0x00, // Value 2 (2.5f as IEEE754) 0x40, 0x60, 0x00, 0x00, // Value 3 (3.5f as IEEE754) // CRC32 0x12, 0x34, 0x56, 0x79 }; // 示例数据3 - 包含5个Value byte[] data3 = { 0x12, 0x34, // MagicNumber 0x11, // Ver(0x1) + BlockCount(0x1) 0x01, // FrameType 0x00, // Flags 0x00, 0x03, // GlobalSequence 0x00, 0x00, 0x00, 0x03, // GlobalTimestamp // Block 1 0x01, // BlockId 0x0A, // Period 0x85, // EndFlag(1) + VarCount(5) 0x00, 0x00, 0x00, 0x1E, // BlockTimestamp 0x3F, 0x80, 0x00, 0x00, // Value 1 (1.0f as IEEE754) 0x40, 0x00, 0x00, 0x00, // Value 2 (2.0f as IEEE754) 0x40, 0x40, 0x00, 0x00, // Value 3 (3.0f as IEEE754) 0x40, 0x80, 0x00, 0x00, // Value 4 (4.0f as IEEE754) 0x40, 0xA0, 0x00, 0x00, // Value 5 (5.0f as IEEE754) // CRC32 0x12, 0x34, 0x56, 0x7A }; _simulatedDataList.Add(data1); _simulatedDataList.Add(data2); _simulatedDataList.Add(data3); // 可以添加更多模拟数据... } /// <summary> /// UDP帧字节解析结果(包含整个帧的信息和多个Block) /// </summary> // CRC32 计算方法 static uint CalculateCrc32(byte[] data, int offset, int length) { uint crc = 0xFFFFFFFF; for (int i = offset; i < offset + length; i++) { crc ^= data[i]; for (int j = 0; j < 8; j++) { if ((crc & 1) != 0) crc = (crc >> 1) ^ 0xEDB88320; else crc >>= 1; } } return crc ^ 0xFFFFFFFF; } /// <summary> /// 带CRC验证的完整帧解析(支持多Block和多Value) /// </summary> public static UdpFrameResult ParseUdpFrameWithCrcCheck(byte[] udpData) { if (udpData == null) throw new ArgumentNullException(nameof(udpData), "UDP数据不能为空"); // 帧头固定11字节 + 至少1个Block(最小7字节) + CRC4字节 = 最小22字节 if (udpData.Length < 22) throw new ArgumentException("UDP数据长度不足,至少需要22字节", nameof(udpData)); // 计算CRC(整个帧数据除去最后4字节CRC) uint calculatedCrc = CalculateCrc32(udpData, 0, udpData.Length - 4); uint receivedCrc = (uint)( (udpData[udpData.Length - 4] << 24) | (udpData[udpData.Length - 3] << 16) | (udpData[udpData.Length - 2] << 8) | udpData[udpData.Length - 1] ); //if (calculatedCrc != receivedCrc) // throw new InvalidDataException($"CRC校验失败(计算值:0x{calculatedCrc:X8},接收值:0x{receivedCrc:X8})"); return ParseUdpFrame(udpData); } /// <summary> /// 核心帧解析逻辑(解析多Block和多Value) /// </summary> static UdpFrameResult ParseUdpFrame(byte[] udpData) { var frame = new UdpFrameResult(); int offset = 0; // 字节偏移量(跟踪当前解析位置) // 1. 解析帧头(固定11字节) frame.MagicNumber = (ushort)((udpData[offset] << 8) | udpData[offset + 1]); offset += 2; byte verAndBlockCount = udpData[offset]; frame.Ver = (byte)((verAndBlockCount >> 4) & 0x0F); // 高4位为Ver frame.BlockCount = (byte)(verAndBlockCount & 0x0F); // 低4位为BlockCount offset += 1; frame.FrameType = udpData[offset]; offset += 1; frame.Flags = udpData[offset]; offset += 1; frame.GlobalSequence = (ushort)((udpData[offset] << 8) | udpData[offset + 1]); offset += 2; frame.GlobalTimestamp = (uint)((udpData[offset] << 24) | (udpData[offset + 1] << 16) | (udpData[offset + 2] << 8) | udpData[offset + 3]); offset += 4; // 2. 解析多个Block(数量由BlockCount决定) for (byte i = 0; i < frame.BlockCount; i++) { // 检查剩余字节是否足够解析一个Block的基础信息(7字节) if (offset + 7 > udpData.Length - 4) // 预留4字节CRC throw new InvalidDataException($"第{i + 1}个Block数据不完整(基础信息不足)"); var block = new UdpBlock(); // 解析Block基础信息(7字节) block.BlockId = udpData[offset]; offset += 1; // 验证BlockId连续性(从1开始,依次+1) if (block.BlockId != i + 1) throw new InvalidDataException($"BlockId不连续(预期:{i + 1},实际:{block.BlockId})"); block.Period = udpData[offset]; offset += 1; byte endFlagAndVarCount = udpData[offset]; block.EndFlag = (byte)((endFlagAndVarCount >> 7) & 0x01); // 最高位为EndFlag block.VarCount = (byte)(endFlagAndVarCount & 0x7F); // 低7位为VarCount offset += 1; block.BlockTimestamp = (uint)((udpData[offset] << 24) | (udpData[offset + 1] << 16) | (udpData[offset + 2] << 8) | udpData[offset + 3]); offset += 4; // 3. 解析当前Block的多个Value(数量由VarCount决定,每个Value占4字节) int valueTotalBytes = block.VarCount * 4; if (offset + valueTotalBytes > udpData.Length - 4) // 预留4字节CRC throw new InvalidDataException($"第{i + 1}个Block的Value数据不完整(预期{block.VarCount}个,实际不足)"); for (byte v = 0; v < block.VarCount; v++) { uint value = (uint)((udpData[offset] << 24) | (udpData[offset + 1] << 16) | (udpData[offset + 2] << 8) | udpData[offset + 3]); block.Values.Add(value); offset += 4; } frame.Blocks.Add(block); } // 4. 解析CRC(最后4字节) frame.Crc = (uint)( (udpData[udpData.Length - 4] << 24) | (udpData[udpData.Length - 3] << 16) | (udpData[udpData.Length - 2] << 8) | udpData[udpData.Length - 1] ); return frame; } /// <summary> /// 生成解析结果的字符串(包含多Block和多Value信息) /// </summary> private string GetFrameResultString(UdpFrameResult frame, int dataLength) { var result = new StringBuilder(); result.AppendLine($"===== UDP帧解析结果(总长度:{dataLength}字节) ====="); result.AppendLine($"1. 帧头信息:"); result.AppendLine($" - Magic Number(前2字节):0x{frame.MagicNumber:X4}"); result.AppendLine($" - Ver(第3字节高4位):0x{frame.Ver:X1}(二进制:{Convert.ToString(frame.Ver, 2).PadLeft(4, '0')})"); result.AppendLine($" - BlockCount(第3字节低4位):0x{frame.BlockCount:X1}(共{frame.BlockCount}个Block)"); result.AppendLine($" - FrameType(第4字节):0x{frame.FrameType:X2}"); result.AppendLine($" - Flags(第5字节):0x{frame.Flags:X2}"); result.AppendLine($" - GlobalSequence(第6-7字节):0x{frame.GlobalSequence:X4}"); result.AppendLine($" - GlobalTimestamp(第8-11字节):0x{frame.GlobalTimestamp:X8}"); result.AppendLine($"\n2. Block详情(共{frame.BlockCount}个):"); foreach (var block in frame.Blocks) { result.AppendLine($" ===== Block {block.BlockId} ====="); result.AppendLine($" - BlockId(第{12 + frame.Blocks.IndexOf(block) * (7 + block.VarCount * 4)}字节):0x{block.BlockId:X2}"); result.AppendLine($" - Period:0x{block.Period:X2}"); result.AppendLine($" - EndFlag(第{12 + frame.Blocks.IndexOf(block) * (7 + block.VarCount * 4) + 2}字节最高位):{block.EndFlag}(1=最后一个Block,0=非最后)"); result.AppendLine($" - VarCount(第{12 + frame.Blocks.IndexOf(block) * (7 + block.VarCount * 4) + 2}字节低7位):{block.VarCount}(共{block.VarCount}个Value)"); result.AppendLine($" - BlockTimestamp(4字节):0x{block.BlockTimestamp:X8}"); // 输出当前Block的所有Value result.AppendLine($" - Values(每个4字节,共{block.VarCount}个):"); for (int i = 0; i < block.Values.Count; i++) { result.AppendLine($" - Value{i + 1}:0x{block.Values[i]:X8}"); } } result.AppendLine($"\n3. CRC校验(最后4字节):0x{frame.Crc:X8}"); return result.ToString(); } } } 在MainWindow.xaml.cs中有如下一些代码: private void MainWindow_Loaded(object sender, RoutedEventArgs e) { InitializeData(); SetupListViewDragDrop(); UDPByteParsing.InitializeSimulatedData(); // 初始化模拟数据 // _a2lEngine = new A2LEngine.A2LEngine(); // 初始化 A2L 引擎 }该代码报错:“UDPByteParsing”中未包含“ InitializeSimulatedData”的定义,应该如何修改
09-02
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值