How to connect to bluetooth device? IOException - android

I implemented the following BluetoothService, it is from the official
Android BluetoothChatService example:
public class BluetoothService extends Thread {
private static final String TAG = BluetoothService.class.getSimpleName();
private static final String NAME_SECURE = TAG + "Secure";
private static final String NAME_INSECURE = TAG + "Insecure";
private static final UUID MY_UUID_SECURE = UUID.fromString("a6fb84f6-20b3-477f-9160-bcd028bddc99");
private static final UUID MY_UUID_INSECURE = UUID.fromString("7dd8441a-1d4b-42f1-9996-a7d507548dfc");
public static final int STATE_NONE = 0;
public static final int STATE_LISTEN = 1;
public static final int STATE_CONNECTING = 2;
public static final int STATE_CONNECTED = 3;
private BluetoothAdapter bluetoothAdapter = null;
private Handler handler = null;
private AcceptThread secureAcceptThread = null;
private AcceptThread insecureAcceptThread = null;
private ConnectThread connectThread = null;
private ConnectedThread connectedThread = null;
private int bluetoothState = STATE_NONE;
public BluetoothService(Handler handler) {
this.bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
this.bluetoothState = STATE_NONE;
this.handler = handler;
}
public synchronized void startConnection() {
Log.d(TAG, "start");
if (this.connectThread != null) {
this.connectThread.cancel();
this.connectThread = null;
}
if (this.connectedThread != null) {
this.connectedThread.cancel();
this.connectedThread = null;
}
this.setBluetoothState(STATE_LISTEN);
if (this.secureAcceptThread == null) {
this.secureAcceptThread = new AcceptThread(true);
this.secureAcceptThread.start();
}
if (this.insecureAcceptThread == null) {
this.insecureAcceptThread = new AcceptThread(false);
this.insecureAcceptThread.start();
}
}
public synchronized void connect(BluetoothDevice device, boolean secure) {
if (this.bluetoothState == STATE_CONNECTING) {
if (this.connectThread != null) {
this.connectThread.cancel();
this.connectThread = null;
}
}
if (this.connectedThread != null) {
this.connectedThread.cancel();
this.connectedThread = null;
}
this.connectThread = new ConnectThread(device, secure);
this.connectThread.start();
this.setBluetoothState(STATE_CONNECTING);
}
public synchronized void connected(BluetoothSocket socket, BluetoothDevice device, final String socketType) {
if (this.connectThread != null) {
this.connectThread.cancel();
this.connectThread = null;
}
if (this.connectedThread != null) {
this.connectedThread.cancel();
this.connectedThread = null;
}
if (this.secureAcceptThread != null) {
this.secureAcceptThread.cancel();
this.secureAcceptThread = null;
}
if (this.insecureAcceptThread != null) {
this.insecureAcceptThread.cancel();
this.insecureAcceptThread = null;
}
this.connectedThread = new ConnectedThread(socket, socketType);
this.connectedThread.start();
Message msg = this.handler.obtainMessage(Globals.MESSAGE_DEVICE_NAME);
Bundle bundle = new Bundle();
bundle.putString(Globals.DEVICE_NAME, device.getName());
msg.setData(bundle);
this.handler.sendMessage(msg);
this.setBluetoothState(STATE_CONNECTED);
}
public synchronized void stopConnection() {
if (this.connectThread != null) {
this.connectThread.cancel();
this.connectThread = null;
}
if (this.connectedThread != null) {
this.connectedThread.cancel();
this.connectedThread = null;
}
if (this.secureAcceptThread != null) {
this.secureAcceptThread.cancel();
this.secureAcceptThread = null;
}
if (this.insecureAcceptThread != null) {
this.insecureAcceptThread.cancel();
this.insecureAcceptThread = null;
}
this.setBluetoothState(STATE_NONE);
}
public void write(byte[] out) {
ConnectedThread connectedThread = null;
synchronized (this) {
if (this.bluetoothState != STATE_CONNECTED) {
return;
}
connectedThread = this.connectedThread;
}
connectedThread.write(out);
}
private void connectionFailed() {
Message msg = this.handler.obtainMessage(Globals.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(Globals.TOAST, "Unable to connect device");
msg.setData(bundle);
this.handler.sendMessage(msg);
BluetoothService.this.start();
}
private void connectionLost() {
Message msg = this.handler.obtainMessage(Globals.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(Globals.TOAST, "Device connection was lost");
msg.setData(bundle);
this.handler.sendMessage(msg);
BluetoothService.this.start();
}
public synchronized int getBluetoothState() {
return this.bluetoothState;
}
private synchronized void setBluetoothState(int bluetoothState) {
this.bluetoothState = bluetoothState;
}
private class AcceptThread extends Thread {
private BluetoothServerSocket serverSocket = null;
private String socketType = null;
public AcceptThread(boolean secure) {
BluetoothServerSocket tempServerSocket = null;
this.socketType = secure ? "Secure" : "Insecure";
try {
if (secure) {
tempServerSocket = bluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME_SECURE, MY_UUID_SECURE);
} else {
tempServerSocket = bluetoothAdapter.listenUsingInsecureRfcommWithServiceRecord(NAME_INSECURE, MY_UUID_INSECURE);
}
} catch (IOException e) {
Log.e(TAG, "Socket Type: " + socketType + "listen() failed", e);
}
this.serverSocket = tempServerSocket;
}
public void run() {
this.setName("AcceptThread" + socketType);
BluetoothSocket socket = null;
while (bluetoothState != STATE_CONNECTED) {
try {
socket = this.serverSocket.accept();
} catch (IOException e) {
break;
}
if (socket != null) {
synchronized (BluetoothService.this) {
switch (bluetoothState) {
case STATE_LISTEN:
case STATE_CONNECTING:
connected(socket, socket.getRemoteDevice(), socketType);
break;
case STATE_NONE:
case STATE_CONNECTED:
try {
socket.close();
} catch (IOException e) {
Log.e(TAG, "Could not close unwanted socket", e);
}
break;
}
}
}
}
}
public void cancel() {
try {
this.serverSocket.close();
} catch (IOException e) {
Log.e(TAG, "Socket Type" + socketType + "close() of server failed", e);
}
}
}
private class ConnectThread extends Thread {
private BluetoothSocket bluetoothSocket = null;
private BluetoothDevice bluetoothDevice = null;
private String socketType = null;
public ConnectThread(BluetoothDevice bluetoothDevice, boolean secure) {
this.bluetoothDevice = bluetoothDevice;
this.socketType = secure ? "Secure" : "Insecure";
BluetoothSocket tempBluetoothSocket = null;
try {
if (secure) {
tempBluetoothSocket = this.bluetoothDevice.createRfcommSocketToServiceRecord(MY_UUID_SECURE);
} else {
tempBluetoothSocket = this.bluetoothDevice.createInsecureRfcommSocketToServiceRecord(MY_UUID_INSECURE);
}
} catch (IOException e) {
Log.e(TAG, "Socket Type: " + this.socketType + "create() failed", e);
}
this.bluetoothSocket = tempBluetoothSocket;
}
public void run() {
Log.i(TAG, "BEGIN mConnectThread");
this.setName("ConnectThread");
bluetoothAdapter.cancelDiscovery();
try {
this.bluetoothSocket.connect();
} catch (IOException e) {
Log.e(TAG, e.getMessage(), e);
connectionFailed();
try {
this.bluetoothSocket.close();
} catch (IOException e2) {
Log.e(TAG, "unable to close() socket during connection failure", e2);
}
return;
}
synchronized (BluetoothService.this) {
connectThread = null;
}
connected(this.bluetoothSocket, this.bluetoothDevice, this.socketType);
}
public void cancel() {
try {
this.bluetoothSocket.close();
} catch (IOException e) {
Log.e(TAG, "close() of connect socket failed", e);
}
}
}
private class ConnectedThread extends Thread {
private BluetoothSocket bluetoothSocket = null;
private InputStream inputStream = null;
private OutputStream outputStream = null;
public ConnectedThread(BluetoothSocket bluetoothSocket, String socketType) {
Log.d(TAG, "create ConnectedThread");
this.bluetoothSocket = bluetoothSocket;
InputStream tempInputStream = null;
OutputStream tempOutputStream = null;
try {
tempInputStream = this.bluetoothSocket.getInputStream();
tempOutputStream = this.bluetoothSocket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "temp sockets not created", e);
}
this.inputStream = tempInputStream;
this.outputStream = tempOutputStream;
}
public void run() {
byte[] buffer = new byte[1024];
int bytes = 0;
while (true) {
try {
bytes = this.inputStream.read(buffer);
handler.obtainMessage(Globals.MESSAGE_READ, bytes, -1, buffer).sendToTarget();
} catch (IOException e) {
Log.e(TAG, "disconnected", e);
connectionLost();
BluetoothService.this.start();
break;
}
}
}
public void write(byte[] buffer) {
try {
this.outputStream.write(buffer);
handler.obtainMessage(Globals.MESSAGE_WRITE, -1, -1, buffer).sendToTarget();
} catch (IOException e) {
Log.e(TAG, "Exception during write", e);
}
}
public void cancel() {
try {
this.bluetoothSocket.close();
} catch (IOException e) {
Log.e(TAG, "close() of connect socket failed", e);
}
}
}
}
When i now want to connect to a BluetoothDevice with this code:
private void connectDevice(Intent data, boolean secure) {
String address = data.getExtras().getString(BluetoothFragment.EXTRA_DEVICE_ADDRESS);
BluetoothDevice device = this.bluetoothAdapter.getRemoteDevice(address);
this.bluetoothService.connect(device, secure);
}
I get the following Error:
02-07 12:47:15.633: E/BluetoothService(17671): read failed, socket might closed or timeout, read ret: -1
02-07 12:47:15.633: E/BluetoothService(17671): java.io.IOException: read failed, socket might closed or timeout, read ret: -1
02-07 12:47:15.633: E/BluetoothService(17671): at android.bluetooth.BluetoothSocket.readAll(BluetoothSocket.java:512)
So everything i do is exactly like the example which android is providing.
You can download the sample code of the BluetoothChat in the Android
Studio sample codes.
The only thing im curious about is the uuid. I dont know how to create them and if it is important to use a special uuid. I just used a uuid generator which i downloaded from the Android Play Store and did the following:
private static final UUID MY_UUID_SECURE = UUID.fromString("a6fb84f6-20b3-477f-9160-bcd028bddc99");
private static final UUID MY_UUID_INSECURE = UUID.fromString("7dd8441a-1d4b-42f1-9996-a7d507548dfc");
So the question is: How can i connect to a BluetoothDevice?
Addition
I use a Nexus 7 and a Nexus 4 with the latest Android Version.
I downloaded several bluetooth connection apps and all of these
apps arent able to build a connection between my devices. So
maybe it isnt a problem with the code? Is it a Nexus or Android
5.0.1 bug?

