Vutivi Mashele
Vutivi Mashele

Reputation: 31

Android studio: Discovered Bluetooth device name not found and struggling to pair to device

I've developed an app that uses a specific Bluetooth module (an HC-06) to communicate with it, but first it needs to pair with it, and it does so using the following code...

BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
ListView lView;
ArrayList<String> devNameList, devAddressList;

private ListAdapter arrayAdapter;
private ConnectThread mConnectThread;
private BluetoothSocket mmSocket = null;
private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
private final static int REQUEST_ID = 2;

// Create a BroadcastReceiver for ACTION_FOUND.
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (BluetoothDevice.ACTION_FOUND.equals(action)) {
            // Discovery has found a device. Get the BluetoothDevice
            // object and its info from the Intent.
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            String devName = device.getName();
            String devAddress = device.getAddress();

            devAddressList.add(devAddress);

            if (devName == null){
                devName = device.getAddress();
            }

            devNameList.add(devName);

            lView.setAdapter(arrayAdapter);
        }
    }
};

private class ConnectThread extends Thread {
    ConnectThread(BluetoothDevice device) {
        BluetoothSocket tmp = null;

        try {
            // Get a BluetoothSocket to connect with the given BluetoothDevice.
            // MY_UUID is the app's UUID string, also used in the server code.
            tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
        } catch (IOException e) {
            Toast.makeText(getBaseContext(), "ERROR: Socket's create() method failed", Toast.LENGTH_SHORT).show();
        }
        mmSocket = tmp;
    }

    public void run() {
        try {
            // Connect to the remote device through the socket. This call blocks
            // until it succeeds or throws an exception.
            mmSocket.connect();
        } catch (IOException connectException) {
            // Unable to connect; close the socket and return.
            try {
                mmSocket.close();
            } catch (IOException closeException) {
                Toast.makeText(getBaseContext(), "ERROR: Could not close the client socket",
                        Toast.LENGTH_SHORT).show();
            }
            return;
        }
        // The connection attempt succeeded. Perform work associated with
        // the connection in a separate thread.
        manageMyConnectedSocket();
    }

    // Closes the client socket and causes the thread to finish.
    void cancel() {
        try {
            mmSocket.close();
        } catch (IOException e) {
            Toast.makeText(getBaseContext(), "ERROR: Could not close the client socket",
                    Toast.LENGTH_SHORT).show();
        }
    }
}

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

    requestPermissions();

    lView = findViewById(R.id.discList);

    devNameList = new ArrayList<>();
    devAddressList = new ArrayList<>();
    arrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, devNameList);

    if (mBluetoothAdapter.isDiscovering()){
        mBluetoothAdapter.cancelDiscovery();
    }
    // Register for broadcasts when a device is discovered.
    IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
    registerReceiver(mReceiver, filter);
    mBluetoothAdapter.startDiscovery();

    lView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            String devName = devNameList.get(position);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                if((Objects.equals(devName, "HC-06"))|| (Objects.equals(devName, "00:21:13:00:97:6A"))){
                    Toast.makeText(AddNewDevice.this, "Please wait...", Toast.LENGTH_SHORT).show();

                    mBluetoothAdapter.cancelDiscovery();

                    String address = devAddressList.get(position);
                    BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
                    mConnectThread = new ConnectThread(device);
                    mConnectThread.run();
                }
                else{
                    Toast.makeText(AddNewDevice.this, "Please connect to an HC-06 device.", Toast.LENGTH_SHORT).show();
                }
            }
            else {
                if("HC-06".equals(devName) || "00:21:13:00:97:6A".equals(devName)){
                Toast.makeText(AddNewDevice.this, "Please wait...", Toast.LENGTH_SHORT).show();

                mBluetoothAdapter.cancelDiscovery();

                String address = devAddressList.get(position);
                BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
                mConnectThread = new ConnectThread(device);
                mConnectThread.run();
                }
                else{
                    Toast.makeText(AddNewDevice.this, "Please connect to an HC-06 device.", Toast.LENGTH_SHORT).show();
                }
            }
        }
    });
}

private void requestPermissions(){
    int androidVersion = Build.VERSION.SDK_INT;
    if (androidVersion >= 23){
        ActivityCompat.requestPermissions(this,
                new String[]{Manifest.permission.ACCESS_FINE_LOCATION,
                        Manifest.permission.ACCESS_COARSE_LOCATION,
                }, REQUEST_ID);
    }
}

@Override
protected void onDestroy() {
    super.onDestroy();
    unregisterReceiver(mReceiver);
    mBluetoothAdapter.cancelDiscovery();
}

private void manageMyConnectedSocket() {
    mConnectThread.cancel();
    finish();
}

The code works well on a device running API 17 (Android 4.2.2), but on an API 23 (android 6.0) device it's a bit glitchy:

Firstly, it sometimes finds the device name and sometimes doesn't ( that's why I added a getAddress line instead of getName to my device list [devNameList] in line 50 and 51 [if you copied the code], line 23 and 24 without the import headers)

Secondly, I noticed that when it doesn't obtain the device name and I try to connect, it struggles to pair/connect to the device (in my bluetooth settings it just shows "paring..." forever) but when it does obtain the device name it pairs properly.

Can anyone help me with this glitch?

Upvotes: 3

Views: 2504

Answers (1)

Zachariah Rabatah
Zachariah Rabatah

Reputation: 312

I answered this question a few days back. The link is below. The issue you are having with newer versions of Android is that it requires the Coarse and Fine location permissions in order to do discovery with the newer versions of android. Finding devices and then pairing with them should work once you include these permissions.

Link: Can not discover available Bluetooth devices

My Post from the link above:

Try to also add the Coarse Location permission. I have both Fine and Coarse on my application and it works with API 19 (Kit Kat), API 21 (Lollipop), API 23 (Marshmallow), and API 24 (Nougat).

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

Also make sure you request the permission before you reach this point in the app. So in onCreate add the following method to make sure your permissions are requested on higher versions of Android. I know I needed to add this code as well to get it working. You can use your own defined int for REQUEST_ID. It will pop up a prompt to the user when you load the app for higher versions of android.

private int androidVersion; //define at top of code as a variable

private void requestPermissions(){
androidVersion = Build.VERSION.SDK_INT;
        if (androidVersion >= 23){
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.ACCESS_FINE_LOCATION,
                            Manifest.permission.ACCESS_COARSE_LOCATION,                                
                    }, REQUEST_ID);
        }
    }

Upvotes: 1

Related Questions