我正在尝试将蓝牙BLE开发人员入门套件中的代码调整到我自己的应用程序中(即,完全相同的代码在示例应用程序上运行良好)。 但是,我无法连接到任何设备,因为当我按下连接按钮(方法onConnect)时,bluetooth_le_adapter为空。
我认为bluetooth_le_adapter没有很好地初始化,因此在启动时为null。
您对如何解决此问题有任何想法吗?感谢
PeripheralControlActivity.java:
public class PeripheralControlActivity extends Activity {
public static final String EXTRA_NAME = "name";
public static final String EXTRA_ID = "id";
private String device_name;
private String device_address;
private Timer mTimer;
private boolean sound_alarm_on_disconnect = false;
private int alert_level;
private boolean back_requested = false;
private boolean share_with_server = false;
private Switch share_switch;
private BleAdapterService bluetooth_le_adapter;
private final ServiceConnection service_connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder service) {
bluetooth_le_adapter = ((BleAdapterService.LocalBinder) service).getService();
bluetooth_le_adapter.setActivityHandler(message_handler);
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
bluetooth_le_adapter = null;
}
};
private Handler message_handler = new Handler() {
@Override
public void handleMessage(Message msg) {
Bundle bundle;
String service_uuid = "";
String characteristic_uuid = "";
byte[] b = null;
switch (msg.what) {
case BleAdapterService.MESSAGE:
bundle = msg.getData();
String text = bundle.getString(BleAdapterService.PARCEL_TEXT);
showMsg(text);
break;
case BleAdapterService.GATT_CONNECTED:
((Button) PeripheralControlActivity.this
.findViewById(R.id.connectButton)).setEnabled(false);
((Button) PeripheralControlActivity.this.findViewById(R.id.noiseButton))
.setEnabled(true);
share_switch.setEnabled(true);
// we're connected
showMsg("CONNECTED");
/*AlarmManager am = AlarmManager.getInstance();
Log.d(Constants.TAG, "alarmIsSounding=" + am.alarmIsSounding());
if (am.alarmIsSounding()) {
Log.d(Constants.TAG, "Stopping alarm");
am.stopAlarm();
}*/
bluetooth_le_adapter.discoverServices();
break;
case BleAdapterService.GATT_DISCONNECT:
((Button) PeripheralControlActivity.this
.findViewById(R.id.connectButton)).setEnabled(true);
// we're disconnected
showMsg("DISCONNECTED");
// hide the rssi distance colored rectangle
((LinearLayout) PeripheralControlActivity.this
.findViewById(R.id.rectangle))
.setVisibility(View.INVISIBLE);
share_switch.setEnabled(false);
// disable the LOW/MID/HIGH alert level selection buttons
((Button) PeripheralControlActivity.this.findViewById(R.id.lowButton)).setEnabled(false);
((Button) PeripheralControlActivity.this.findViewById(R.id.midButton)).setEnabled(false);
((Button) PeripheralControlActivity.this.findViewById(R.id.highButton)).setEnabled(false);
// stop the rssi reading timer
stopTimer();
/*if (alert_level > 0) {
AlarmManager.getInstance().soundAlarm(getResources().openRawResourceFd(R.raw.alarm));
}*/
if (back_requested) {
PeripheralControlActivity.this.finish();
}
break;
case BleAdapterService.GATT_SERVICES_DISCOVERED:
// validate services and if ok....
List<BluetoothGattService> slist = bluetooth_le_adapter.getSupportedGattServices();
boolean link_loss_present = false;
boolean immediate_alert_present = false;
boolean tx_power_present = false;
boolean proximity_monitoring_present = false;
for (BluetoothGattService svc : slist) {
Log.d(Constants.TAG, "UUID=" + svc.getUuid().toString().toUpperCase() + " INSTANCE=" + svc.getInstanceId());
if (svc.getUuid().toString().equalsIgnoreCase(BleAdapterService.LINK_LOSS_SERVICE_UUID)) {
link_loss_present = true;
continue;
}
if (svc.getUuid().toString().equalsIgnoreCase(BleAdapterService.IMMEDIATE_ALERT_SERVICE_UUID)) {
immediate_alert_present = true;
continue;
}
if (svc.getUuid().toString().equalsIgnoreCase(BleAdapterService.TX_POWER_SERVICE_UUID)) {
tx_power_present = true;
continue;
}
if (svc.getUuid().toString().equalsIgnoreCase(BleAdapterService.PROXIMITY_MONITORING_SERVICE_UUID)) {
proximity_monitoring_present = true;
continue;
}
}
if (link_loss_present && immediate_alert_present && tx_power_present && proximity_monitoring_present) {
showMsg("Device has expected services");
// show the rssi distance colored rectangle
((LinearLayout) PeripheralControlActivity.this
.findViewById(R.id.rectangle))
.setVisibility(View.VISIBLE);
// enable the LOW/MID/HIGH alert level selection buttons
((Button) PeripheralControlActivity.this.findViewById(R.id.lowButton)).setEnabled(true);
((Button) PeripheralControlActivity.this.findViewById(R.id.midButton)).setEnabled(true);
((Button) PeripheralControlActivity.this.findViewById(R.id.highButton)).setEnabled(true);
showMsg("Reading alert_level");
bluetooth_le_adapter.readCharacteristic(
BleAdapterService.LINK_LOSS_SERVICE_UUID,
BleAdapterService.ALERT_LEVEL_CHARACTERISTIC);
} else {
showMsg("Device does not have expected GATT services");
}
break;
case BleAdapterService.GATT_REMOTE_RSSI:
bundle = msg.getData();
int rssi = bundle.getInt(BleAdapterService.PARCEL_RSSI);
PeripheralControlActivity.this.updateRssi(rssi);
break;
case BleAdapterService.GATT_CHARACTERISTIC_READ:
bundle = msg.getData();
Log.d(Constants.TAG, "Service=" + bundle.get(BleAdapterService.PARCEL_SERVICE_UUID).toString().toUpperCase() + " Characteristic=" + bundle.get(BleAdapterService.PARCEL_CHARACTERISTIC_UUID).toString().toUpperCase());
if (bundle.get(BleAdapterService.PARCEL_CHARACTERISTIC_UUID).toString().toUpperCase()
.equals(BleAdapterService.ALERT_LEVEL_CHARACTERISTIC)
&& bundle.get(BleAdapterService.PARCEL_SERVICE_UUID).toString().toUpperCase()
.equals(BleAdapterService.LINK_LOSS_SERVICE_UUID)) {
b = bundle.getByteArray(BleAdapterService.PARCEL_VALUE);
if (b.length > 0) {
PeripheralControlActivity.this.setAlertLevel((int) b[0]);
Log.d(Constants.TAG, "Current alert_level is set to: " + b[0]);
// show the rssi distance colored rectangle
((LinearLayout) PeripheralControlActivity.this
.findViewById(R.id.rectangle))
.setVisibility(View.VISIBLE);
// start off the rssi reading timer
startReadRssiTimer();
}
}
break;
case BleAdapterService.GATT_CHARACTERISTIC_WRITTEN:
bundle = msg.getData();
Log.d(Constants.TAG, "Service=" + bundle.get(BleAdapterService.PARCEL_SERVICE_UUID).toString().toUpperCase() + " Characteristic=" + bundle.get(BleAdapterService.PARCEL_CHARACTERISTIC_UUID).toString().toUpperCase());
if (bundle.get(BleAdapterService.PARCEL_CHARACTERISTIC_UUID).toString()
.toUpperCase().equals(BleAdapterService.ALERT_LEVEL_CHARACTERISTIC)
&& bundle.get(BleAdapterService.PARCEL_SERVICE_UUID).toString()
.toUpperCase().equals(BleAdapterService.LINK_LOSS_SERVICE_UUID)) {
b = bundle.getByteArray(BleAdapterService.PARCEL_VALUE);
Log.d(Constants.TAG, "New alert_level set to: " + b[0]);
PeripheralControlActivity.this.setAlertLevel((int) b[0]);
}
break;
}
}
};
public void onLow(View view) {
bluetooth_le_adapter.writeCharacteristic(BleAdapterService.LINK_LOSS_SERVICE_UUID, BleAdapterService.ALERT_LEVEL_CHARACTERISTIC, Constants.ALERT_LEVEL_LOW);
}
public void onMid(View view) {
bluetooth_le_adapter.writeCharacteristic(BleAdapterService.LINK_LOSS_SERVICE_UUID, BleAdapterService.ALERT_LEVEL_CHARACTERISTIC, Constants.ALERT_LEVEL_MID);
}
public void onHigh(View view) {
bluetooth_le_adapter.writeCharacteristic(BleAdapterService.LINK_LOSS_SERVICE_UUID, BleAdapterService.ALERT_LEVEL_CHARACTERISTIC, Constants.ALERT_LEVEL_HIGH);
}
public void onNoise(View view) {
byte[] al = new byte[1];
al[0] = (byte) alert_level;
bluetooth_le_adapter.writeCharacteristic(BleAdapterService.IMMEDIATE_ALERT_SERVICE_UUID, BleAdapterService.ALERT_LEVEL_CHARACTERISTIC, al);
}
public void onBackPressed() {
Log.d(Constants.TAG, "onBackPressed");
back_requested = true;
if (bluetooth_le_adapter.isConnected()) {
try {
bluetooth_le_adapter.disconnect();
} catch (Exception e) {
}
} else {
finish();
}
}
private void setAlertLevel(int alert_level) {
this.alert_level = alert_level;
((Button) this.findViewById(R.id.lowButton)).setTextColor(Color.parseColor("#000000"));
;
((Button) this.findViewById(R.id.midButton)).setTextColor(Color.parseColor("#000000"));
;
((Button) this.findViewById(R.id.highButton)).setTextColor(Color.parseColor("#000000"));
;
switch (alert_level) {
case 0:
((Button) this.findViewById(R.id.lowButton)).setTextColor(Color.parseColor("#FF0000"));
;
break;
case 1:
((Button) this.findViewById(R.id.midButton)).setTextColor(Color.parseColor("#FF0000"));
;
break;
case 2:
((Button) this.findViewById(R.id.highButton)).setTextColor(Color.parseColor("#FF0000"));
;
break;
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_peripheral_control);
// read intent data
final Intent intent = getIntent();
device_name = intent.getStringExtra(EXTRA_NAME);
device_address = intent.getStringExtra(EXTRA_ID);
// show the device name
((TextView) this.findViewById(R.id.nameTextView)).setText("Device : " + device_name + " [" + device_address + "]");
// hide the coloured rectangle used to show green/amber/red rssi distance
((LinearLayout) this.findViewById(R.id.rectangle)).setVisibility(View.INVISIBLE);
// hide the coloured rectangle used to show green/amber/red rssi
// distance
((LinearLayout) this.findViewById(R.id.rectangle))
.setVisibility(View.INVISIBLE);
// disable the noise button
((Button) PeripheralControlActivity.this.findViewById(R.id.noiseButton))
.setEnabled(false);
// disable the LOW/MID/HIGH alert level selection buttons
((Button) this.findViewById(R.id.lowButton)).setEnabled(false);
((Button) this.findViewById(R.id.midButton)).setEnabled(false);
((Button) this.findViewById(R.id.highButton)).setEnabled(false);
share_switch = (Switch) this.findViewById(R.id.switch1);
share_switch.setEnabled(false);
share_switch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
if (bluetooth_le_adapter != null) {
share_with_server = isChecked;
if (!isChecked && bluetooth_le_adapter.isConnected()) {
showMsg("Switched off sharing proximity data");
// write 0,0 to cause Arduino to switch off all LEDs
if (bluetooth_le_adapter.writeCharacteristic(
BleAdapterService.PROXIMITY_MONITORING_SERVICE_UUID,
BleAdapterService.CLIENT_PROXIMITY_CHARACTERISTIC,
new byte[]{0, 0})) {
} else {
showMsg("Failed to inform Arduino sharing has been disabled");
}
}
}
}
});
// connect to the Bluetooth adapter service
Intent gattServiceIntent = new Intent(this, BleAdapterService.class);
bindService(gattServiceIntent, service_connection, BIND_AUTO_CREATE);
showMsg("READY");
}
@Override
protected void onDestroy() {
super.onDestroy();
stopTimer();
unbindService(service_connection);
bluetooth_le_adapter = null;
}
private void showMsg(final String msg) {
Log.i(Constants.TAG, msg);
runOnUiThread(new Runnable() {
@Override
public void run() {
((TextView) findViewById(R.id.msgTextView)).setText(msg);
}
});
}
public void onConnect(View view) {
showMsg("onConnect");
if (bluetooth_le_adapter != null) {
if (bluetooth_le_adapter.connect(device_address)) {
((Button) PeripheralControlActivity.this
.findViewById(R.id.connectButton)).setEnabled(false);
} else {
showMsg("onConnect: failed to connect");
}
} else {
showMsg("onConnect: bluetooth_le_adapter=null");
}
}
private void startReadRssiTimer() {
mTimer = new Timer();
mTimer.schedule(new TimerTask() {
@Override
public void run() {
bluetooth_le_adapter.readRemoteRssi();
}
}, 0, 2000);
}
private void stopTimer() {
if (mTimer != null) {
mTimer.cancel();
mTimer = null;
}
}
private void updateRssi(int rssi) {
((TextView) findViewById(R.id.rssiTextView)).setText("RSSI = "
+ Integer.toString(rssi));
LinearLayout layout = ((LinearLayout) PeripheralControlActivity.this
.findViewById(R.id.rectangle));
byte proximity_band = 3;
if (rssi < -80) {
layout.setBackgroundColor(0xFFFF0000);
} else if (rssi < -50) {
layout.setBackgroundColor(0xFFFF8A01);
proximity_band = 2;
} else {
layout.setBackgroundColor(0xFF00FF00);
proximity_band = 1;
}
layout.invalidate();
if (share_with_server) {
if (bluetooth_le_adapter.writeCharacteristic(
BleAdapterService.PROXIMITY_MONITORING_SERVICE_UUID,
BleAdapterService.CLIENT_PROXIMITY_CHARACTERISTIC,
new byte[]{proximity_band, (byte) rssi})) {
showMsg("proximity data shared: proximity_band:" + proximity_band + ",rssi:" + rssi);
} else {
showMsg("Failed to share proximity data");
}
}
}
}
BleAdapterService.java
public class BleAdapterService extends Service {
private BluetoothAdapter bluetooth_adapter;
private BluetoothGatt bluetooth_gatt;
private BluetoothManager bluetooth_manager;
private Handler activity_handler = null;
private BluetoothDevice device;
private BluetoothGattDescriptor descriptor;
private final IBinder binder = new LocalBinder();
public boolean isConnected() {
return connected;
}
private boolean connected = false;
// messages sent back to activity
public static final int GATT_CONNECTED = 1;
public static final int GATT_DISCONNECT = 2;
public static final int GATT_SERVICES_DISCOVERED = 3;
public static final int GATT_CHARACTERISTIC_READ = 4;
public static final int GATT_CHARACTERISTIC_WRITTEN = 5;
public static final int GATT_REMOTE_RSSI = 6;
public static final int MESSAGE = 7;
// message params
public static final String PARCEL_DESCRIPTOR_UUID = "DESCRIPTOR_UUID";
public static final String PARCEL_CHARACTERISTIC_UUID = "CHARACTERISTIC_UUID";
public static final String PARCEL_SERVICE_UUID = "SERVICE_UUID";
public static final String PARCEL_VALUE = "VALUE";
public static final String PARCEL_RSSI = "RSSI";
public static final String PARCEL_TEXT = "TEXT";
// service uuids
public static String IMMEDIATE_ALERT_SERVICE_UUID = "00001802-0000-1000-8000-00805F9B34FB";
public static String LINK_LOSS_SERVICE_UUID = "00001803-0000-1000-8000-00805F9B34FB";
public static String TX_POWER_SERVICE_UUID = "00001804-0000-1000-8000-00805F9B34FB";
public static String PROXIMITY_MONITORING_SERVICE_UUID = "3E099910-293F-11E4-93BD-AFD0FE6D1DFD";
// service characteristics
public static String ALERT_LEVEL_CHARACTERISTIC = "00002A06-0000-1000-8000-00805F9B34FB";
public static String CLIENT_PROXIMITY_CHARACTERISTIC = "3E099911-293F-11E4-93BD-AFD0FE6D1DFD";
public class LocalBinder extends Binder {
public BleAdapterService getService() {
return BleAdapterService.this;
}
}
@Override
public IBinder onBind(Intent intent) {
return binder;
}
@Override
public boolean onUnbind(Intent intent) {
return super.onUnbind(intent);
}
// set activity the will receive the messages
public void setActivityHandler(Handler handler) {
activity_handler = handler;
}
private void sendConsoleMessage(String text) {
Message msg = Message.obtain(activity_handler, MESSAGE);
Bundle data = new Bundle();
data.putString(PARCEL_TEXT, text);
msg.setData(data);
msg.sendToTarget();
}
@Override
public void onCreate() {
if (bluetooth_manager == null) {
bluetooth_manager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
if (bluetooth_manager == null) {
return;
}
}
bluetooth_adapter = bluetooth_manager.getAdapter();
if (bluetooth_adapter == null) {
return;
}
}
// connect to the device
public boolean connect(final String address) {
if (bluetooth_adapter == null || address == null) {
sendConsoleMessage("connect: bluetooth_adapter=null");
return false;
}
device = bluetooth_adapter.getRemoteDevice(address);
if (device == null) {
sendConsoleMessage("connect: device=null");
return false;
}
bluetooth_gatt = device.connectGatt(this, false, gatt_callback);
return true;
}
// disconnect from device
public void disconnect() {
sendConsoleMessage("disconnecting");
if (bluetooth_adapter == null || bluetooth_gatt == null) {
sendConsoleMessage("disconnect: bluetooth_adapter|bluetooth_gatt null");
return;
}
if (bluetooth_gatt != null) {
bluetooth_gatt.disconnect();
}
}
public void readRemoteRssi() {
if (bluetooth_adapter == null || bluetooth_gatt == null) {
return;
}
bluetooth_gatt.readRemoteRssi();
}
public void discoverServices() {
if (bluetooth_adapter == null || bluetooth_gatt == null) {
return;
}
Log.d(Constants.TAG,"Discovering GATT services");
bluetooth_gatt.discoverServices();
}
public List<BluetoothGattService> getSupportedGattServices() {
if (bluetooth_gatt == null)
return null;
return bluetooth_gatt.getServices();
}
public boolean readCharacteristic(String serviceUuid,
String characteristicUuid) {
Log.d(Constants.TAG,"readCharacteristic:"+characteristicUuid+" of " +serviceUuid);
if (bluetooth_adapter == null || bluetooth_gatt == null) {
sendConsoleMessage("readCharacteristic: bluetooth_adapter|bluetooth_gatt null");
return false;
}
BluetoothGattService gattService = bluetooth_gatt
.getService(java.util.UUID.fromString(serviceUuid));
if (gattService == null) {
sendConsoleMessage("readCharacteristic: gattService null");
return false;
}
BluetoothGattCharacteristic gattChar = gattService
.getCharacteristic(java.util.UUID.fromString(characteristicUuid));
if (gattChar == null) {
sendConsoleMessage("readCharacteristic: gattChar null");
return false;
}
return bluetooth_gatt.readCharacteristic(gattChar);
}
public boolean writeCharacteristic(String serviceUuid,
String characteristicUuid, byte[] value) {
Log.d(Constants.TAG,"writeCharacteristic:"+characteristicUuid+" of " +serviceUuid);
if (bluetooth_adapter == null || bluetooth_gatt == null) {
sendConsoleMessage("writeCharacteristic: bluetooth_adapter|bluetooth_gatt null");
return false;
}
BluetoothGattService gattService = bluetooth_gatt
.getService(java.util.UUID.fromString(serviceUuid));
if (gattService == null) {
sendConsoleMessage("writeCharacteristic: gattService null");
return false;
}
BluetoothGattCharacteristic gattChar = gattService
.getCharacteristic(java.util.UUID.fromString(characteristicUuid));
if (gattChar == null) {
sendConsoleMessage("writeCharacteristic: gattChar null");
return false;
}
gattChar.setValue(value);
return bluetooth_gatt.writeCharacteristic(gattChar);
}
private final BluetoothGattCallback gatt_callback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status,
int newState) {
Log.d(Constants.TAG, "onConnectionStateChange: status=" + status);
if (newState == BluetoothProfile.STATE_CONNECTED) {
Log.d(Constants.TAG, "onConnectionStateChange: CONNECTED");
connected = true;
Message msg = Message.obtain(activity_handler, GATT_CONNECTED);
msg.sendToTarget();
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
Log.d(Constants.TAG, "onConnectionStateChange: DISCONNECTED");
Message msg = Message.obtain(activity_handler, GATT_DISCONNECT);
msg.sendToTarget();
if (bluetooth_gatt != null) {
Log.d(Constants.TAG,"Closing and destroying BluetoothGatt object");
connected = false;
bluetooth_gatt.close();
bluetooth_gatt = null;
}
}
}
@Override
public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
sendConsoleMessage("RSSI read OK");
Bundle bundle = new Bundle();
bundle.putInt(PARCEL_RSSI, rssi);
Message msg = Message
.obtain(activity_handler, GATT_REMOTE_RSSI);
msg.setData(bundle);
msg.sendToTarget();
} else {
sendConsoleMessage("RSSI read err:"+status);
}
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
sendConsoleMessage("Services Discovered");
Message msg = Message.obtain(activity_handler,
GATT_SERVICES_DISCOVERED);
msg.sendToTarget();
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
Bundle bundle = new Bundle();
bundle.putString(PARCEL_CHARACTERISTIC_UUID, characteristic.getUuid()
.toString());
bundle.putString(PARCEL_SERVICE_UUID, characteristic.getService().getUuid().toString());
bundle.putByteArray(PARCEL_VALUE, characteristic.getValue());
Message msg = Message.obtain(activity_handler,
GATT_CHARACTERISTIC_READ);
msg.setData(bundle);
msg.sendToTarget();
} else {
Log.d(Constants.TAG, "failed to read characteristic:"+characteristic.getUuid().toString()+" of service "+characteristic.getService().getUuid().toString()+" : status="+status);
sendConsoleMessage("characteristic read err:"+status);
}
}
public void onCharacteristicWrite(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, int status) {
Log.d(Constants.TAG, "onCharacteristicWrite");
if (status == BluetoothGatt.GATT_SUCCESS) {
Bundle bundle = new Bundle();
bundle.putString(PARCEL_CHARACTERISTIC_UUID, characteristic.getUuid().toString());
bundle.putString(PARCEL_SERVICE_UUID, characteristic.getService().getUuid().toString());
bundle.putByteArray(PARCEL_VALUE, characteristic.getValue());
Message msg = Message.obtain(activity_handler, GATT_CHARACTERISTIC_WRITTEN);
msg.setData(bundle);
msg.sendToTarget();
} else {
sendConsoleMessage("characteristic write err:" + status);
}
}
};
}
答案 0 :(得分:0)
我忘了在Manifest中添加服务:
<service
android:name=".bluetooth.BleAdapterService"
android:enabled="true" />