Can you try this code?
You can pass the string to the BT device by calling
BluetoothPrinterHelper.BT.send(context, data)
Note: The code assumes that you have connected and paired to the BT device and is the only device in the paired list. You can change this behaviour in the findDevice(BluetoothAdapter) method.
Also, the UUID can be generated in Java itself by calling UUID.randomUUID().toString(), but in this case UUID plays a different role. This identifies the profile the target BT device is running. You check more about that here BT-UUID
package com.example.bt;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.os.AsyncTask;
public enum class BluetoothPrinterHelper {
BT;
private BluetoothDevice device;
private static BluetoothSocket socket;
private BluetoothSocket tmp;
private BluetoothAdapter adapter;
private String deviceName;
public void send(Context ctx, String data) {
mTryConnect = new TryConnect();
mTryConnect.execute();
boolean isConnected = false;
try {
Log.d(TAG, "Establishing connection to device");
isConnected = mTryConnect.get();
} catch (InterruptedException e) {
Log.e(TAG, "Error connecting to device");
return;
} catch (ExecutionException e) {
Log.e(TAG, "Error connecting to device");
return;
}
if (isConnected) {
Log.d(TAG, "Connection to device successfully established");
mTrySend = new TrySend(data);
mTrySend.execute();
} else {
Toast.makeText(ctx, "No BT device connected", Toast.LENGTH_LONG).show();
}
}
private BluetoothDevice findDevice(BluetoothAdapter adapter) {
Log.d(TAG, "Finding BT devices");
Set<BluetoothDevice> pairedDevices = null;
try {
pairedDevices = adapter.getBondedDevices();
} catch (NullPointerException e) {
Log.e(TAG, "Error retrieving paired devices");
}
if (pairedDevices != null && pairedDevices.size() == 1) {
Log.d(TAG, "Found 1 paired device");
for (BluetoothDevice bluetoothDevice : pairedDevices) {
return bluetoothDevice;
}
} else {
Log.w(TAG, "Many/No paired BT devices found");
}
return null;
}
private class TryConnect extends AsyncTask<Void, Void, Boolean> {
public TryConnect() {
adapter = BluetoothAdapter.getDefaultAdapter();
}
#Override
protected Boolean doInBackground(Void... params) {
// Check bonded devices list
device = findDevice(adapter);
if (adapter.isDiscovering()) {
adapter.cancelDiscovery();
}
// Create a socket for the device connection
if (device != null) {
try {
deviceName = device.getName();
Log.d(TAG, "Creating socket");
tmp = device.createRfcommSocketToServiceRecord(DEVICE_UUID);
} catch (NoSuchMethodException e) {
Log.e(TAG, "Printing - NoSuchMethodException", e);
return false;
} catch (IllegalArgumentException e) {
Log.e(TAG, "Printing - IllegalArgumentException", e);
return false;
} catch (IllegalAccessException e) {
Log.e(TAG, "Printing - IllegalAccessException", e);
return false;
} catch (InvocationTargetException e) {
Log.e(TAG, "Printing - InvocationTargetException", e);
return false;
}
}
socket = tmp;
// Connect to the created socket and device
try {
Log.d(TAG, "Creating connection to: " + deviceName);
socket.connect();
} catch (IOException e) {
Log.e(TAG, "Unable to connect. Closing connection", e);
try {
socket.close();
} catch (IOException e1) {
Log.e(TAG, "Unable to close connection during connection failure", e1);
}
return false;
} catch (NullPointerException e) {
Log.e(TAG, "NPE during BT socket connection");
}
return true;
}
}
private class TrySend extends AsyncTask<Void, Void, Boolean> {
byte[] out;
public TrySend(String data) {
try {
out = data.getBytes("UTF-8");
} catch (UnsupportedEncodingException e1) {
Log.w(TAG, "UnsupportedEncodingException");
}
}
#Override
protected Boolean doInBackground(Void... params) {
try {
// Get the output stream and ready for write
try {
Log.d(TAG, "Creating output stream");
outStream = socket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "Socket not created", e);
return false;
} catch (NullPointerException e) {
Log.e(TAG, "NPE retreiving socket stream");
return false;
}
// Write data to the socket for printing
try {
Log.d(TAG, "Write to output stream");
// Write format
outStream.write(command);
// Write data to print
DataOutputStream dataOutputStream = new DataOutputStream(outStream);
dataOutputStream.write(out);
dataOutputStream.flush();
} catch (IOException e) {
Log.e(TAG, "Exception during BT write to device", e);
return false;
} catch (NullPointerException e) {
Log.e(TAG, "NPE during socket write");
} finally {
try {
outStream.close();
} catch (IOException e) {
Log.e(TAG, "Exception during closing outstream", e);
} catch (NullPointerException e) {
Log.e(TAG, "NPE during BT socket close");
}
}
// Close the socket and cleanup
try {
Log.d(TAG, "Closing socket");
socket.close();
} catch (IOException e) {
Log.e(TAG, "Socket closing exception", e);
return false;
} catch (NullPointerException e) {
Log.e(TAG, "NPE during BT socket close");
}
} finally {
adapter = null;
device = null;
socket = null;
outStream = null;
}
return true;
}
}
}
UPDATE: Can you try this code:
Method m = device.getClass().getMethod("createInsecureRfcommSocket", new Class[] { int.class });
tmp = (BluetoothSocket) m.invoke(device, 1);
instead of
tmp = device.createRfcommSocketToServiceRecord(DEVICE_UUID);

