Android 以格式发送 BLE 数据
Android send BLE data in format
我想以下面给出的图像格式发送 BLE 数据。Advertising Data packet。
我只是以字节格式发送测试数据 1,但如图所示,我必须在 0x11 处发送第一种广告数据类型的 0x22 长度数据,我已发送第二种数据类型的长度,依此类推。那么我应该如何根据图像设置它。
public class MainActivity extends AppCompatActivity {
private Button mAdvertiseButton,stopAdvertiseButton;
private static final String TAG = "BLEApp";
private BluetoothAdapter mBluetoothAdapter;
public static final int REQUEST_ENABLE_BT = 1;
private String Device_Name="Abc";
private String Device_Id ="0x34Abc";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAdvertiseButton=(Button) findViewById(R.id.adv);
stopAdvertiseButton=(Button) findViewById(R.id.stopadv);
mAdvertiseButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (savedInstanceState == null)
mBluetoothAdapter = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE))
.getAdapter();
// Is Bluetooth supported on this device?
if (mBluetoothAdapter != null) {
// Is Bluetooth turned on?
if (mBluetoothAdapter.isEnabled()) {
// Are Bluetooth Advertisements supported on this device?
if (mBluetoothAdapter.isMultipleAdvertisementSupported()) {
// Everything is supported and enabled, load the method
advertise();
} else {
// Bluetooth Advertisements are not supported.
showErrorText(R.string.bt_ads_not_supported);
}
} else {
// Prompt user to turn on Bluetooth (logic continues in onActivityResult()).
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
} else {
// Bluetooth is not supported.
showErrorText(R.string.bt_not_supported);
}
}
});
stopAdvertiseButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// stopAdv();
}
});
}
@RequiresApi(api = Build.VERSION_CODES.O)
private void stopAdv() {
AdvertiseCallback callback= null;
BluetoothLeAdvertiser advertiser = BluetoothAdapter.getDefaultAdapter().getBluetoothLeAdvertiser();
advertiser.stopAdvertising(null);
}
private void advertise() {
BluetoothLeAdvertiser advertiser = BluetoothAdapter.getDefaultAdapter().getBluetoothLeAdvertiser();
AdvertisingSetParameters parameters = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
parameters = (new AdvertisingSetParameters.Builder())
.setLegacyMode(true) // True by default, but set here as a reminder.
.setConnectable(false)
.setInterval(AdvertisingSetParameters.INTERVAL_HIGH)
.setTxPowerLevel(AdvertisingSetParameters.TX_POWER_MEDIUM)
.build();
}
byte[] manufacturerData = new byte[] {
// 0x12, 0x34,
// 0x56, 0x66,
0x41,0x4d,0x4f,0x4c
};
String testData = "abcdefghij";
byte[] testData1=testData.getBytes();
ParcelUuid pUuid = new ParcelUuid( UUID.fromString("CDB7950D-73F1-4D4D-8E47-C090502DBD63"));
AdvertiseData data = (new AdvertiseData.Builder())
.addManufacturerData(1, testData1)
.setIncludeDeviceName(true)
.build();
//.addServiceData( pUuid, "Data".getBytes(Charset.forName("UTF-8") ) )
AdvertisingSetCallback callback= null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
callback = new AdvertisingSetCallback() {
@Override
public void onAdvertisingSetStarted(AdvertisingSet advertisingSet, int txPower, int status) {
super.onAdvertisingSetStarted(advertisingSet, txPower, status);
Log.d(TAG, "onAdvertisingSetStarted(): txPower:" + txPower + " , status: "
+ status);
AdvertisingSet currentAdvertisingSet = advertisingSet;
// After onAdvertisingSetStarted callback is called, you can modify the
// advertising data and scan response data:
currentAdvertisingSet.setAdvertisingData(new AdvertiseData.Builder().
addManufacturerData(67, testData1)
.setIncludeDeviceName(true)
.setIncludeTxPowerLevel(true).build());
// Wait for onAdvertisingDataSet callback...
ParcelUuid pUuid = new ParcelUuid(UUID.randomUUID());
currentAdvertisingSet.setScanResponseData(new
AdvertiseData.Builder().addServiceUuid(pUuid).build());
Log.d(TAG,"UUID"+pUuid);
//
// Wait for onScanResponseDataSet callback...
Log.d(TAG, data.toString() + status);
// currentAdvertisingSet.setScanResponseData(new AdvertiseData.Builder());
}
@Override
public void onAdvertisingSetStopped(AdvertisingSet advertisingSet) {
super.onAdvertisingSetStopped(advertisingSet);
Log.d(TAG, "onAdvertisingSetStopped():");
}
@Override
public void onAdvertisingEnabled(AdvertisingSet advertisingSet, boolean enable, int status) {
super.onAdvertisingEnabled(advertisingSet, enable, status);
}
@Override
public void onAdvertisingDataSet(AdvertisingSet advertisingSet, int status) {
super.onAdvertisingDataSet(advertisingSet, status);
Log.d(TAG, "onAdvertisingDataSet() :status:" + status);
}
@Override
public void onScanResponseDataSet(AdvertisingSet advertisingSet, int status) {
super.onScanResponseDataSet(advertisingSet, status);
Log.d(TAG, "onScanResponseDataSet(): status:" + status);
}
};
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
advertiser.startAdvertisingSet(parameters, data, null, null, null, callback);
Toast.makeText(MainActivity.this, "Data"+data, Toast.LENGTH_LONG).show();
}
// When done with the advertising:
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// advertiser.stopAdvertisingSet(callback);
// }
//
}
Android 提供用于构建 BLE 广告消息负载的高级 API,因此您只需添加每个 handles
的值(句柄是长度的三元组-dataType-data) 图像中的消息。
例如,要添加 service(消息的第二个句柄),您不必设置 length (0x11) 和 data type (0x07) but only use addServiceUuid
of the AdvertiseData.Builder
,SDK会设置length and 为你输入。这对最后一个句柄(制造商数据)也有效,您必须使用 addManufacturerData
.
对于第一个句柄(标志),您无法使用 AdvertiseData.Builder
设置,但 AdvertisingSetParameters.Builder()
、here. But according this answer 不再支持 limited discoverable
模式
我想以下面给出的图像格式发送 BLE 数据。Advertising Data packet。 我只是以字节格式发送测试数据 1,但如图所示,我必须在 0x11 处发送第一种广告数据类型的 0x22 长度数据,我已发送第二种数据类型的长度,依此类推。那么我应该如何根据图像设置它。
public class MainActivity extends AppCompatActivity {
private Button mAdvertiseButton,stopAdvertiseButton;
private static final String TAG = "BLEApp";
private BluetoothAdapter mBluetoothAdapter;
public static final int REQUEST_ENABLE_BT = 1;
private String Device_Name="Abc";
private String Device_Id ="0x34Abc";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAdvertiseButton=(Button) findViewById(R.id.adv);
stopAdvertiseButton=(Button) findViewById(R.id.stopadv);
mAdvertiseButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (savedInstanceState == null)
mBluetoothAdapter = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE))
.getAdapter();
// Is Bluetooth supported on this device?
if (mBluetoothAdapter != null) {
// Is Bluetooth turned on?
if (mBluetoothAdapter.isEnabled()) {
// Are Bluetooth Advertisements supported on this device?
if (mBluetoothAdapter.isMultipleAdvertisementSupported()) {
// Everything is supported and enabled, load the method
advertise();
} else {
// Bluetooth Advertisements are not supported.
showErrorText(R.string.bt_ads_not_supported);
}
} else {
// Prompt user to turn on Bluetooth (logic continues in onActivityResult()).
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
} else {
// Bluetooth is not supported.
showErrorText(R.string.bt_not_supported);
}
}
});
stopAdvertiseButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// stopAdv();
}
});
}
@RequiresApi(api = Build.VERSION_CODES.O)
private void stopAdv() {
AdvertiseCallback callback= null;
BluetoothLeAdvertiser advertiser = BluetoothAdapter.getDefaultAdapter().getBluetoothLeAdvertiser();
advertiser.stopAdvertising(null);
}
private void advertise() {
BluetoothLeAdvertiser advertiser = BluetoothAdapter.getDefaultAdapter().getBluetoothLeAdvertiser();
AdvertisingSetParameters parameters = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
parameters = (new AdvertisingSetParameters.Builder())
.setLegacyMode(true) // True by default, but set here as a reminder.
.setConnectable(false)
.setInterval(AdvertisingSetParameters.INTERVAL_HIGH)
.setTxPowerLevel(AdvertisingSetParameters.TX_POWER_MEDIUM)
.build();
}
byte[] manufacturerData = new byte[] {
// 0x12, 0x34,
// 0x56, 0x66,
0x41,0x4d,0x4f,0x4c
};
String testData = "abcdefghij";
byte[] testData1=testData.getBytes();
ParcelUuid pUuid = new ParcelUuid( UUID.fromString("CDB7950D-73F1-4D4D-8E47-C090502DBD63"));
AdvertiseData data = (new AdvertiseData.Builder())
.addManufacturerData(1, testData1)
.setIncludeDeviceName(true)
.build();
//.addServiceData( pUuid, "Data".getBytes(Charset.forName("UTF-8") ) )
AdvertisingSetCallback callback= null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
callback = new AdvertisingSetCallback() {
@Override
public void onAdvertisingSetStarted(AdvertisingSet advertisingSet, int txPower, int status) {
super.onAdvertisingSetStarted(advertisingSet, txPower, status);
Log.d(TAG, "onAdvertisingSetStarted(): txPower:" + txPower + " , status: "
+ status);
AdvertisingSet currentAdvertisingSet = advertisingSet;
// After onAdvertisingSetStarted callback is called, you can modify the
// advertising data and scan response data:
currentAdvertisingSet.setAdvertisingData(new AdvertiseData.Builder().
addManufacturerData(67, testData1)
.setIncludeDeviceName(true)
.setIncludeTxPowerLevel(true).build());
// Wait for onAdvertisingDataSet callback...
ParcelUuid pUuid = new ParcelUuid(UUID.randomUUID());
currentAdvertisingSet.setScanResponseData(new
AdvertiseData.Builder().addServiceUuid(pUuid).build());
Log.d(TAG,"UUID"+pUuid);
//
// Wait for onScanResponseDataSet callback...
Log.d(TAG, data.toString() + status);
// currentAdvertisingSet.setScanResponseData(new AdvertiseData.Builder());
}
@Override
public void onAdvertisingSetStopped(AdvertisingSet advertisingSet) {
super.onAdvertisingSetStopped(advertisingSet);
Log.d(TAG, "onAdvertisingSetStopped():");
}
@Override
public void onAdvertisingEnabled(AdvertisingSet advertisingSet, boolean enable, int status) {
super.onAdvertisingEnabled(advertisingSet, enable, status);
}
@Override
public void onAdvertisingDataSet(AdvertisingSet advertisingSet, int status) {
super.onAdvertisingDataSet(advertisingSet, status);
Log.d(TAG, "onAdvertisingDataSet() :status:" + status);
}
@Override
public void onScanResponseDataSet(AdvertisingSet advertisingSet, int status) {
super.onScanResponseDataSet(advertisingSet, status);
Log.d(TAG, "onScanResponseDataSet(): status:" + status);
}
};
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
advertiser.startAdvertisingSet(parameters, data, null, null, null, callback);
Toast.makeText(MainActivity.this, "Data"+data, Toast.LENGTH_LONG).show();
}
// When done with the advertising:
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// advertiser.stopAdvertisingSet(callback);
// }
//
}
Android 提供用于构建 BLE 广告消息负载的高级 API,因此您只需添加每个 handles
的值(句柄是长度的三元组-dataType-data) 图像中的消息。
例如,要添加 service(消息的第二个句柄),您不必设置 length (0x11) 和 data type (0x07) but only use addServiceUuid
of the AdvertiseData.Builder
,SDK会设置length and 为你输入。这对最后一个句柄(制造商数据)也有效,您必须使用 addManufacturerData
.
对于第一个句柄(标志),您无法使用 AdvertiseData.Builder
设置,但 AdvertisingSetParameters.Builder()
、here. But according this answer 不再支持 limited discoverable
模式