Android bluetooth socket closing

Android: Bluetooth Socket closed

I have been working on a Bluetooth device and am creating an app for it. I should be able to turn on or off this devices LED by sending it the code 0 or 1. I have some error catching in place to help me with the issue, and after staring at it for ages cannot see where the problem lies. I find devices correctly, and have checked the MAC address returned of the device, that is all fine. From what I can see with logs I also appear to open all the sockets correctly. The error occurs on the final stage of the process with sending byte data to the device. Can anyone spot something I can’t? Perhaps the connection is not being made successfully? To clarify the exception triggered is in the sendData() method. If you find the error I will love you forever haha. The error message: Fatal Error, In onResume() and an exception occurred during write:socket closed. So what the socket is closing before the data sends or is never successfully opened? Anyway, a lot of code inbound:

public class ScanFragment extends Fragment < ArrayListscannedList; Button scanningButton; TextView scanningText; ListView scannedListView; BluetoothAdapter mBluetoothAdapter; DeviceItem item; DeviceCustomAdapter adapter; BluetoothDevice device; String TAG = "TEST"; private BluetoothAdapter btAdapter = null; private BluetoothSocket btSocket = null; private OutputStream outStream = null; // Intent request codes private static final int REQUEST_CONNECT_DEVICE_SECURE = 1; private static final int REQUEST_ENABLE_BT = 3; // Well known SPP UUID private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); // Insert your bluetooth devices MAC address private static String address = "00:00:00:00:00:00"; public ScanFragment() < // Required empty public constructor >@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) < return inflater.inflate(R.layout.fragment_scan, container, false); >@Override public void onDestroy() < getActivity().unregisterReceiver(mReceiver); super.onDestroy(); >private final BroadcastReceiver mReceiver = new BroadcastReceiver() < public void onReceive(Context context, Intent intent) < Log.i("found", "hello" + ""); String action = intent.getAction(); if (BluetoothDevice.ACTION_FOUND.equals(action)) < device = intent .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); item = new DeviceItem(); item.setDeviceName(device.getName()); item.setDeviceCode(device.getAddress()); item.setDeviceId(MY_UUID); scannedList.add(item); Log.i("BT", device.getName() + "\n" + device.getAddress()); >else < Log.i("BT", "none" + ""); >adapter = new DeviceCustomAdapter( getActivity().getApplicationContext(), scannedList); scannedListView.setAdapter(adapter); > >; @Override public void onActivityCreated(Bundle savedInstanceState) < // TODO Auto-generated method stub super.onActivityCreated(savedInstanceState); super.onActivityCreated(savedInstanceState); scannedList = new ArrayList<>(); scanningButton = (Button) getActivity().findViewById(R.id.scanningButton); scanningText = (TextView) getActivity().findViewById(R.id.scanningText); scannedListView = (ListView) getActivity().findViewById(R.id.scannedListView); scannedListView.setVisibility(View.VISIBLE); mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); if (Build.VERSION.SDK_INT >= 15 && ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) < ActivityCompat.requestPermissions(getActivity(), new String[], 1); > if (mBluetoothAdapter == null) < scanningText.setText("Your device does not support Bluetooth, Sorry!"); >else if (!mBluetoothAdapter.isEnabled()) < scanningText.setText("You need to enable bluetooth to use this app.."); Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); >scanningButton.setOnClickListener(new View.OnClickListener() < @Override public void onClick(View view) < scanningText.setText("Scanning. "); mBluetoothAdapter.startDiscovery(); mBluetoothAdapter.isDiscovering(); scanningText.setText("Click on a device to connect"); >>); // Register for broadcasts when a device is discovered. IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND); getActivity().registerReceiver(mReceiver, filter); scannedListView.setOnItemClickListener(new AdapterView.OnItemClickListener() < @Override public void onItemClick(AdapterViewparent, View view, int position, long id) < item = scannedList.get(position); String name= scannedList.get(position).getDeviceName(); Toast toast = Toast.makeText(getActivity().getApplicationContext(), "Connecting to " + item.getDeviceCode() + "" + name, Toast.LENGTH_SHORT); toast.show(); scanningText.setText(item.getDeviceCode()); mBluetoothAdapter.cancelDiscovery(); address = item.getDeviceCode(); // Create the result Intent and include the MAC address connectDevice(address, true); ledOff(view); >>); > public void ledOn(View v) < sendData("1"); Toast msg = Toast.makeText(getActivity().getApplicationContext(), "LED is ON", Toast.LENGTH_SHORT); msg.show(); >public void ledOff(View v) < sendData("0"); Toast msg = Toast.makeText(getActivity().getApplicationContext(), "LED is OFF", Toast.LENGTH_SHORT); msg.show(); >public void connectToDevice(String adr) < super.onResume(); //enable buttons once connection established. // btnOn.setEnabled(true); // btnOff.setEnabled(true); // Set up a pointer to the remote node using it's address. btAdapter = mBluetoothAdapter; BluetoothDevice device = btAdapter.getRemoteDevice(adr); // 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) < errorExit("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(); >catch (IOException e) < try < btSocket.close(); >catch (IOException e2) < errorExit("Fatal Error", "In onResume() and unable to close socket during connection failure" + e2.getMessage() + "."); >> // Create a data stream so we can talk to server. try < outStream = btSocket.getOutputStream(); >catch (IOException e) < errorExit("Fatal Error", "In onResume() and output stream creation failed:" + e.getMessage() + "."); >> private void errorExit(String title, String message) < Toast msg = Toast.makeText(getActivity().getApplicationContext(), title + " - " + message, Toast.LENGTH_SHORT); msg.show(); // finish(); >private void sendData(String message) < byte[] msgBuffer = message.getBytes(); try < outStream.write(msgBuffer); >catch (IOException e) < String msg = "In onResume() and an exception occurred during write: " + e.getMessage(); errorExit("Fatal Error", msg); >> private void connectDevice(String address, boolean secure) < // Get the device MAC address connectToDevice(address); // Get the BluetoothDevice object BluetoothDevice device = btAdapter.getRemoteDevice(address); >> 

