gpt4 book ai didi

android - 获得蓝牙低功耗 (BLE) 设备通知的步骤是什么?

转载 作者:塔克拉玛干 更新时间:2023-11-02 07:57:40 28 4
gpt4 key购买 nike

我正在开发低功耗蓝牙 (BLE) 应用程序。我有一个测量重量的 BLE 设备(秤)。我可以连接这个设备。但我不知道如何从中读取数据(重量值)。

我想知道我的应用程序是否已连接到任何 BLE 设备,那么获得设备通知以获取更新数据的步骤是什么。

好的,下面是我正在使用的 Activity..

public class BlogBLEActivity extends Activity implements OnItemClickListener
{
private final static String TAG = BlogBLEActivity.class.getSimpleName();

private BluetoothAdapter bluetoothAdapter;
BluetoothManager bluetoothManager;

boolean hasBleFeature = false;

TextView tvMessage;
int messageId = R.string.doesnt_support_ble;
int colorId = android.R.color.holo_red_light;

private boolean mScanning;
private Handler handler = new Handler();

private static final long SCAN_PERIOD = 10000;
private static final int REQUEST_ENABLE_BT = 1209;

ListView listView;
ArrayList<BluetoothDevice> listDevices;

BleDeviceAdapter bleDeviceAdapter;

TextView tvHumidity;
TextView tvTemperature;
TextView tvPressure;

boolean isConnected = false;

@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.blog_ble);

initParameters();
initViews();

scanLeDevice(true);
}

@SuppressLint("NewApi")
void initParameters()
{
hasBleFeature = getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE);
Log.i(TAG, "hasBleFeature : " + hasBleFeature);

if (hasBleFeature)
{
messageId = R.string.supports_ble;
colorId = android.R.color.holo_blue_light;
} else
{
messageId = R.string.doesnt_support_ble;
colorId = android.R.color.holo_red_light;
}

bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
bluetoothAdapter = bluetoothManager.getAdapter();// BluetoothAdapter.getDefaultAdapter();

if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled())
{
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}

listDevices = new ArrayList<BluetoothDevice>();
bleDeviceAdapter = new BleDeviceAdapter(this, listDevices);
}

void initViews()
{
tvHumidity = (TextView) findViewById(R.id.blog_ble_tv_humidity);
tvTemperature = (TextView) findViewById(R.id.blog_ble_tv_temprature);
tvPressure = (TextView) findViewById(R.id.blog_ble_tv_pressure);

tvMessage = (TextView) findViewById(R.id.blog_ble_tv_message);
tvMessage.setText(getResources().getString(messageId));
tvMessage.setTextColor(getResources().getColor(colorId));

listView = (ListView) findViewById(R.id.blog_ble_list_view);
listView.setAdapter(bleDeviceAdapter);
listView.setOnItemClickListener(this);
}

@SuppressLint("NewApi")
void scanLeDevice(final boolean enable)
{
if (enable)
{
handler.postDelayed(new Runnable()
{
@SuppressLint("NewApi")
@Override
public void run()
{
mScanning = false;
bluetoothAdapter.stopLeScan(leScanCallback);
}
}, SCAN_PERIOD);

mScanning = false;
bluetoothAdapter.startLeScan(leScanCallback);
} else
{
mScanning = false;
bluetoothAdapter.stopLeScan(leScanCallback);
}
}

@SuppressLint("NewApi")
private BluetoothAdapter.LeScanCallback leScanCallback = new BluetoothAdapter.LeScanCallback()
{
@Override
public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord)
{
runOnUiThread(new Runnable()
{
@Override
public void run()
{
if (device != null)
{
bleDeviceAdapter.add(device);
bleDeviceAdapter.notifyDataSetChanged();
}
}
});
}
};

class BleDeviceAdapter extends ArrayAdapter<BluetoothDevice>
{
public BleDeviceAdapter(Context context, List<BluetoothDevice> objects)
{
super(context, R.layout.row_ble_device, R.id.row_ble_device_tv_name, objects);
}

@SuppressLint("NewApi")
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
View row = super.getView(position, convertView, parent);
ViewHolder holder = (ViewHolder) row.getTag();
if (holder == null)
{
holder = new ViewHolder(row);
row.setTag(holder);
}

BluetoothDevice device = getDevice(position);
holder.tvName.setText("" + device.getName());

Log.i(TAG, "" + device.getName());
return row;
}
}

BluetoothDevice getDevice(int position)
{
return (BluetoothDevice) listView.getAdapter().getItem(position);
}

