添加权限提示 QianXun
authorliangzhenying <867174124@qq.com>
Mon, 2 Sep 2024 07:28:41 +0000 (15:28 +0800)
committerliangzhenying <867174124@qq.com>
Mon, 2 Sep 2024 07:28:41 +0000 (15:28 +0800)
14 files changed:
Document/arm M7 鼠标USB连接 闪退9月2日.docx [new file with mode: 0644]
MouseSdk/AiMouseSdk/AiMouseSdk.xcodeproj/project.pbxproj
MouseSdk/AiMouseSdk/AiMouseSdk/AiMouseTools.m
MouseSdk/AiMouseSdk/AiMouseSdk/AiRecordManager.m
MouseSdk/AiMouseSdk/Manager/AiDeviceAuthManager.h [new file with mode: 0644]
MouseSdk/AiMouseSdk/Manager/AiDeviceAuthManager.m [new file with mode: 0644]
MouseSdk/AiMouseSdk/Manager/BleManager.m
MouseSdk/AiMouseSdk/Manager/HidManager.m
MouseSdk/AiMouseSdk/Manager/TimerManager.m
MouseSdk/AiMouseSdk/TlwMouseSdk/TlwMouseSdk.h
MouseSdk/AiMouseSdk/TlwMouseSdk/TlwMouseSdk.m
MouseSdk/MouseSdk.xcworkspace/xcuserdata/apple.xcuserdatad/UserInterfaceState.xcuserstate
MouseSdk/MouseSdk.xcworkspace/xcuserdata/apple.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
MouseSdk/MouseSdk/ViewController.m

diff --git a/Document/arm M7 鼠标USB连接 闪退9月2日.docx b/Document/arm M7 鼠标USB连接 闪退9月2日.docx
new file mode 100644 (file)
index 0000000..6666200
Binary files /dev/null and "b/Document/arm M7 \351\274\240\346\240\207USB\350\277\236\346\216\245 \351\227\252\351\200\2009\346\234\2102\346\227\245.docx" differ
index 6ef92f2..85c8b6e 100644 (file)
                18862BDB2C806BD900D3564D /* libavcodec.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 180E7C7F2BD8FC4E008558E8 /* libavcodec.a */; };
                18862BDC2C806BD900D3564D /* libswresample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 180E7C822BD8FC4E008558E8 /* libswresample.a */; };
                18862BDD2C806BD900D3564D /* libavformat.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 180E7C802BD8FC4E008558E8 /* libavformat.a */; };
+               1888148E2C85766B009299A9 /* AiDeviceAuthManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 1888148C2C85766B009299A9 /* AiDeviceAuthManager.h */; };
+               1888148F2C85766B009299A9 /* AiDeviceAuthManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 1888148C2C85766B009299A9 /* AiDeviceAuthManager.h */; };
+               188814902C85766B009299A9 /* AiDeviceAuthManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1888148D2C85766B009299A9 /* AiDeviceAuthManager.m */; };
+               188814912C85766B009299A9 /* AiDeviceAuthManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1888148D2C85766B009299A9 /* AiDeviceAuthManager.m */; };
                189C15862C05726600676A80 /* AiConnectManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 189C15842C05726600676A80 /* AiConnectManager.h */; };
                189C15872C05726600676A80 /* AiConnectManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 189C15852C05726600676A80 /* AiConnectManager.m */; };
                18AD83252BFAE8B9009BDE3B /* AiDeviceInfoManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 18AD83232BFAE8B9009BDE3B /* AiDeviceInfoManager.h */; };
                18862A1E2C8064E300D3564D /* BleManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BleManager.m; sourceTree = "<group>"; };
                18862A202C8064E300D3564D /* TimerManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TimerManager.m; sourceTree = "<group>"; };
                18862A212C8064E300D3564D /* HidManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HidManager.h; sourceTree = "<group>"; };
+               1888148C2C85766B009299A9 /* AiDeviceAuthManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AiDeviceAuthManager.h; sourceTree = "<group>"; };
+               1888148D2C85766B009299A9 /* AiDeviceAuthManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AiDeviceAuthManager.m; sourceTree = "<group>"; };
                189C15842C05726600676A80 /* AiConnectManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AiConnectManager.h; sourceTree = "<group>"; };
                189C15852C05726600676A80 /* AiConnectManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AiConnectManager.m; sourceTree = "<group>"; };
                18AD83232BFAE8B9009BDE3B /* AiDeviceInfoManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AiDeviceInfoManager.h; sourceTree = "<group>"; };
                                18862A1E2C8064E300D3564D /* BleManager.m */,
                                18862A1A2C8064E300D3564D /* TimerManager.h */,
                                18862A202C8064E300D3564D /* TimerManager.m */,
