Отправка и получение данных из ESL (электронных этикеток полки) через приложение Android через Bluetooth - PullRequest
0 голосов
/ 23 ноября 2018

Я пытаюсь связаться с ESL через приложение для Android.Я устанавливаю соединение и могу читать данные из ESL, используя основные функции Bluetooth.Но теперь производитель говорит, что для записи данных в ESL сначала нужно выполнить аутентификацию, а затем я могу записать данные в этот ESL.Они также дают мне блок-схему, но я не могу этого понять.Поэтому я с нетерпением жду вашей помощи.Ниже мой код:

public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getSimpleName();
private static final int REQUEST_ENABLE_BT = 1111;
private static final int REQUEST_LOCATION = 1;
private static String[] PERMISSIONS_LOCATION = {Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION};
private ConstraintLayout cl_mMain;
private ScanCallback scanCallback;
private BluetoothAdapter.LeScanCallback leScanCallback;
private BluetoothGatt gatt;
private BluetoothGattCallback gattCallback;
private BluetoothDevice bluetoothDevice;
private int mConnectionState = 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);

public static final ParcelUuid PARCE_UUID_EDDYSTONE =
        ParcelUuid.fromString("0000FEA0-0000-1000-8000-00805f9b34fb");

private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        final String action = intent.getAction();
        if (ACTION_GATT_CONNECTED.equals(action)) {

        } else if (ACTION_GATT_DISCONNECTED.equals(action)) {

        } else if (ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
            // Show all the supported services and characteristics on the
            // user interface.
            displayGattServices(getSupportedGattServices());
        } else if (ACTION_DATA_AVAILABLE.equals(action)) {
            //displayData(intent.getStringExtra(EXTRA_DATA));
            Log.e(TAG, "Result " + intent.getStringExtra(EXTRA_DATA));
        }
    }
};

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

    cl_mMain = findViewById(R.id.cl_main);

    checkLocationPermission();
    IntentFilter intentFilter = new IntentFilter();
    intentFilter.addAction(ACTION_DATA_AVAILABLE);
    intentFilter.addAction(ACTION_GATT_CONNECTED);
    intentFilter.addAction(ACTION_GATT_DISCONNECTED);
    intentFilter.addAction(ACTION_GATT_SERVICES_DISCOVERED);
    registerReceiver(mGattUpdateReceiver, intentFilter);
}

public List<BluetoothGattService> getSupportedGattServices() {
    if (gatt == null) return null;

    return gatt.getServices();
}

public void connectService() {
    BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    if (mBluetoothAdapter != null) {
        leScanCallback = new BluetoothAdapter.LeScanCallback() {
            @Override
            public void onLeScan(final BluetoothDevice bluetoothDevice, int receivedSignalStrengthIndicator, byte[] bytes) {
                if (bluetoothDevice.getAddress().trim().equals("DD:33:0A:00:83:35")) {
                    MainActivity.this.bluetoothDevice = bluetoothDevice;
                    Log.e(TAG, "Device: " + bluetoothDevice.getName() + "\n" + bluetoothDevice.getAddress());
                    gatt = bluetoothDevice.connectGatt(MainActivity.this, true, gattCallback);
                }
            }
        };
        mBluetoothAdapter.startLeScan(leScanCallback);

        //Gatt callback
        gattCallback = new BluetoothGattCallback() {
            @Override
            public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
                super.onConnectionStateChange(gatt, status, newState);
                String intentAction;
                if (newState == STATE_CONNECTED) {
                    intentAction = ACTION_GATT_CONNECTED;
                    mConnectionState = STATE_CONNECTED;
                    broadcastUpdate(intentAction);
                    Log.e(TAG, "Connected to GATT server.");
                    Log.e(TAG, "Attempting to start service discovery:" +
                            gatt.discoverServices());

                } else if (newState == STATE_DISCONNECTED) {
                    intentAction = ACTION_GATT_DISCONNECTED;
                    mConnectionState = STATE_DISCONNECTED;
                    Log.e(TAG, "Disconnected from GATT server.");
                    broadcastUpdate(intentAction);
                }
            }

            @Override
            public void onServicesDiscovered(BluetoothGatt gatt, int status) {
                super.onServicesDiscovered(gatt, status);
                Log.e(TAG, "size " + gatt.getServices().size());
                if (status == BluetoothGatt.GATT_SUCCESS) {
                    broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
                    Log.e(TAG, "onServicesDiscovered received: " + status);
                } else {
                    Log.e(TAG, "onServicesDiscovered received: " + status);
                }
            }

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

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

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

private void checkLocationPermission() {
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        requestLocationPermission();
    } else {
        BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        if (mBluetoothAdapter != null && mBluetoothAdapter.isEnabled()) {
            connectService();
        } else {
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
        }
    }
}

private void requestLocationPermission() {
    if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_COARSE_LOCATION) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) {
        Snackbar.make(cl_mMain, "Location permission is needed to access the location.", Snackbar.LENGTH_INDEFINITE).setAction("Ok", new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                ActivityCompat.requestPermissions(MainActivity.this, PERMISSIONS_LOCATION, REQUEST_LOCATION);
            }
        }).show();
    } else {
        ActivityCompat.requestPermissions(this, PERMISSIONS_LOCATION, REQUEST_LOCATION);
    }
}

