我正在尝试通过Android App与ESL通信。我建立了连接,并且可以使用核心蓝牙功能从ESL读取数据。但是现在制造商说要向ESL写入数据,我必须先进行身份验证,然后才能向该ESL写入数据。他们也给了我一个流程图,但我听不懂。因此,期待您的帮助。 下面是我的代码:
execute_command_line
尝试执行此调用时出现异常
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
private static final int REQUEST_ENABLE_BT = 1111;
private static final int REQUEST_LOCATION = 1;
private static String[] PERMISSIONS_LOCATION = {Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION};
private ConstraintLayout cl_mMain;
private ScanCallback scanCallback;
private BluetoothAdapter.LeScanCallback leScanCallback;
private BluetoothGatt gatt;
private BluetoothGattCallback gattCallback;
private BluetoothDevice bluetoothDevice;
private int mConnectionState = STATE_DISCONNECTED;
private static final int STATE_DISCONNECTED = 0;
private static final int STATE_CONNECTING = 1;
private static final int STATE_CONNECTED = 2;
public final static String ACTION_GATT_CONNECTED =
"com.example.bluetooth.le.ACTION_GATT_CONNECTED";
public final static String ACTION_GATT_DISCONNECTED =
"com.example.bluetooth.le.ACTION_GATT_DISCONNECTED";
public final static String ACTION_GATT_SERVICES_DISCOVERED =
"com.example.bluetooth.le.ACTION_GATT_SERVICES_DISCOVERED";
public final static String ACTION_DATA_AVAILABLE =
"com.example.bluetooth.le.ACTION_DATA_AVAILABLE";
public final static String EXTRA_DATA =
"com.example.bluetooth.le.EXTRA_DATA";
public final static UUID UUID_HEART_RATE_MEASUREMENT =
UUID.fromString(SampleGattAttributes.HEART_RATE_MEASUREMENT);
public static final ParcelUuid PARCE_UUID_EDDYSTONE =
ParcelUuid.fromString("0000FEA0-0000-1000-8000-00805f9b34fb");
private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (ACTION_GATT_CONNECTED.equals(action)) {
} else if (ACTION_GATT_DISCONNECTED.equals(action)) {
} else if (ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
// Show all the supported services and characteristics on the
// user interface.
displayGattServices(getSupportedGattServices());
} else if (ACTION_DATA_AVAILABLE.equals(action)) {
//displayData(intent.getStringExtra(EXTRA_DATA));
Log.e(TAG, "Result " + intent.getStringExtra(EXTRA_DATA));
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
cl_mMain = findViewById(R.id.cl_main);
checkLocationPermission();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(ACTION_DATA_AVAILABLE);
intentFilter.addAction(ACTION_GATT_CONNECTED);
intentFilter.addAction(ACTION_GATT_DISCONNECTED);
intentFilter.addAction(ACTION_GATT_SERVICES_DISCOVERED);
registerReceiver(mGattUpdateReceiver, intentFilter);
}
public List<BluetoothGattService> getSupportedGattServices() {
if (gatt == null) return null;
return gatt.getServices();
}
public void connectService() {
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter != null) {
leScanCallback = new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(final BluetoothDevice bluetoothDevice, int receivedSignalStrengthIndicator, byte[] bytes) {
if (bluetoothDevice.getAddress().trim().equals("DD:33:0A:00:83:35")) {
MainActivity.this.bluetoothDevice = bluetoothDevice;
Log.e(TAG, "Device: " + bluetoothDevice.getName() + "\n" + bluetoothDevice.getAddress());
gatt = bluetoothDevice.connectGatt(MainActivity.this, true, gattCallback);
}
}
};
mBluetoothAdapter.startLeScan(leScanCallback);
//Gatt callback
gattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
super.onConnectionStateChange(gatt, status, newState);
String intentAction;
if (newState == STATE_CONNECTED) {
intentAction = ACTION_GATT_CONNECTED;
mConnectionState = STATE_CONNECTED;
broadcastUpdate(intentAction);
Log.e(TAG, "Connected to GATT server.");
Log.e(TAG, "Attempting to start service discovery:" +
gatt.discoverServices());
} else if (newState == STATE_DISCONNECTED) {
intentAction = ACTION_GATT_DISCONNECTED;
mConnectionState = STATE_DISCONNECTED;
Log.e(TAG, "Disconnected from GATT server.");
broadcastUpdate(intentAction);
}
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
super.onServicesDiscovered(gatt, status);
Log.e(TAG, "size " + gatt.getServices().size());
if (status == BluetoothGatt.GATT_SUCCESS) {
broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
Log.e(TAG, "onServicesDiscovered received: " + status);
} else {
Log.e(TAG, "onServicesDiscovered received: " + status);
}
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicRead(gatt, characteristic, status);
if (status == BluetoothGatt.GATT_SUCCESS) {
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
}
}
@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicWrite(gatt, characteristic, status);
}
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
super.onCharacteristicChanged(gatt, characteristic);
}
};
}
}
private void checkLocationPermission() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
requestLocationPermission();
} else {
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter != null && mBluetoothAdapter.isEnabled()) {
connectService();
} else {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
}
}
private void requestLocationPermission() {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_COARSE_LOCATION) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
Snackbar.make(cl_mMain, "Location permission is needed to access the location.", Snackbar.LENGTH_INDEFINITE).setAction("Ok", new View.OnClickListener() {
@Override
public void onClick(View view) {
ActivityCompat.requestPermissions(MainActivity.this, PERMISSIONS_LOCATION, REQUEST_LOCATION);
}
}).show();
} else {
ActivityCompat.requestPermissions(this, PERMISSIONS_LOCATION, REQUEST_LOCATION);
}
}
public UUID convertFromInteger(int i) {
final long MSB = 0x0000000000001000L;
final long LSB = 0x800000805f9b34fbL;
long value = i & 0xFFFFFFFF;
return new UUID(MSB | (value << 32), LSB);
}
private void broadcastUpdate(final String action) {
final Intent intent = new Intent(action);
sendBroadcast(intent);
}
private void broadcastUpdate(final String action, final BluetoothGattCharacteristic characteristic) {
final Intent intent = new Intent(action);
// This is special handling for the Heart Rate Measurement profile. Data
// parsing is carried out as per profile specifications.
if (UUID_HEART_RATE_MEASUREMENT.equals(characteristic.getUuid())) {
int flag = characteristic.getProperties();
int format = -1;
if ((flag & 0x01) != 0) {
format = BluetoothGattCharacteristic.FORMAT_UINT16;
Log.d(TAG, "Heart rate format UINT16.");
} else {
format = BluetoothGattCharacteristic.FORMAT_UINT8;
Log.d(TAG, "Heart rate format UINT8.");
}
final int heartRate = characteristic.getIntValue(format, 1);
Log.d(TAG, String.format("Received heart rate: %d", heartRate));
intent.putExtra(EXTRA_DATA, String.valueOf(heartRate));
} else {
// For all other profiles, writes the data formatted in HEX.
final byte[] data = characteristic.getValue();
if (data != null && data.length > 0) {
final StringBuilder stringBuilder = new StringBuilder(data.length);
for (byte byteChar : data)
stringBuilder.append(String.format("%02X ", byteChar));
intent.putExtra(EXTRA_DATA, new String(data) + "\n" +
stringBuilder.toString());
Log.e(TAG, stringBuilder.toString());
}
}
sendBroadcast(intent);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_ENABLE_BT) {
if (resultCode == Activity.RESULT_OK) {
connectService();
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_LOCATION) {
if (PermissionUtil.verifyPermissions(grantResults)) {
Snackbar.make(cl_mMain, "Location permission is granted", Snackbar.LENGTH_SHORT).show();
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter != null && mBluetoothAdapter.isEnabled()) {
connectService();
} else {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
} else {
Snackbar.make(cl_mMain, "Location permission is not granted", Snackbar.LENGTH_SHORT).show();
}
}
}
// Demonstrates how to iterate through the supported GATT
// Services/Characteristics.
// In this sample, we populate the data structure that is bound to the
// ExpandableListView on the UI.
private void displayGattServices(List<BluetoothGattService> gattServices) {
if (gattServices == null) return;
String uuid = null;
String unknownServiceString = "Unknown services";
String unknownCharaString = "unknown_characteristic";
ArrayList<HashMap<String, String>> gattServiceData = new ArrayList<HashMap<String, String>>();
ArrayList<ArrayList<HashMap<String, String>>> gattCharacteristicData = new ArrayList<ArrayList<HashMap<String, String>>>();
ArrayList<ArrayList<BluetoothGattCharacteristic>> mGattCharacteristics = new ArrayList<>();
// Get the default adapter
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
// Loops through available GATT Services.
for (BluetoothGattService gattService : gattServices) {
HashMap<String, String> currentServiceData = new HashMap<String, String>();
uuid = gattService.getUuid().toString();
Log.e(TAG, uuid);
BluetoothSocket bluetoothSocket;
Log.e(TAG, bluetoothDevice.getAddress() + "\n" + bluetoothDevice.getName());
try {
Log.e(TAG, String.valueOf(bluetoothDevice.fetchUuidsWithSdp()));
bluetoothSocket = bluetoothDevice.createRfcommSocketToServiceRecord(UUID.fromString("0000FEA0-0000-1000-8000-00805f9b34fb"));
// Cancel discovery because it otherwise slows down the connection.
mBluetoothAdapter.cancelDiscovery();
bluetoothSocket.connect();
if (bluetoothSocket.isConnected())
Log.e(TAG, "connected ");
else
Log.e(TAG, "not connected ");
} catch (IOException e) {
e.printStackTrace();
}
/*currentServiceData.put(LIST_NAME, SampleGattAttributes.
lookup(uuid, unknownServiceString));
currentServiceData.put(LIST_UUID, uuid);
gattServiceData.add(currentServiceData);
ArrayList<HashMap<String, String>> gattCharacteristicGroupData = new ArrayList<HashMap<String, String>>();
List<BluetoothGattCharacteristic> gattCharacteristics = gattService.getCharacteristics();
ArrayList<BluetoothGattCharacteristic> charas = new ArrayList<BluetoothGattCharacteristic>();
// Loops through available Characteristics.
for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
charas.add(gattCharacteristic);
HashMap<String, String> currentCharaData = new HashMap<String, String>();
uuid = gattCharacteristic.getUuid().toString();
currentCharaData.put(LIST_NAME, SampleGattAttributes.lookup(uuid,
unknownCharaString));
currentCharaData.put(LIST_UUID, uuid);
gattCharacteristicGroupData.add(currentCharaData);
}
mGattCharacteristics.add(charas);
gattCharacteristicData.add(gattCharacteristicGroupData);*/
}
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(mGattUpdateReceiver);
}}
预先感谢