+                               1888148C2C85766B009299A9 /* AiDeviceAuthManager.h */,
+                               1888148D2C85766B009299A9 /* AiDeviceAuthManager.m */,
                        );
                        path = Manager;
                        sourceTree = "<group>";
                                180E7CAD2BD8FC4E008558E8 /* attributes.h in Headers */,
                                18AD83252BFAE8B9009BDE3B /* AiDeviceInfoManager.h in Headers */,
                                180E7C932BD8FC4E008558E8 /* murmur3.h in Headers */,
+                               1888148E2C85766B009299A9 /* AiDeviceAuthManager.h in Headers */,
                                180E7CE52BD8FC4E008558E8 /* version.h in Headers */,
                                180E7CC62BD8FC4E008558E8 /* tea.h in Headers */,
                                180E7CF12BD8FC4F008558E8 /* mediacodec.h in Headers */,
                                18862B1B2C806BD900D3564D /* attributes.h in Headers */,
                                18862B1C2C806BD900D3564D /* AiDeviceInfoManager.h in Headers */,
                                18862B1D2C806BD900D3564D /* murmur3.h in Headers */,
+                               1888148F2C85766B009299A9 /* AiDeviceAuthManager.h in Headers */,
                                18862B1E2C806BD900D3564D /* version.h in Headers */,
                                18862B1F2C806BD900D3564D /* tea.h in Headers */,
                                18862B202C806BD900D3564D /* mediacodec.h in Headers */,
                                184A71202BDD11C70025A332 /* AiTrippleModel.m in Sources */,
                                180E7AAC2BD7BB12008558E8 /* AiMouseSdk.m in Sources */,
                                180E7BE12BD7BD84008558E8 /* AiAudioConverter.m in Sources */,
+                               188814902C85766B009299A9 /* AiDeviceAuthManager.m in Sources */,
                                184A71072BDA4C050025A332 /* AFHTTPSessionManager.m in Sources */,
                                180E7BE02BD7BD84008558E8 /* AiMouseTools.m in Sources */,
                                184A710A2BDA4C050025A332 /* AFURLRequestSerialization.m in Sources */,
                                18862BB52C806BD900D3564D /* AiTrippleModel.m in Sources */,
                                18862BB62C806BD900D3564D /* AiMouseSdk.m in Sources */,
                                18862BB72C806BD900D3564D /* AiAudioConverter.m in Sources */,
+                               188814912C85766B009299A9 /* AiDeviceAuthManager.m in Sources */,
                                18862BB82C806BD900D3564D /* AFHTTPSessionManager.m in Sources */,
                                18862BB92C806BD900D3564D /* AiMouseTools.m in Sources */,
                                18862BBA2C806BD900D3564D /* AFURLRequestSerialization.m in Sources */,
index 4c77e62..60a2179 100644 (file)
@@ -7,6 +7,8 @@
 
 #import "AiRecordManager.h"
 #import <AVFoundation/AVFoundation.h>
+#import <Cocoa/Cocoa.h>
+#import "AiDeviceAuthManager.h"
 
 @interface AiRecordManager()
 @property (nonatomic,assign)BOOL isAllowRecord;
             [self openSettings];
             break;
     }
+}
 
