visual studio – How can a client obtain the server’s Bluetooth address or Name in a Client-Server application to connect correctly?


I am developing a server in VB.Net (Visual Studio) and a client in Java (Android Studio). My server sets a UUID with the following code: Dim serviceGuid As New Guid("00001101-0000-1000-8000-00805F9B34FB"). How can I enable the client to automatically discover which device the server is running on so that it can establish the connection with the correct device? My android client code scan all devices and show all devices into ListView. However, I would like the client to be able to identify which device in the list is hosting the server.I have tried several methods, but without success. Can anyone help me?

This is the server code:

Imports InTheHand.Net.Bluetooth
Imports InTheHand.Net.Sockets
Imports System.IO
Imports System.Text
Imports System.Threading

Public Class Form1

    Private btListener As BluetoothListener
    Private btClient As BluetoothClient

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        StartBTServer()
    End Sub

    Private Sub StartBTServer()
        Try

            Dim serviceGuid As New Guid("00001101-0000-1000-8000-00805F9B31FF")


            btListener = New BluetoothListener(serviceGuid)
            btListener.Start()
            Console.WriteLine("Server started...")


            Task.Run(Sub()
                         While True
                             Try

                                 Console.WriteLine("Await connections...")
                                 btClient = btListener.AcceptBluetoothClient()


                                 Dim writer As New StreamWriter(btClient.GetStream(), Encoding.UTF8) With {
                                     .AutoFlush = True
                                 }
                                 Dim localRadio As BluetoothRadio = BluetoothRadio.Default
                                 If localRadio IsNot Nothing Then
                                     writer.WriteLine(localRadio.Name)
                                     Console.WriteLine("Send device name: " & localRadio.Name)
                                 Else
                                     writer.WriteLine("???")
                                 End If


                                 Me.Invoke(Sub()
                                               statusText.Text = ("CONNECTED WITH: " & btClient.RemoteMachineName).ToUpper()
                                           End Sub)


                                 StartReadingCommands(btClient)
                             Catch ex As Exception
                                 Console.WriteLine("Error on accept connection: " & ex.Message)
                                 Me.Invoke(Sub()
                                               statusText.Text = "Error on accept connection: " & ex.Message
                                           End Sub)
                             End Try
                         End While
                     End Sub)
        Catch ex As Exception
            Me.Invoke(Sub()
                          statusText.Text = "Error on start server: " & ex.Message
                      End Sub)
        End Try
    End Sub

    Private Sub StartReadingCommands(btClient As BluetoothClient)
        Task.Run(Sub()
                     Try

                         Dim reader As New StreamReader(btClient.GetStream(), Encoding.UTF8)


                         While btClient.Connected
                             Try

                                 If btClient.GetStream().DataAvailable Then

                                     Dim command As String = reader.ReadLine()
                                     If Not String.IsNullOrEmpty(command) Then
                                         Console.WriteLine("Command received: " & command)
                                         HandleBTClientCommand(command)
                                     Else
                                         Console.WriteLine("Empty command.")
                                     End If
                                 Else
                                     Console.WriteLine("No data.")
                                     Thread.Sleep(100)
                                 End If
                             Catch ex As IOException
                                 Console.WriteLine("Error on read command: " & ex.Message)
                                 Exit While
                             Catch ex As Exception
                                 Console.WriteLine("Error on read command: " & ex.Message)
                             End Try
                         End While

                         Console.WriteLine("Connection closed.")
                     Catch ex As Exception
                         Me.Invoke(Sub()
                                       statusText.Text = "error: " & ex.Message
                                   End Sub)
                     End Try
                 End Sub)
    End Sub

    Public Sub StopBTServer()
        If btClient IsNot Nothing Then btClient.Close()
        If btListener IsNot Nothing Then btListener.Stop()

    End Sub

    Private Sub HandleBTClientCommand(command As String)
        Me.Invoke(Sub()
                      '' [...]
                  End Sub)
    End Sub
End Class

This is my client code:

package br.com.myapplication;