Источник

Android closing bluetooth sockets/threads

I’m connecting 2 devices via bluetooth and when I press the logout button on one device I want to send a message to the other device (telling the other to also logout), close the bluetooth connection, and close the current activity (i.e. go back to my login activity) The problem is I keep getting this exception which makes me think I’m not closing my connections properly:

java.io.IOException: bt socket closed, read return: -1 at android.bluetooth.BluetoothSocket.read(BluetoothSocket.java:517) at android.bluetooth.BluetoothInputStream.read(BluetoothInputStream.java:96) at java.io.InputStream.read(InputStream.java:162) at com.example.BTService$ConnectedThread.run(BTService.java:269) 

BTService.java:269 is where the connectedThread is reading from the input stream When logout is pressed, I basically destroy the MainActivity , and in onDestroy() I stop my bluetooth service: this.stopService(new Intent(this, BTService.class)) Which should call onDestroy() of my service, which calls stopConnect() :

public static void stopConnect() < if (connectThread != null) < connectThread.cancel(); connectThread = null; >if (connectedThread != null) < connectedThread.cancel(); connectedThread = null; >> 

So as soon as the service is destroyed by clicking logout, the cancel() method of my connectedThread should be called:

public static class ConnectedThread extends Thread < private BluetoothSocket mmSocket; private InputStream mmInStream; private OutputStream mmOutStream; public ConnectedThread(BluetoothSocket socket) < mmSocket = socket; InputStream tmpIn = null; OutputStream tmpOut = null; // Get the input and output streams, using temp objects because // member streams are final try < tmpIn = socket.getInputStream(); tmpOut = socket.getOutputStream(); >catch (IOException e) < e.printStackTrace(); >mmInStream = tmpIn; mmOutStream = tmpOut; //Tell other phone that we have connected write("connected".getBytes()); > public void run() < byte[] buffer = new byte[1024]; // buffer store for the stream int bytes; // bytes returned from read() // Keep listening to the InputStream until an exception occurs while (!this.isInterrupted()) < try < // Read from the InputStream bytes = mmInStream.read(buffer); // Send the obtained bytes to the UI activity mHandler.obtainMessage(Constants.MESSAGE_READ, bytes, -1, buffer) .sendToTarget(); >catch (IOException e) < e.printStackTrace(); break; >> > /* Call this from the main activity to send data to the remote device */ public void write(byte[] bytes) < try < mmOutStream.write(bytes); >catch (IOException e) < e.printStackTrace(); >> /* Call this from the main activity to shutdown the connection */ public void cancel() < if (mmInStream != null) < try catch (Exception e) <> mmInStream = null; > if (mmOutStream != null) < try catch (Exception e) <> mmOutStream = null; > if (mmSocket != null) < try catch (Exception e) <> mmSocket = null; > this.interrupt(); > > 