-    
-
+- (void)checkPermissions2{
+    [self showLog:@"查询录音授权状态"];
+    switch ([AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio]) {
+        case AVAuthorizationStatusAuthorized:
+            self.isAllowRecord = true;
+            [self showLog:@"录音已经授权"];
+            break;
+        case AVAuthorizationStatusNotDetermined:
+        {
+            [self showLog:@"录音未授权"];
+            [AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio completionHandler:^(BOOL granted) {
+                if (granted) {
+                    self.isAllowRecord = true;
+                    [self showLog:@"录音已经授权"];
+                }
+                else{
+                    [self showLog:@"已拒绝"];
+                }
+            }];
+        }
+            break;
+        case AVAuthorizationStatusDenied:
+            [self showLog:@"已拒绝"];
+            [[AiDeviceAuthManager shared] showMicrophoneAlert];
+            break;
+        default:
+            [self showLog:@"已拒绝"];
+            [[AiDeviceAuthManager shared] showMicrophoneAlert];
+            break;
+    }
 }
 
+//// 表明用户尚未选择关于客户端是否可以访问硬件
+//AVAuthorizationStatusNotDetermined
+//
+//// 客户端未被授权访问硬件的媒体类型。用户不能改变客户机的状态,可能由于活跃的限制,如家长控制
+// AVAuthorizationStatusRestricted,
+//
+//// 明确拒绝用户访问硬件支持的媒体类型的客户
+//AVAuthorizationStatusDenied,
+//
+//// 客户端授权访问硬件支持的媒体类型
+//AVAuthorizationStatusAuthorized
+//————————————————
+//
+//                       版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
+//                   
+//原文链接:https://blog.csdn.net/skl5879166/article/details/115365332
+
+
 - (void)openSettings{
-//    NSURL *url = [NSURL URLWithString:@""];
+    [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"x-apple.systempreferences:com.apple.preference.security?Privacy_Microphone"]];
 }
 
 - (void)showLog:(NSString *)log{
diff --git a/MouseSdk/AiMouseSdk/Manager/AiDeviceAuthManager.h b/MouseSdk/AiMouseSdk/Manager/AiDeviceAuthManager.h
new file mode 100644 (file)
index 0000000..fd1f4ea
--- /dev/null
@@ -0,0 +1,23 @@
+//
+//  AiDeviceAuthManager.h
+//  AiMouseSdk
+//
+//  Created by incar on 2024/9/2.
+//
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface AiDeviceAuthManager : NSObject
+
+
+///单例
++(AiDeviceAuthManager *)shared;
+
+- (void)showHidAlert;
+
+- (void)showMicrophoneAlert;
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/MouseSdk/AiMouseSdk/Manager/AiDeviceAuthManager.m b/MouseSdk/AiMouseSdk/Manager/AiDeviceAuthManager.m
new file mode 100644 (file)
index 0000000..13c0a31
--- /dev/null
@@ -0,0 +1,57 @@
+//
+//  AiDeviceAuthManager.m
+//  AiMouseSdk
+//
+//  Created by incar on 2024/9/2.
+//
+
+#import "AiDeviceAuthManager.h"
+#import <Cocoa/Cocoa.h>
+
+@interface AiDeviceAuthManager()<NSAlertDelegate>
+
+@property (nonatomic, strong) NSAlert *hidAlerl;
+@end
+
+
+@implementation AiDeviceAuthManager
++(AiDeviceAuthManager *)shared{
+    static AiDeviceAuthManager *manager = nil;
+    static dispatch_once_t oncePredicate;
+    dispatch_once(&oncePredicate, ^{
+        manager = [[AiDeviceAuthManager alloc]init];
+    });
+    return manager;
+}
+
+
+- (void)showHidAlert{
+        NSAlert *alert = [[NSAlert alloc] init];
+        [alert setMessageText:@"请前往设置-隐私与安全性-输入监控,将输入监控打开并重启app才能使用AI功能"];
+        [alert addButtonWithTitle:@"确定"];
+//        [alert addButtonWithTitle:@"取消"];
+        NSInteger result = [alert runModal];
+        if (result == NSAlertFirstButtonReturn) {
+            NSLog(@"用户点击了确定");
+            [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"x-apple.systempreferences:com.apple.preference.security?Privacy_ListenEvent"]];
+        } else if (result == NSAlertSecondButtonReturn) {
+            NSLog(@"用户点击了取消");
+        }
+}
+
+
+- (void)showMicrophoneAlert{
+        NSAlert *alert = [[NSAlert alloc] init];
+        [alert setMessageText:@"请前往设置-隐私与安全性-麦克风,将麦克风打开并重启app才能使用AI功能"];
+        [alert addButtonWithTitle:@"确定"];
+//        [alert addButtonWithTitle:@"取消"];
+        NSInteger result = [alert runModal];
+        if (result == NSAlertFirstButtonReturn) {
+            NSLog(@"用户点击了确定");
+            [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"x-apple.systempreferences:com.apple.preference.security?Privacy_Microphone"]];
+        } else if (result == NSAlertSecondButtonReturn) {
+            NSLog(@"用户点击了取消");
+        }
+}
+
+@end
index 2dc5d3b..744f7fc 100644 (file)
     if(self.curentPeripheral == nil || self.curentPeripheral.state == CBPeripheralStateDisconnected){
         [self startScan];
     }
