Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/194.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android BLE响应返回到移动设备到移动设备的外围连接_Android_Bluetooth Lowenergy_Android Bluetooth_Bluetooth Gatt_Bluetooth Peripheral - Fatal编程技术网

Android BLE响应返回到移动设备到移动设备的外围连接

Android BLE响应返回到移动设备到移动设备的外围连接,android,bluetooth-lowenergy,android-bluetooth,bluetooth-gatt,bluetooth-peripheral,Android,Bluetooth Lowenergy,Android Bluetooth,Bluetooth Gatt,Bluetooth Peripheral,嘿,我正在开发一个应用程序,在这个应用程序中,我使用BLE将用户ID从移动设备传输到移动设备,当他们相互交互时,我的应用程序将使用我的应用程序,这意味着在一个移动设备中,我的应用程序将作为外围模式工作,在另一个移动设备中,它将作为中心模式工作。所以我所做的就是打开我的第一个应用程序作为外围模式,启动广告,另一个作为中央模式,在后台启动一项服务,扫描设备并连接读取数据。当我将消息(用户ID)从外围设备发送到中央设备时,该功能工作正常,它会在中央设备上弹出。现在我想把中央模式设备的用户ID发送到外设

嘿,我正在开发一个应用程序,在这个应用程序中,我使用BLE将用户ID从移动设备传输到移动设备,当他们相互交互时,我的应用程序将使用我的应用程序,这意味着在一个移动设备中,我的应用程序将作为外围模式工作,在另一个移动设备中,它将作为中心模式工作。所以我所做的就是打开我的第一个应用程序作为外围模式,启动广告,另一个作为中央模式,在后台启动一项服务,扫描设备并连接读取数据。当我将消息(用户ID)从外围设备发送到中央设备时,该功能工作正常,它会在中央设备上弹出。现在我想把中央模式设备的用户ID发送到外设

据我所知,在BLE中,我们不能将数据从中央发送到外围设备,我们只能从中央进行扫描。但我听说,我们可以从外围设备写入特征,以便在后面得到一些响应,所以我是否可以通过响应或任何其他可能的替代方式将我使用的ID从中央设备发送到外围设备? 我想这样做

我只是BLE的新手,所以我不知道如何执行此功能。我正在分享我的代码,我正在做以下工作:

所以我在后台服务中启动的中央模式或你说的扫描是:

关贸总协定服务

public class GattService extends Service {
private static int NOTIFICATION_ID = 0;
public static final ParcelUuid UUID = ParcelUuid.fromString("0000FED8-0000-1000-8000-00805F9B34FB");
public static final java.util.UUID SERVICE_UUID = java.util.UUID.fromString("00001111-0000-1000-8000-00805F9B34FB");
public static final java.util.UUID CHAR_UUID = java.util.UUID.fromString("00002222-0000-1000-8000-00805F9B34FB");

private BluetoothAdapter bluetoothAdapter;
private BluetoothGattServer server;
private BluetoothLeAdvertiser bluetoothLeAdvertiser;
private boolean start;

@Override
public void onCreate() {
    super.onCreate();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    setupBluetooth();
    return Service.START_STICKY;
}

private void setupBluetooth() {

    BluetoothManager bluetoothManager = (BluetoothManager) this.getApplicationContext().getSystemService(Context.BLUETOOTH_SERVICE);
    server = bluetoothManager.openGattServer(this, serverCallback);
    initServer();
    bluetoothAdapter = bluetoothManager.getAdapter();
    advertise();
}

private void initServer() {
    BluetoothGattService service = new BluetoothGattService(SERVICE_UUID, BluetoothGattService.SERVICE_TYPE_PRIMARY);
    BluetoothGattCharacteristic characteristic = new BluetoothGattCharacteristic(CHAR_UUID, BluetoothGattCharacteristic.PROPERTY_WRITE | BluetoothGattCharacteristic.PROPERTY_READ, BluetoothGattCharacteristic.PERMISSION_READ | BluetoothGattCharacteristic.PERMISSION_WRITE);
    service.addCharacteristic(characteristic);
    server.addService(service);
}

private void advertise() {

    bluetoothLeAdvertiser = bluetoothAdapter.getBluetoothLeAdvertiser();
    AdvertiseData advertisementData = getAdvertisementData();
    AdvertiseSettings advertiseSettings = getAdvertiseSettings();
    bluetoothLeAdvertiser.startAdvertising(advertiseSettings, advertisementData, advertiseCallback);
    start = true;
}

private AdvertiseData getAdvertisementData() {
    AdvertiseData.Builder builder = new AdvertiseData.Builder();
    builder.setIncludeTxPowerLevel(true);
    builder.addServiceUuid(UUID);
    bluetoothAdapter.setName("BLE client");
    builder.setIncludeDeviceName(true);
    return builder.build();
}

private AdvertiseSettings getAdvertiseSettings() {
    AdvertiseSettings.Builder builder = new AdvertiseSettings.Builder();
    builder.setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_BALANCED);
    builder.setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_HIGH);
    builder.setConnectable(true);
    return builder.build();
}