import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "BluetoothClient";
    private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B31FF");
    private static final int REQUEST_PERMISSIONS = 1;

    private BluetoothAdapter bluetoothAdapter;
    private List<BluetoothDevice> deviceList = new ArrayList<>();
    private Set<String> discoveredDevices = new HashSet<>();
    private ArrayAdapter<String> deviceArrayAdapter;
    private OutputStream outputStream;
    private InputStream inputStream;
    private BluetoothSocket bluetoothSocket;
    private ListView lvDevices;

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

        // Initialize UI components
        Button btnDiscover = findViewById(R.id.btnDiscover);
        Button btnStart = findViewById(R.id.btnStart);
        Button btnNext = findViewById(R.id.btnNext);
        Button btnPrevious = findViewById(R.id.btnPrevious);
        Button btnStop = findViewById(R.id.btnStop);
        lvDevices = findViewById(R.id.lvDevices);

        // Set up ArrayAdapter for ListView
        deviceArrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1);
        lvDevices.setAdapter(deviceArrayAdapter);

        // Initialize BluetoothAdapter
        bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

        if (bluetoothAdapter == null) {
            Toast.makeText(this, "Not supported", Toast.LENGTH_LONG).show();
            finish();
            return;
        }

        // Check and request necessary permissions
        checkPermissions();

        // Set up button click listeners
        btnDiscover.setOnClickListener(v -> discoverDevices());

        lvDevices.setOnItemClickListener((parent, view, position, id) -> {
            BluetoothDevice selectedDevice = deviceList.get(position);
            connectToServer(selectedDevice);
        });

       

        // Register receiver for Bluetooth device discovery
        IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        registerReceiver(receiver, filter);
    }

    private void checkPermissions() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED ||
                    ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED ||
                    ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {

                ActivityCompat.requestPermissions(this, new String[]{
                        Manifest.permission.BLUETOOTH_SCAN,
                        Manifest.permission.BLUETOOTH_CONNECT,
                        Manifest.permission.ACCESS_FINE_LOCATION,
                        Manifest.permission.ACCESS_COARSE_LOCATION
                }, REQUEST_PERMISSIONS);
            }
        } else {
            // Permissions for earlier versions
            if (ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH) != PackageManager.PERMISSION_GRANTED ||
                    ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_ADMIN) != PackageManager.PERMISSION_GRANTED) {

                ActivityCompat.requestPermissions(this, new String[]{
                        Manifest.permission.BLUETOOTH,
                        Manifest.permission.BLUETOOTH_ADMIN,
                        Manifest.permission.ACCESS_FINE_LOCATION,
                        Manifest.permission.ACCESS_COARSE_LOCATION
                }, REQUEST_PERMISSIONS);
            }
        }
    }

    private void discoverDevices() {
        if (!bluetoothAdapter.isEnabled()) {
            bluetoothAdapter.enable();
        }

        // Clear previous device list
        deviceList.clear();
        discoveredDevices.clear();
        deviceArrayAdapter.clear();

        Log.d(TAG, "Scanning devices");
        bluetoothAdapter.startDiscovery();
    }

    // Receiver to handle found Bluetooth devices
    private final BroadcastReceiver receiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

                if (device != null && !discoveredDevices.contains(device.getAddress())) {
                    Log.d(TAG, "Devices found: " + device.getName() + " [" + device.getAddress() + "]");
                    discoveredDevices.add(device.getAddress());
                    deviceList.add(device);
                    deviceArrayAdapter.add(device.getName() + "\n" + device.getAddress());
                    deviceArrayAdapter.notifyDataSetChanged();  // Notify adapter about data changes
                }
            }
        }
    };

    private void connectToServer(BluetoothDevice serverDevice) {
        new Thread(() -> {
            try {
                Log.d(TAG, "Trying to connect: " + serverDevice.getName());
                bluetoothSocket = serverDevice.createRfcommSocketToServiceRecord(MY_UUID);

                bluetoothAdapter.cancelDiscovery();

                bluetoothSocket.connect();
                outputStream = bluetoothSocket.getOutputStream();
                inputStream = bluetoothSocket.getInputStream();

                runOnUiThread(() -> Toast.makeText(this, "Connected wuth: " + serverDevice.getName(), Toast.LENGTH_SHORT).show());
                Log.d(TAG, "Success connected with: " + serverDevice.getName());

            } catch (IOException e) {
                Log.e(TAG, "Error to connect with: " + e.getMessage());
                runOnUiThread(() -> Toast.makeText(this, "Error on connect: " + e.getMessage(), Toast.LENGTH_SHORT).show());
                try {
                    if (bluetoothSocket != null) {
                        bluetoothSocket.close();
                    }
                } catch (IOException closeException) {
                    Log.e(TAG, "Error on close socket: " + closeException.getMessage());
                }
            }
        }).start();
    }

    private void sendCommand(String command) {
        if (outputStream != null) {
            try {
                outputStream.write((command + "\n").getBytes());
                outputStream.flush();
                Log.d(TAG, "Send command: " + command);
            } catch (IOException e) {
                Log.e(TAG, "Error os send: " + e.getMessage());
                Toast.makeText(this, "Error on send: " + e.getMessage(), Toast.LENGTH_SHORT).show();
            }
        } else {
            Log.e(TAG, "OutputStream null, no open connections");
            Toast.makeText(this, "No connected", Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (bluetoothAdapter != null) {
            bluetoothAdapter.cancelDiscovery();
        }
        unregisterReceiver(receiver);
        try {
            if (bluetoothSocket != null) {
                bluetoothSocket.close();
            }
        } catch (IOException e) {
            Log.e(TAG, "Error on close socket: " + e.getMessage());
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == REQUEST_PERMISSIONS) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(this, "Permissions granted", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(this, "Granted", Toast.LENGTH_SHORT).show();
                finish();
            }
        }
    }
}

Leave a Reply

Your email address will not be published. Required fields are marked *