我写了一个简单的工作示例,相对简单,并将其开源包含在 Github 上:https ://github.com/GitGarage 。到目前为止,它只在 Android Nexus 9 和 iPhone 5s 上进行了测试,但我认为它也适用于 Nexus 6 和各种 iPhone 类型。到目前为止,它已明确设置为在一台 Android 和一台 iPhone 之间进行通信,但我认为它可以进行更多调整。
以下是关键方法...
DROID SIDE - 发送到 iOS:
private void sendMessage() {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
if (mBTAdapter == null) {
return;
}
if (mBTAdvertiser == null) {
mBTAdvertiser = mBTAdapter.getBluetoothLeAdvertiser();
}
// get the full message from the UI
String textMessage = mEditText.getText().toString();
if (textMessage.length() > 0)
{
// add 'Android' as the user name
String message = "Android: " + textMessage;
while (message.length() > 0) {
String subMessage;
if(message.length() > 8)
{ // add dash to unfinished messages
subMessage = message.substring(0,8) + "-";
message = message.substring(8);
for (int i = 0; i < 20; i++) // twenty times (better safe than sorry) send this part of the message. duplicate parts will be ignored
{
AdvertiseData ad = BleUtil.makeAdvertiseData(subMessage);
mBTAdvertiser.startAdvertising(BleUtil.createAdvSettings(true, 100), ad, mAdvCallback);
mBTAdvertiser.stopAdvertising(mAdvCallback);
}
}
else
{ // otherwise, send the last part
subMessage = message;
message = "";
for (int i = 0; i < 5; i++)
{
AdvertiseData ad = BleUtil.makeAdvertiseData(subMessage);
mBTAdvertiser.startAdvertising(
BleUtil.createAdvSettings(true, 40), ad,
mAdvCallback);
mBTAdvertiser.stopAdvertising(mAdvCallback);
}
}
}
threadHandler.post(updateRunnable);
}
}
});
thread.start();
}
DROID SIDE - 从 iOS 接收:
@Override
public void onLeScan(final BluetoothDevice newDevice, final int newRssi,
final byte[] newScanRecord) {
int startByte = 0;
String hex = asHex(newScanRecord).substring(0,29);
// check five times, startByte was used for something else before
while (startByte <= 5) {
// check if this is a repeat message
if (!Arrays.asList(used).contains(hex)) {
used[ui] = hex;
String message = new String(newScanRecord);
String firstChar = message.substring(5, 6);
Pattern pattern = Pattern.compile("[ a-zA-Z0-9~!@#$%^&*()_+{}|:\"<>?`\\-=;',\\./\\[\\]\\\\]", Pattern.DOTALL);
// if the message is comprised of standard characters...
Matcher matcher = pattern.matcher(firstChar);
if (firstChar.equals("L"))
{
firstChar = message.substring(6, 7);
pattern = Pattern.compile("[ a-zA-Z0-9~!@#$%^&*()_+{}|:\"<>?`\\-=;',\\./\\[\\]\\\\]", Pattern.DOTALL);
matcher = pattern.matcher(firstChar);
}
if(matcher.matches())
{
TextView textViewToChange = (TextView) findViewById(R.id.textView);
String oldText = textViewToChange.getText().toString();
int len = 0;
String subMessage = "";
// add this portion to our final message
while (matcher.matches())
{
subMessage = message.substring(5, 6+len);
matcher = pattern.matcher(message.substring(5+len, 6+len));
len++;
}
subMessage = subMessage.substring(0,subMessage.length()-1);
Log.e("Address",newDevice.getAddress());
Log.e("Data",asHex(newScanRecord));
boolean enter = subMessage.length() == 16;
enter = enter && !subMessage.substring(15).equals("-");
enter = enter || subMessage.length() < 16;
textViewToChange.setText(oldText + subMessage.substring(0, subMessage.length() - 1) + (enter ? "\n" : ""));
ui = ui == 2 ? -1 : ui;
ui++;
Log.e("String", subMessage);
}
break;
}
startByte++;
}
}
iOS 端 - 发送到 Android:
func startAdvertisingToPeripheral() {
var allTime:UInt64 = 0;
if (dataToSend != nil)
{
datastring = NSString(data:dataToSend, encoding:NSUTF8StringEncoding) as String
datastring = "iPhone: " + datastring
if (datastring.length > 15)
{
for (var i:Double = 0; i < Double(datastring.length)/15.000; i++)
{
let delay = i/10.000 * Double(NSEC_PER_SEC)
let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay))
allTime = time
dispatch_after(time, dispatch_get_main_queue(), { () -> Void in self.sendPart() });
}
}
else
{
var messageUUID = StringToUUID(datastring)
if !peripheralManager.isAdvertising {
peripheralManager.startAdvertising([CBAdvertisementDataServiceUUIDsKey: [CBUUID(string: messageUUID)]])
}
}
}
}
iOS 端 - 从 Android 接收:
func centralManager(central: CBCentralManager!, didDiscoverPeripheral peripheral: CBPeripheral!, advertisementData: [NSObject : AnyObject]!, RSSI: NSNumber!) {
delegate?.didDiscoverPeripheral(peripheral)
var splitUp = split("\(advertisementData)") {$0 == "\n"}
if (splitUp.count > 1)
{
var chop = splitUp[1]
chop = chop[0...chop.length-2]
var chopSplit = split("\(chop)") {$0 == "\""}
if !(chopSplit.count > 1 && chopSplit[1] == "Device Information")
{
var hexString = chop[4...7] + chop[12...19] + chop[21...26]
var datas = hexString.dataFromHexadecimalString()
var string = NSString(data: datas!, encoding: NSUTF8StringEncoding) as String
if (!contains(usedList,string))
{
usedList.append(string)
if (string.length == 9 && string[string.length-1...string.length-1] == "-")
{
finalString = finalString + string[0...string.length-2]
}
else
{
lastString = finalString + string + "\n"
println(lastString)
finalString = ""
usedList = newList
usedList.append(string)
}
}
}
}
}