private final AdvertiseCallback advertiseCallback = new AdvertiseCallback() {
    @SuppressLint("Override")
    @Override
    public void onStartSuccess(AdvertiseSettings advertiseSettings) {
        final String message = "Advertisement successful";
        sendNotification(message);
    }

    @SuppressLint("Override")
    @Override
    public void onStartFailure(int i) {
        final String message = "Advertisement failed error code: " + i;
        sendNotification(message);

    }

};

private BluetoothGattServerCallback serverCallback = new BluetoothGattServerCallback() {
    @Override
    public void onConnectionStateChange(BluetoothDevice device, int status, int newState) {
        super.onConnectionStateChange(device, status, newState);
        if (newState == BluetoothProfile.STATE_CONNECTED) {
            sendNotification("Client connected");
        }
    }

    @Override
    public void onServiceAdded(int status, BluetoothGattService service) {
        super.onServiceAdded(status, service);
    }

    @Override
    public void onCharacteristicReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattCharacteristic characteristic) {
        super.onCharacteristicReadRequest(device, requestId, offset, characteristic);

        server.sendResponse(device, requestId, BluetoothGatt.GATT_FAILURE, 0, null);
    }


    @Override
    public void onCharacteristicWriteRequest(BluetoothDevice device, int requestId, BluetoothGattCharacteristic characteristic, boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) {
        super.onCharacteristicWriteRequest(device, requestId, characteristic, preparedWrite, responseNeeded, offset, value);
        byte[] bytes = value;
        String message = new String(bytes);
        sendNotification(message);

        if (characteristic.getUuid().equals(CHAR_UUID)) {
            server.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, 0, null);

        }

        int length = value.length;
        byte[] reversed = new byte[length];
        for (int i = 0; i < length; i++) {
            reversed[i] = value[length - (i + 1)];
        }
        characteristic.setValue(reversed);
        server.notifyCharacteristicChanged(device, characteristic, true);

    }

    @Override
    public void onDescriptorReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattDescriptor descriptor) {
        super.onDescriptorReadRequest(device, requestId, offset, descriptor);
    }

    @Override
    public void onDescriptorWriteRequest(BluetoothDevice device, int requestId, BluetoothGattDescriptor descriptor, boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) {
        super.onDescriptorWriteRequest(device, requestId, descriptor, preparedWrite, responseNeeded, offset, value);


    }

    @Override
    public void onExecuteWrite(BluetoothDevice device, int requestId, boolean execute) {
        super.onExecuteWrite(device, requestId, execute);
    }

    @Override
    public void onNotificationSent(BluetoothDevice device, int status) {
        super.onNotificationSent(device, status);
    }

    @Override
    public void onMtuChanged(BluetoothDevice device, int mtu) {
        super.onMtuChanged(device, mtu);
    }

};

@Override
public void onDestroy() {
    if (start) {
        bluetoothLeAdvertiser.stopAdvertising(advertiseCallback);
    }
    super.onDestroy();
}

private void sendNotification(String message) {
    NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);

    int notificationId = 1;
    String channelId = "channel-01";
    String channelName = "Channel Name";
    int importance = NotificationManager.IMPORTANCE_HIGH;

    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
        NotificationChannel mChannel = new NotificationChannel(
                channelId, channelName, importance);
        notificationManager.createNotificationChannel(mChannel);
    }

    NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, channelId)
            .setSmallIcon(R.mipmap.ic_launcher)
            .setContentTitle(getString(R.string.app_name))
            .setContentText(message)
            .setAutoCancel(true);

    Intent intent = new Intent(this, MainActivity.class);

    TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
    stackBuilder.addNextIntent(intent);
    PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(
            0,
            PendingIntent.FLAG_UPDATE_CURRENT
    );
    mBuilder.setContentIntent(resultPendingIntent);

    notificationManager.notify(notificationId, mBuilder.build());
}

