Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
930 views
in Technique[技术] by (71.8m points)

android - Bluetooth BLE can't connect and don't know if i'm on the wrong way to do it

I'm a begginner on Bluetooth LE, I can scan all Bluetooth Device but I can't connect to the device. I got an error and I don't know where I'm wrong. I'm not sure if I use the good method to connect to another device, the Android doc is not very clear. I try to create an application to scan all device, when i get the device i wanted, the application automatically connect to the device without click on a button or other stuff.

MainActivity (I scan all device and take only the device i needed)

public class MainActivity extends AppCompatActivity
{

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    if(!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE))
    {
        Toast.makeText(this, "BLE not supported", Toast.LENGTH_SHORT).show();
        finish();
    }

    final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
    BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();

    if(bluetoothAdapter == null)
    {
        Toast.makeText(this, "Bluetooth not supported", Toast.LENGTH_SHORT).show();
        finish();
        return;
    }

    scanLeDevice();
}

private BluetoothLeScanner bluetoothLeScanner = BluetoothAdapter.getDefaultAdapter().getBluetoothLeScanner();
private boolean mScanning;
private Handler handler = new Handler();

private static final long SCAN_PERIOD = 1000;

private void scanLeDevice()
{
    if(!mScanning)
    {
        handler.postDelayed(new Runnable()
        {
            @Override
            public void run()
            {
                mScanning = false;
                bluetoothLeScanner.stopScan(leScanCallBack);
            }
        }, SCAN_PERIOD);

        mScanning = true;
        bluetoothLeScanner.startScan(leScanCallBack);
    }
    else
    {
        mScanning = false;
        bluetoothLeScanner.stopScan(leScanCallBack);
    }
}

private  String Device_name = "";
private String Device_address;

private ScanCallback leScanCallBack = new ScanCallback()
{
    @Override
    public void onScanResult(int callbackType, ScanResult result)
    {
        super.onScanResult(callbackType, result);

        if(result.getDevice().getName() != null && result.getDevice().getName().contains("ETNA") && result.getDevice().getName() != Device_name)
        {
            Device_name = String.valueOf(result.getDevice().getName());
            Device_address = String.valueOf(result.getDevice().getAddress());
            BluetoothLeService blService = new BluetoothLeService();
            blService.connect(Device_address);
            Log.e("Device Name : ", Device_name);
            Log.e("Device address", Device_address);
            Button button = findViewById(R.id.button);
            button.setText(Device_name);
        }
    }
};}

BluetoothLeService use to get the connection state and connect to a device :

public class BluetoothLeService extends Service
{
private final static String TAG = BluetoothLeService.class.getSimpleName();

private BluetoothManager bluetoothManager;
private BluetoothAdapter bluetoothAdapter;
private String bluetoothDeviceAddress;
private BluetoothGatt bluetoothGatt;
private int connectionState = STATE_DISCONNECTED;

private static final int STATE_DISCONNECTED = 0;
private static final int STATE_CONNECTING = 1;
private static final int STATE_CONNECTED = 2;

public final static String ACTION_GATT_CONNECTED = "com.example.bluetooth.le.ACTION_GATT_CONNECTED";
public final static String ACTION_GATT_DISCONNECTED = "com.example.bluetooth.le.ACTION_GATT_DISCONNECTED";
public final static String ACTION_GATT_SERVICES_DISCOVERED = "com.example.bluetooth.le.ACTION_GATT_SERVICES_DISCOVERED";
public final static String ACTION_DATA_AVAILABLE = "com.example.bluetooth.le.ACTION_DATA_AVAILABLE";
public final static String EXTRA_DATA = "com.example.bluetooth.le.EXTRA_DATA";

public final static UUID UUID_HEART_RATE_MEASUREMENT = UUID.fromString(SampleGattAttributes.HEART_RATE_MEASUREMENT);

private final BluetoothGattCallback gattCallback = new BluetoothGattCallback()
{
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState)
    {
        String intentAction;
        if(newState == BluetoothProfile.STATE_CONNECTED)
        {
            intentAction = ACTION_GATT_CONNECTED;
            connectionState = STATE_CONNECTED;
            broadcastUpdate(intentAction);
            Log.i(TAG, "Connected to GATT server.");
            Log.i(TAG, "Attemping to start service discovery:" + bluetoothGatt.discoverServices());
        }
        else if(newState == BluetoothProfile.STATE_DISCONNECTED)
        {
            intentAction = ACTION_GATT_DISCONNECTED;
            connectionState = STATE_DISCONNECTED;
            Log.i(TAG, "Disconnected from GATT server.");
            broadcastUpdate(intentAction);
        }
    }

    public void onServicesDiscovered(BluetoothGatt gatt, int status)
    {
        if(status == BluetoothGatt.GATT_SUCCESS)
        {
            broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
        }
        else
        {
            Log.i(TAG, "onServiceDiscovered received: " + status);
        }
    }

    public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status)
    {
        if(status == BluetoothGatt.GATT_SUCCESS)
        {
            broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
        }
    }
};

private void broadcastUpdate(final String action)
{
    final Intent intent = new Intent(action);
    sendBroadcast(intent);
}

private void broadcastUpdate(final String action, final BluetoothGattCharacteristic characteristic)
{
    final Intent intent = new Intent(action);

    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(TAG, "HEART RATE FORMAT UINT16.");
        }
        else
        {
            format = BluetoothGattCharacteristic.FORMAT_UINT8;
            Log.d(TAG, "HEART RATE FORMAT UINT8.");
        }
        final int heartRate = characteristic.getIntValue(format, 1);
        Log.d(TAG, String.format("Received heart rate: %d", heartRate));
        intent.putExtra(EXTRA_DATA, String.valueOf(heartRate));
    }
    else
    {
        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));
            }
            String data_string = new String(data) + "
" + stringBuilder.toString();
            Log.d(TAG, data_string);
            intent.putExtra(EXTRA_DATA, data_string);
        }
    }
    sendBroadcast(intent);
}

@Nullable
@Override
public IBinder onBind(Intent intent)
{
    return null;
}

public boolean connect(final String address)
{
    final BluetoothDevice device = bluetoothAdapter.getRemoteDevice(address);
    if(device == null)
    {
        Log.e(TAG, "Device not found");
        return false;
    }

    bluetoothGatt = device.connectGatt(this, false, gattCallback);
    Log.e(TAG, "Trying to create a new connection");
    connectionState = STATE_CONNECTING;
    return true;
}}

Error :

FATAL EXCEPTION: main
Process: com.example.myapplication, PID: 14400
java.lang.NullPointerException: Attempt to invoke virtual method 'android.bluetooth.BluetoothDevice android.bluetooth.BluetoothAdapter.getRemoteDevice(java.lang.String)' on a null object reference
    at com.example.myapplication.BluetoothLeService.connect(BluetoothLeService.java:139)
    at com.example.myapplication.MainActivity$2.onScanResult(MainActivity.java:96)
    at android.bluetooth.le.BluetoothLeScanner$BleScanCallbackWrapper$1.run(BluetoothLeScanner.java:650)
    at android.os.Handler.handleCallback(Handler.java:888)
    at android.os.Handler.dispatchMessage(Handler.java:100)
    at android.os.Looper.loop(Looper.java:213)
    at android.app.ActivityThread.main(ActivityThread.java:8178)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1101)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
等待大神答复

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...