-
Notifications
You must be signed in to change notification settings - Fork 172
Expand file tree
/
Copy pathFlutterBluetoothBasicPlugin.m
More file actions
199 lines (174 loc) · 7.17 KB
/
FlutterBluetoothBasicPlugin.m
File metadata and controls
199 lines (174 loc) · 7.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
#import "FlutterBluetoothBasicPlugin.h"
#import "ConnecterManager.h"
@interface FlutterBluetoothBasicPlugin ()
@property(nonatomic, retain) NSObject<FlutterPluginRegistrar> *registrar;
@property(nonatomic, retain) FlutterMethodChannel *channel;
@property(nonatomic, retain) BluetoothPrintStreamHandler *stateStreamHandler;
@property(nonatomic) NSMutableDictionary *scannedPeripherals;
@property(nonatomic,assign) NSInteger stateIndex;
@property(nonatomic,assign) NSInteger bluetoothState;
;
@end
@implementation FlutterBluetoothBasicPlugin
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
FlutterMethodChannel* channel = [FlutterMethodChannel
methodChannelWithName:NAMESPACE @"/methods"
binaryMessenger:[registrar messenger]];
FlutterEventChannel* stateChannel = [FlutterEventChannel eventChannelWithName:NAMESPACE @"/state" binaryMessenger:[registrar messenger]];
FlutterBluetoothBasicPlugin* instance = [[FlutterBluetoothBasicPlugin alloc] init];
instance.channel = channel;
instance.scannedPeripherals = [NSMutableDictionary new];
// STATE
BluetoothPrintStreamHandler* stateStreamHandler = [[BluetoothPrintStreamHandler alloc] init];
[stateChannel setStreamHandler:stateStreamHandler];
instance.stateStreamHandler = stateStreamHandler;
instance.stateIndex = -1;
instance.bluetoothState = 1;
[registrar addMethodCallDelegate:instance channel:channel];
}
- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
NSLog(@"call method -> %@", call.method);
if ([@"state" isEqualToString:call.method]) {
result(nil);
} else if([@"isAvailable" isEqualToString:call.method]) {
bool isAvailable = self.bluetoothState ==1;
result(@(isAvailable));
} else if([@"isConnected" isEqualToString:call.method]) {
result(@(NO));
}
else if([@"connectStateInteger" isEqualToString:call.method]) {
result(@(self.stateIndex));
} else if([@"isOn" isEqualToString:call.method]) {
result(@(YES));
}else if([@"startScan" isEqualToString:call.method]) {
NSLog(@"getDevices method -> %@", call.method);
[self.scannedPeripherals removeAllObjects];
if (Manager.bleConnecter == nil) {
[Manager didUpdateState:^(NSInteger state) {
switch (state) {
case CBCentralManagerStateUnsupported:
self.bluetoothState = 4;
NSLog(@"The platform/hardware doesn't support Bluetooth Low Energy.");
break;
case CBCentralManagerStateUnauthorized:
self.bluetoothState = 3;
NSLog(@"The app is not authorized to use Bluetooth Low Energy.");
break;
case CBCentralManagerStatePoweredOff:
self.bluetoothState = 2;
NSLog(@"Bluetooth is currently powered off.");
break;
case CBCentralManagerStatePoweredOn:
[self startScan];
self.bluetoothState = 1;
NSLog(@"Bluetooth power on");
break;
case CBCentralManagerStateUnknown:
default: self.bluetoothState = -1;
break;
}
}];
} else {
[self startScan];
}
result(nil);
} else if([@"stopScan" isEqualToString:call.method]) {
[Manager stopScan];
result(nil);
} else if([@"connect" isEqualToString:call.method]) {
NSDictionary *device = [call arguments];
@try {
NSLog(@"connect device begin -> %@", [device objectForKey:@"name"]);
CBPeripheral *peripheral = [_scannedPeripherals objectForKey:[device objectForKey:@"address"]];
self.state = ^(ConnectState state) {
[self updateConnectState:state];
};
[Manager connectPeripheral:peripheral options:nil timeout:2 connectBlack: self.state];
result(nil);
} @catch(FlutterError *e) {
result(e);
}
} else if([@"disconnect" isEqualToString:call.method]) {
@try {
[Manager close];
result(nil);
} @catch(FlutterError *e) {
result(e);
}
} else if([@"writeData" isEqualToString:call.method]) {
@try {
NSDictionary *args = [call arguments];
NSMutableArray *bytes = [args objectForKey:@"bytes"];
NSNumber* lenBuf = [args objectForKey:@"length"];
int len = [lenBuf intValue];
char cArray[len];
for (int i = 0; i < len; ++i) {
// NSLog(@"** ind_%d (d): %@, %d", i, bytes[i], [bytes[i] charValue]);
cArray[i] = [bytes[i] charValue];
}
NSData *data2 = [NSData dataWithBytes:cArray length:sizeof(cArray)];
// NSLog(@"bytes in hex: %@", [data2 description]);
[Manager write:data2];
result(nil);
} @catch(FlutterError *e) {
result(e);
}
}
}
-(void)startScan {
[Manager scanForPeripheralsWithServices:nil options:nil discover:^(CBPeripheral * _Nullable peripheral, NSDictionary<NSString *,id> * _Nullable advertisementData, NSNumber * _Nullable RSSI) {
if (peripheral.name != nil) {
NSLog(@"find device -> %@", peripheral.name);
[self.scannedPeripherals setObject:peripheral forKey:[[peripheral identifier] UUIDString]];
NSDictionary *device = [NSDictionary dictionaryWithObjectsAndKeys:peripheral.identifier.UUIDString,@"address",peripheral.name,@"name",nil,@"type",nil];
[_channel invokeMethod:@"ScanResult" arguments:device];
}
}];
}
-(void)updateConnectState:(ConnectState)state {
dispatch_async(dispatch_get_main_queue(), ^{
NSNumber *ret = @0;
switch (state) {
case CONNECT_STATE_CONNECTING:
NSLog(@"status -> %@", @"Connecting ...");
self.stateIndex = 0;
ret = @0;
break;
case CONNECT_STATE_CONNECTED:
NSLog(@"status -> %@", @"Connection success");
ret = @1;
self.stateIndex = 1;
break;
case CONNECT_STATE_FAILT:
NSLog(@"status -> %@", @"Connection failed");
ret = @0;
self.stateIndex = 2;
break;
case CONNECT_STATE_DISCONNECT:
NSLog(@"status -> %@", @"Disconnected");
self.stateIndex = 3;
ret = @0;
break;
default:
NSLog(@"status -> %@", @"Connection timed out");
ret = @0;
self.stateIndex = -1;
break;
}
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:ret,@"id",nil];
if(_stateStreamHandler.sink != nil) {
self.stateStreamHandler.sink([dict objectForKey:@"id"]);
}
});
}
@end
@implementation BluetoothPrintStreamHandler
- (FlutterError*)onListenWithArguments:(id)arguments eventSink:(FlutterEventSink)eventSink {
self.sink = eventSink;
return nil;
}
- (FlutterError*)onCancelWithArguments:(id)arguments {
self.sink = nil;
return nil;
}
@end