Related

Android - Connect to socket in separate thread

I am trying to create a very-very simple server-client application in Android.
The server is running on my pc, it was written in python. (just a simple while (true) loop which receives a string and responses with an other string.)
The problem is in the Android client. So i tried to create a singleton class in a separate thread, which:
create the socket
connect to the socket
is reachable from other activites
write to socket
read from socket
I try to write and read from an other asynctask.
It is working until i try to write to the socket again. (1 write is ok, any other attempts are failed.) I do not get any exception, i checked if the socket closed or the writer null, etc. The message just not wrote to the socket.
What's wrong with this solution? :/
Could you please help me?
Here is the thread:
public class ConnectThread extends Thread
{
// singleton Part
private static class ThreadHolder {
static final ConnectThread instance = new ConnectThread();
}
public static synchronized ConnectThread getInstance(){
if(ThreadHolder.instance == null)
Log.d("mytag", "NEW INSTANCE CREATED");
// return (ThreadHolder.instance == null) ? ThreadHolder.instance = new ConnectThread() : ThreadHolder.instance;
return ThreadHolder.instance;
}
private ConnectThread(){
}
// implementation part
private Socket mSocket;
private BufferedWriter socketWriter;
private BufferedReader socketReader;
public Socket getSocket() {
return mSocket;
}
public void WriteToSocket(String msg)
{
try{
if(!(mSocket.isClosed()))
{
Log.d("mytag", "Writing to socket");
if(socketWriter == null)
Log.d("mytag", "Writer closed - in write to socket");
socketWriter.write(msg);
socketWriter.flush();
}else
Log.d("mytag", "CANT write to socket");
}catch(IOException e)
{
e.printStackTrace();
Log.d("mytag", e.toString());
}
}
public String ReadFromSocket()
{
try
{
if(!(mSocket.isClosed())) {
Log.d("mytag", "Reading from socket");
if(socketReader == null)
{
Log.d("mytag", "Reader closed - in read from socket");
}
return socketReader.readLine();
}else
{
Log.d("mytag", "CANT from socket");
return null;
}
}catch (IOException e)
{
e.printStackTrace();
return null;
}
}
#Override
public void run() {
try
{
mSocket = new Socket();
mSocket.setKeepAlive(true);
try
{
mSocket.setTcpNoDelay(true);
}
catch (SocketException e)
{
}
mSocket.connect(new InetSocketAddress("192.168.0.128", 8888), 2000);
if(!(mSocket.isClosed()))
{
Log.d("mytag", "SOCKET IS RUNNING");
socketWriter = new BufferedWriter(new OutputStreamWriter(this.mSocket.getOutputStream()));
socketReader = new BufferedReader(new InputStreamReader(this.mSocket.getInputStream()));
if(socketWriter == null)
{
Log.d("mytag", "WRITER NOT CREATED");
}else
Log.d("mytag", "WRITER READY");
if(socketReader == null)
{
Log.d("mytag", "READER NOT CREATED");
}else
Log.d("mytag", "READER READY");
}
}catch (IOException e)
{
e.printStackTrace();
}
}
}
And here are the attempts to read, write:
#Override
protected Void doInBackground(Void... params)
{
PrintDebugMsg("do in background");
//--------------------------------------------------------------------------------------
changeProgressMsg(progressDialog, "Checking network availability...");
//progressDialog.setTitle("Checking network availability...");
//check network:
ConnectivityManager cm = (ConnectivityManager) getApplicationContext().getSystemService(parentContext.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if(netInfo != null && netInfo.isConnected())
{
networkAvail = true;
response += "| Network available |";
}
PrintDebugMsg("do in background 2");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
changeStatusImg(imgvNetworkStatus, networkAvail?R.drawable.online:R.drawable.offline);
//--------------------------------------------------------------------------------------
changeProgressMsg(progressDialog, "Pinging server");
//progressDialog.setTitle("Pinging server...");
//check server status
try {
PrintDebugMsg("do in background 3");
if(!(ConnectThread.getInstance().getSocket().isClosed()))
{
ConnectThread.getInstance().WriteToSocket(PING_FROM_DROID);
String line = "";
line = ConnectThread.getInstance().ReadFromSocket();
if(line.equals(PING_ACK))
{
serverAvail = true;
response += " | pinged |";
PrintDebugMsg("do in background 4", true);
}
}
else{
response += " | NOT pinged |";
PrintDebugMsg("do in background 5", true);
throw new UnknownHostException();
}
PrintDebugMsg("do in background 6", true);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response += " | UnknownHostException: " + e.toString() + " - during server check |";
PrintDebugMsg("do in background 7", true);
} finally{
PrintDebugMsg("do in background 9", true);
if(ConnectThread.getInstance().getSocket() != null){
}
}
PrintDebugMsg("do in background 10", true);
if(serverAvail)
{
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
changeStatusImg(imgvServerStatus, serverAvail?R.drawable.online:R.drawable.offline);
//--------------------------------------------------------------------------------------
changeProgressMsg(progressDialog, "Connectiong to server...");
//connect to server:
try {
PrintDebugMsg("do in background 11",true);
//socket = new Socket(dstAddress, dstPort);
//socket = ConnectThread.getInstance().getSocket();
PrintDebugMsg("do in background 12",true);
if(!(ConnectThread.getInstance().getSocket().isClosed())) {
PrintDebugMsg("do in background 13",true);
PrintDebugMsg("do in background 14",true);
PrintDebugMsg("do in background 15",true);
ConnectThread.getInstance().WriteToSocket(CONN_REQ_FROM_DROID);
String line = "";
line = ConnectThread.getInstance().ReadFromSocket();
PrintDebugMsg("conn line = " + line, true);
if(line != null && line.equals(CONN_ACK))
{
connected = true;
response += "| connected |";
PrintDebugMsg("do in background 12");
}
}else
{
response += "| NOT connected |";
PrintDebugMsg("do in background 13");
throw new UnknownHostException();
}
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response += " | UnknownHostException: " + e.toString() + " - during connecting |";
}finally{
PrintDebugMsg("connection finished");
}
if(connected) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
changeStatusImg(imgvConnectionStatus, connected?R.drawable.online:R.drawable.offline);
//--------------------------------------------------------------------------
------------
return null;
}
The "util" functions:
private void PrintDebugMsg(String msg, boolean b)
{
if(b)
Log.d("mytag", msg);
}
private void changeProgressMsg(final ProgressDialog dialog,final String value){
runOnUiThread(new Runnable() {
#Override
public void run() {
dialog.setMessage(value);
}
});
}
private void changeStatusImg(final ImageView imgView, final int imgId){
runOnUiThread(new Runnable() {
#Override
public void run() {
imgView.setImageResource(imgId);
}
});
}
Sever.java
public class Server {
public static void main(String[] args) {
new Server().startServer();
}
public void startServer() {
final ExecutorService clientProcessingPool = Executors.newFixedThreadPool(10);
Runnable serverTask = new Runnable() {
#Override
public void run() {
try {
ServerSocket serverSocket = new ServerSocket(8000);
System.out.println("Waiting for clients to connect...");
while (true) {
Socket clientSocket = serverSocket.accept();
clientProcessingPool.submit(new ClientTask(clientSocket));
}
} catch (IOException e) {
System.err.println("Unable to process client request");
e.printStackTrace();
}
}
};
Thread serverThread = new Thread(serverTask);
serverThread.start();
}
private class ClientTask implements Runnable {
private final Socket clientSocket;
private ClientTask(Socket clientSocket) {
this.clientSocket = clientSocket;
}
#Override
public void run() {
System.out.println("Got a client !");
// Do whatever required to process the client's request
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

Bluetooth: Do i need to know the UUID of the Devices?

I want to connect my Nexus 7 device with my Nexus 4 device and later i want to connect my Nexus 7 device with a micro controller. Do i have to know the UUID of my devices to connect them using bluetooth?
Are the UUID's being exchanged when i pair my devices?
If yes: Why is there a defined UUID in android example?
public class BluetoothService extends Thread {
private static final String TAG = BluetoothService.class.getSimpleName();
private static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
public static final int STATE_NONE = 0;
public static final int STATE_LISTEN = 1;
public static final int STATE_CONNECTING = 2;
public static final int STATE_CONNECTED = 3;
private BluetoothAdapter bluetoothAdapter = null;
private Handler handler = null;
private ConnectThread connectThread = null;
private ConnectedThread connectedThread = null;
private int bluetoothState = STATE_NONE;
public BluetoothService(Handler handler) {
this.bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
this.bluetoothState = STATE_NONE;
this.handler = handler;
}
public synchronized void startConnection() {
Log.d(TAG, "start");
if (this.connectThread != null) {
this.connectThread.cancel();
this.connectThread = null;
}
if (this.connectedThread != null) {
this.connectedThread.cancel();
this.connectedThread = null;
}
this.setBluetoothState(STATE_LISTEN);
}
public synchronized void connect(BluetoothDevice device) {
if (this.bluetoothState == STATE_CONNECTING) {
if (this.connectThread != null) {
this.connectThread.cancel();
this.connectThread = null;
}
}
if (this.connectedThread != null) {
this.connectedThread.cancel();
this.connectedThread = null;
}
this.connectThread = new ConnectThread(device);
this.connectThread.start();
this.setBluetoothState(STATE_CONNECTING);
}
public synchronized void connected(BluetoothSocket socket, BluetoothDevice device) {
if (this.connectThread != null) {
this.connectThread.cancel();
this.connectThread = null;
}
if (this.connectedThread != null) {
this.connectedThread.cancel();
this.connectedThread = null;
}
this.connectedThread = new ConnectedThread(socket);
this.connectedThread.start();
Message msg = this.handler.obtainMessage(Globals.MESSAGE_DEVICE_NAME);
Bundle bundle = new Bundle();
bundle.putString(Globals.DEVICE_NAME, device.getName());
msg.setData(bundle);
this.handler.sendMessage(msg);
this.setBluetoothState(STATE_CONNECTED);
}
public synchronized void stopConnection() {
if (this.connectThread != null) {
this.connectThread.cancel();
this.connectThread = null;
}
if (this.connectedThread != null) {
this.connectedThread.cancel();
this.connectedThread = null;
}
this.setBluetoothState(STATE_NONE);
}
public void write(byte[] out) {
ConnectedThread connectedThread = null;
synchronized (this) {
if (this.bluetoothState != STATE_CONNECTED) {
return;
}
connectedThread = this.connectedThread;
}
connectedThread.write(out);
}
private void connectionFailed() {
Message msg = this.handler.obtainMessage(Globals.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(Globals.TOAST, "Unable to connect device");
msg.setData(bundle);
this.handler.sendMessage(msg);
BluetoothService.this.startConnection();
}
private void connectionLost() {
Message msg = this.handler.obtainMessage(Globals.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(Globals.TOAST, "Device connection was lost");
msg.setData(bundle);
this.handler.sendMessage(msg);
BluetoothService.this.startConnection();
}
public synchronized int getBluetoothState() {
return this.bluetoothState;
}
private synchronized void setBluetoothState(int bluetoothState) {
this.bluetoothState = bluetoothState;
}
private class ConnectThread extends Thread {
private BluetoothSocket bluetoothSocket = null;
private BluetoothDevice bluetoothDevice = null;
public ConnectThread(BluetoothDevice bluetoothDevice) {
this.bluetoothDevice = bluetoothDevice;
BluetoothSocket tempBluetoothSocket = null;
try {
tempBluetoothSocket = this.bluetoothDevice.createInsecureRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) {
Log.e(TAG, "Socket Type: " + "create() failed", e);
}
this.bluetoothSocket = tempBluetoothSocket;
}
public void run() {
Log.i(TAG, "BEGIN mConnectThread");
this.setName("ConnectThread");
bluetoothAdapter.cancelDiscovery();
try {
this.bluetoothSocket.connect();
} catch (IOException e) {
Log.e(TAG, e.getMessage(), e);
connectionFailed();
try {
this.bluetoothSocket.close();
} catch (IOException e2) {
Log.e(TAG, "unable to close() socket during connection failure", e2);
}
return;
}
synchronized (BluetoothService.this) {
connectThread = null;
}
connected(this.bluetoothSocket, this.bluetoothDevice);
}
public void cancel() {
try {
this.bluetoothSocket.close();
} catch (IOException e) {
Log.e(TAG, "close() of connect socket failed", e);
}
}
}
private class ConnectedThread extends Thread {
private BluetoothSocket bluetoothSocket = null;
private InputStream inputStream = null;
private OutputStream outputStream = null;
public ConnectedThread(BluetoothSocket bluetoothSocket) {
Log.d(TAG, "create ConnectedThread");
this.bluetoothSocket = bluetoothSocket;
InputStream tempInputStream = null;
OutputStream tempOutputStream = null;
try {
tempInputStream = this.bluetoothSocket.getInputStream();
tempOutputStream = this.bluetoothSocket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "temp sockets not created", e);
}
this.inputStream = tempInputStream;
this.outputStream = tempOutputStream;
}
public void run() {
byte[] buffer = new byte[1024];
int bytes = 0;
while (true) {
try {
bytes = this.inputStream.read(buffer);
handler.obtainMessage(Globals.MESSAGE_READ, bytes, -1, buffer).sendToTarget();
} catch (IOException e) {
Log.e(TAG, "disconnected", e);
connectionLost();
BluetoothService.this.start();
break;
}
}
}
public void write(byte[] buffer) {
try {
this.outputStream.write(buffer);
handler.obtainMessage(Globals.MESSAGE_WRITE, -1, -1, buffer).sendToTarget();
} catch (IOException e) {
Log.e(TAG, "Exception during write", e);
}
}
public void cancel() {
try {
this.bluetoothSocket.close();
} catch (IOException e) {
Log.e(TAG, "close() of connect socket failed", e);
}
}
}
}
If no: How to exchange the UUID's to be able to connect the devices?
The UUID defined in the google sample/example must be known by the server and the client :
The server create a RFcomm ServerSocket that listen for incoming connection with this UUID
The client create a RFcomm bluetoothsocket that will try to connect to the server socket
if the uuids matches the connection is established.
The pairing saves the informations about the remote device (name, adress, ... etc) so that when you want to connect again you don't have to search for the device to get them =)

Receive text data via Bluetooth in between Android devices in android?

I am working on an Android app in which I need to transfer text from one device to another device using Bluetooth interface.
Problem is, MY BROADCAST RECEIVER IS NOT WORKING AS IT SHOULD WORK. When data is sent from one device, Broadcast listener of my receiver device doesn't function at all.
I am using below code currently:
The below code is to connect to a Bluetooth device:
protected void connect(BluetoothDevice device) {
try {
ConfigClass.isFirstBluetoothSignal=true;
Log.d(TAG,"connect bluetooth");
// Create a Socket connection: need the server's UUID number of
// registered
Method m = device.getClass().getMethod("createRfcommSocket",
new Class[] { int.class });
socket = (BluetoothSocket) m.invoke(device, 1);
// socket=device.createRfcommSocketToServiceRecord(MY_UUID_INSECURE);
socket.connect();
Log.d(TAG, ">>Client connectted");
inputStream = socket.getInputStream();
socket.getOutputStream();
int read = -1;
final byte[] bytes = new byte[1024];
while (true) {
synchronized (obj1) {
read = inputStream.read(bytes);
//_handler.obtainMessage(RECIEVE_MESSAGE, -1, read).sendToTarget();
Log.d(TAG, "read:" + read);
if (read > 0) {
ConfigClass.isFirstBluetoothSignal=false;
final int count = read;
String str = SamplesUtils.byteToHex(bytes, count);
// Log.d(TAG, "test1:" + str);
hex = hexString.toString();
if (hex == "") {
hexString.append("<--");
} else {
if (hex.lastIndexOf("<--") < hex.lastIndexOf("-->")) {
hexString.append("\n<--");
}
}
hexString.append(str);
hex = hexString.toString();
// Log.d(TAG, "test2:" + hex);
if (hex.length() > maxlength) {
try {
hex = hex.substring(hex.length() - maxlength,
hex.length());
hex = hex.substring(hex.indexOf(" "));
hex = "<--" + hex;
hexString = new StringBuffer();
hexString.append(hex);
}catch (NullPointerException e) {
e.printStackTrace();
}
catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "e", e);
}
}
_handler.post(new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(), hex, Toast.LENGTH_LONG);
}
});
}
}
}
} catch (Exception e) {
ConfigClass.isFirstBluetoothSignal=false;
Log.e(TAG, ">>", e);
Toast.makeText(getBaseContext(),
getResources().getString(R.string.ioexception),
Toast.LENGTH_SHORT).show();
return;
} finally {
if (socket != null) {
try {
Log.d(TAG, ">>Client Socket Close");
socket.close();
socket = null;
// this.finish();
return;
} catch (IOException e) {
Log.e(TAG, ">>", e);
}
}
}
}
The below code is to accept incoming connection:
public class AcceptThread extends Thread{
// The local server socket
private final BluetoothServerSocket mmServerSocket;
private String mSocketType;
private BluetoothAdapter mAdapter=BluetoothAdapter.getDefaultAdapter();
public AcceptThread(boolean secure) {
BluetoothServerSocket tmp = null;
mSocketType = secure ? "Secure":"Insecure";
// Create a new listening server socket
try {
if (secure) {
tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME_SECURE, MY_UUID_SECURE);
} else {
tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME_SECURE, MY_UUID_INSECURE);
}
} catch (IOException e) {
Log.e(TAG, "Socket Type: " + mSocketType + "listen() failed", e);
}
mmServerSocket = tmp;
}
public void run() {
//BluetoothSocket socket = null;
// Listen to the server socket if we're not connected
while (true) {
try {
// This is a blocking call and will only return on a
// successful connection or an exception
socket = mmServerSocket.accept();
//InputStream ins=socket.getInputStream();
/*BufferedReader r = new BufferedReader(new InputStreamReader(ins));
StringBuilder total = new StringBuilder();
String line;
while ((line = r.readLine()) != null) {
total.append(line);
}*/
//System.out.println("Data============================================>>>"+line);
} catch (IOException e) {
Log.e(TAG, "Socket Type: " + mSocketType + "accept() failed", e);
break;
}
// If a connection was accepted
if (socket != null) {
synchronized (SearchDeviceActivity.this) {
ConnectedThread connectedThread=new ConnectedThread(socket, device.getAddress());
connectedThread.start();
//socket.close();
break;
}
}
}
}
}
The below code is to fetch incoming data:
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
#SuppressLint({ "NewApi", "NewApi" })
public ConnectedThread(BluetoothSocket socket, String socketType) {
Log.d(TAG, "create ConnectedThread: " + socketType);
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the BluetoothSocket input and output streams
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
} catch (IOException e) {
Log.e(TAG, "temp sockets not created", e);
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
Log.i(TAG, "BEGIN mConnectedThread");
byte[] buffer = new byte[1024];
int bytes;
// Keep listening to the InputStream while connected
while (true) {
try {
// Read from the InputStream
bytes = mmInStream.read(buffer);
// Send the obtained bytes to the UI Activity
_handler.obtainMessage(SearchDeviceActivity.MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
} catch (IOException e) {
Log.e(TAG, "disconnected", e);
//connectionLost();
break;
}
}
}
/**
* Write to the connected OutStream.
* #param buffer The bytes to write
*/
#SuppressLint("NewApi")
public void write(byte[] buffer) {
try {
mmOutStream.write(buffer);
// Share the sent message back to the UI Activity
_handler.obtainMessage(SearchDeviceActivity.MESSAGE_WRITE, -1, -1, buffer)
.sendToTarget();
} catch (IOException e) {
Log.e(TAG, "Exception during write", e);
}
}
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) {
Log.e(TAG, "close() of connect socket failed", e);
}
}
}

