javaandroidbluecove

Connect Bluetooth Android Client to Bluetooth Java Server


I've been following these two posts SPP Server and Client and this stackoverflow post. I have the server running on a Linux VM and the Android app running on a Samsung Galaxy S6. When I run the server code in Intellij, it says:

"Server Started. Waiting for clients to connect".

When I run the Android app, I get the following Alert box saying:

"Fatal Error. In OnResume()and an exception occurred during write: socket closed. Check that the SPP UUID: 00001101-0000-1000-8000-00805F9B34FB exists on server. Press OK to exit.

Why is this happening and how can I resolve it so the server will connect and receive a string from the Android app?

SPP Server Code:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;

import javax.bluetooth.*;
import javax.microedition.io.*;


public class SampleSPPServer {

    //start server
    private void startServer() throws IOException{

        //Create a UUID for SPP
        UUID uuid = new UUID("0000110100001000800000805F9B34FB", false);
        //Create the servicve url
        String connectionString = “btspp://localhost:” + uuid +”;name=Sample 
        SPP Server”;

        //open server url
        StreamConnectionNotifier streamConnNotifier = 
        (StreamConnectionNotifier)Connector.open( connectionString );

        //Wait for client connection
        System.out.println(“\nServer Started. Waiting for clients to connect…”);
        StreamConnection connection=streamConnNotifier.acceptAndOpen();

        RemoteDevice dev = RemoteDevice.getRemoteDevice(connection);
        System.out.println(“Remote device address: “+dev.getBluetoothAddress());
        System.out.println(“Remote device name: “+dev.getFriendlyName(true));

        //read string from spp client
        InputStream inStream=connection.openInputStream();
        BufferedReader bReader=new BufferedReader(new 
        InputStreamReader(inStream));
        String lineRead=bReader.readLine();
        System.out.println(lineRead);

        //send response to spp client
        OutputStream outStream=connection.openOutputStream();
        PrintWriter pWriter=new PrintWriter(new OutputStreamWriter(outStream));
        pWriter.write(“Response String from SPP Server\r\n”);
        pWriter.flush();

        pWriter.close();
        streamConnNotifier.close();

    }

    public static void main(String[] args) throws IOException {

        //display local device address and name
        LocalDevice localDevice = LocalDevice.getLocalDevice();
        System.out.println(“Address: “+localDevice.getBluetoothAddress());
        System.out.println(“Name: “+localDevice.getFriendlyName());

        SampleSPPServer sampleSPPServer=new SampleSPPServer();
        sampleSPPServer.startServer();

    }
}

Android Client Code:

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.DialogInterface;
import android.content.Intent;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.UUID;

public class BluetoothClient extends AppCompatActivity {

    TextView out;
    private static final int REQUEST_ENABLE_BT = 1;
    private BluetoothAdapter btAdapter = null;
    private BluetoothSocket btSocket = null;
    private OutputStream outStream = null;

    // Well known SPP UUID
    private static final UUID MY_UUID =
            UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

    // Insert your server's MAC address
    private static String address = "00:10:60:AA:B9:B2";

    /** Called when the activity is first created. */
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bluetooth_client);

        out = (TextView) findViewById(R.id.out);

        out.append("\n...In onCreate()...");

        btAdapter = BluetoothAdapter.getDefaultAdapter();
        CheckBTState();
    }

    public void onStart() {
        super.onStart();
        out.append("\n...In onStart()...");
    }

    public void onResume() {
        super.onResume();

        out.append("\n...In onResume...\n...Attempting client connect...");

        // Set up a pointer to the remote node using it's address.
        BluetoothDevice device = btAdapter.getRemoteDevice(address);

        // Two things are needed to make a connection:
        //   A MAC address, which we got above.
        //   A Service ID or UUID.  In this case we are using the
        //     UUID for SPP.
        try {
            btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
        } catch (IOException e) {
            AlertBox("Fatal Error", "In onResume() and socket create failed: " + e.getMessage() + ".");
        }

        // Discovery is resource intensive.  Make sure it isn't going on
        // when you attempt to connect and pass your message.
        btAdapter.cancelDiscovery();

        // Establish the connection.  This will block until it connects.
        try {
            btSocket.connect();
            out.append("\n...Connection established and data link opened...");
        } catch (IOException e) {
            try {
                btSocket.close();
            } catch (IOException e2) {
                AlertBox("Fatal Error", "In onResume() and unable to close socket during connection failure" + e2.getMessage() + ".");
            }
        }

        // Create a data stream so we can talk to server.
        out.append("\n...Sending message to server...");
        String message = "Hello from Android.\n";
        out.append("\n\n...The message that we will send to the server is: "+message);

        try {
            outStream = btSocket.getOutputStream();
        } catch (IOException e) {
            AlertBox("Fatal Error", "In onResume() and output stream creation failed:" + e.getMessage() + ".");
        }

        byte[] msgBuffer = message.getBytes();
        try {
            outStream.write(msgBuffer);
        } catch (IOException e) {
            String msg = "In onResume() and an exception occurred during write: " + e.getMessage();
            if (address.equals("00:00:00:00:00:00"))
                msg = msg + ".\n\nUpdate your server address from 00:00:00:00:00:00 to the correct address on line 37 in the java code";
            msg = msg +  ".\n\nCheck that the SPP UUID: " + MY_UUID.toString() + " exists on server.\n\n";

            AlertBox("Fatal Error", msg);
        }
    }

    public void onPause() {
        super.onPause();

        //out.append("\n...Hello\n");
        InputStream inStream;
        try {
            inStream = btSocket.getInputStream();
            BufferedReader bReader=new BufferedReader(new InputStreamReader(inStream));
            String lineRead=bReader.readLine();
            out.append("\n..."+lineRead+"\n");

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        out.append("\n...In onPause()...");



        if (outStream != null) {
            try {
                outStream.flush();
            } catch (IOException e) {
                AlertBox("Fatal Error", "In onPause() and failed to flush output stream: " + e.getMessage() + ".");
            }
        }

        try     {
            btSocket.close();
        } catch (IOException e2) {
            AlertBox("Fatal Error", "In onPause() and failed to close socket." + e2.getMessage() + ".");
        }
    }

    public void onStop() {
        super.onStop();
        out.append("\n...In onStop()...");
    }

    public void onDestroy() {
        super.onDestroy();
        out.append("\n...In onDestroy()...");
    }

    private void CheckBTState() {
        // Check for Bluetooth support and then check to make sure it is turned on

        // Emulator doesn't support Bluetooth and will return null
        if(btAdapter==null) {
            AlertBox("Fatal Error", "Bluetooth Not supported. Aborting.");
        } else {
            if (btAdapter.isEnabled()) {
                out.append("\n...Bluetooth is enabled...");
            } else {
                //Prompt user to turn on Bluetooth
                Intent enableBtIntent = new Intent(btAdapter.ACTION_REQUEST_ENABLE);
                startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
            }
        }
    }

    public void AlertBox( String title, String message ){
        new AlertDialog.Builder(this)
                .setTitle( title )
                .setMessage( message + " Press OK to exit." )
                .setPositiveButton("OK", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface arg0, int arg1) {
                        finish();
                    }
                }).show();
    }
}

