Android Studio Ble Gatt连接将数据写入自定义服务特征

问题描述 投票:0回答:1

我正在尝试将一些自定义数据写入带有自定义服务的BLE设备。我遵循了本教程:https://www.youtube.com/watch?v=vUbFB1Qypg8&feature=emb_logo,它来自android。

我可以看到带有数据的自定义服务。也可以通过另一个应用程序(NRF连接)将数据写入此自定义服务。因此,我知道有可能将数据写入服务。

我遇到的问题是如何使用BluetoothGatt将数据写入自定义服务的其他示例,而此代码似乎改为使用BluetoothLeService。这是一个问题,因为文档似乎没有针对BluetoothLeService的读取API。所以我不能使用类似mBluetoothGatt.readCharacteristic(mReadCharacteristic);

的东西

我如何创建一个函数来向特征写入值(整数)。我对该服务的UUID是:“ f3641400-00b0-4240-ba50-05ca45bf8abc”

我的特征的UUID是:“ f3641401-00b0-4240-ba50-05ca45bf8abc”

供参考,我的代码如下:

public class DeviceControlActivity extends Activity {
private final static String TAG = 
DeviceControlActivity.class.getSimpleName();

public static final String EXTRAS_DEVICE_NAME = "DEVICE_NAME";
public static final String EXTRAS_DEVICE_ADDRESS = "DEVICE_ADDRESS";

private TextView mConnectionState;
private TextView mDataField;
private EditText Command_string;
private BluetoothGatt mGatt;
private Button btn_gatt_connect;
private Button btn_live,btn_command;
private String mDeviceName;
private String mDeviceAddress;
private String User_data;
private ExpandableListView mGattServicesList;
private BluetoothLeService mBluetoothLeService;
private ArrayList<ArrayList<BluetoothGattCharacteristic>> mGattCharacteristics =
        new ArrayList<ArrayList<BluetoothGattCharacteristic>>();
private boolean mConnected = false;
private BluetoothGattCharacteristic mNotifyCharacteristic;

private final String LIST_NAME = "NAME";
private final String LIST_UUID = "UUID";
private String Switch_case ="Connect";
private boolean Write_ble_command = true;

// Code to manage Service lifecycle.
private final ServiceConnection mServiceConnection = new ServiceConnection() {

    @Override
    public void onServiceConnected(ComponentName componentName, IBinder service) {
        mBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService();
        if (!mBluetoothLeService.initialize()) {
            Log.e(TAG, "Unable to initialize Bluetooth");
            finish();
        }
        // Automatically connects to the device upon successful start-up initialization.
        mBluetoothLeService.connect(mDeviceAddress);
    }

    @Override
    public void onServiceDisconnected(ComponentName componentName) {
        mBluetoothLeService = null;
    }
};

// Handles various events fired by the Service.
// ACTION_GATT_CONNECTED: connected to a GATT server.
// ACTION_GATT_DISCONNECTED: disconnected from a GATT server.
// ACTION_GATT_SERVICES_DISCOVERED: discovered GATT services.
// ACTION_DATA_AVAILABLE: received data from the device.  This can be a result of read
//                        or notification operations.
private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        final String action = intent.getAction();
        if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {
            mConnected = true;
            updateConnectionState(R.string.connected);
            invalidateOptionsMenu();
        } else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {
            mConnected = false;
            updateConnectionState(R.string.disconnected);
            invalidateOptionsMenu();
            clearUI();
        } else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
            // Show all the supported services and characteristics on the user interface.
            displayGattServices(mBluetoothLeService.getSupportedGattServices());
        } else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) {
            displayData(intent.getStringExtra(BluetoothLeService.EXTRA_DATA));
        }
    }
};
// If a given GATT characteristic is selected, check for supported features.  This sample
// demonstrates 'Read' and 'Notify' features.  See
// http://d.android.com/reference/android/bluetooth/BluetoothGatt.html for the complete
// list of supported characteristic features.
private final ExpandableListView.OnChildClickListener servicesListClickListner =
        new ExpandableListView.OnChildClickListener() {
            @Override
            public boolean onChildClick(ExpandableListView parent, View v, int groupPosition,
                                        int childPosition, long id) {
                if (mGattCharacteristics != null) {
                    final BluetoothGattCharacteristic characteristic =
                            mGattCharacteristics.get(groupPosition).get(childPosition);
                    final int charaProp = characteristic.getProperties();
                    if ((charaProp | BluetoothGattCharacteristic.PROPERTY_READ) > 0) {
                        // If there is an active notification on a characteristic, clear
                        // it first so it doesn't update the data field on the user interface.
                        if (mNotifyCharacteristic != null) {
                            mBluetoothLeService.setCharacteristicNotification(
                                    mNotifyCharacteristic, false);
                            mNotifyCharacteristic = null;
                        }
                        mBluetoothLeService.readCharacteristic(characteristic);
                    }
                    if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
                        mNotifyCharacteristic = characteristic;
                        mBluetoothLeService.setCharacteristicNotification(
                                characteristic, true);
                    }
                    return true;
                }
                return false;
            }
        };