Sending data over bluetooth via SPP using an android device

I'm trying to send data from an android device to a remote bluetooth device supporting Serial Port Profile(SPP). I notice whenever I open and close a socket after each press of a button, it is too slow. What socket commands should be executed in the Run() and Onclick() functions? The following is a class which does Bluetooth IO:
public class Selecteddevice extends Activity implements OnClickListener {
private static final String TAG = "THINBTCLIENT";
private BluetoothAdapter mBluetoothAdapter = null;
private BluetoothDevice device;
private BluetoothSocket btSocket = null;
private OutputStream outStream = null;
private static final UUID MY_UUID =
UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
public static String address;
#Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
this.setContentView(R.layout.selecteddevice);
findViewById(R.id.toggleButton1).setOnClickListener(this);
findViewById(R.id.toggleButton2).setOnClickListener(this);
findViewById(R.id.toggleButton3).setOnClickListener(this);
}
#Override
public void onStart() {
super.onStart();
String address = getIntent().getStringExtra("address");
TextView tv1 = (TextView) findViewById(R.id.textView_address);
tv1.setText(" DEVICE ADDRESS: " + address);
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
device = mBluetoothAdapter.getRemoteDevice(address);
run();
}
public void run(){
mBluetoothAdapter.cancelDiscovery();
try {
btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e)
{
Log.e(TAG, "ON START: Socket creation failed.", e);
}
try {
btSocket.connect();
} catch (IOException e)
{
Log.e(TAG, "sendTestByte: Socket connection failed.", e);
}
}
public void sendTestString(String s){
try {
outStream = btSocket.getOutputStream();
} catch (IOException e)
{
Log.e(TAG, "sendTestByte: OutputStream creation failed.", e);
}
try {
outStream.write(s.getBytes());
Log.d(TAG, "sendTestByte: OutputStream write succeeded.");
} catch (IOException e)
{
Log.e(TAG, "sendTestByte: OutputStream writefailed.", e);
}
}
public void onClick(View v){
switch(v.getId())
{
case R.id.toggleButton1:
this.sendTestString("1");
break;
case R.id.toggleButton2:
this.sendTestString("2");
break;
case R.id.toggleButton3:
this.sendTestString("3");
break;
}
}
#Override
public void onPause() {
super.onPause();
if (outStream != null) {
try {
outStream.flush();
} catch (IOException e5)
{
Log.e(TAG, "ON PAUSE: Couldn't flush output stream.", e5);
}
}
try {
btSocket.close();
} catch (IOException e6)
{
Log.e(TAG, "ON PAUSE: Unable to close socket.", e6);
}
}
#Override
public void onStop() {
super.onStop();
}
#Override
public void onDestroy() {
super.onDestroy();
}
}
My program crashes after pairing with the error message:
07-27 13:00:57.483: E/THINBTCLIENT(7855): sendTestByte: OutputStream writefailed.
07-27 13:00:57.483: E/THINBTCLIENT(7855): java.io.IOException: socket closed
07-27 13:00:57.483: E/THINBTCLIENT(7855): at
android.bluetooth.BluetoothSocket.write(BluetoothSocket.java:331)
...
What am I doing wrong?
Thanks.
If you are sure the connection is established without any error and you can get the socket, try assigning your OutputStream member in run() method as follows:
public void run()
{
mBluetoothAdapter.cancelDiscovery();
try
{
btSocket = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e)
{
Log.e(TAG, "ON START: Socket creation failed.", e);
}
try
{
btSocket.connect();
} catch (IOException e)
{
Log.e(TAG, "sendTestByte: Socket connection failed.", e);
}
try
{
outStream = btSocket.getOutputStream();
} catch (IOException e)
{
Log.e(TAG, "sendTestByte: OutputStream creation failed.", e);
}
}
public void sendTestString(String s)
{
try
{
outStream.write(s.getBytes());
outSttream.flush(); // <-- Try flush to force sending data in buffer
Log.d(TAG, "sendTestByte: OutputStream write succeeded.");
} catch (IOException e)
{
Log.e(TAG, "sendTestByte: OutputStream writefailed.", e);
}
}
You are not actually closing socket but this should work. Make sure connection with master device is not lost before write() call