I thought I was doing this correctly by first closing my input and output streams, then closing the socket, and then closing the thread. I got this from an answer here: Disconnect a bluetooth socket in Android However, as soon as logout is pressed, I get the ioexception as its still trying to read from the input stream. I have also tried placing my input/output/socket close code in a method outside of the ConnectedThread class but that results in the same issue

Источник

Bluetooth connected thread instantly closes socket after connection

I have an Android app targetting the latest at the type Android API (29). The user has the ability to search for nearby bluetooth devices and connect to them to send data. The bluetooth connection is made with the app being the client. I copied much of the code from Anroid’s documentation and changed it to fit my needs. The app does find the devices, pairs correctly and connects. The problem is that right after it has connected, on the first loop in the Connected thread when it tries to read for incoming stream, an exception is thrown and the socket disconnects. I have connecting directly to the correct uuid for the device, to test if the looping through the possible server bluetooth uuids might interfere with the rfcomsocket. I tried in the connected thread in the loop to check for mInputStream.available() > 0 before trying to read, but it appears that it throws an exception there too. To test the connection I activate my laptops bluetooth adapter and set it to receive a file(as a server). I used to have this app in Xamarin.Android and the code used to work that way. Currently it runs in Kotlin. The code bellow shoes the Connect and Connected threads, called from the according functions.

fun connect(device: BluetoothDevice, uuids: ArrayList) < if (connectionState == STATE_CONNECTING) < if (connectThread != null) < connectThread?.cancel() connectThread = null >> // Cancel any thread currently running a connection if (connectedThread != null) < connectedThread?.cancel() connectedThread = null >connectThread = ConnectThread(device, this, uuids) connectThread?.start() > private inner class ConnectThread( val device: BluetoothDevice, service: BTService, val uuids: ArrayList ) : Thread() < var socket: BluetoothSocket? = null init < service.connectionState = STATE_CONNECTING >override fun run() < // Cancel discovery because it otherwise slows down the connection. btAdapter?.cancelDiscovery() for (uuid in uuids) < try < val mmSocket: BluetoothSocket? by lazy(LazyThreadSafetyMode.NONE) < device.createRfcommSocketToServiceRecord(uuid.uuid) >mmSocket?.use < thisSocket ->// Connect to the remote device through the socket. This call blocks // until it succeeds or throws an exception. thisSocket.connect() // The connection attempt succeeded. Perform work associated with // the connection in a separate thread. socket = thisSocket connected(thisSocket) > break > catch (e: IOException) < // Close the socket cancel() // Start the service over to restart listening mode Log.e(TAG, "unable to connect() to socket.", e) >> > // Closes the client socket and causes the thread to finish. fun cancel() < try < socket?.close() >catch (e: IOException) < Log.e(TAG, "Could not close the client socket", e) >> > //##################################### ##################################### //#####################################----->Connected // Cancel any thread currently running a connection if (connectedThread != null) < connectedThread?.cancel() connectedThread = null >// Start the thread to manage the connection and perform transmissions connectedThread = ConnectedThread(socket) connectedThread?.start() // Send the name of the connected device back to the UI Activity MainActivity.settingsFragment?.activity?.runOnUiThread < (MainActivity.settingsFragment as SettingsFragment).btConnected() >> private inner class ConnectedThread(private val mmSocket: BluetoothSocket) : Thread() < private val mmInStream: InputStream = mmSocket.inputStream private val mmOutStream: OutputStream = mmSocket.outputStream private val mmBuffer: ByteArray = ByteArray(1024) // mmBuffer store for the stream init < connectionState = STATE_CONNECTED >override fun run() < // Keep listening to the InputStream until an exception occurs. while (true) < // Read from the InputStream. try < mmInStream.read(mmBuffer) >catch (e: IOException) < connectionLost() Log.d(TAG, "Input stream was disconnected", e) break >//Do something with stream. > > // Call this from the main activity to send data to the remote device. fun write(bytes: ByteArray) < try < mmOutStream.write(bytes) >catch (e: IOException) < Log.e(TAG, "Error occurred when sending data", e) // Send a failure message back to the activity. return >> // Call this method from the main activity to shut down the connection. fun cancel() < try < mmSocket.close() >catch (e: IOException) < Log.e(TAG, "Could not close the connect socket", e) >> > // Stop all threads. fun stop() < if (connectThread != null) < connectThread?.cancel() connectThread = null >if (connectedThread != null) < connectedThread?.cancel() connectedThread = null >connectionState = STATE_NONE > fun write(bytes: ByteArray) < if (connectionState != STATE_CONNECTED) < return >val temp: ConnectedThread? = connectedThread temp?.write(bytes) > fun connectionLost() < MainActivity.settingsFragment?.activity?.runOnUiThread < (MainActivity.settingsFragment as SettingsFragment).btLost() >connectionState = STATE_NONE > 