+    if (self.curentPeripheral && self.curentPeripheral.state == CBPeripheralStateConnected && [DeviceManger shared].connectType == AiMouseConnectType_hid ) {
+        self.connectStateCallBack(self.curentPeripheral.name,true);
+    }
 }
 
 @end
index 16719a2..9875582 100644 (file)
@@ -8,7 +8,10 @@
 #import "HidManager.h"
 #include <IOKit/hid/IOHIDLib.h>
 #include <IOKit/hid/IOHIDKeys.h>
-
+#import <Security/Security.h>
+#import <Carbon/Carbon.h>
+#import <Cocoa/Cocoa.h>
+#import "AiDeviceAuthManager.h"
 
 @interface HidManager ()
 @property(nonatomic, assign) IOHIDManagerRef hidManager;///hid管理
@@ -57,10 +60,12 @@ static void hidAppearDevice(void *inContext,IOReturn inResult,void *inSender,IOH
         IOReturn result = IOHIDDeviceOpen([HidManager shared].deviceInfoCha, kIOHIDOptionsTypeNone);
         if (result != kIOReturnSuccess) {
             [[HidManager shared] showLog:[NSString stringWithFormat:@"打开设备失败! %d",result]];
+            [[AiDeviceAuthManager shared] showHidAlert];
+            return;
         }else{
             [[HidManager shared] showLog:@"打开设备成功!"];
 //            [HidManager shared].connectStateCallBack(true) ;
-            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(4 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                 [HidManager shared].connectStateCallBack(true);
             });
         }