@SuppressLint("NewApi")
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3)
{
BluetoothDevice device = getDevice(position);
Toast.makeText(this, "" + device.getName(), Toast.LENGTH_SHORT).show();
BluetoothGatt connectGatt = device.connectGatt(this, false, mGattCallback);

}

/* Client Configuration Descriptor */
private static final UUID CONFIG_DESCRIPTOR = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");

private static final UUID KITCHEN_SCALE_SERVICE = UUID.fromString("0000780a-0000-1000-8000-00805f9b34fb");
private static final UUID KITCHEN_SCALE_FEATURE_CHAR = UUID.fromString("00008aa0-0000-1000-8000-00805f9b34fb");
private static final UUID KITCHEN_SCALE_MEASUREMENT_CHAR = UUID.fromString("00008aa1-0000-1000-8000-00805f9b34fb");
private static final UUID KITCHEN_SCALE_INTERMEDIATE_CHAR = UUID.fromString("00008aa2-0000-1000-8000-00805f9b34fb");

/*
* In this callback, we've created a bit of a state machine to enforce that
* only one characteristic be read or written at a time until all of our
* sensors are enabled and we are registered to get notifications.
*/
@SuppressLint("NewApi")
private BluetoothGattCallback mGattCallback = new BluetoothGattCallback()
{

/* State Machine Tracking */
private int mState = 0;

private void reset()
{
mState = 0;
}

private void advance()
{
mState++;
}

/*
* Send an enable command to each sensor by writing a configuration
* characteristic. This is specific to the SensorTag to keep power low
* by disabling sensors you aren't using.
*/
private void enableNextSensor(BluetoothGatt gatt)
{
BluetoothGattCharacteristic characteristic;
switch (mState)
{
case 0:
Log.i(TAG, "Enabling weight scale");
characteristic = gatt.getService(KITCHEN_SCALE_SERVICE).getCharacteristic(KITCHEN_SCALE_FEATURE_CHAR);
Log.i(TAG, "Feature Properties : "+characteristic.getProperties());
characteristic.setValue(new byte[]
{ 0x09 });
break;

default:
mHandler.sendEmptyMessage(MSG_DISMISS);
Log.i(TAG, "All Sensors Enabled");
return;
}

gatt.writeCharacteristic(characteristic);
}

/*
* Read the data characteristic's value for each sensor explicitly
*/
private void readNextSensor(BluetoothGatt gatt)
{
BluetoothGattCharacteristic characteristic;
switch (mState)
{
case 0:
Log.i(TAG, "Reading weight cal");
characteristic = gatt.getService(KITCHEN_SCALE_SERVICE).getCharacteristic(KITCHEN_SCALE_MEASUREMENT_CHAR);
break;

default:
mHandler.sendEmptyMessage(MSG_DISMISS);
Log.i(TAG, "All Sensors Enabled");
return;
}

gatt.readCharacteristic(characteristic);
}

/*
* Enable notification of changes on the data characteristic for each
* sensor by writing the ENABLE_NOTIFICATION_VALUE flag to that
* characteristic's configuration descriptor.
*/
private void setNotifyNextSensor(BluetoothGatt gatt)
{
BluetoothGattCharacteristic characteristic;
switch (mState)
{
case 0:
Log.i(TAG, "Set notify weight ");
characteristic = gatt.getService(KITCHEN_SCALE_SERVICE).getCharacteristic(KITCHEN_SCALE_MEASUREMENT_CHAR);
break;

default:
mHandler.sendEmptyMessage(MSG_DISMISS);
Log.i(TAG, "All Sensors Enabled");
return;
}

// Enable local notifications
gatt.setCharacteristicNotification(characteristic, true);
// Enabled remote notifications
BluetoothGattDescriptor desc = characteristic.getDescriptor(CONFIG_DESCRIPTOR);
desc.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
gatt.writeDescriptor(desc);
}

@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState)
{
Log.i(TAG, "Connection State Change: " + status + " -> " + connectionState(newState));
if (status == BluetoothGatt.GATT_SUCCESS && newState == BluetoothProfile.STATE_CONNECTED)
{
/*
* Once successfully connected, we must next discover all the
* services on the device before we can read and write their
* characteristics.
*/
gatt.discoverServices();
mHandler.sendMessage(Message.obtain(null, MSG_PROGRESS, "Discovering Services..."));
} else if (status == BluetoothGatt.GATT_SUCCESS && newState == BluetoothProfile.STATE_DISCONNECTED)
{
/*
* If at any point we disconnect, send a message to clear the
* weather values out of the UI
*/

mHandler.sendEmptyMessage(MSG_CLEAR);
} else if (status != BluetoothGatt.GATT_SUCCESS)
{
/*
* If there is a failure at any stage, simply disconnect
*/
gatt.disconnect();
}
}

