BLE 4.0 autoconnect&扫描

时间:2014-07-16 10:38:02

标签: android bluetooth-lowenergy gatt

我正在尝试创建一个应用程序来切换连接到BLE设备的LED。 当我尝试扫描设备并连接到服务时,它不起作用。变量“mBTdevice”始终显示在LE扫描

上使用的nulll值

这是我的code.java文件

package org.bluetooth.bledemo;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.UUID;

import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.content.pm.PackageManager;
import android.view.MenuItem;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.ToggleButton;
import android.support.v4.app.NavUtils;

import com.epsilonteknologies.smartlight.R;

/* this activity's purpose is to show how to use particular type of devices in easy and fast way */
public class SmartLight extends Activity {

    private Handler mHandler = null;
    private BluetoothManager mBTManager = null;
    private BluetoothAdapter mBTAdapter = null;
    private BluetoothDevice  mBTDevice = null;
    private BluetoothGatt    mBTGatt = null;
    private BluetoothGattService mBTService = null;
    private boolean mScanning=false;
    private BluetoothGattCharacteristic mBTValueCharacteristic = null;
    // UUDI of Smart Light:
    final static private UUID mSmartLightServiceUuid = BleDefinedUUIDs.Service.SMART_LIGHT;
    final static private UUID mSmartLightCharacteristicUuid = BleDefinedUUIDs.Characteristic.SMART_LIGHT_ON_OFF;