Android Studio Logcat:

android.view.WindowLeaked: Activity         com.example.toby.btclientapp.BluetoothClient has leaked window     com.android.internal.policy.PhoneWindow$DecorView{b73d40d V.E......     R.....I. 0,0-1368,1249} that was originally added here
                                                at     android.view.ViewRootImpl.<init>(ViewRootImpl.java:569)
                                                at     android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:326)
                                                at     android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
                                                at android.app.Dialog.show(Dialog.java:350)
                                                at android.support.v7.app.AlertDialog$Builder.show(AlertDialog.java:955)
                                                at com.example.toby.btclientapp.BluetoothClient.AlertBox(BluetoothClient.java:181)
                                                at com.example.toby.btclientapp.BluetoothClient.onResume(BluetoothClient.java:107)
                                                at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1286)
                                                at android.app.Activity.performResume(Activity.java:6987)
                                                at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4145)
                                                at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4250)
                                                at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3361)
                                                at android.app.ActivityThread.access$1100(ActivityThread.java:222)
                                                at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1795)
                                                at android.os.Handler.dispatchMessage(Handler.java:102)
                                                at android.os.Looper.loop(Looper.java:158)
                                                at android.app.ActivityThread.main(ActivityThread.java:7229)
                                                at java.lang.reflect.Method.invoke(Native Method)
                                                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
                                                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
07-26 13:09:21.574 3857-3857/? E/WindowManager: android.view.WindowLeaked: Activity com.example.toby.btclientapp.BluetoothClient has leaked window com.android.internal.policy.PhoneWindow$DecorView{9723488 V.E...... R....... 0,0-1368,1249} that was originally added here
                                                at android.view.ViewRootImpl.<init>(ViewRootImpl.java:569)
                                                at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:326)
                                                at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
                                                at android.app.Dialog.show(Dialog.java:350)
                                                at android.support.v7.app.AlertDialog$Builder.show(AlertDialog.java:955)
                                                at com.example.toby.btclientapp.BluetoothClient.AlertBox(BluetoothClient.java:181)
                                                at com.example.toby.btclientapp.BluetoothClient.onResume(BluetoothClient.java:107)
                                                at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1286)
                                                at android.app.Activity.performResume(Activity.java:6987)
                                                at android.app.ActivityThread.performResumeActivity(ActivityThread.java:4145)
                                                at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:4250)
                                                at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1839)
                                                at android.os.Handler.dispatchMessage(Handler.java:102)
                                                at android.os.Looper.loop(Looper.java:158)
                                                at android.app.ActivityThread.main(ActivityThread.java:7229)
                                                at java.lang.reflect.Method.invoke(Native Method)
                                                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
                                                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
07-26 13:09:21.574 3857-3857/? E/WindowManager: android.view.WindowLeaked: Activity com.example.toby.btclientapp.BluetoothClient has leaked window com.android.internal.policy.PhoneWindow$DecorView{cea821b V.E...... R....... 0,0-1368,799} that was originally added here
                                                at android.view.ViewRootImpl.<init>(ViewRootImpl.java:569)
                                                at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:326)
                                                at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
                                                at android.app.Dialog.show(Dialog.java:350)
                                                at android.support.v7.app.AlertDialog$Builder.show(AlertDialog.java:955)
                                                at com.example.toby.btclientapp.BluetoothClient.AlertBox(BluetoothClient.java:181)
                                                at com.example.toby.btclientapp.BluetoothClient.onPause(BluetoothClient.java:135)
                                                at android.app.Activity.performPause(Activity.java:7033)
                                                at android.app.Instrumentation.callActivityOnPause(Instrumentation.java:1339)
                                                at android.app.ActivityThread.performPauseActivity(ActivityThread.java:4577)
                                                at android.app.ActivityThread.performPauseActivity(ActivityThread.java:4550)
                                                at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:4525)
                                                at android.app.ActivityThread.access$1300(ActivityThread.java:222)
                                                at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1813)
                                                at android.os.Handler.dispatchMessage(Handler.java:102)
                                                at android.os.Looper.loop(Looper.java:158)
                                                at android.app.ActivityThread.main(ActivityThread.java:7229)
                                                at java.lang.reflect.Method.invoke(Native Method)
                                                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
                                                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

Solution

  • I needed to change the MAC address of the Bluetooth adapter. It works now.