@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status)
{
Log.i(TAG, "Services Discovered: " + status);
if (status == BluetoothGatt.GATT_SUCCESS)
{
Log.i(TAG, "No of services discovered: " + gatt.getServices().size());
mHandler.sendMessage(Message.obtain(null, MSG_PROGRESS, "No of services discovered: " + gatt.getServices().size()));

List<BluetoothGattService> services = gatt.getServices();
for (BluetoothGattService bluetoothGattService : services)
{
UUID uuid = bluetoothGattService.getUuid();
Log.e(TAG, ""+uuid.toString());
List<BluetoothGattCharacteristic> characteristics = bluetoothGattService.getCharacteristics();
for (BluetoothGattCharacteristic bluetoothGattCharacteristic : characteristics)
{
UUID uuidC = bluetoothGattCharacteristic.getUuid();
Log.i(TAG, "Gatt Properties : "+bluetoothGattCharacteristic.getProperties());
Log.i(TAG, ""+uuidC.toString());
CharacteristicHelper helper = new CharacteristicHelper(bluetoothGattCharacteristic);
Log.i(TAG, "isRead : "+helper.isRead());
Log.i(TAG, "isWrite : "+helper.isWrite());
Log.i(TAG, "isNotify : "+helper.isNotify());
Log.i(TAG, "isWriteNoResponse : "+helper.isWriteNoResponse());
}
}
}
// mHandler.sendMessage(Message.obtain(null, MSG_PROGRESS,
// "Enabling Sensors..."));
/*
* With services discovered, we are going to reset our state machine
* and start working through the sensors we need to enable
*/
reset();
enableNextSensor(gatt);
}

@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status)
{
Log.i(TAG, "onCharacteristicRead");
// For each read, pass the data up to the UI thread to update the
// display
/**methodToUpdateUI().*/

// After reading the initial value, next we enable notifications
setNotifyNextSensor(gatt);
}

@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status)
{
Log.i(TAG, "onCharacteristicWrite");
// After writing the enable flag, next we read the initial value
readNextSensor(gatt);
}

@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic)
{
Log.i(TAG, "onCharacteristicChanged");
/*
* After notifications are enabled, all updates from the device on
* characteristic value changes will be posted here. Similar to
* read, we hand these up to the UI thread to update the display.
*/
}

@Override
public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status)
{
Log.i(TAG, "onDescriptorWrite");
// Once notifications are enabled, we move to the next sensor and
// start over with enable
advance();
enableNextSensor(gatt);
}

@Override
public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status)
{
Log.i(TAG, "Remote RSSI: " + rssi);
}

private String connectionState(int status)
{
switch (status)
{
case BluetoothProfile.STATE_CONNECTED:
return "Connected";
case BluetoothProfile.STATE_DISCONNECTED:
return "Disconnected";
case BluetoothProfile.STATE_CONNECTING:
return "Connecting";
case BluetoothProfile.STATE_DISCONNECTING:
return "Disconnecting";
default:
return String.valueOf(status);
}
}
};

/*
* We have a Handler to process event results on the main thread
*/
private static final int MSG_PROGRESS = 201;
private static final int MSG_DISMISS = 202;
private static final int MSG_CLEAR = 301;
private Handler mHandler = new Handler()
{
@SuppressLint("NewApi")
@Override
public void handleMessage(Message msg)
{
BluetoothGattCharacteristic characteristic;
switch (msg.what)
{
case MSG_PROGRESS:
tvMessage.setText((String) msg.obj);
break;
case MSG_DISMISS:
tvMessage.setText("Service Enabled");
break;
case MSG_CLEAR:
tvMessage.setText("");
break;
}
}
};
}

在我的 Activity 中,首先我正在扫描所有可用的设备并准备 ListView。单击列表项后,我连接到该特定设备。当设备的状态变为已连接时,我就会发现服务。我有设备服务及其特性的 UUID。但我不确定如何写入任何特定特征或从中启用或读取数据。 虽然我已经尝试过这个东西,但我没有看到任何成功。

如果有人对此有任何想法,请帮助我。

最佳答案

有一个需要我使用的设备

descriptor.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE)

代替

descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE)

正如这个问题中所解释的那样

Android BLE API: GATT Notification not received

关于android - 获得蓝牙低功耗 (BLE) 设备通知的步骤是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20907411/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com