@@ -78,6 +83,8 @@ static void hidAppearDevice(void *inContext,IOReturn inResult,void *inSender,IOH
             IOReturn result = IOHIDDeviceOpen(inIOHIDDeviceRef, kIOHIDOptionsTypeNone);
             if (result != kIOReturnSuccess) {
                 [[HidManager shared] showLog:[NSString stringWithFormat:@"打开设备信息失败! %d",result]];
+                [[AiDeviceAuthManager shared] showHidAlert];
+                return;
             }else{
 //                CFRetain(inIOHIDDeviceRef);
 //                IOHIDDeviceScheduleWithRunLoop(inIOHIDDeviceRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
@@ -96,6 +103,9 @@ static void hidAppearDevice(void *inContext,IOReturn inResult,void *inSender,IOH
             IOReturn result = IOHIDDeviceOpen(inIOHIDDeviceRef, kIOHIDOptionsTypeNone);
             if (result != kIOReturnSuccess) {
                 [[HidManager shared] showLog:[NSString stringWithFormat:@"打开设备voice失败! %d",result]];
+                [[AiDeviceAuthManager shared] showHidAlert];
+                return;
+                return;
             }else{
 //                CFRetain(inIOHIDDeviceRef);
 //                IOHIDDeviceScheduleWithRunLoop(inIOHIDDeviceRef, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
@@ -280,4 +290,51 @@ static uint32_t IOHIDDevGetUInt32Property(IOHIDDeviceRef inIOHIDDeviceRef, CFStr
     }
     return outValue;
 }
+
+
+
+//// 判断输入监控权限的方法
+//-(BOOL)checkInputMonitoringPermission{
+//    AuthorizationRef authorizationRef;
+//    OSStatus status = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &authorizationRef);
+//    if (status!= errAuthorizationSuccess) {
+//        return NO;
+//    }
+//
+//    CFDictionaryRef query = CFDictionaryCreate(NULL,
+//                                                (const void **)&kSecClass,
+//                                                (const void **)&kSecClassGenericPassword,
+//                                                (const void **)&kSecMatchLimit,
+//                                                (const void **)&kSecMatchLimitOne,
+//                                                (const void **)&kSecReturnAttributes,
+//                                                (const void **)&kCFBooleanTrue,
+//                                                (const void **)&kSecUseDataProtectionKeychain,
+//                                                (const void **)&kCFBooleanFalse,
+//                                                NULL);
+//
+//    CFArrayRef resultArray = NULL;
+//    status = SecItemCopyMatching(query, (CFTypeRef *)&resultArray);
+//    CFRelease(query);
+//
+//    if (status!= errSecSuccess) {
+//        AuthorizationFree(authorizationRef, kAuthorizationFlagDestroyRights);
+//        return NO;
+//    }
+//
+//    BOOL hasInputMonitoring = NO;
+//    if (resultArray && CFArrayGetCount(resultArray) > 0) {
+//        CFDictionaryRef itemDict = CFArrayGetValueAtIndex(resultArray, 0);
+//        CFBooleanRef inputMonitoringValue = (CFBooleanRef)CFDictionaryGetValue(itemDict, CFSTR("kSecAttrCanAccessWhenUnlocked"));
+//        if (inputMonitoringValue && CFBooleanGetValue(inputMonitoringValue)) {
+//            hasInputMonitoring = YES;
+//        }
+//    }
+//
+//    if (resultArray) {
+//        CFRelease(resultArray);
+//    }
+//    AuthorizationFree(authorizationRef, kAuthorizationFlagDestroyRights);
+//
+//    return hasInputMonitoring;
+//}
 @end
index 87d4517..331ff84 100644 (file)
@@ -32,7 +32,7 @@
 //        [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
 //        [[NSRunLoop currentRunLoop] run];
 //    });
-    self.timer = [NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(timerAction) userInfo:nil repeats:true];
+    self.timer = [NSTimer scheduledTimerWithTimeInterval:8 target:self selector:@selector(timerAction) userInfo:nil repeats:true];
 }
 
 - (void)timerAction{
index 86e604a..005d5ef 100644 (file)
@@ -20,6 +20,7 @@
 @property (nonatomic, strong) NSString *brand;///型号
 @property (nonatomic, strong) NSString *batch;/// 批次
 @property (nonatomic, strong) NSString *sn;/// 设备号
+@property (nonatomic, strong) NSString *mac;/// mac地址
 @end
 
 /// 日志等级
index 423e6d3..76efa1f 100644 (file)
@@ -18,7 +18,7 @@
 @end
 @implementation TlwSnInfo
 -(NSString *)description{
-    NSString *info = [NSString stringWithFormat:@"code = %@ brand = %@ batch = %@ sn = %@",self.code,self.brand,self.batch,self.sn];
+    NSString *info = [NSString stringWithFormat:@"code = %@ brand = %@ batch = %@ mac = %@ sn = %@",self.code,self.brand,self.batch,self.mac,self.sn];
     return info;
 }
 @end
 
 
 - (void)getFullDeviceInfo:(void (^)(AiMouseDeviceInfo *deviceInfo,NSError *error))finished{
+    if (self.getFullInfoCallBack) {
+        return;
+    }
     self.getFullInfoCallBack = finished;
     self.questTimes = 0;
     [self checkFullInfoAction];
     }
 }
 - (void)reGetFullInfoAction{
+    if(self.getFullInfoCallBack == nil)return;;
     __weak typeof(self) ws = self;
     [self getDeviceInfo:^(TlwDeviceInfo *deviceInfo, NSError *error) {
         if(deviceInfo != nil){
                 if( info != nil){
                     info.brand = snInfo.brand;
                     info.sn = snInfo.sn;
-                    info.mac = snInfo.sn;
+                    info.mac = snInfo.mac;
                     [ws showLog:info.description];
                     if(ws.getFullInfoCallBack)ws.getFullInfoCallBack(info, nil);
                     ws.getFullInfoCallBack = nil;
             
         case 0x22:
         {
-            //            220210 48584D33303030313031E6FCFF68D7D000
             NSString *code = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(3, 2)] encoding:NSUTF8StringEncoding];
             NSString *brand = [self getBrand:[data subdataWithRange:NSMakeRange(5, 6)]];
-            NSString *batch = [TlwTools dataToHexString:[data subdataWithRange:NSMakeRange(11, 2)]];
-            NSString *sn = [TlwTools dataToHexString:[data subdataWithRange:NSMakeRange(13, 6)]];
+            NSString *batch = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(11, 2)] encoding:NSUTF8StringEncoding];
+            NSString *mac = [TlwTools dataToHexString:[data subdataWithRange:NSMakeRange(13, 6)]];
+            
+            NSString *fullBrand =  [self getFullBrand:[data subdataWithRange:NSMakeRange(5, 6)]];
+            NSString *sn = [[NSString stringWithFormat:@"%@%@%@%@",code,fullBrand,batch,mac] lowercaseString];
             TlwSnInfo *info = [[TlwSnInfo alloc] init];
             info.code = code;
             info.brand = brand;
             info.batch = batch;
+            info.mac = mac;
             info.sn = sn;
             [self showLog:info.description];
             if(self.getSnInfoCallBack)self.getSnInfoCallBack(info, nil);
     //    0x05fff1fec09f0114ef
     if(data.length < 7 ){
         [self showLog:@"收到异常数据"];
-        //        [self switchConnect:AiMouseConnectType_hid isConnected:false ];
         return;
     }
     if(![[[TlwTools dataToHexString:[data subdataWithRange:NSMakeRange(1, 2)]] lowercaseString] isEqualToString:@"fff1"]){
         [self showLog:@"收到异常数据"];
-        //        [self switchConnect:AiMouseConnectType_hid isConnected:false ];
         return;
     }
     
             //语音开启回复
             uint8 state;
             [[data subdataWithRange:NSMakeRange(6, 1)] getBytes:&state length:1];
-            BOOL success = state == 0x02;
+            BOOL success = state == 0;
             [self showLog:[NSString stringWithFormat:@"语音开启回复 %@",@(success)]];
             if(self.openRecordCallBack)self.openRecordCallBack(true, nil);
             [self startRecord];
             //语音停止回复
             uint8 state;
             [[data subdataWithRange:NSMakeRange(6, 1)] getBytes:&state length:1];
-            BOOL success = state == 0x02;
+            BOOL success = state == 0;
             
             [self showLog:[NSString stringWithFormat:@"语音停止回复 %@",@(success)]];
             [self stopRecord];
             //设置DPI回复
             uint8 state;
             [[data subdataWithRange:NSMakeRange(6, 1)] getBytes:&state length:1];
-            BOOL success = state == 0x02;
+            BOOL success = state == 0;
             
             [self showLog:[NSString stringWithFormat:@"设置DPI回复 %@",@(success)]];
             if(self.setDpiCallBack)self.setDpiCallBack(true, nil);
         case 0x22:
         { //sn查询回复
             //            05FFF1FEC022 1048584D33303030313031E6FCFF68D7D0EF00000000000000000000000000000000000000000000000000000000000000000000000000000000
-            //            220210 48584D33303030313031E6FCFF68D7D000
             data = [data subdataWithRange:NSMakeRange(4, data.length - 4)];
             NSString *code = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(3, 2)] encoding:NSUTF8StringEncoding];
             NSString *brand = [self getBrand:[data subdataWithRange:NSMakeRange(5, 6)]];
-            NSString *batch = [TlwTools dataToHexString:[data subdataWithRange:NSMakeRange(11, 2)]];
-            NSString *sn = [TlwTools dataToHexString:[data subdataWithRange:NSMakeRange(13, 6)]];
+            NSString *batch = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(11, 2)] encoding:NSUTF8StringEncoding];
+            NSString *mac = [TlwTools dataToHexString:[data subdataWithRange:NSMakeRange(13, 6)]];
+            
+            NSString *fullBrand =  [self getFullBrand:[data subdataWithRange:NSMakeRange(5, 6)]];
+            NSString *sn = [[NSString stringWithFormat:@"%@%@%@%@",code,fullBrand,batch,mac] lowercaseString];
             TlwSnInfo *info = [[TlwSnInfo alloc] init];
             info.code = code;
             info.brand = brand;
             info.batch = batch;
+            info.mac = mac;
             info.sn = sn;
             [self showLog:info.description];
             if(self.getSnInfoCallBack)self.getSnInfoCallBack(info, nil);
 - (NSString *)getBrand:(NSData *)data{
     NSString *text = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
     for (NSInteger i = 0; i < text.length;i++) {
-        if ([[text substringWithRange:NSMakeRange(i, 1)] isEqual:@"0"]) {
+        if ([[text substringWithRange:NSMakeRange(i, 1)] isEqual:@"\0"]) {
             return [text substringWithRange:NSMakeRange(0, i)];
         }
     }
     return text;
 }
+- (NSString *)getFullBrand:(NSData *)data{
+    NSString *text = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
+    NSString *replacedString = [text stringByReplacingOccurrencesOfString:@"\0" withString:@"0"];
+    return replacedString;
+}
 @end
 
index 843f3b1..3b65f60 100644 (file)
Binary files a/MouseSdk/MouseSdk.xcworkspace/xcuserdata/apple.xcuserdatad/UserInterfaceState.xcuserstate and b/MouseSdk/MouseSdk.xcworkspace/xcuserdata/apple.xcuserdatad/UserInterfaceState.xcuserstate differ
index c3ddbcd..cef1dca 100644 (file)
             </Locations>
          </BreakpointContent>
       </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            uuid = "31993B35-9DA9-4381-B863-11397B6D9184"
+            shouldBeEnabled = "Yes"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "AiMouseSdk/TlwMouseSdk/TlwMouseSdk.m"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "22"
+            endingLineNumber = "22"
+            landmarkName = "-description"
+            landmarkType = "7">
+         </BreakpointContent>
+      </BreakpointProxy>
+      <BreakpointProxy
+         BreakpointExtensionID = "Xcode.Breakpoint.FileBreakpoint">
+         <BreakpointContent
+            uuid = "B9B9032E-D4BF-479C-B350-7D0E383A7C18"
+            shouldBeEnabled = "Yes"
+            ignoreCount = "0"
+            continueAfterRunningActions = "No"
+            filePath = "AiMouseSdk/TlwMouseSdk/TlwMouseSdk.m"
+            startingColumnNumber = "9223372036854775807"
+            endingColumnNumber = "9223372036854775807"
+            startingLineNumber = "656"
+            endingLineNumber = "656"
+            landmarkName = "TlwMouse"
+            landmarkType = "3">
+         </BreakpointContent>
+      </BreakpointProxy>
    </Breakpoints>
 </Bucket>
index e0cbb55..9f1588f 100644 (file)
         [self.view addSubview:label];
     }
     {
-        NSTextField *label = [[NSTextField alloc] initWithFrame:CGRectMake(180, self.view.bounds.size.height - 260, 300, 100)];
+        NSTextField *label = [[NSTextField alloc] initWithFrame:CGRectMake(180, self.view.bounds.size.height - 360, 300, 200)];
         label.editable = NO;
         label.bordered = NO;
         label.stringValue = @"";
 }
 
 - (void)geviceInfoAction{
+//    [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:@"x-apple.systempreferences:com.apple.preference.security?Privacy_ListenEvent"]];
+//    return;
     [[DeviceManger shared] getDeviceInfo:^(AiMouseDeviceInfo *deviceInfo, NSError *error) {
         if (deviceInfo) {
             NSString *info = deviceInfo.description;
     }];
 }
 
+
 - (void)moreAction:(NSButton *)sender {
     NSMenu *popupMenu = [[NSMenu alloc] initWithTitle:@"Popup Menu"];
     NSMenuItem *item1 = [[NSMenuItem alloc] initWithTitle:@"语音开启" action:@selector(voiceStart:) keyEquivalent:@"1"];