Is it possible to “unpair” a Bluetooth device in C

2019-04-06 16:29发布

问题:

I've paired an IOBluetoothDevice in my Mac/Cocoa app and would like to "unpair" it programmatically. That is, I would like to remove the device from the left pane of the Bluetooth section of System Preferences.

I've seen [IOBluetoothDevice removeFromFavorites], but that just removes the heart icon next to the "Favorite" attribute of the device -- the device is still listed in the left pane.

Is this possible through Cocoa?

In the above picture, I would like to programmatically remove "Apple Mighty Mouse" from the left pane.

回答1:

Paired devices are a part of System Preferences.

You can find the file with the bluetooth preferences in /Library/Preferences, its name is com.apple.Bluetooth.plist.

However, you cannot edit the file directly. You should use SCPreferences class from System Configuration framework.

Note the API for accessing/modifying system preferences is pretty low level.

EDIT: The following code works if run in superuser mode. I am not a Mac OS developer myself but it should be possible to init it with an AuthorizationRef and run it with user mode (the user will confirm access to system configuration).

SCPreferencesRef prefs = SCPreferencesCreate(kCFAllocatorDefault,
                                             CFSTR("Test"),
                                             CFSTR("/Library/Preferences/com.apple.Bluetooth.plist"));

const CFStringRef PAIRED_DEVICES_KEY = CFSTR("PairedDevices");

NSArray *pairedDevices = (__bridge NSArray *) SCPreferencesGetValue(prefs, PAIRED_DEVICES_KEY);

NSLog(@"Paired devices: %@", pairedDevices);

NSString *deviceToRemove = @"e4-32-cb-da-ca-2f";        

NSMutableArray *newPairedDevices = [pairedDevices mutableCopy];
[newPairedDevices removeObject:deviceToRemove];

Boolean valueSet = SCPreferencesSetValue(prefs, PAIRED_DEVICES_KEY, (__bridge CFPropertyListRef) [NSArray arrayWithArray:newPairedDevices]);

NSLog(@"Value set: %@", (valueSet) ? @"YES" : @"NO");

if (!valueSet) {
    NSLog(@"Error: %@", SCCopyLastError());
}

Boolean saved = SCPreferencesCommitChanges(prefs);

if (!saved) {
    NSLog(@"Error: %@", SCCopyLastError());
}

NSLog(@"Saved: %@", (saved) ? @"YES" : @"NO");

CFRelease(prefs);