Getting a strange NPE in one of my Bluetooth classes, it didn't happen before

Using Android's Bluetooth Chat sample app as my guide http://developer.android.com/resources/samples/BluetoothChat/index.html, I've tried to create my own bluetooth function for an app I am working on.
Last night I tested it with two Android phones and had some issues, but there were no force closes. It simply didn't connect my devices when I asked it to. I went in and added a few Log lines to make sure the program was following the proper course. When I reinstalled and launched the app on my phone today, I got a force close error when attempting to turn on Bluetooth, a problem I did not have at all last night. The only code I changed was the addition of 2-3 log commands. I checked logcat and got the following:
As you can see, the problem is caused by an NPE # line 185. Here is my code for the BluetoothService class, I will repost the specific area of issue below it.
package com.tagapp.android;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.UUID;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
public class BluetoothService {
private static final String TAG = "BluetoothService";
private static final boolean D = true;
private static final String NAME = "BluetoothTag";
private static final UUID MY_UUID =
UUID.fromString("93845760-234e-11e0-ac64-0800200c9a66");
private final BluetoothAdapter mAdapter;
private final Handler mHandler;
private AcceptThread mAcceptThread;
private ConnectThread mConnectThread;
private ConnectedThread mConnectedThread;
private int mState;
public static final int STATE_NONE = 0;
public static final int STATE_LISTEN = 1;
public static final int STATE_CONNECTING = 2;
public static final int STATE_CONNECTED = 3;
public BluetoothService(Context context, Handler handler) {
mAdapter = BluetoothAdapter.getDefaultAdapter();
mState = STATE_NONE;
mHandler = handler;
}
private synchronized void setState(int state) {
if (D) Log.d(TAG, "setState() " + mState + " -> " + state);
mState = state;
mHandler.obtainMessage(BluetoothTransfer.MESSAGE_STATE_CHANGE, state, -1).sendToTarget();
}
public synchronized int getState() {
return mState;
}
public synchronized void start() {
if (D) Log.d(TAG, "start");
if(mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
if(mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
if(mAcceptThread == null) {
mAcceptThread = new AcceptThread();
mAcceptThread.start();
}
setState(STATE_LISTEN);
}
public synchronized void connect(BluetoothDevice device) {
if (D) Log.d(TAG, "connect to: " + device);
if(mState == STATE_CONNECTING) {
if(mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
}
if(mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
mConnectThread = new ConnectThread(device);
mConnectThread.start();
setState(STATE_CONNECTING);
}
public synchronized void connected(BluetoothSocket socket, BluetoothDevice device) {
if (D) Log.d(TAG, "connected");
if(mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
if(mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
if(mAcceptThread != null) {
mAcceptThread.cancel();
mAcceptThread = null;
}
mConnectedThread = new ConnectedThread(socket);
mConnectedThread.start();
Message msg = mHandler.obtainMessage(BluetoothTransfer.MESSAGE_DEVICE_NAME);
Bundle bundle = new Bundle();
bundle.putString(BluetoothTransfer.DEVICE_NAME, device.getName());
msg.setData(bundle);
mHandler.sendMessage(msg);
setState(STATE_CONNECTED);
}
public synchronized void stop() {
if (D) Log.d(TAG, "stop");
if(mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
if(mConnectedThread != null) {
mConnectedThread.cancel();
mConnectedThread = null;
}
if(mAcceptThread != null) {
mAcceptThread.cancel();
mAcceptThread = null;
}
setState(STATE_NONE);
}
public void write(byte[] out) {
ConnectedThread ct;
synchronized(this) {
if(mState != STATE_CONNECTED) return;
ct = mConnectedThread;
}
ct.write(out);
}
private void connectionFailed() {
setState(STATE_LISTEN);
Message msg = mHandler.obtainMessage(BluetoothTransfer.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(BluetoothTransfer.TOAST, "Unable to connect device");
msg.setData(bundle);
mHandler.sendMessage(msg);
}
private void connectionLost() {
setState(STATE_LISTEN);
Message msg = mHandler.obtainMessage(BluetoothTransfer.MESSAGE_TOAST);
Bundle bundle = new Bundle();
bundle.putString(BluetoothTransfer.TOAST, "Device connection was lost");
msg.setData(bundle);
mHandler.sendMessage(msg);
}
private class AcceptThread extends Thread {
private final BluetoothServerSocket mmServerSocket;
public AcceptThread() {
BluetoothServerSocket tmp = null;
try {
tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
}
catch (IOException e) {
Log.e(TAG, "listen() failed", e);
}
mmServerSocket = tmp;
}
public void run() {
if (D) Log.d(TAG, "BEGIN mAcceptThread" + this);
setName("AcceptThread");
BluetoothSocket socket = null;
while (mState != STATE_CONNECTED) {
try {
socket = mmServerSocket.accept();
}
catch (IOException e) {
Log.e(TAG, "accept() failed", e);
break;
}
if(socket != null) {
synchronized (BluetoothService.this) {
switch(mState) {
case STATE_LISTEN :
case STATE_CONNECTING :
connected(socket, socket.getRemoteDevice());
break;
case STATE_NONE :
case STATE_CONNECTED :
try {
socket.close();
}
catch (IOException e) {
Log.e(TAG, "Could not close unwanted socket", e);
}
break;
}
}
}
}
if (D) Log.i(TAG, "END mAcceptThread");
}
public void cancel() {
if (D) Log.d(TAG, "cancel " + this);
try {
mmServerSocket.close();
}
catch (IOException e) {
Log.e(TAG, "close() of server failed", e);
}
}
}
private class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
public ConnectThread(BluetoothDevice device) {
mmDevice = device;
BluetoothSocket tmp = null;
try {
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
}
catch (IOException e) {
Log.e(TAG, "create() failed", e);
}
mmSocket = tmp;
}
public void run() {
Log.i(TAG, "BEGIN mConnectThread");
setName("ConnectThread");
mAdapter.cancelDiscovery();
try {
mmSocket.connect();
}
catch (IOException e) {
connectionFailed();
try {
mmSocket.close();
}
catch (IOException e2) {
Log.e(TAG, "unable to close() socket during connection failure", e2);
}
BluetoothService.this.start();
return;
}
synchronized (BluetoothService.this) {
mConnectThread = null;
}
connected(mmSocket, mmDevice);
}
public void cancel() {
try {
mmSocket.close();
}
catch (IOException e) {
Log.e(TAG, "close() of connect socket failed", e);
}
}
}
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
Log.d(TAG, "create ConnectedThread");
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
try {
tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();
}
catch (IOException e) {
Log.e(TAG, "tempt sockets not created", e);
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void run() {
Log.i(TAG, "BEGIN mConnectedThread");
byte[] buffer = new byte[1024];
int bytes;
while (true) {
try {
bytes = mmInStream.read(buffer);
mHandler.obtainMessage(BluetoothTransfer.CONTACT_RECEIVE, bytes, -1, buffer).sendToTarget();
}
catch (IOException e) {
Log.e(TAG, "disconnected", e);
connectionLost();
break;
}
}
}
public void write(byte[] buffer) {
try {
mmOutStream.write(buffer);
mHandler.obtainMessage(BluetoothTransfer.CONTACT_SEND, -1, -1, buffer).sendToTarget();
}
catch (IOException e) {
Log.e(TAG, "exception during write", e);
}
}
public void cancel() {
try {
mmSocket.close();
}
catch (IOException e) {
Log.e(TAG, "close() of connect socket failed", e);
}
}
}
}
The lines which are causing the NPE (the AcceptThread):
private class AcceptThread extends Thread {
private final BluetoothServerSocket mmServerSocket;
public AcceptThread() {
BluetoothServerSocket tmp = null;
try {
tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
}
catch (IOException e) {
Log.e(TAG, "listen() failed", e);
}
mmServerSocket = tmp;
}
public void run() {
if (D) Log.d(TAG, "BEGIN mAcceptThread" + this);
setName("AcceptThread");
BluetoothSocket socket = null;
while (mState != STATE_CONNECTED) {
try {
socket = mmServerSocket.accept();//THIS LINE CAUSES NPE
}
catch (IOException e) {
Log.e(TAG, "accept() failed", e);
break;
}
The object socket should by initialized # null, but it is supposed to try socket = mmServerSocket.accept();
This is directly from Google's sample app provided on the Android dev website. I have two concerns: 1, why isn't this working, and 2, why did it work just fine just hours ago?
Thanks for your help.
Regarding "strange NPE" - it's not strange at all. The reason you get NPE at this line
socket = mmServerSocket.accept(); //THIS LINE CAUSES NPE
is pretty obvious - variable mmServerSocket equals NULL, and this is the only possible reason to get NPE at this line of code. The reason why mmServerSocket equals NULL is simple too - look at a constructor of your class:
public AcceptThread() {
BluetoothServerSocket tmp = null;
try {
tmp = mAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
}
catch (IOException e) {
Log.e(TAG, "listen() failed", e);
}
mmServerSocket = tmp;
}
You are calling method listenUsingRfcommWithServiceRecord which throws IOException, you catching this exception, as we can clearly see in logcat. Next, tmp variable stays initialized as NULL, same as mmServerSocket, which leads as to NPE mentioned above.
The reason why listenUsingRfcommWithServiceRecord is throwing IOException - because bluetooth is turned off, as you mention in your question. Android documentation says nothing about your assumption that this method should automatically turn on bluetooth if it's turned off. I think you should manually check if bluetooth is turned off and turn it on manually, before calling listenUsingRfcommWithServiceRecord.
You can find how to check is bluetooth turned on/off and turn it on here and here

Categories

Resources