Java 蓝牙适配器服务仍为空

Java 蓝牙适配器服务仍为空,java,android,service,bluetooth,bluetooth-lowenergy,Java,Android,Service,Bluetooth,Bluetooth Lowenergy,我正在尝试将Bluetooth BLE developer starter kit中的代码改编为我自己的应用程序(即,这个完全相同的代码在示例应用程序中运行良好)。 但是,我无法连接到任何设备,因为当我按下连接按钮(方法onConnect)时,蓝牙适配器为空 我认为bluetooth_le_适配器没有很好地初始化,因此在启动时为空 你知道如何解决这个问题吗?谢谢 PeripheraldControlActivity.java: public class PeripheralControlActi

我正在尝试将Bluetooth BLE developer starter kit中的代码改编为我自己的应用程序(即,这个完全相同的代码在示例应用程序中运行良好)。 但是,我无法连接到任何设备,因为当我按下连接按钮(方法onConnect)时,蓝牙适配器为空

我认为bluetooth_le_适配器没有很好地初始化,因此在启动时为空

你知道如何解决这个问题吗?谢谢

PeripheraldControlActivity.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");
        }
    }

}
}
公共类外围设备控制活动扩展活动{
公共静态最终字符串EXTRA_NAME=“NAME”;
公共静态最终字符串EXTRA_ID=“ID”;
私有字符串设备名称;
专用字符串设备地址;
私人定时器;
断开连接时的专用布尔声音报警=false;
私人内部警报级别;
私有布尔值back_requested=false;
与_服务器共享_的私有布尔值=false;
专用交换机共享交换机;
专用蓝牙适配器;
专用最终服务连接服务\u连接=新服务连接(){
@凌驾
服务连接上的公共无效(组件名称组件名称,IBinder服务){
蓝牙适配器=((BleAdapterService.LocalBinder)服务).getService();
蓝牙适配器setActivityHandler(消息处理程序);
}
@凌驾
ServiceDisconnected上的公共无效(ComponentName ComponentName){
蓝牙适配器=空;
}
};
私有处理程序消息\u Handler=new Handler(){
@凌驾
公共无效handleMessage(消息消息消息){
束;
字符串服务_uuid=“”;
字符串特征_uuid=“”;
字节[]b=null;
开关(msg.what){
案例BleAdapterService.MESSAGE:
bundle=msg.getData();
String text=bundle.getString(BleAdapterService.PARCEL_text);
showMsg(文本);
打破
案例BLADAPTERSERVICE.GATT_已连接:
((按钮)外围设备控制活动。此
.findViewById(R.id.connectButton)).setEnabled(false);
((按钮)PeripheralControlActivity.this.findViewById(R.id.noiseButton))
.setEnabled(true);
share_开关。setEnabled(真);
//我们有联系
showMsg(“已连接”);
/*AlarmManager am=AlarmManager.getInstance();
Log.d(Constants.TAG,“alarmIsSounding=“+am.alarmIsSounding());
如果(am.alarmIsSounding()){
Log.d(Constants.TAG,“停止报警”);
am.stopAlarm();
}*/
蓝牙适配器。discoverServices();
打破
案例BLADAPTERSERVICE.GATT\U断开连接:
((按钮)外围设备控制活动。此
.findViewById(R.id.connectButton)).setEnabled(true);
//我们断开了
showMsg(“断开”);
//隐藏rssi距离彩色矩形
((线性布局)外围设备控制活动。此
.findViewById(R.id.矩形))
.setVisibility(视图.不可见);
share_开关。setEnabled(错误);
//禁用低/中/高警报级别选择按钮
((按钮)PeripheraldControlActivity.this.findViewById(R.id.lowButton)).setEnabled(false);
((按钮)PeripheralControlActivity.this.findViewById(R.id.midButton)).setEnabled(false);
((按钮)PeripheraldControlActivity.this.findViewById(R.id.highButton)).setEnabled(false);
//停止rssi读取计时器
停止计时器();
/*如果(警报级别>0){
AlarmManager.getInstance().soundAlarm(getResources().openRawResourceFd(R.raw.alarm));
}*/
如果(请求支持){
peripheraldControlActivity.this.finish();
}
打破
案例BLADAPTERSERVICE.GATT_服务_发现:
//验证服务,如果确定。。。。
List slist=bluetooth_le_adapter.getSupportedGattServices();
布尔链接丢失存在=假;
布尔立即警告存在=假;
布尔值tx_power_present=假;
布尔近似值\u监控\u存在=假;
用于(BluetoothGattService svc:slist){
Log.d(Constants.TAG,“UUID=“+svc.getUuid().toString().toUpperCase()+”INSTANCE=“+svc.getInstanceId());
if(svc.getUuid().toString().equalsIgnoreCase(BleAdapterService.LINK\u LOSS\u SERVICE\u UUID)){
链路损耗存在=真;
继续;
}
if(svc.getUuid().toString().equalsIgnoreCase(BleAdapterService.IMMEDIATE\u ALERT\u SERVICE\u UUID)){
即时警报当前=真;
继续;
}
if(svc.getUuid().toString().equalsIgnoreCase(BleAdapterService.TX\u POWER\u SERVICE\u UUID)){
tx_功率_当前=真;
继续;
}
if(svc.getUuid().toString().equalsIgnoreCase(BleAdapterService.Proximition\u MONITORING\u SERVICE\u UUID)){
近距离监测存在=真;
继续;
}
}
如果(链路丢失、即时告警、发送、电源、近距离监控){
showMsg(“设备具有预期服务”);
//以彩色矩形显示rssi距离
((线性布局)外围设备控制活动。此
.findViewById(R.id.矩形))
.
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);
        }
    }
};
}
    <service
        android:name=".bluetooth.BleAdapterService"
        android:enabled="true" />