public UUID convertFromInteger(int i) {
    final long MSB = 0x0000000000001000L;
    final long LSB = 0x800000805f9b34fbL;
    long value = i & 0xFFFFFFFF;
    return new UUID(MSB | (value << 32), LSB);
}

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

    // This is special handling for the Heart Rate Measurement profile. Data
    // parsing is carried out as per profile specifications.
    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 {
        // For all other profiles, writes the data formatted in HEX.
        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));
            intent.putExtra(EXTRA_DATA, new String(data) + "\n" +
                    stringBuilder.toString());

            Log.e(TAG, stringBuilder.toString());
        }
    }
    sendBroadcast(intent);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == REQUEST_ENABLE_BT) {
        if (resultCode == Activity.RESULT_OK) {
            connectService();
        }
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    if (requestCode == REQUEST_LOCATION) {
        if (PermissionUtil.verifyPermissions(grantResults)) {
            Snackbar.make(cl_mMain, "Location permission is granted", Snackbar.LENGTH_SHORT).show();
            BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
            if (mBluetoothAdapter != null && mBluetoothAdapter.isEnabled()) {
                connectService();
            } else {
                Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
            }
        } else {
            Snackbar.make(cl_mMain, "Location permission is not granted", Snackbar.LENGTH_SHORT).show();
        }
    }
}

// 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 = "Unknown services";
    String unknownCharaString = "unknown_characteristic";
    ArrayList<HashMap<String, String>> gattServiceData = new ArrayList<HashMap<String, String>>();
    ArrayList<ArrayList<HashMap<String, String>>> gattCharacteristicData = new ArrayList<ArrayList<HashMap<String, String>>>();
    ArrayList<ArrayList<BluetoothGattCharacteristic>> mGattCharacteristics = new ArrayList<>();

    // Get the default adapter
    BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

    // Loops through available GATT Services.
    for (BluetoothGattService gattService : gattServices) {
        HashMap<String, String> currentServiceData = new HashMap<String, String>();
        uuid = gattService.getUuid().toString();
        Log.e(TAG, uuid);
        BluetoothSocket bluetoothSocket;
        Log.e(TAG, bluetoothDevice.getAddress() + "\n" + bluetoothDevice.getName());
        try {
            Log.e(TAG, String.valueOf(bluetoothDevice.fetchUuidsWithSdp()));
            bluetoothSocket = bluetoothDevice.createRfcommSocketToServiceRecord(UUID.fromString("0000FEA0-0000-1000-8000-00805f9b34fb"));
            // Cancel discovery because it otherwise slows down the connection.
            mBluetoothAdapter.cancelDiscovery();
            bluetoothSocket.connect();
            if (bluetoothSocket.isConnected())
                Log.e(TAG, "connected ");
            else
                Log.e(TAG, "not connected ");
        } catch (IOException e) {
            e.printStackTrace();
        }


        /*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);*/
    }
}

@Override
protected void onDestroy() {
    super.onDestroy();
    unregisterReceiver(mGattUpdateReceiver);
}}

Я получаю исключения, когда пытаюсь выполнить этот вызов

bluetoothSocket.connect();

Заранее спасибо

...