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 =)
Related
I am using 3 fragment on my app. First and second fragments are connecting and receiving data with other devices correctly. And at the 3th fragment i want to send message to other devices. I am using BluetoothConnectionService for this things. But my ConnectedThread return null. Although i am calling bluetoothservice in fragment 3 how can i solve ?
My Log return : mConnectedThread empty
Fragment 3:
BluetoothConnectionService mBluetoothConnection;
BluetoothAdapter mBluetoothAdapter;
private View convertView;
String data;
StringBuffer sbuffer= new StringBuffer();
TextView text;
int read;
int data_set;
Button send;
BluetoothDevice mBTDevice;
private static final UUID MY_UUID_INSECURE =
UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if(convertView==null) {
convertView = inflater.inflate(R.layout.fragment_ota__update, container, false);
text=(TextView)convertView.findViewById(R.id.text);
InputStream is =this.getResources().openRawResource(R.raw.blink);
BufferedReader reader = new BufferedReader( new InputStreamReader(is));
send =(Button) convertView.findViewById(R.id.send);
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
mBluetoothConnection = new BluetoothConnectionService(getActivity().getApplicationContext());
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
getActivity().registerReceiver(mBroadcastReceiver4, filter);
if(is!=null){
try {
while ((data = reader.readLine()) != null) {
char [] ch =data.toCharArray();
for (char c: ch) {
int i= (int) c;
sbuffer.append(Integer.toHexString(i).toUpperCase());
text.setText(sbuffer);
}
}
is.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
send.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if(sbuffer!=null) {
byte[] bytes = sbuffer.toString().getBytes(Charset.defaultCharset());
mBluetoothConnection.write(bytes);
}
}
});
}
return convertView;
// Inflate the layout for this fragment
}
private final BroadcastReceiver mBroadcastReceiver4 = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if(action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)){
BluetoothDevice mDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
//3 cases:
//case1: bonded already
if (mDevice.getBondState() == BluetoothDevice.BOND_BONDED){
Log.d(TAG, "BroadcastReceiver: BOND_BONDED.");
//inside BroadcastReceiver4
mBTDevice = mDevice;
}
//case2: creating a bone
if (mDevice.getBondState() == BluetoothDevice.BOND_BONDING) {
Log.d(TAG, "BroadcastReceiver: BOND_BONDING.");
}
//case3: breaking a bond
if (mDevice.getBondState() == BluetoothDevice.BOND_NONE) {
Log.d(TAG, "BroadcastReceiver: BOND_NONE.");
}
}
}
};
}
BluetoothService
package com.example.duygu.mybluetoothdevicelist;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.content.Intent;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.util.UUID;
public class BluetoothConnectionService {
private static final String TAG = "BluetoothConnectionServ";
private static final String appName = "MYAPP";
private static final UUID MY_UUID_INSECURE =
UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
private final BluetoothAdapter mBluetoothAdapter;
Context mContext;
private AcceptThread mInsecureAcceptThread;
private ConnectThread mConnectThread;
private BluetoothDevice mmDevice;
private UUID deviceUUID;
ProgressDialog mProgressDialog;
private ConnectedThread mConnectedThread;
public BluetoothConnectionService(Context context) {
mContext = context;
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
start();
}
/**
* This thread runs while listening for incoming connections. It behaves
* like a server-side client. It runs until a connection is accepted
* (or until cancelled).
*/
private class AcceptThread extends Thread {
// The local server socket
private final BluetoothServerSocket mmServerSocket;
public AcceptThread(){
BluetoothServerSocket tmp = null;
// Create a new listening server socket
try{
tmp = mBluetoothAdapter.listenUsingInsecureRfcommWithServiceRecord(appName, MY_UUID_INSECURE);
Log.d(TAG, "AcceptThread: Setting up Server using: " + MY_UUID_INSECURE);
}catch (IOException e){
Log.e(TAG, "AcceptThread: IOException: " + e.getMessage() );
}
mmServerSocket = tmp;
}
public void run(){
Log.d(TAG, "run: AcceptThread Running.");
BluetoothSocket socket = null;
try{
// This is a blocking call and will only return on a
// successful connection or an exception
Log.d(TAG, "run: RFCOM server socket start.....");
socket = mmServerSocket.accept();
Log.d(TAG, "run: RFCOM server socket accepted connection.");
}catch (IOException e){
Log.e(TAG, "AcceptThread: IOException: " + e.getMessage() );
}
//talk about this is in the 3rd
if(socket != null){
connected(socket,mmDevice);
}
Log.i(TAG, "END mAcceptThread ");
}
public void cancel() {
Log.d(TAG, "cancel: Canceling AcceptThread.");
try {
mmServerSocket.close();
} catch (IOException e) {
Log.e(TAG, "cancel: Close of AcceptThread ServerSocket failed. " + e.getMessage() );
}
}
}
/**
* This thread runs while attempting to make an outgoing connection
* with a device. It runs straight through; the connection either
* succeeds or fails.
*/
private class ConnectThread extends Thread {
private BluetoothSocket mmSocket;
public ConnectThread(BluetoothDevice device, UUID uuid) {
Log.d(TAG, "ConnectThread: started.");
mmDevice = device;
deviceUUID = uuid;
}
public void run(){
BluetoothSocket tmp = null;
Log.i(TAG, "RUN mConnectThread ");
// Get a BluetoothSocket for a connection with the
// given BluetoothDevice
try {
Log.d(TAG, "ConnectThread: Trying to create InsecureRfcommSocket using UUID: "
+MY_UUID_INSECURE );
tmp = mmDevice.createRfcommSocketToServiceRecord(deviceUUID);
} catch (IOException e) {
Log.e(TAG, "ConnectThread: Could not create InsecureRfcommSocket " + e.getMessage());
}
mmSocket = tmp;
// Always cancel discovery because it will slow down a connection
mBluetoothAdapter.cancelDiscovery();
// Make a connection to the BluetoothSocket
try {
// This is a blocking call and will only return on a
// successful connection or an exception
mmSocket.connect();
Log.d(TAG, "run: ConnectThread connected.");
} catch (IOException e) {
// Close the socket
try {
mmSocket.close();
Log.d(TAG, "run: Closed Socket.");
} catch (IOException e1) {
Log.e(TAG, "mConnectThread: run: Unable to close connection in socket " + e1.getMessage());
}
Log.d(TAG, "run: ConnectThread: Could not connect to UUID: " + MY_UUID_INSECURE );
}
//will talk about this in the 3rd video
connected(mmSocket,mmDevice);
}
public void cancel() {
try {
Log.d(TAG, "cancel: Closing Client Socket.");
mmSocket.close();
} catch (IOException e) {
Log.e(TAG, "cancel: close() of mmSocket in Connectthread failed. " + e.getMessage());
}
}
}
/**
* Start the chat service. Specifically start AcceptThread to begin a
* session in listening (server) mode. Called by the Activity onResume()
*/
public synchronized void start() {
Log.d(TAG, "start");
// Cancel any thread attempting to make a connection
if (mConnectThread != null) {
mConnectThread.cancel();
mConnectThread = null;
}
if (mInsecureAcceptThread == null) {
mInsecureAcceptThread = new AcceptThread();
mInsecureAcceptThread.start();
}
}
/**
AcceptThread starts and sits waiting for a connection.
Then ConnectThread starts and attempts to make a connection with the other devices AcceptThread.
**/
public void startClient(BluetoothDevice device,UUID uuid){
Log.d(TAG, "startClient: Started.");
//initprogress dialog
mProgressDialog = ProgressDialog.show(mContext,"Connecting Bluetooth"
,"Please Wait...",true);
mConnectThread = new ConnectThread(device, uuid);
mConnectThread.start();
}
/**
Finally the ConnectedThread which is responsible for maintaining the BTConnection, Sending the data, and
receiving incoming data through input/output streams respectively.
**/
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
public ConnectedThread(BluetoothSocket socket) {
Log.d(TAG, "ConnectedThread: Starting.");
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
//dismiss the progressdialog when connection is established
try{
mProgressDialog.dismiss();
}catch (NullPointerException e){
e.printStackTrace();
}
try {
tmpIn = mmSocket.getInputStream();
tmpOut = mmSocket.getOutputStream();
} catch (IOException e) {
e.printStackTrace();
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
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 (true) {
// Read from the InputStream
try {
bytes = mmInStream.read(buffer);
String incomingMessage = new String(buffer, 0, bytes);
Log.d(TAG, "InputStream: " + incomingMessage);
Intent incomingMessageIntent = new Intent("incomingMessage");
incomingMessageIntent.putExtra("theMessage", incomingMessage);
LocalBroadcastManager.getInstance(mContext).sendBroadcast(incomingMessageIntent);
} catch (IOException e) {
Log.e(TAG, "write: Error reading Input Stream. " + e.getMessage() );
break;
}
}
}
//Call this from the main activity to send data to the remote device
public void write(byte[] bytes) {
String text = new String(bytes, Charset.defaultCharset());
Log.d(TAG, "write: Writing to outputstream: " + text);
try {
mmOutStream.write(bytes);
} catch (IOException e) {
Log.e(TAG, "write: Error writing to output stream. " + e.getMessage() );
}
}
/* Call this from the main activity to shutdown the connection */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
private void connected(BluetoothSocket mmSocket, BluetoothDevice mmDevice) {
Log.d(TAG, "connected: Starting.");
// Start the thread to manage the connection and perform transmissions
mConnectedThread = new ConnectedThread(mmSocket);
mConnectedThread.start();
}
/**
* Write to the ConnectedThread in an unsynchronized manner
*
* #param out The bytes to write
* #see ConnectedThread#write(byte[])
*/
public void write(byte[] out) {
if(mConnectedThread !=null ){
// Create temporary object
// Synchronize a copy of the ConnectedThread
Log.d(TAG, "write: Write Called.");
//perform the write
mConnectedThread.write(out);
}
else{
Log.d(TAG, "mConnectedThread empty ");
}
}
}
My demo is just determined to build a connection between two phones.But when my client tries to call bluetoothSocket.connect() it throws an IOException with the message no route to host.I have tried many approaches but it doesn't work.
Here is my code about AcceptThread and ConnectThread (deleted some unrelated code to make it more concise)
class AcceptThread extends Thread {
private final BluetoothServerSocket mmServerSocket;
BluetoothServerSocket tmp;
public AcceptThread() {
Method listenMethod = null;
try {
listenMethod = bluetoothAdapter.getClass().getMethod("listenUsingRfcommOn",new Class[]{int.class});
}
try {
tmp = ( BluetoothServerSocket) listenMethod.invoke(bluetoothAdapter, new Object[]{30});
}
mmServerSocket = tmp;
}
public void run() {
BluetoothSocket socket = null;
while (isAcceptRun) {
try {
socket = mmServerSocket.accept();
} catch (IOException e) {
Log.i(TAG, "run: AB "+e);
break;
}
if (socket != null) {
try {
mmServerSocket.close();
}
break;
}
}
}
}
class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
public ConnectThread(BluetoothDevice device) {
BluetoothSocket tmp = null;
mmDevice = device;
Method m = null;
try {
m = device.getClass().getMethod("createRfcommSocket", new Class[]{int.class});
}
try {
tmp = (BluetoothSocket) m.invoke(device, Integer.valueOf(30));
}
mmSocket = tmp;
}
public void run() {
// Cancel discovery because it will slow down the connection
bluetoothAdapter.cancelDiscovery();
try {
mmSocket.connect();
} catch (IOException connectException) {
try {
mmSocket.close();
} catch (IOException closeException) {
}
return;
}
}
/** Will cancel an in-progress connection, and close the socket */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
In the BluetoothChat example from Google, the BluetoothSocket is constructed by:
private static final UUID MY_UUID_SECURE =
UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66");
private static final UUID MY_UUID_INSECURE =
UUID.fromString("8ce255c0-200a-11e0-ac64-0800200c9a66");
if (secure) {
tmp = device.createRfcommSocketToServiceRecord(
MY_UUID_SECURE);
} else {
tmp = device.createInsecureRfcommSocketToServiceRecord(
MY_UUID_INSECURE);
}
static class BluetoothInHandler extends Handler {
private final WeakReference<Bluetooth_dataDisplay> mActivity;
BluetoothInHandler(Bluetooth_dataDisplay activity) {
mActivity = new WeakReference<>(activity);
}
#Override
public void handleMessage(Message msg) {
final Bluetooth_dataDisplay thizz = mActivity.get();
if (thizz == null) return;
if (msg.what == thizz.handlerState) {
String readMessage = (String) msg.obj;
thizz.myLabel.setText(readMessage);
}
}//end of handle message
}//end of Bluetoothin handler
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.bluetooth_datadisplay);
myLabel = (TextView)findViewById(R.id.label);
mMyHandler = new BluetoothInHandler(this);
}//end oncreate
#Override
public void onResume() {
super.onResume();
String MAC = getIntent().getStringExtra("MAC");
mAdapter = BluetoothAdapter.getDefaultAdapter();
BluetoothDevice bluetoothDevice = mAdapter.getRemoteDevice(MAC);
ConnectingThread t = new ConnectingThread(bluetoothDevice);
t.start();
}
//Setting Up a Connecting Client
private class ConnectingThread extends Thread {
OutputStream mmOutputStream;
InputStream mmInputStream;
StringBuilder recDataString = new StringBuilder();
// private final BluetoothSocket bluetoothSocket;
private final BluetoothDevice bluetoothDevice;
final Handler handler = new Handler();
public ConnectingThread(BluetoothDevice device) {
BluetoothSocket temp = null;
bluetoothDevice = device;
// Get a BluetoothSocket to connect with the given BluetoothDevice
try {
temp = bluetoothDevice.createRfcommSocketToServiceRecord(uuid);
} catch (IOException e) {
e.printStackTrace();
}
bluetoothSocket = temp;
}
public void run() {
// Cancel any discovery as it will slow down the connection
mAdapter.cancelDiscovery();
try {
// This will block until it succeeds in connecting to the device
// through the bluetoothSocket or throws an exception
bluetoothSocket.connect();
Log.e("bluetooth socket",".connect");
mmOutputStream = bluetoothSocket.getOutputStream();
mmInputStream = bluetoothSocket.getInputStream();
//beginListenForData();
Bluetooth_dataDisplay.this.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(Bluetooth_dataDisplay.this, "Connected with Device!", Toast.LENGTH_SHORT).show();
}
});
handler.post(new Runnable() {
public void run() {
byte[] buffer = new byte[1024];
int bytes;
// Keep looping to listen for received messages
while (true) {
try {
bytes = mmInputStream.read(buffer);
String readMessage = new String(buffer, 0, bytes);
// Send the obtained bytes to the UI Activity via handler
mMyHandler.obtainMessage(handlerState, bytes, -1, readMessage).sendToTarget();
} catch (IOException e) {
break;
}
}
}
});
//beginListenForData();
//Log.e("begin", "begindata");
} catch (IOException connectException) {
connectException.printStackTrace();
try {
bluetoothSocket.close();
Log.e("click6", "blueclose");
} catch (IOException closeException) {
closeException.printStackTrace();
}
}
}
Trying to send data from thread back to UI activity but my app just stuck. :( I don't know what wrong with it. Please help. No error and no crashes of app. I had tried runnableUIthread as well. It didn't work too. So I don't know what to do now.
static class BluetoothInHandler extends Handler {
private final WeakReference<Bluetooth_dataDisplay> mActivity;
BluetoothInHandler(Bluetooth_dataDisplay activity) {
mActivity = new WeakReference<>(activity);
}
#Override
public void handleMessage(Message msg) {
//change 3
Log.e("test","handleMessage");
final Bluetooth_dataDisplay thizz = mActivity.get();
if (thizz == null) return;
if (msg.what == thizz.handlerState) {
String readMessage = (String) msg.obj;
thizz.myLabel.setText(readMessage);
}
}//end of handle message
}//end of Bluetoothin handler
#Override
public void onResume() {
super.onResume();
String MAC = getIntent().getStringExtra("MAC");
mAdapter = BluetoothAdapter.getDefaultAdapter();
BluetoothDevice bluetoothDevice = mAdapter.getRemoteDevice(MAC);
ConnectingThread t = new ConnectingThread(bluetoothDevice,mMyHandler );
t.start();
}
//Setting Up a Connecting Client
private class ConnectingThread extends Thread {
OutputStream mmOutputStream;
InputStream mmInputStream;
StringBuilder recDataString = new StringBuilder();
// private final BluetoothSocket bluetoothSocket;
private final BluetoothDevice bluetoothDevice;
Handler handler;
public ConnectingThread(BluetoothDevice device,Handler mHandler) {
handler = mHandler
BluetoothSocket temp = null;
bluetoothDevice = device;
// Get a BluetoothSocket to connect with the given BluetoothDevice
try {
temp = bluetoothDevice.createRfcommSocketToServiceRecord(uuid);
} catch (IOException e) {
e.printStackTrace();
}
bluetoothSocket = temp;
}
public void run() {
// Cancel any discovery as it will slow down the connection
mAdapter.cancelDiscovery();
try {
// This will block until it succeeds in connecting to the device
// through the bluetoothSocket or throws an exception
bluetoothSocket.connect();
Log.e("bluetooth socket",".connect");
mmOutputStream = bluetoothSocket.getOutputStream();
mmInputStream = bluetoothSocket.getInputStream();
//beginListenForData();
Bluetooth_dataDisplay.this.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(Bluetooth_dataDisplay.this, "Connected with Device!", Toast.LENGTH_SHORT).show();
}
});
//change 7
//handler.post(
new Runnable() {
public void run() {
byte[] buffer = new byte[1024];
int bytes;
// Keep looping to listen for received messages
while (true) {
//change 1
try{
Thread.sleep(1000);
}catch(Throwable e){
e.printStackTrace();
}
try {
bytes = mmInputStream.read(buffer);
String readMessage = new String(buffer, 0, bytes);
// Send the obtained bytes to the UI Activity via handler
//change 4;
handler.obtainMessage(handlerState, bytes, -1, readMessage).sendToTarget();
} catch (IOException e) {
//change 6
Log.e("test","6")
//change 2
e.printStackTrace();
break;
}catch(Throwable e1){
//change 5;
Log.e("test","5")
}
}
}.run();
//});
//beginListenForData();
//Log.e("begin", "begindata");
} catch (IOException connectException) {
connectException.printStackTrace();
try {
bluetoothSocket.close();
Log.e("click6", "blueclose");
} catch (IOException closeException) {
closeException.printStackTrace();
}
}
}
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);
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