@Override
public IBinder onBind(Intent intent) {
    return null;
}
}
公共类GattService扩展服务{
私有静态int通知_ID=0;
公共静态最终PARCELUID UUID=PARCELUID.fromString(“0000FED8-0000-1000-8000-00805F9B34FB”);
公共静态最终java.util.UUID服务_UUID=java.util.UUID.fromString(“00001111-0000-1000-8000-00805F9B34FB”);
public static final java.util.UUID CHAR_UUID=java.util.UUID.fromString(“00002222-0000-1000-8000-00805F9B34FB”);
私人蓝牙适配器;
私有BluetoothGattServer服务器;
私人BluetoothLeAdvertiser BluetoothLeAdvertiser;
私有布尔启动;
@凌驾
public void onCreate(){
super.onCreate();
}
@凌驾
公共int onStartCommand(Intent Intent、int标志、int startId){
设置蓝牙();
return Service.START\u STICKY;
}
私有无效设置蓝牙(){
BluetoothManager BluetoothManager=(BluetoothManager)this.getApplicationContext().getSystemService(Context.BLUETOOTH_服务);
server=bluetoothManager.openGattServer(这是serverCallback);
initServer();
bluetoothAdapter=bluetoothManager.getAdapter();
做广告();
}
私有void initServer(){
BluetoothGattService服务=新的BluetoothGattService(服务UUID、BluetoothGattService.service类型主服务);
BluetoothGattCharacteristic特征=新的BluetoothGattCharacteristic(字符UUID,BluetoothGattCharacteristic.PROPERTY|u写| BluetoothGattCharacteristic.PROPERTY|u读| BluetoothGattCharacteristic.PERMISSION|u写);
服务特性(特征);
addService(服务);
}
私有无效广告(){
bluetoothLeAdvertiser=bluetoothAdapter.getBluetoothLeAdvertiser();
AdvertiseData advertisementData=getAdvertisementData();
AdvertiseSettings AdvertiseSettings=getAdvertiseSettings();
Bluetooth LeadVertiser.StartVertising(广告设置、广告数据、广告回调);
开始=真;
}
私有AdvertiseData getAdvertisementData(){
AdvertiseData.Builder=新的AdvertiseData.Builder();
builder.setIncludeExpowerLevel(true);
builder.addServiceUuid(UUID);
bluetoothAdapter.setName(“BLE客户端”);
builder.setIncludeDeviceName(true);
返回builder.build();
}
私有广告设置getAdvertiseSettings(){
AdvertiseSettings.Builder=新的AdvertiseSettings.Builder();
builder.setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_BALANCED);
builder.setTxPowerLevel(AdvertiseSettings.ADVERTISE\u TX\u POWER\u HIGH);
builder.setConnectable(true);
返回builder.build();
}
private final AdvertiseCallback AdvertiseCallback=新的AdvertiseCallback(){
@SuppressLint(“覆盖”)
@凌驾
public void onStartSuccess(广告设置广告设置){
最终字符串消息=“广告成功”;
发送通知(消息);
}
@SuppressLint(“覆盖”)
@凌驾
启动失败时的公共无效(int i){
最终字符串message=“播发失败错误代码:”+i;
发送通知(消息);
}
};
私有BluetoothGattServerCallback serverCallback=新的BluetoothGattServerCallback(){
@凌驾
连接状态更改(Bluetooth设备、int状态、int新闻状态)上的公共无效{
super.onConnectionStateChange(设备、状态、新闻状态);
if(newState==BluetoothProfile.STATE\u CONNECTED){
发送通知(“客户连接”);
}
}
@凌驾
公共void onServiceAdded(int状态,BluetoothGattService服务){
super.onServiceAdded(状态、服务);
}
@凌驾
public void onCharacteristicReadRequest(蓝牙设备设备、int-requestId、int-offset、蓝牙GATTCharacteristic特征){
super.onCharacteristicReadRequest(设备、请求ID、偏移量、特征);
sendResponse(设备,请求ID,BluetoothGatt.GATT_失败,0,null);
}
@凌驾
public void onCharacteristicWriteRequest(蓝牙设备设备、int请求ID、蓝牙gattCharacteristic特征、布尔准备写入、布尔响应eded、int偏移量、字节[]值){
super.onCharacteristicWriterRequest(设备、请求ID、特征、准备写入、响应写入、偏移量、值);
字节[]字节=值;
字符串消息=新字符串(字节);
发送通知(消息);
if(characteristic.getUuid().equals(CHAR_UUID)){
sendResponse(设备,requestId,BluetoothGatt.GATT_SUCCESS,0,null);
}
int length=value.length;
字节[]反向=新字节[长度];
for(int i=0;ipublic class ServicesList extends AppCompatActivity implements AdapterView.OnItemClickListener {
private ListView servicesList;
private LinearLayout messageContainer;
private BluetoothDevice device;
private List<String> servicesListNames;
private ArrayAdapter<String> servicesAdapter;
private Handler handler;
private List<BluetoothGattService> services;
private BluetoothGatt currentGatt;
private EditText message;
private Button send;
private BluetoothGattCharacteristic characteristic;
private ProgressDialog dialog;
public static final java.util.UUID DES_UUID = java.util.UUID.fromString("00003333-0000-1000-8000-00805F9B34FB");

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.services_list);
    handler = new Handler();
    dialog = new ProgressDialog(this);
    dialog.setCancelable(false);
    dialog.setMessage("Loading");
    device = getIntent().getExtras().getParcelable("device");
    servicesList = (ListView) findViewById(R.id.services_list);
    messageContainer = (LinearLayout) findViewById(R.id.message_container);
    message = (EditText) findViewById(R.id.message);
    send = (Button) findViewById(R.id.send);
    currentGatt = device.connectGatt(this, false, gattCallback);
    dialog.show();
    servicesListNames = new ArrayList<>();
    servicesAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, servicesListNames);
    servicesList.setAdapter(servicesAdapter);
    servicesList.setOnItemClickListener(this);
    send.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(!message.getText().toString().trim().isEmpty()) {
                characteristic.setValue(message.getText().toString().getBytes());
                currentGatt.writeCharacteristic(characteristic);
                message.setText("");
            }
        }
    });


}

