- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我正在开发一个 BLE 应用程序,基于 google 提供的 Gatt 示例项目:https://developer.android.com/samples/BluetoothLeGatt/index.html。所以,我可以成功发送数据写入一个特性。现在我需要知道这个特征什么时候改变它的值。我知道我需要实现 setCharacteristicNotification() 方法和 onDescriptorWrite() 方法。但我不能这样做。搜索,我发现了一些想法: Android BLE API: GATT Notification not received , What are the steps to get notified by Bluetooth Low Energy (BLE) device? ,但仍然没有运气我不明白它是如何工作的,我需要定义什么参数或我需要做什么!!!。一些好的灵魂可以分享我一个完整的项目来做到这一点。我所需要的只是在 BLE 设备返回一些数据时可视化特征值。
我阅读了官方的 Android 文档,但并没有那么具体。提前致谢
这些是我的代码:
设备
public class DeviceControlActivity extends Activity {
public static final String EXTRAS_DEVICE_NAME = "DEVICE_NAME";
public static final String EXTRAS_DEVICE_ADDRESS = "DEVICE_ADDRESS";
private TextView mConnectionState;
private TextView mDataField;
private TextView mRssiField;
private String mDeviceName;
private String mDeviceAddress;
private ExpandableListView mGattServicesList;
private BluetoothLeService mBluetoothLeService;
static ArrayList<ArrayList<BluetoothGattCharacteristic>> mGattCharacteristics = new ArrayList<ArrayList<BluetoothGattCharacteristic>>();
private boolean mConnected = false;
private BluetoothGattCharacteristic mNotifyCharacteristic;
private BluetoothGattCharacteristic mWriteCharacteristic, mReadCharacteristic;
Button Escritor;
byte hello[] = { 0 };
private final String LIST_NAME = "NAME";
private final String LIST_UUID = "UUID";
// BluetoothGattCharacteristic characteristic;
// public BluetoothGatt mBluetoothGatt;
// Code to manage Service lifecycle.
private final ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder service) {
mBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService();
if (!mBluetoothLeService.initialize()) {
Log.e("Unable to initialize Bluetooth");
finish();
}
// Automatically connects to the device upon successful start-up
// initialization.
mBluetoothLeService.connect(mDeviceAddress);
mBluetoothLeService.setBLEServiceCb(mDCServiceCb);
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
mBluetoothLeService = null;
}
};
// If a given GATT characteristic is selected, check for supported features.
// This sample
// demonstrates 'Read' and 'Notify' features. See
// http://d.android.com/reference/android/bluetooth/BluetoothGatt.html for
// the complete
// list of supported characteristic features.
private final ExpandableListView.OnChildClickListener servicesListClickListner = new ExpandableListView.OnChildClickListener() {
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
@Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
if (mGattCharacteristics != null) {
final BluetoothGattCharacteristic characteristic = mGattCharacteristics.get(groupPosition).get(childPosition);
final int charaProp = characteristic.getProperties();
if ((charaProp & BluetoothGattCharacteristic.PROPERTY_READ) > 0) {
// If there is an active notification on a characteristic,
// clear
// it first so it doesn't update the data field on the user
// interface.
Log.d("BluetoothGattCharacteristic has PROPERTY_READ, so send read request");
if (mNotifyCharacteristic != null) {
mBluetoothLeService.setCharacteristicNotification(mNotifyCharacteristic, true);
mNotifyCharacteristic = null;
}
mBluetoothLeService.readCharacteristic(characteristic);
/*Toast.makeText(getApplicationContext(), "Leyó Algo",
Toast.LENGTH_SHORT).show();*/
}
if ((charaProp & BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
Log.d("BluetoothGattCharacteristic has PROPERTY_NOTIFY, so send notify request");
mNotifyCharacteristic = characteristic;
mBluetoothLeService.setCharacteristicNotification(characteristic, true);
}
if (((charaProp & BluetoothGattCharacteristic.PROPERTY_WRITE) | (charaProp & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE)) > 0) {
Log.d("BluetoothGattCharacteristic has PROPERY_WRITE | PROPERTY_WRITE_NO_RESPONSE");
mWriteCharacteristic = characteristic;
// popup an dialog to write something.
showCharactWriteDialog();
}
return true;
}
return false;
}
};
private void showCharactWriteDialog() {
DialogFragment newFrame = new BleCharacterDialogFragment();
newFrame.show(getFragmentManager(), "blewrite");
}
private void clearUI() {
mGattServicesList.setAdapter((SimpleExpandableListAdapter) null);
mDataField.setText(R.string.no_data);
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.gatt_services_characteristics);
final Intent intent = getIntent();
mDeviceName = intent.getStringExtra(EXTRAS_DEVICE_NAME);
mDeviceAddress = intent.getStringExtra(EXTRAS_DEVICE_ADDRESS);
// Sets up UI references.
((TextView) findViewById(R.id.device_address)).setText(mDeviceAddress);
mGattServicesList = (ExpandableListView) findViewById(R.id.gatt_services_list);
mGattServicesList.setOnChildClickListener(servicesListClickListner);
mConnectionState = (TextView) findViewById(R.id.connection_state);
mDataField = (TextView) findViewById(R.id.data_value);
mRssiField = (TextView) findViewById(R.id.signal_rssi);
getActionBar().setTitle(mDeviceName);
getActionBar().setDisplayHomeAsUpEnabled(true);
Intent gattServiceIntent = new Intent(this, BluetoothLeService.class);
bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE);
}
@Override
protected void onResume() {
super.onResume();
// registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter());
if (mBluetoothLeService != null) {
final boolean result = mBluetoothLeService.connect(mDeviceAddress);
Log.d("Connect request result=" + result);
}
}
@Override
protected void onPause() {
super.onPause();
// unregisterReceiver(mGattUpdateReceiver);
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(mServiceConnection);
mBluetoothLeService = null;
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.gatt_services, menu);
if (mConnected) {
menu.findItem(R.id.menu_connect).setVisible(false);
menu.findItem(R.id.menu_disconnect).setVisible(true);
} else {
menu.findItem(R.id.menu_connect).setVisible(true);
menu.findItem(R.id.menu_disconnect).setVisible(false);
}
return true;
}
@TargetApi(Build.VERSION_CODES.ECLAIR)
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_connect:
mBluetoothLeService.connect(mDeviceAddress);
return true;
case R.id.menu_disconnect:
mBluetoothLeService.disconnect();
return true;
case android.R.id.home:
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
private void updateConnectionState(final int resourceId) {
runOnUiThread(new Runnable() {
@Override
public void run() {
mConnectionState.setText(resourceId);
}
});
}
private void displayData(String data) {
if (data != null) {
mDataField.setText(data);
}
}
private void displayRssi(String rssi) {
if (rssi != null) {
// Log.d("-- dispaly Rssi: " + rssi);
mRssiField.setText(rssi);
}
}
private void displayRetorno(String rssi) {
if (rssi != null) {
// Log.d("-- dispaly Rssi: " + rssi);
mRssiField.setText(rssi+"Ñ");
Toast.makeText(getApplicationContext(), "SsSsSs"+"viendo", Toast.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.
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
private void displayGattServices(List<BluetoothGattService> gattServices) {
Log.d("displayGATTServices");
if (gattServices == null)
return;
String uuid = null;
String unknownServiceString = getResources().getString(R.string.unknown_service);
String unknownCharaString = getResources().getString(R.string.unknown_characteristic);
ArrayList<HashMap<String, String>> gattServiceData = new ArrayList<HashMap<String, String>>();
ArrayList<ArrayList<HashMap<String, String>>> gattCharacteristicData = new ArrayList<ArrayList<HashMap<String, String>>>();
mGattCharacteristics = new ArrayList<ArrayList<BluetoothGattCharacteristic>>();
// Loops through available GATT Services.
for (BluetoothGattService gattService : gattServices) {
HashMap<String, String> currentServiceData = new HashMap<String, String>();
uuid = gattService.getUuid().toString();
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);
}
SimpleExpandableListAdapter gattServiceAdapter = new SimpleExpandableListAdapter(this, gattServiceData, android.R.layout.simple_expandable_list_item_2, new String[] { LIST_NAME, LIST_UUID },
new int[] { android.R.id.text1, android.R.id.text2 }, gattCharacteristicData, android.R.layout.simple_expandable_list_item_2, new String[] { LIST_NAME, LIST_UUID }, new int[] {
android.R.id.text1, android.R.id.text2 });
mGattServicesList.setAdapter(gattServiceAdapter);
final BluetoothGattCharacteristic characteristic = mGattCharacteristics.get(2).get(0);
final int charaProp = characteristic.getProperties();
mWriteCharacteristic = characteristic;
mBluetoothLeService.setCharacteristicNotification(mWriteCharacteristic, true);
if (mWriteCharacteristic != null) {
byte[] value = { (byte) 0x0D };
mWriteCharacteristic.setValue("ATZ");
Toast.makeText(getApplicationContext(), String.valueOf(mWriteCharacteristic.getStringValue(0)), Toast.LENGTH_SHORT).show();
mBluetoothLeService.mBluetoothGatt.writeCharacteristic(mWriteCharacteristic);
mWriteCharacteristic.setValue(value);
mBluetoothLeService.mBluetoothGatt.writeCharacteristic(mWriteCharacteristic);
boolean jo=mBluetoothLeService.mBluetoothGatt.readCharacteristic(mWriteCharacteristic);
Toast.makeText(getApplicationContext(), String.valueOf(mWriteCharacteristic.getStringValue(0)), Toast.LENGTH_SHORT).show();
/*mWriteCharacteristic.setValue("ATE0");
mBluetoothLeService.mBluetoothGatt.writeCharacteristic(mWriteCharacteristic);
mWriteCharacteristic.setValue(value);
mBluetoothLeService.mBluetoothGatt.writeCharacteristic(mWriteCharacteristic);
mWriteCharacteristic.setValue("ATE0");
mBluetoothLeService.mBluetoothGatt.writeCharacteristic(mWriteCharacteristic);
mWriteCharacteristic.setValue(value);
mBluetoothLeService.mBluetoothGatt.writeCharacteristic(mWriteCharacteristic);
mWriteCharacteristic.setValue("ATL0");
mBluetoothLeService.mBluetoothGatt.writeCharacteristic(mWriteCharacteristic);
mWriteCharacteristic.setValue(value);
mBluetoothLeService.mBluetoothGatt.writeCharacteristic(mWriteCharacteristic);
mWriteCharacteristic.setValue("ATM0");
mBluetoothLeService.mBluetoothGatt.writeCharacteristic(mWriteCharacteristic);
mWriteCharacteristic.setValue(value);
mBluetoothLeService.mBluetoothGatt.writeCharacteristic(mWriteCharacteristic);
mWriteCharacteristic.setValue("ATS0");
mBluetoothLeService.mBluetoothGatt.writeCharacteristic(mWriteCharacteristic);
mWriteCharacteristic.setValue(value);
mBluetoothLeService.mBluetoothGatt.writeCharacteristic(mWriteCharacteristic);
mWriteCharacteristic.setValue("ATH0");
mBluetoothLeService.mBluetoothGatt.writeCharacteristic(mWriteCharacteristic);
mWriteCharacteristic.setValue(value);
mBluetoothLeService.mBluetoothGatt.writeCharacteristic(mWriteCharacteristic);
mWriteCharacteristic.setValue("ATAT2");
mBluetoothLeService.mBluetoothGatt.writeCharacteristic(mWriteCharacteristic);
mWriteCharacteristic.setValue(value);
mBluetoothLeService.mBluetoothGatt.writeCharacteristic(mWriteCharacteristic);*/
/*mWriteCharacteristic.setValue("ATZ");
mBluetoothLeService.mBluetoothGatt.writeCharacteristic(mWriteCharacteristic);
mWriteCharacteristic.setValue(value);
mBluetoothLeService.mBluetoothGatt.writeCharacteristic(mWriteCharacteristic);*/
}
final BluetoothGattCharacteristic characteristic2 = mGattCharacteristics.get(0).get(0);
final int charaProp2 = characteristic2.getProperties();
mReadCharacteristic = characteristic2;
mBluetoothLeService.readCharacteristic(mReadCharacteristic);
}
private DCServiceCb mDCServiceCb = new DCServiceCb();
public class DCServiceCb implements BluetoothLeService.BLEServiceCallback {
@Override
public void displayRssi(final int rssi) {
runOnUiThread(new Runnable() {
@Override
public void run() {
DeviceControlActivity.this.displayRssi(String.valueOf(rssi));
}
});
}
@Override
public void displayRetorno (final int rssi) {
runOnUiThread(new Runnable() {
@Override
public void run() {
DeviceControlActivity.this.displayRetorno("algo!!!!");
}
});
}
@Override
public void displayData(final String data) {
runOnUiThread(new Runnable() {
@Override
public void run() {
DeviceControlActivity.this.displayData(data);
Toast.makeText(getApplicationContext(), data+"SsSsSs", Toast.LENGTH_SHORT).show();
}
});
}
@Override
public void notifyConnectedGATT() {
runOnUiThread(new Runnable() {
@Override
public void run() {
mConnected = true;
updateConnectionState(R.string.connected);
invalidateOptionsMenu();
}
});
}
@Override
public void notifyDisconnectedGATT() {
runOnUiThread(new Runnable() {
@Override
public void run() {
mConnected = false;
updateConnectionState(R.string.disconnected);
invalidateOptionsMenu();
clearUI();
}
});
}
@Override
public void displayGATTServices() {
Log.d("displayGATTServices.");
runOnUiThread(new Runnable() {
@Override
public void run() {
if (mBluetoothLeService != null) {
DeviceControlActivity.this.displayGattServices(mBluetoothLeService.getSupportedGattServices());
}
}
});
}
}
@SuppressLint("ValidFragment")
public class BleCharacterDialogFragment extends DialogFragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.write_charact_dialog, container, false);
final EditText ed = (EditText) v.findViewById(R.id.charact_value);
Button ok = (Button) v.findViewById(R.id.dialog_confirm);
Button cancel = (Button) v.findViewById(R.id.dialog_cancel);
ok.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mWriteCharacteristic != null) {
mWriteCharacteristic.setValue("AA");
mBluetoothLeService.mBluetoothGatt.writeCharacteristic(mWriteCharacteristic);
}
// characteristic.setValue("FF");
// characteristic.setValue(new byte[] {(byte) 0xFF});
// writeCharacteristicValue(characteristic);
//
Toast.makeText(getApplicationContext(), "Se envío el dato", Toast.LENGTH_SHORT).show();
dismiss();
return;
}
});
cancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dismiss();
}
});
return v;
}
}
public void writeCharacteristicValue(BluetoothGattCharacteristic characteristica) {
byte[] value = { (byte) 0xFF };
characteristica.setValue(bytesToHex(value));
boolean status = mBluetoothLeService.mBluetoothGatt.writeCharacteristic(characteristica);
}
final protected static char[] hexArray = "0123456789ABCDEF".toCharArray();
public String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
int v;
for (int j = 0; j < bytes.length; j++) {
v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
}
服务
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
public class BluetoothLeService extends Service {
// private final static String TAG =
// BluetoothLeService.class.getSimpleName();
private BluetoothManager mBluetoothManager;
private BluetoothAdapter mBluetoothAdapter;
private String mBluetoothDeviceAddress;
BluetoothGatt mBluetoothGatt;
private int mConnectionState = STATE_DISCONNECTED;
private BLEServiceCallback mBLEServiceCb = null;
private static final int STATE_DISCONNECTED = 0;
private static final int STATE_CONNECTING = 1;
private static final int STATE_CONNECTED = 2;
private static final int GATT_SUCCESS=0;
public final static UUID UUID_HEART_RATE_MEASUREMENT = UUID.fromString(SampleGattAttributes.HEART_RATE_MEASUREMENT);
private final long READING_RSSI_TASK_FREQENCY = 500;
private static final int READ_RSSI_REPEAT = 1;
private final Handler mHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case READ_RSSI_REPEAT:
if (mBluetoothGatt != null) {
mBluetoothGatt.readRemoteRssi();
if(DeviceControlActivity.mGattCharacteristics.size()==3)
{
boolean pp=mBluetoothGatt.readCharacteristic(DeviceControlActivity.mGattCharacteristics.get(2).get(0));//
//BluetoothGattCallback.onCharacteristicRead(mBluetoothGatt, DeviceControlActivity.mGattCharacteristics.get(2).get(0), GATT_SUCCESS);
}
}
sendMessageDelayed(obtainMessage(READ_RSSI_REPEAT), READING_RSSI_TASK_FREQENCY);
break;
}
}
};
private void startReadRssi() {
if (mHandler.hasMessages(READ_RSSI_REPEAT)) {
Log.w("+++++++++ Handler already has Message: READ_RSSI_REPEAT");
}
mHandler.sendEmptyMessage(READ_RSSI_REPEAT);
}
private void stopReadRssi() {
mHandler.removeMessages(READ_RSSI_REPEAT);
}
// Implements callback methods for GATT events that the app cares about. For
// example,
// connection change and services discovered.
private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
Log.d("onConnectionStateChange status = " + status + ", newState = " + newState);
if (newState == BluetoothProfile.STATE_CONNECTED) {
if (mBLEServiceCb != null) {
mBLEServiceCb.notifyConnectedGATT();
}
Log.d("Connected to GATT server.");
// Attempts to discover services after successful connection.
Log.d("Attempting to start service discovery:" + mBluetoothGatt.discoverServices());
startReadRssi();
//si se conecta empiece a leer mi caracteritica
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
if (mBLEServiceCb != null) {
mBLEServiceCb.notifyDisconnectedGATT();
}
stopReadRssi();
Log.d("Disconnected from GATT server.");
}
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
Log.d("onServicesDiscovered status = " + status);
if (status == BluetoothGatt.GATT_SUCCESS) {
if (mBLEServiceCb != null) {
mBLEServiceCb.displayGATTServices();
}
} else {
Log.d("onServicesDiscovered received: " + status);
}
setCharacteristicNotification(DeviceControlActivity.mGattCharacteristics.get(2).get(0), true);//puede que sea mejor no ponerlo, pero no se
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
Log.d("onCharacteristicRead status: " + status);
Toast.makeText(getApplicationContext(), "MMMM"+"BBB"+"SsSsSs", Toast.LENGTH_SHORT).show();
if (status == BluetoothGatt.GATT_SUCCESS) {
displayCharacteristic(characteristic);
}
}
@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
Log.d("------------- onCharacteristicWrite status: " + status);
// handler callback of write characteristic.
// do somethings here.
}
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
Log.d("onCharacteristicChanged");
Toast.makeText(getApplicationContext(), "se ejecutó el metodo de cambio en caracteristica", Toast.LENGTH_SHORT).show();
displayCharacteristic(characteristic);
}
@Override
public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
// Log.d("onReadRemoteRssi rssi = " + rssi + "; status = " +
// status);
if (mBLEServiceCb != null) {
mBLEServiceCb.displayRssi(rssi);
}
}
};
public void setBLEServiceCb(BLEServiceCallback cb) {
if (cb != null) {
mBLEServiceCb = cb;
}
}
private void displayCharacteristic(final BluetoothGattCharacteristic characteristic) {
String msg = null;
// This is special handling for the Heart Rate Measurement profile. Data
// parsing is
// carried out as per profile specifications:
// http://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml
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("Heart rate format UINT16.");
} else {
format = BluetoothGattCharacteristic.FORMAT_UINT8;
Log.d("Heart rate format UINT8.");
}
final int heartRate = characteristic.getIntValue(format, 1);
Log.d(String.format("Received heart rate: %d", heartRate));
msg = 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));
msg = new String(data) + "\n" + stringBuilder.toString();
}
}
if (mBLEServiceCb != null) {
mBLEServiceCb.displayData(msg);
}
}
public class LocalBinder extends Binder {
BluetoothLeService getService() {
return BluetoothLeService.this;
}
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
@Override
public boolean onUnbind(Intent intent) {
close();
return super.onUnbind(intent);
}
private final IBinder mBinder = new LocalBinder();
public boolean initialize() {
// For API level 18 and above, get a reference to BluetoothAdapter
// through
// BluetoothManager.
if (mBluetoothManager == null) {
mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
if (mBluetoothManager == null) {
Log.e("Unable to initialize BluetoothManager.");
return false;
}
}
mBluetoothAdapter = mBluetoothManager.getAdapter();
if (mBluetoothAdapter == null) {
Log.e("Unable to obtain a BluetoothAdapter.");
return false;
}
return true;
}
public boolean connect(final String address) {
if (mBluetoothAdapter == null || address == null) {
Log.w("BluetoothAdapter not initialized or unspecified address.");
return false;
}
// Previously connected device. Try to reconnect.
if (mBluetoothDeviceAddress != null && address.equals(mBluetoothDeviceAddress) && mBluetoothGatt != null) {
Log.d("Trying to use an existing mBluetoothGatt for connection.");
if (mBluetoothGatt.connect()) {
mConnectionState = STATE_CONNECTING;
return true;
} else {
return false;
}
}
final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
if (device == null) {
Log.w("Device not found. Unable to connect.");
return false;
}
// We want to directly connect to the device, so we are setting the
// autoConnect
// parameter to false.
mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
Log.d("Trying to create a new connection.");
mBluetoothDeviceAddress = address;
mConnectionState = STATE_CONNECTING;
return true;
}
public void disconnect() {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.w("BluetoothAdapter not initialized");
return;
}
mBluetoothGatt.disconnect();
}
public void close() {
if (mBluetoothGatt == null) {
return;
}
mBluetoothGatt.close();
mBluetoothGatt = null;
}
/**
* Request a read on a given {@code BluetoothGattCharacteristic}. The read
* result is reported asynchronously through the
* {@code BluetoothGattCallback#onCharacteristicRead(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic, int)}
* callback.
*
* @param characteristic
* The characteristic to read from.
*/
public void readCharacteristic(BluetoothGattCharacteristic characteristic) {
Toast.makeText(getApplicationContext(), "readCharacteristic en Servicio", Toast.LENGTH_SHORT).show();
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.w("BluetoothAdapter not initialized");
return;
}
mBluetoothGatt.readCharacteristic(characteristic);
}
/**
* Requst a write on a give {@code BluetoothGattCharacteristic}. The write
* result is reported asynchronously through the
* {@code BluetoothGattCallback#onCharacteristicWrite(andorid.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic, int)}
* callback.
*/
public void writeCharacteristic(BluetoothGattCharacteristic characteristic) {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.w("BluetoothAdapter not initialized");
return;
}
mBluetoothGatt.writeCharacteristic(characteristic);
}
/**
* Enables or disables notification on a give characteristic.
*
* @param characteristic
* Characteristic to act on.
* @param enabled
* If true, enable notification. False otherwise.
*/
public void setCharacteristicNotification(BluetoothGattCharacteristic characteristic, boolean enabled) {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.w("BluetoothAdapter not initialized");
return;
}
mBluetoothGatt.setCharacteristicNotification(characteristic, true);
// This is specific to Heart Rate Measurement.
if (UUID_HEART_RATE_MEASUREMENT.equals(characteristic.getUuid())) {
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString(SampleGattAttributes.CLIENT_CHARACTERISTIC_CONFIG));
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
mBluetoothGatt.writeDescriptor(descriptor);
}
}
/**
* Retrieves a list of supported GATT services on the connected device. This
* should be invoked only after {@code BluetoothGatt#discoverServices()}
* completes successfully.
*
* @return A {@code List} of supported services.
*/
public List<BluetoothGattService> getSupportedGattServices() {
if (mBluetoothGatt == null)
return null;
return mBluetoothGatt.getServices();
}
public interface BLEServiceCallback {
public void displayRssi(int rssi);
public void displayData(String data);
public void notifyConnectedGATT();
public void notifyDisconnectedGATT();
public void displayGATTServices();
public void displayRetorno(int rssi);
}
}
最佳答案
要在 Android 中接收通知,您需要将特征通知设置为 true
gatt.setCharacteristicNotification(characteristic, true);
还需要设置客户端特征配置描述符0x2902
// 0x2902 org.bluetooth.descriptor.gatt.client_characteristic_configuration.xml
UUID uuid = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb");
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(uuid);
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
gatt.writeDescriptor(descriptor);
更好的 API 是让 setCharacteristicNotification 设置描述符,但不幸的是,它似乎不是那样工作的。
关于android - 订阅 BLE Gatt 通知 Android,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27068673/
我有一个应用程序应该在应用程序处于前台和后台(不在历史记录中)时显示提醒通知。 在前景情况下,我通过以下方法实现了这一点。 PendingIntent pendingIntent = PendingI
如何为我的 WPF 应用程序创建通知,例如浏览器上的通知,它们通过浏览器顶部的“工具栏”显示消息或通过在右下角向上/向下滑动的弹出窗口显示“MSN”样式通知屏幕。也许在应用程序中心淡入/淡出的面板可以
关闭。这个问题是opinion-based .它目前不接受答案。 想要改进这个问题? 更新问题,以便 editing this post 可以用事实和引用来回答它. 关闭 9 年前。 Improve
我正在使用 Redis 作为分布式缓存。我有不同的应用程序,它们只听特定的键。例如:App1 听 App1.*App2 监听 App2.* 等等。 我的应用程序使用以下模式接收通知:App1:“ ke
我正在尝试构建一个基于官方节点 docker 镜像的 docker 镜像,我想知道是否有某种方法可以在推送新版本的官方节点镜像时自动重建镜像。这样我的图像就不会基于过时的基础图像。 也许有类似 rss
我在一个项目中工作,我需要在添加或修改文件时在数据库中记录文件信息,以便它们保持同步。这些文件应该存储在 Nextcloud 服务器中,那么 Nextcloud 是否有办法通知这些更改(例如 webh
通知类中的方法via 如何根据用户的偏好动态变化,一个用户可能想通过电子邮件接收,而另一个用户则不想 public function via($notifiable) { return ['d
我有一个应用程序,我正在发送推送通知,如果用户登录到应用程序,这很好 - 但是,如果他们没有/如果他们没有在 X 分钟内阅读通知,我想给他们发送一封电子邮件. 我要解决的方法是使用 Laravel N
我正在使用 Django 的 contrib.comments 并想了解以下内容。 是否有任何实用程序或应用程序可以插入到某个应用程序中,当对某个项目发表评论时向您发送通知? 我并没有真正使用过那么多
我希望用户在启动应用程序之前接受协议(protocol)。所以在 appDelegate.m 中我有以下内容: - (BOOL)application:(UIApplication *)applica
我正在创建一个新指令,我想知道如何在 angular 从 DOM 中删除元素时收到通知。 我的目标是在删除元素时添加 jquery 动画。 最佳答案 如果您尝试对元素的移除进行动画处理,则需要在移除元
我正在编写一个应用程序,其工作方式与Apple的Weather.app非常相似:底部有一个UIPageControl,屏幕中间有一个UIScrollView。在我的代码中,我实现了 - (void)s
如何查明 iPhone 注册了哪些通知? 例如: notify_post("com.apple.springboard/Prefs"); 最佳答案 虽然这个问题的答案已经得到确认,但由于 @Nate
我的 Cocoa 应用程序中有一个 TextField。该文本字段有时会被填充,有时会为空。 我希望当字段为空时按钮被禁用。现在,每当我对 Core Data 执行某些操作时,我都会检查该字段,Tex
我的应用程序在其数据库中包含文档。用户可以打开文档,在这种情况下,文档将保存到临时文件夹并在用户计算机上打开。 我希望在这些临时文件之一发生更改时收到通知,并让用户将更改后的文档保存回数据库。 在 D
我目前正在开发一个网络应用程序,它不断对 php 进行 ajax 调用(轮询),以从数据库中提取新的“任务”,有点像 gmail/facebook 检查新电子邮件和消息的方式。当前的 JavaScri
我正在尝试让通知适用于我使用 Angular 5 和 Electron 制作的 Electron 应用程序。到目前为止,我的 index.html 文件中有以下代码: function doNo
我有一个录音/播放应用程序。它在后台运行。当它进入后台时,如果任何其他音频应用程序打开或开始使用音频资源,我想适本地处理我的应用程序。 iOS 提供了一种发送此类通知的方法,如在 ipod 播放器中看
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 4 年前。 Improve this ques
是否有 Subversion 的工具可以在对某些文件提交更改时自动通知我? 最佳答案 您可以创建一个 post-commit hook script “ Hook ”提交。 在钩子(Hook)脚本中,
我是一名优秀的程序员,十分优秀!