Th result is a IO catch from the connected thread due to the crash when trying to read. I would expect it to just loop in an active connection, and if if any data are transmitted to be sent to me. I am aware that the inputStream is not saved anywhere (it is intentional), but I doubt that is the problem. Edit 1: The debug log from the connection start to connection failure(end).

2019-08-03 18:30:40.583 24961-25088/com.konkarapas.rcs.full.debug W/BluetoothAdapter: getBluetoothService() called with no BluetoothManagerCallback 2019-08-03 18:30:40.776 24961-25088/com.konkarapas.rcs.full.debug D/BluetoothSocket: close() this: android.bluetooth.BluetoothSocket@39f9369, channel: -1, mSocketIS: android.net.LocalSocketImpl$SocketInputStream@611f1ee, mSocketOS: android.net.LocalSocketImpl$SocketOutputStream@96eb68fmSocket: android.net.LocalSocket@15d7d1c impl:android.net.LocalSocketImpl@94fd25 fd:java.io.FileDescriptor@42f3efa, mSocketState: INIT 2019-08-03 18:30:40.780 24961-25088/com.konkarapas.rcs.full.debug E/BluetoothService: unable to connect() to socket. java.io.IOException: read failed, socket might closed or timeout, read ret: -1 at android.bluetooth.BluetoothSocket.readAll(BluetoothSocket.java:762) at android.bluetooth.BluetoothSocket.readInt(BluetoothSocket.java:776) at android.bluetooth.BluetoothSocket.connect(BluetoothSocket.java:399) at com.konkarapas.rcs.models.BTService$ConnectThread.run(BluetoothService.kt:172) 2019-08-03 18:30:40.782 24961-25088/com.konkarapas.rcs.full.debug W/BluetoothAdapter: getBluetoothService() called with no BluetoothManagerCallback 2019-08-03 18:30:40.934 24961-25088/com.konkarapas.rcs.full.debug D/BluetoothSocket: close() this: android.bluetooth.BluetoothSocket@5534f08, channel: 4, mSocketIS: android.net.LocalSocketImpl$SocketInputStream@ebd46a1, mSocketOS: android.net.LocalSocketImpl$SocketOutputStream@3a250c6mSocket: android.net.LocalSocket@fdce887 impl:android.net.LocalSocketImpl@f5253b4 fd:java.io.FileDescriptor@cc6abdd, mSocketState: CONNECTED 2019-08-03 18:30:40.938 24961-25088/com.konkarapas.rcs.full.debug D/BluetoothSocket: close() this: android.bluetooth.BluetoothSocket@5534f08, channel: 4, mSocketIS: android.net.LocalSocketImpl$SocketInputStream@ebd46a1, mSocketOS: android.net.LocalSocketImpl$SocketOutputStream@3a250c6mSocket: null, mSocketState: CLOSED 2019-08-03 18:30:40.943 24961-25089/com.konkarapas.rcs.full.debug D/BluetoothService: Input stream was disconnected java.io.IOException: socket closed at android.net.LocalSocketImpl$SocketInputStream.read(LocalSocketImpl.java:104) at android.bluetooth.BluetoothSocket.read(BluetoothSocket.java:555) at android.bluetooth.BluetoothInputStream.read(BluetoothInputStream.java:88) at java.io.InputStream.read(InputStream.java:101) at com.konkarapas.rcs.models.BTService$ConnectedThread.run(BluetoothService.kt:245) 

Источник

Читайте также:  Тратит ли блютуз интернет
Оцените статью
Adblock
detector