private void Gatt_Connect()
{
    switch(Switch_case) {
        case "Connect":
            btn_gatt_connect.setText("Disconnect");//Presently connected allow to disconnect
            mBluetoothLeService.connect(mDeviceAddress);
            Switch_case = "Disconnect";
            break;
        case "Disconnect":
            btn_gatt_connect.setText("Connect");//Presently disconnected allow to connect
            mBluetoothLeService.disconnect();
            Switch_case = "Connect";
            break;
    }

}
private void Live_data(){
    //Ensure you are disconnected
    btn_gatt_connect.setText("Connect");//Presently disconnected allow to connect
    mBluetoothLeService.disconnect();//Might only run if connected
    Switch_case = "Connect";
    Intent myIntent = new Intent(DeviceControlActivity.this, MainActivity.class);
    Bundle bundle = new Bundle();
    bundle.putString("User_data", User_data);//Pass through the user's email address to the main activity for display
    myIntent.putExtras(bundle);
    DeviceControlActivity.this.startActivity(myIntent);//Run the main activity}
}
private void clearUI() {
    mGattServicesList.setAdapter((SimpleExpandableListAdapter) null);
    mDataField.setText(R.string.no_data);
}
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.gatt_services_characteristics);

    //Get the extras passed in
    Bundle bundle = getIntent().getExtras();
    mDeviceName = bundle.getString("Device_Name");
    mDeviceAddress = bundle.getString("Device_Address");
    User_data = bundle.getString("User_data");

    // Sets up UI references.
    ((TextView) findViewById(R.id.device_address)).setText(mDeviceAddress);

    Command_string = (EditText)findViewById(R.id.Command_string);
    btn_gatt_connect = (Button)findViewById(R.id.btn_gatt_connect);
    btn_live = (Button) findViewById(R.id.btn_live);
    btn_command = (Button) findViewById(R.id.btn_command);
    btn_gatt_connect.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Gatt_Connect();
        }
    });

    btn_gatt_connect.setText("Disconnect");//Presently disconnected allow to connect

    btn_live.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Live_data();
        }
    });
    btn_command.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Send_Command();//Sends the command in the text box to the nordic board
        }
    });

    mGattServicesList = (ExpandableListView) findViewById(R.id.gatt_services_list);
    mGattServicesList.setOnChildClickListener(servicesListClickListner);
    mConnectionState = (TextView) findViewById(R.id.connection_state);
    mDataField = (TextView) findViewById(R.id.data_value);

    //setTitle(mDeviceAddress);//Change the title to Scanner as the device is no longer being read
    Intent gattServiceIntent = new Intent(DeviceControlActivity.this, BluetoothLeService.class);
    bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE);
}
@Override
protected void onResume() {
    super.onResume();
    registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter());
    if (mBluetoothLeService != null) {
        final boolean result = mBluetoothLeService.connect(mDeviceAddress);
        Log.d(TAG, "Connect request result=" + result);
    }
}
@Override
protected void onPause() {
    super.onPause();
    unregisterReceiver(mGattUpdateReceiver);
}
@Override
protected void onDestroy() {
    super.onDestroy();
    unbindService(mServiceConnection);
    mBluetoothLeService = null;
}