private BluetoothGattCallback gattCallback = new BluetoothGattCallback() {
    @Override
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
        super.onConnectionStateChange(gatt, status, newState);
        if(newState == BluetoothProfile.STATE_CONNECTED) {
            currentGatt.discoverServices();
        }else{
            if(dialog.isShowing()){
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        dialog.hide();
                    }
                });
            }
        }
    }

    @Override
    public void onServicesDiscovered(final BluetoothGatt gatt, int status) {
        super.onServicesDiscovered(gatt, status);
        services = currentGatt.getServices();
        for(BluetoothGattService service : services){
            Log.d("Khurram", "Uuid = " + service.getUuid().toString());
            servicesListNames.add(Helper.getServiceName(service.getUuid().toString()));
            handler.post(new Runnable() {
                @Override
                public void run() {
                    servicesAdapter.notifyDataSetChanged();
                }
            });
        }
        if (dialog.isShowing()){
            handler.post(new Runnable() {
                @Override
                public void run() {
                    dialog.hide();
                }
            });
        }
    }

    @Override
    public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
        super.onCharacteristicRead(gatt, characteristic, status);

        if (status == BluetoothGatt.GATT_SUCCESS) {
   //                log("Characteristic read successfully");
            readCharacteristic(characteristic);
        } else {
   //                logError("Characteristic read unsuccessful, status: " + status);
            // Trying to read from the Time Characteristic? It doesnt have the property or 
   permissions
            // set to allow this. Normally this would be an error and you would want to:
            // disconnectGattServer();
        }
    }

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

    }

    @Override
    public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic 
   characteristic) {
        super.onCharacteristicChanged(gatt, characteristic);

        readCharacteristic(characteristic);
    }

    @Override
    public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) 
{
        super.onDescriptorRead(gatt, descriptor, status);

    }

    @Override
    public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) 
 {
        super.onDescriptorWrite(gatt, descriptor, status);
    }

    @Override
    public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
        super.onReliableWriteCompleted(gatt, status);


    }

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

    @Override
    public void onMtuChanged(BluetoothGatt gatt, int mtu, int status) {
        super.onMtuChanged(gatt, mtu, status);
    }
};

@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    if(services != null){
        BluetoothGattService notificationService = services.get(position);
        if(notificationService.getUuid().equals(GattService.SERVICE_UUID)){
            characteristic = notificationService.getCharacteristic(GattService.CHAR_UUID);
            if(characteristic != null) {
                messageContainer.setVisibility(View.VISIBLE);
            }

        }else{
            Toast.makeText(this, "Testing", Toast.LENGTH_SHORT).show();
        }
    }
}

private void readCharacteristic(BluetoothGattCharacteristic characteristic) {
    byte[] messageBytes = characteristic.getValue();
  log("Read: " + StringUtils.byteArrayInHexFormat(messageBytes));
    String message = StringUtils.stringFromBytes(messageBytes);
    if (message == null) {
        logError("Unable to convert bytes to string");
        Toast.makeText(this, "Unable to convert bytes to string", Toast.LENGTH_SHORT).show();
        return;
    }

    Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
}
}