当你的蓝牙不支持被动扫描,即不为外部设备所搜索时,采用ibeacon广播信号以及数据是个不错的解决方案。下面废话不多说,直接上代码。
1、初始化蓝牙
private void initBluetooth(Context context){
BluetoothManager bluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
mBluetoothAdapter.setName("aiqi");
if (!mBluetoothAdapter.isEnabled()) {
mBluetoothAdapter.enable();
mBluetoothAdapter.setName("aiqi");
if(mBluetoothAdapter.getAddress()!=null){
Log.i("ibeacon",mBluetoothAdapter.getAddress());
}
Log.e("ibeacon",mBluetoothAdapter.getAddress()+"");
}
}2、配置蓝牙广播
public AdvertiseSettings createAdvertiseSettings(boolean connectable, int timeoutMillis) {
AdvertiseSettings.Builder mSettingsbuilder = new AdvertiseSettings.Builder();
mSettingsbuilder.setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_LOW_LATENCY);
mSettingsbuilder.setConnectable(connectable);
mSettingsbuilder.setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_HIGH);
mSettingsbuilder.setTimeout(0);
AdvertiseSettings mAdvertiseSettings = mSettingsbuilder.build();
return mAdvertiseSettings;
}3、加入广播数据(测试的是本机蓝牙地址)
public AdvertiseData createAdvertiseData() {
AdvertiseData.Builder mDataBuilder = new AdvertiseData.Builder();
String uuidString ="FDA50693-A4E2-4FB1-AFCF-C6EB07647825".toUpperCase();
String uuid=uuidString.replace("-","");
String beaconType="0215";
String[] split=mBluetoothAdapter.getAddress().split(":");
String finishaddress=split[0]+split[1]+split[2]+split[3]+split[4]+split[5];
String dataStr=beaconType+finishaddress;
Log.e("ibeacon",dataStr+"");
byte[] data=Conversion.hexStringToBytes(dataStr);
mDataBuilder.addManufacturerData(0x004C, data);
AdvertiseData mAdvertiseData = mDataBuilder.build();
return mAdvertiseData;
}广播数据时要进行的进制转换类
public class Conversion {
public static byte loUint16(short v) {
return (byte) (v & 0xFF);
}
public static byte hiUint16(short v) {
return (byte) (v >> 8);
}
public static short buildUint16(byte hi, byte lo) {
return (short) ((hi << 8) + (lo & 0xff));
}
public static boolean isAsciiPrintable(String str) {
if (str == null) {
return false;
}
int sz = str.length();
for (int i = 0; i < sz; i++) {
if (isAsciiPrintable(str.charAt(i)) == false) {
return false;
}
}
return true;
}
private static boolean isAsciiPrintable(char ch) {
return ch >= 32 && ch < 127;
}
public static byte[] hexStringToBytes(String hexString) {
if (hexString == null || hexString.equals("")) {
return null;
}
hexString = hexString.toUpperCase();
if (hexString.length() % 2 != 0) {
hexString = "0" + hexString;
}
int length = hexString.length() / 2;
char[] hexChars = hexString.toCharArray();
byte[] d = new byte[length];
for (int i = 0; i < length; i++) {
int pos = i * 2;
d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
}
return d;
}
public static byte charToByte(char c) {
return (byte) "0123456789ABCDEF".indexOf(c);
}
private final static byte[] hex = "0123456789ABCDEF".getBytes();
// 从字节数组到十六进制字符串转�?
public static String Bytes2HexString(byte[] b) {
byte[] buff = new byte[2 * b.length];
for (int i = 0; i < b.length; i++) {
buff[2 * i] = hex[(b[i] >> 4) & 0x0f];
buff[2 * i + 1] = hex[b[i] & 0x0f];
}
return new String(buff);
}
public static int byteStrToInt(String valueStr) {
valueStr = valueStr.toUpperCase();
if (valueStr.length() % 2 != 0) {
valueStr = "0" + valueStr;
}
int returnValue = 0;
int length = valueStr.length();
for (int i = 0; i < length; i++) {
int value = charToByte(valueStr.charAt(i));
returnValue += Math.pow(16, length - i - 1) * value;
}
return returnValue;
}
public static int bytesToInt(byte[] values) {
String valueStr = Bytes2HexString(values);
if (valueStr.length() % 2 != 0) {
valueStr = "0" + valueStr;
}
int returnValue = 0;
int length = valueStr.length();
for (int i = 0; i < length; i++) {
int value = charToByte(valueStr.charAt(i));
returnValue += Math.pow(16, length - i - 1) * value;
}
return returnValue;
}
/**
* Byte转Bit
*/
public static String byteToBit(byte b) {
return "" + (byte) ((b >> 7) & 0x1) +
(byte) ((b >> 6) & 0x1) +
(byte) ((b >> 5) & 0x1) +
(byte) ((b >> 4) & 0x1) +
(byte) ((b >> 3) & 0x1) +
(byte) ((b >> 2) & 0x1) +
(byte) ((b >> 1) & 0x1) +
(byte) ((b >> 0) & 0x1);
}
/**
* Bit转Byte
*/
public static byte BitToByte(String byteStr) {
int re, len;
if (null == byteStr) {
return 0;
}
len = byteStr.length();
if (len != 4 && len != 8) {
return 0;
}
if (len == 8) {// 8 bit处理
if (byteStr.charAt(0) == '0') {// 正数
re = Integer.parseInt(byteStr, 2);
} else {// 负数
re = Integer.parseInt(byteStr, 2) - 256;
}
} else {//4 bit处理
re = Integer.parseInt(byteStr, 2);
}
return (byte) re;
}
/**
* @param src
* @param start
* @param length
* @return
*/
public static byte[] subByteArray(byte[] src, int start, int length) {
byte[] result = new byte[length];
System.arraycopy(src, start, result, 0, length);
return result;
}
/**
*
* @param targetLenth 补齐后的长度
* @param src 需要补齐的字符串
* @param leftCharacter 用来补齐长度的字符
* @return 补齐字符串
*/
public static String formatStringLenth(int targetLenth, String src, char leftCharacter) {
if(src.length()>targetLenth){
return src.substring(src.length()-targetLenth);
}else{
int delta=targetLenth-src.length();
for (int i = 0; i <delta ; i++) {
src=leftCharacter+src;
}
return src;
}
}
4、开始广播及开始回调
private AdvertiseCallback mAdvCallback = new AdvertiseCallback() {
public void onStartSuccess(android.bluetooth.le.AdvertiseSettings settingsInEffect) {
Log.e("ibeacon", "开启广播成功" );
}
public void onStartFailure(int errorCode) {
Log.e("ibeacon", "onStartFailure errorCode=" + errorCode);
// ToastUtils.showToast(MainActivity.this,"开启失败" + errorCode,1000);
}
};public void startAdvertise(Context context) {
initBluetooth(context);
Log.e("ibeacon", "执行广播" );
if (!mBluetoothAdapter.isEnabled()) {
Log.e("ibeacon", "请打开蓝牙开关" );
mBluetoothAdapter.enable();
}
if (!mBluetoothAdapter.isMultipleAdvertisementSupported()) {
Log.e("ibeacon", "当前手机不支持BLE Advertise");
}
mBluetoothLeAdvertiser = mBluetoothAdapter.getBluetoothLeAdvertiser();
if (mBluetoothLeAdvertiser == null) {
Log.e("ibeacon", "当前手机不支持BLE Advertise" );
}
AdvertiseSettings advertiseSettings = createAdvertiseSettings(false, 0);
if (advertiseSettings == null) {
Log.e("ibeacon", "当前手机不支持BLE Advertise" );
}
mBluetoothLeAdvertiser.startAdvertising(createAdvertiseSettings(true, 0), createAdvertiseData(), mAdvCallback);
}看到这里,调试肯定是成功的,至于接收Scan自己百度下呗。看完记得点赞哦