0

I am trying to make an app that toggles LED connected to a BLE device. when I try to scan device and connect to the service it aint working. The variable "mBTdevice" always shows a nulll value using on LE Scan

here is my code.java file

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());
            }       
        });
    }
}

this is my xml file

<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>
Xauð Mùghal
  • 51
  • 1
  • 4
  • you'll need to be much more specific, do you not even get a callback from the scan for your device? what do you see in the logcat? most devices will have have output from the frameworks BTLE classes going into the main logcat buffer, so you should include that here too... – Maks Aug 01 '14 at 07:53
  • You have to separate the main class into three things , 1.backend classes for BLE connection and sending commands , and bind 2.set callback method 3. register and unregister the broadcast receiver as using/ not using the callback – Jeff Bootsholz Mar 02 '15 at 04:01

0 Answers0