protected void Send_Command()
{
    Write_ble_command = true;//Write command issued on display gatt service
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.gatt_services, menu);
    if (mConnected) {
        menu.findItem(R.id.menu_connect).setVisible(false);
        menu.findItem(R.id.menu_disconnect).setVisible(true);
    } else {
        menu.findItem(R.id.menu_connect).setVisible(true);
        menu.findItem(R.id.menu_disconnect).setVisible(false);
    }
    return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch(item.getItemId()) {
        case R.id.menu_connect:
            mBluetoothLeService.connect(mDeviceAddress);
            return true;
        case R.id.menu_disconnect:
            mBluetoothLeService.disconnect();
            return true;
        case android.R.id.home:
            onBackPressed();
            return true;
    }
    return super.onOptionsItemSelected(item);
}
private void updateConnectionState(final int resourceId) {
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            mConnectionState.setText(resourceId);
        }
    });
}
private void displayData(String data) {
    if (data != null) {
        mDataField.setText(data);
    }
}
// Demonstrates how to iterate through the supported GATT Services/Characteristics.
// In this sample, we populate the data structure that is bound to the ExpandableListView
// on the UI.
private void displayGattServices(List<BluetoothGattService> gattServices) {
    if (gattServices == null) return;
    String uuid = null;
    String unknownServiceString = getResources().getString(R.string.unknown_service);
    String unknownCharaString = getResources().getString(R.string.unknown_characteristic);
    ArrayList<HashMap<String, String>> gattServiceData = new ArrayList<HashMap<String, String>>();
    ArrayList<ArrayList<HashMap<String, String>>> gattCharacteristicData
            = new ArrayList<ArrayList<HashMap<String, String>>>();
    mGattCharacteristics = new ArrayList<ArrayList<BluetoothGattCharacteristic>>();

    // Loops through available GATT Services.
    for (BluetoothGattService gattService : gattServices) {
        HashMap<String, String> currentServiceData = new HashMap<String, String>();
        uuid = gattService.getUuid().toString();
        currentServiceData.put(
                LIST_NAME, SampleGattAttributes.lookup(uuid, unknownServiceString));
        currentServiceData.put(LIST_UUID, uuid);
        gattServiceData.add(currentServiceData);

        ArrayList<HashMap<String, String>> gattCharacteristicGroupData =
                new ArrayList<HashMap<String, String>>();
        List<BluetoothGattCharacteristic> gattCharacteristics =
                gattService.getCharacteristics();
        ArrayList<BluetoothGattCharacteristic> charas =
                new ArrayList<BluetoothGattCharacteristic>();

        // Loops through available Characteristics.
        for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
            charas.add(gattCharacteristic);
            HashMap<String, String> currentCharaData = new HashMap<String, String>();
            uuid = gattCharacteristic.getUuid().toString();
            currentCharaData.put(
                    LIST_NAME, SampleGattAttributes.lookup(uuid, unknownCharaString));
            currentCharaData.put(LIST_UUID, uuid);
            gattCharacteristicGroupData.add(currentCharaData);
        }
        mGattCharacteristics.add(charas);
        gattCharacteristicData.add(gattCharacteristicGroupData);
    }

    SimpleExpandableListAdapter gattServiceAdapter = new SimpleExpandableListAdapter(
            this,
            gattServiceData,
            android.R.layout.simple_expandable_list_item_2,
            new String[] {LIST_NAME, LIST_UUID},
            new int[] { android.R.id.text1, android.R.id.text2 },
            gattCharacteristicData,
            android.R.layout.simple_expandable_list_item_2,
            new String[] {LIST_NAME, LIST_UUID},
            new int[] { android.R.id.text1, android.R.id.text2 }
    );
    mGattServicesList.setAdapter(gattServiceAdapter);

}
private static IntentFilter makeGattUpdateIntentFilter() {
    final IntentFilter intentFilter = new IntentFilter();
    intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED);
    intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED);
    intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED);
    intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE);
    return intentFilter;
}

}

java android-studio bluetooth bluetooth-lowenergy gatt
1个回答
0
投票

我通过在Bluetoothle服务内部创建函数来解决我的问题。这是蓝牙gatt连接所在的位置。功能是这样的。

public void writeCharacteristic(int Data) {
    if (mBluetoothAdapter == null || mBluetoothGatt == null) {
        Log.w(TAG, "BluetoothAdapter not initialized");
        return;
    }

    byte[] value = intToByteArray(Data);

    BluetoothGattService mCustomService = mBluetoothGatt.getService(UUID.fromString("f3641400-00b0-4240-ba50-05ca45bf8abc"));
    if(mCustomService == null){
        Log.w(TAG, "Custom BLE Service not found");
        return;
    }
    /*get the read characteristic from the service*/
    BluetoothGattCharacteristic characteristic = mCustomService.getCharacteristic(UUID.fromString("f3641401-00b0-4240-ba50-05ca45bf8abc"));
    characteristic.setValue(value);
    mBluetoothGatt.writeCharacteristic(characteristic);
}

它只需要一个数据(将Int值传递给它)。然后这将由我的蓝牙板接收,并且可以在正确发送的终端上看到其数据。

© www.soinside.com 2019 - 2024. All rights reserved.