    private EditText mConsole = null;
    private TextView mTextView  = null;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_smartlight);
        mConsole = (EditText) findViewById(R.id.hr_console_item);
        log("Creating activity");

        // Show the Up button in the action bar.
        getActionBar().setDisplayHomeAsUpEnabled(true);
        setTitle("Smart Light");
        mConsole = (EditText) findViewById(R.id.hr_console_item);
        mTextView = (TextView) findViewById(R.id.sl_text_view);



        mHandler = new Handler();
        log("Activity created");
    }

    /*@Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case android.R.id.home:
            NavUtils.navigateUpFromSameTask(this);
            return true;
        }
        return super.onOptionsItemSelected(item);
    }*/

    @Override
    protected void onResume() {
        super.onResume();
        log("Resuming activity");

        // first check if BT/BLE is available and enabled
        if(initBt() == false) return;
        if(isBleAvailable() == false) return;
        if(isBtEnabled() == false) return;
        connectToDevice();

        // then start discovering devices around
        startSearchingForSL();

        log("Activity resumed");
    }

    /*@Override
    protected void onPause() {
        super.onPause();

        disableNotificationForSL();
        disconnectFromDevice();
        closeGatt();
    };*/

    private boolean initBt() {
        mBTManager = (BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE);
        if(mBTManager != null) mBTAdapter = mBTManager.getAdapter();

        return (mBTManager != null) && (mBTAdapter != null);
    }

    private boolean isBleAvailable() {
        log("Checking if BLE hardware is available");

        boolean hasBle = getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE);
        if(hasBle && mBTManager != null && mBTAdapter != null) {
            log("BLE hardware available");
        }
        else {
            log("BLE hardware is missing!");
            return false;
        }
        return true;
    }

    private boolean isBtEnabled() {
        log("Checking if BT is enabled");
        if(mBTAdapter.isEnabled()) {
            log("BT is enabled");
        }
        else {
            log("BT is disabled. Use Setting to enable it and then come back to this app");
            return false;
        }
        return true;
    }

    private void startSearchingForSL() {
        // we define what kind of services found device needs to provide. In our case we are interested only in
        // Smart Light Service
        final UUID[] uuids = new UUID[] {mSmartLightServiceUuid};
        mBTAdapter.startLeScan(uuids, mDeviceFoundCallback);
        // results will be returned by callback
        log("Search for devices providing Smart Light service started");

        // please, remember to add timeout for that scan
        Runnable timeout = new Runnable() {
            @Override
            public void run() {
                if(mBTAdapter.isDiscovering() == false) return;
                stopSearchingForSL();   
            }
        };
        mHandler.postDelayed(timeout, 20000); //20 seconds      
    }

    private void stopSearchingForSL() {
        mBTAdapter.stopLeScan(mDeviceFoundCallback);
        log("Searching for devices with Smart Light service stopped");
    }

    private void connectToDevice() {
        log("Connecting to the device NAME: " + mBTDevice.getName() + " HWADDR: " + mBTDevice.getAddress());
        //mBTGatt = mBTDevice.connectGatt(this, true, mGattCallback);
    }

    private void disconnectFromDevice() {
        log("Disconnecting from device");
        if(mBTGatt != null) mBTGatt.disconnect();
    }

    private void closeGatt() {
        if(mBTGatt != null) mBTGatt.close();
        mBTGatt = null;
    }

    private void discoverServices() {
        log("Starting discovering services");
        mBTGatt.discoverServices();
    }

    private void getSLService() {
        log("Getting Smart Light Service");
        mBTService = mBTGatt.getService(mSmartLightServiceUuid);

        if(mBTService == null) {
            log("Could not get Smart Light Service");
        }
        else {
            log("Smart Light Service successfully retrieved");
            setSLCharacteristic();
        }
    }

    private void setSLCharacteristic() {
        log("Getting Smart Light On-Off characteristic");
        mBTValueCharacteristic = mBTService.getCharacteristic(mSmartLightCharacteristicUuid);
        final ToggleButton mTogBut = (ToggleButton) findViewById(R.id.toggleButton1);
        if(mBTValueCharacteristic == null) {
            log("Could not find Smart Light On-Off Characteristic");
        }
        else {
            log("Smart Light On-Off characteristic retrieved properly");
            enableNotificationForSL();
        }
        mTogBut.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                if (mTogBut.isChecked()){
                    mBTValueCharacteristic.setValue("1");
                }else{
                    mBTValueCharacteristic.setValue("2");
                }
            }
        });
    }

    private void enableNotificationForSL() {
        log("Enabling notification for Smart Light");
        boolean success = mBTGatt.setCharacteristicNotification(mBTValueCharacteristic, true);
        if(!success) {
            log("Enabling notification failed!");
            return;
        }

        BluetoothGattDescriptor descriptor = mBTValueCharacteristic.getDescriptor(BleDefinedUUIDs.Descriptor.CHAR_CLIENT_CONFIG);
        if(descriptor != null) {
            descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
            mBTGatt.writeDescriptor(descriptor);
            log("Notification enabled");
        }       
        else {
            log("Could not get descriptor for characteristic! Notification are not enabled.");
        }
    }

    private void disableNotificationForSL() {
        log("Disabling notification for Smart Light");
        boolean success = mBTGatt.setCharacteristicNotification(mBTValueCharacteristic, false);
        if(!success) {
            log("Disabling notification failed!");
            return;
        }

        BluetoothGattDescriptor descriptor = mBTValueCharacteristic.getDescriptor(BleDefinedUUIDs.Descriptor.CHAR_CLIENT_CONFIG);
        if(descriptor != null) {
            descriptor.setValue(BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE);
            mBTGatt.writeDescriptor(descriptor);
            log("Notification disabled");
        }       
        else {
            log("Could not get descriptor for characteristic! Notification could be still enabled.");
        }
    }   

    private void getAndDisplaySLValue() {
        byte[] raw = mBTValueCharacteristic.getValue();
        int index = ((raw[0] & 0x01) == 1) ? 2 : 1;
        int format = (index == 1) ? BluetoothGattCharacteristic.FORMAT_UINT8 : BluetoothGattCharacteristic.FORMAT_UINT16;
        int value = mBTValueCharacteristic.getIntValue(format, index);
        final String description = value + " bpm";

        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mTextView.setText(description);
            }
        });
    }
    public BluetoothAdapter.LeScanCallback mDeviceFoundCallback =
            new BluetoothAdapter.LeScanCallback() {

        @Override
        public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    SmartLight.this.mBTDevice=device;
                    log("Device with Smart Light service discovered. HW Address: "  + device.getAddress());
                    //stopSearchingForSL();

                    connectToDevice();
                }
            });
        }
    };
    /* callbacks called for any action on HR Device */
    private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            if (newState == BluetoothProfile.STATE_CONNECTED) {
                log("Device connected");
                discoverServices();
            }
            else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                log("Device disconnected");
            }
        }

        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            if(status == BluetoothGatt.GATT_SUCCESS) {
                log("Services discovered");
                getSLService();
            }
            else {
                log("Unable to discover services");
            }
        }

        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt,
                                            BluetoothGattCharacteristic characteristic)
        {
            if(characteristic.equals(mBTValueCharacteristic)) {
                getAndDisplaySLValue();
            }
        }       

        /* the rest of callbacks are not interested for us */

        @Override
        public void onCharacteristicRead(BluetoothGatt gatt,
                                         BluetoothGattCharacteristic characteristic,
                                         int status) {}



        @Override
        public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {};

        @Override
        public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {};
    };


    // put new logs into the UI console
    private void log(final String txt) {
        if(mConsole == null) return;

        final String timestamp = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss.SSS", Locale.US).format(new Date());
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                mConsole.setText(timestamp + " : " + txt + "\n" + mConsole.getText());
            }       
        });
    }
}

这是我的xml文件

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="org.bluetooth.bledemo.SmartLight" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="0"
        android:gravity="center_horizontal"
        android:text="@string/activity_name" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="0" >

        <TextView
            android:id="@+id/textView20"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:clickable="false"
            android:gravity="top"
            android:text="@string/status"
            android:textColor="#888"
            android:textSize="12sp" />

        <TextView
            android:id="@+id/sl_text_view"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="20dp"
            android:textColor="#666"
            android:textSize="28sp"
            android:textStyle="bold" />
    </LinearLayout>

    <ToggleButton
        android:id="@+id/toggleButton1"
        android:layout_width="280dp"
        android:layout_height="37dp"
        android:layout_gravity="center_horizontal"
        android:gravity="center"
        android:text="@string/ToggleButton"
        android:textOff="OFF"
        android:textOn="ON"
        android:textSize="50sp" />

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_weight="0"
        android:text="Console:"
        android:textColor="#888"
        android:textSize="12sp" />

    <EditText
        android:id="@+id/hr_console_item"
        android:layout_width="281dp"
        android:layout_height="315dp"
        android:ems="10"
        android:enabled="false"
        android:gravity="top"
        android:inputType="textMultiLine"
        android:textSize="12sp" >

        <requestFocus />
    </EditText>

</LinearLayout>

0 个答案:

没有答案