Sending events through bluetooth in android - android

I have created a bluetooth connection between two phones(the paired device don't have my app). How to send events to the phone like screen lock/ volume up
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter.isEnabled()){
handler.sendEmptyMessageDelayed(connectionCheckTimeout,30000);
BluetoothReciever bluetoothReciever = new BluetoothReciever();
bluetoothReciever.registerBluetoothRecieverForConnection(this,this);
SocketThread socketThread = SocketThread.getInstance();
socketThread.registerBluetoothRecieverForCommunication(this,this);
Thread thread = new Thread(socketThread);
thread.start();
}
my socket thread class is here, i am getting a connected device(not just paired).
Now i have to send events like volume up/down to the other device which doesn't run my app.
public class SocketThread implements Runnable {
private static SocketThread ourInstance = new SocketThread();
BluetoothAdapter bluetoothAdapter;
BluetoothDevice device;
BluetoothSocket bluetoothSocket;
static BluetoothSocketListener bluetoothSocketListener;
public static SocketThread getInstance() {
return ourInstance;
}
private SocketThread() {
}
#Override
public void run() {
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
device = connectedDevice(bluetoothAdapter);
if (device!=null){
// Toast.makeText(getApplicationContext(),"connected to "+device.getName(),Toast.LENGTH_SHORT).show();
if (bluetoothSocketListener!=null) {
bluetoothSocketListener.deviceIsConnected(device,bluetoothSocket);
}
try {
bluetoothSocket.getOutputStream().flush();
} catch (IOException e) {
e.printStackTrace();
}
}else{
if (bluetoothSocketListener!=null) {
bluetoothSocketListener.deviceIsNotConnected();
}
}
}
private BluetoothDevice connectedDevice(BluetoothAdapter bluetoothAdapter){
if (bluetoothAdapter == null)
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter.getBondedDevices().size() == 0)
return null;
//now create socket to all paired devices. Check if connected. then return true
Set<BluetoothDevice> btDevices = bluetoothAdapter.getBondedDevices();
for (BluetoothDevice device : btDevices){
Log.d("main activity"," trying to create socket for paired device "+device.getName());
try {
bluetoothSocket
= device.createRfcommSocketToServiceRecord(device.getUuids()[0].getUuid());
bluetoothSocket.connect();
if (bluetoothSocket.isConnected()){
return device;
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
public void registerBluetoothRecieverForCommunication(Context context, BluetoothSocketListener bluetoothSocketListener){
this.bluetoothSocketListener = bluetoothSocketListener;
}
}

Bluetooth sends raw data. Apparently, you have to parse those somehow and transform into calls in your app, doing some work

Related

How to programmatically pair and connect a HID bluetooth device(Bluetooth Keyboard) on Android

I am able to pair a bluetooth keyboard but not able to connect so as to make it an input device.
I went through the documentation provided at developer site - http://developer.android.com/guide/topics/connectivity/bluetooth.html#Profiles
It says that the Android Bluetooth API provides implementations for the following Bluetooth profiles but you can implement the interface BluetoothProfile to write your own classes to support a particular Bluetooth profile.
Headset
A2DP
Health Device
There is no documentation how to implement BluetoothProfile for HID bluetooth device(Keyboard)
Android has itself implemented bluetooth connection for HID devices but those API's are hidden. I tried reflection to use them too. I do not get any error but keyboard does not get connected as input device. This is what i have done -
private void connect(final BluetoothDevice bluetoothDevice) {
if(bluetoothDevice.getBluetoothClass().getDeviceClass() == 1344){
final BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
BluetoothProfile.ServiceListener mProfileListener = new BluetoothProfile.ServiceListener() {
#Override
public void onServiceConnected(int profile, BluetoothProfile proxy) {
Log.i("btclass", profile + "");
if (profile == getInputDeviceHiddenConstant()) {
Class instance = null;
try {
//instance = Class.forName("android.bluetooth.IBluetoothInputDevice");
instance = Class.forName("android.bluetooth.BluetoothInputDevice");
Method connect = instance.getDeclaredMethod("connect", BluetoothDevice.class);
Object value = connect.invoke(proxy, bluetoothDevice);
Log.e("btclass", value.toString());
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
#Override
public void onServiceDisconnected(int profile) {
}
};
mBluetoothAdapter.getProfileProxy(this, mProfileListener,getInputDeviceHiddenConstant());
}
}
public static int getInputDeviceHiddenConstant() {
Class<BluetoothProfile> clazz = BluetoothProfile.class;
for (Field f : clazz.getFields()) {
int mod = f.getModifiers();
if (Modifier.isStatic(mod) && Modifier.isPublic(mod) && Modifier.isFinal(mod)) {
try {
if (f.getName().equals("INPUT_DEVICE")) {
return f.getInt(null);
}
} catch (Exception e) {
Log.e("", e.toString(), e);
}
}
}
return -1;
}
Due to security reasons, it is not possible for third party applications to connect to a bluetooth keyboard as the application can be a keylogger. So it can be only done manually by the user.
Here is the code I used on Android Marshmallow (6.0).. To get an L2CAP connection started (Needed for HID)
public static BluetoothSocket createL2CAPBluetoothSocket(String address, int psm){
return createBluetoothSocket(BluetoothSocket.TYPE_L2CAP, -1, false,false, address, psm);
}
// method for creating a bluetooth client socket
private static BluetoothSocket createBluetoothSocket(int type, int fd, boolean auth, boolean encrypt, String address, int port){
Log.e(TAG, "Creating socket with " + address + ":" + port);
try {
Constructor<BluetoothSocket> constructor = BluetoothSocket.class.getDeclaredConstructor(
int.class, int.class,boolean.class,boolean.class,String.class, int.class);
constructor.setAccessible(true);
BluetoothSocket clientSocket = (BluetoothSocket) constructor.newInstance(type,fd,auth,encrypt,address,port);
return clientSocket;
}catch (Exception e) {
e.printStackTrace();
}
return null;
}
public Boolean connect(View v) {
try {
// TODO: Check bluetooth enabled
mDevice = getController();
if (mDevice != null) {
Log.e(TAG, "Controller is paired");
// Create socket
mSocket = createL2CAPBluetoothSocket(mDevice.getAddress(), 0x1124);
if (mSocket != null) {
if (!mSocket.isConnected()) {
mSocket.connect();
}
Log.e(TAG, "Socket successfully created");
ConnectedThread mConnectedThread = new ConnectedThread(mSocket);
mConnectedThread.run();
}
} else {
showToast("Controller is not connected");
}
return true;
} catch (Exception e) {
e.printStackTrace();
if (e instanceof IOException){
// handle this exception type
} else {
// We didn't expect this one. What could it be? Let's log it, and let it bubble up the hierarchy.
}
return false;
}
}
private BluetoothDevice getController() {
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
for (BluetoothDevice device : pairedDevices) {
if (device.getName().equals("Wireless Controller")) // Change to match DS4 - node name
{
Log.d(TAG, "Found device named: " + device.getName());
return device;
}
}
}
return null;
}
It can still have problems creating the Service, and you need to set the correct L2CAP PSAM for the device, but hope it can help..

Create a listening stuck at listenUsingRfcommWithServiceRecord

I am using Bluetooth API of android. I am here creating client-server connection using BluetoothServerSocket & BluetoothSocket but my program stuck at the certain point.
// Create a BroadcastReceiver for ACTION_FOUND
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// When discovery find a device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// get the BluetoothDevice object from the Intent
BluetoothDevice mBluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.i("MainActivity", "Device Name: " + mBluetoothDevice.getName() + " Address: " + mBluetoothDevice.getAddress());
new AcceptThread().start();
}
}
};
private class AcceptThread extends Thread {
private BluetoothServerSocket mBluetoothServerSocket ;
public AcceptThread() {
try {
mBluetoothServerSocket = mBluetoothAdapter.listenUsingRfcommWithServiceRecord("BT_SERVER", UUID.fromString("a60f35f0-b93a-11de-8a39-08002009c666"));
} catch (IOException e) {
Log.e("MainActivity", e.getMessage());
}
}
#Override
public void run() {
BluetoothSocket mBluetoothSocket;
// Keep listening until exception occurs or a socket is returned
while(true) {
try {
mBluetoothSocket = mBluetoothServerSocket.accept();
} catch (IOException e) {
break;
}
// If a connection was accepted
if(mBluetoothSocket != null) {
// transfer the data here
Toast.makeText(MainActivity.this, "Socket is created", Toast.LENGTH_LONG).show();;
try {
// close the connection to stop to listen any connection now
mBluetoothSocket.close();
} catch(IOException e) { }
}
}
}
}
Here my program stuck
mBluetoothServerSocket = mBluetoothAdapter.listenUsingRfcommWithServiceRecord("BT_SERVER", UUID.fromString("a60f35f0-b93a-11de-8a39-08002009c666"));
I could not catch why it getting stuck at this point, Any idea to you for this ?
From your question it is unclear whether your application is a client or server or both. For writing bluetooth client-server applications, android phone at any instance plays a single role of server or a client. If your phone is server, then you need to listen for connections from other bluetooth devices using method listenUsingRfcommWithServiceRecord(). Then use accept() to complete the connection.
In case android phone acts as client, it will initiate a bluetooth connection to other devices. For such scenario, your broadcast receiver is needed. We need to scan for available bluetooth devices with startDiscovery() method. Your broadcast receiver's onReceive() is called when a new bluetooth device is found. To connect to this found device, call createRfcommSocketToServiceRecord() with desired UUID.
Hope this helps.
This may be obvious but did you instantiate your BluetoothAdapter? Accept Thread uses the adapter without intializing it.
myBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
While listening, set the discovery name to a specific value then used listenUsingRfcommWithServiceRecord method in broadcast receiver.
private class AcceptTask extends AsyncTask<UUID,Void,BluetoothSocket> {
#Override
protected BluetoothSocket doInBackground(UUID... params) {
String name = mBtAdapter.getName();
try {
//While listening, set the discovery name to a specific value
mBtAdapter.setName(SEARCH_NAME);
BluetoothServerSocket socket = mBtAdapter.listenUsingRfcommWithServiceRecord("BluetoothRecipe", params[0]);
BluetoothSocket connected = socket.accept();
//Reset the BT adapter name
mBtAdapter.setName(name);
return connected;
} catch (IOException e) {
e.printStackTrace();
mBtAdapter.setName(name);
return null;
}
}
#Override
protected void onPostExecute(BluetoothSocket socket) {
if(socket == null) {
return;
}
mBtSocket = socket;
ConnectedTask task = new ConnectedTask();
task.execute(mBtSocket);
}
}
// End

android bluetooth can't connect

I've been having this problem for a while and haven't been able to figure it out.
I have a android application that puts all paired devices in a listview. When you click one of the list items, it will initiate a request to connect to that bluetooth device.
I can get the list of devices with their addresses no problem.
The problem is that once I try to connect I get an IOException on socket.connect();
The error message is as follows:
"connect read failed, socket might closed or timeout, read ret: -1"
Here is my code. ANY suggestions would be appreciated. I'm pretty stuck on this.
fyi: the "onEvent" methods is a library that simplifies callbacks...that part works.
When the user clicks on a list items this method is called "public void onEvent(EventMessage.DeviceSelected event)"
public class EcoDashActivity extends BaseActivity {
public static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
private BluetoothAdapter mBluetoothAdapter;
private int REQUEST_ENABLE_BT = 100;
private ArrayList<BluetoothDevice> mDevicesList;
private BluetoothDeviceDialog mDialog;
private ProgressDialog progressBar;
private int progressBarStatus = 0;
private Handler progressBarHandler = new Handler();
#Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.main);
mDevicesList = new ArrayList<BluetoothDevice>();
// Register the BroadcastReceiver
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter);
setupBluetooth();
}
private void setupBluetooth() {
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
// Device does not support Bluetooth
Toast.makeText(this, "Device does not support Bluetooth", Toast.LENGTH_SHORT).show();
}
if (!mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
} else {
searchForPairedDevices();
mDialog = new BluetoothDeviceDialog(this, mDevicesList);
mDialog.show(getFragmentManager(), "");
}
}
private void searchForPairedDevices() {
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
// If there are paired devices
if (pairedDevices.size() > 0) {
// Loop through paired devices
for (BluetoothDevice device : pairedDevices) {
// Add the name and address to an array adapter to show in a ListView
mDevices.add(device.getName() + "\n" + device.getAddress());
mDevicesList.add(device);
}
}
}
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// Add the name and address to an array adapter to show in a ListView
mDevicesList.add(device);
}
}
};
#Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(mReceiver);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_ENABLE_BT) {
if (resultCode == RESULT_OK) {
Toast.makeText(this, "BT turned on!", Toast.LENGTH_SHORT).show();
searchForPairedDevices();
mDialog = new BluetoothDeviceDialog(this, mDevicesList);
mDialog.show(getFragmentManager(), "");
}
}
super.onActivityResult(requestCode, resultCode, data);
}
public void onEvent(EventMessage.DeviceSelected event) {
mDialog.dismiss();
BluetoothDevice device = event.getDevice();
ConnectThread connectThread = new ConnectThread(device);
connectThread.start();
}
public class ConnectThread extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
public ConnectThread(BluetoothDevice device) {
// Use a temporary object that is later assigned to mmSocket,
// because mmSocket is final
BluetoothSocket tmp = null;
mmDevice = device;
// Get a BluetoothSocket to connect with the given BluetoothDevice
try {
// MY_UUID is the app's UUID string, also used by the server code
tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
} catch (IOException e) { }
mmSocket = tmp;
}
public void run() {
setName("ConnectThread");
// Cancel discovery because it will slow down the connection
mBluetoothAdapter.cancelDiscovery();
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
Log.d("kent", "trying to connect to device");
mmSocket.connect();
Log.d("kent", "Connected!");
} catch (IOException connectException) {
// Unable to connect; close the socket and get out
try {
Log.d("kent", "failed to connect");
mmSocket.close();
} catch (IOException closeException) { }
return;
}
Log.d("kent", "Connected!");
}
/** Will cancel an in-progress connection, and close the socket */
public void cancel() {
try {
mmSocket.close();
} catch (IOException e) { }
}
}
Here is my logcat. Pretty short.
07-22 10:37:05.129: DEBUG/kent(17512): trying to connect to device
07-22 10:37:05.129: WARN/BluetoothAdapter(17512): getBluetoothService() called with no BluetoothManagerCallback
07-22 10:37:05.129: DEBUG/BluetoothSocket(17512): connect(), SocketState: INIT, mPfd: {ParcelFileDescriptor: FileDescriptor[98]}
07-22 10:37:40.757: DEBUG/dalvikvm(17512): GC_CONCURRENT freed 6157K, 9% free 62793K/68972K, paused 7ms+7ms, total 72ms
07-22 10:38:06.975: DEBUG/kent(17512): failed to connect
07-22 10:38:06.975: DEBUG/kent(17512): read failed, socket might closed or timeout, read ret: -1
That last line is in the "Catch" section of a try/catch...I'm just logging the error message.
Please note, there is about a 20 second gap between "trying to connect to device" and "failed to connect"
The jelly bean bluetooth stack is markedly different from the other versions.
This might help: http://wiresareobsolete.com/wordpress/2010/11/android-bluetooth-rfcomm/
In gist:
The UUID is a value that must point to a published service on your embedded device, it is not just randomly generated. The RFCOMM SPP connection you want to access has a specific UUID that it publishes to identify that service, and when you create a socket it must match the same UUID.
If you are targeting 4.0.3 device and above , use fetchUuidsWithSdp() and getUuids() to find all the published services and their associated UUID values. For backward compatibility read the article
I got the same error message after connecting the socket a second time. I simply checked if the socket is already connected.
if(!mmSocket.isConnected())
mmSocket.connect();
I was testing on Android 4.4.2 (Moto G).

Android bluetooth application process killed

I'm very new with programming for android. I have two classes : main and btmanager. When i try to test my app on phone, all I get is a information that procees was killed. What am I doing wrong ?
Code implementation :
Main class :
public class MainActivity extends Activity {
BluetoothAdapter bluetooth = BluetoothAdapter.getDefaultAdapter();
Btmanager manager;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (bluetooth == null)
{
Toast.makeText(this, "Bluetooth is not enabled on this device", Toast.LENGTH_LONG).show();
System.exit(0);
}
}
#Override
public void onStart()
{
super.onStart();
if (!bluetooth.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, 2);
}
manager.run();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
public void closeApp (View view)
{
System.exit(0);
}
}
Btmanager class :
public class Btmanager extends Thread {
private final BluetoothSocket mmSocket;
private final BluetoothDevice mmDevice;
public static final UUID myUUID = UUID.fromString("0x1101");
BluetoothAdapter bluetooth = BluetoothAdapter.getDefaultAdapter();
public Btmanager(BluetoothDevice device) {
// Use a temporary object that is later assigned to mmSocket,
// because mmSocket is final
BluetoothSocket tmp = null;
mmDevice = device;
// Get a BluetoothSocket to connect with the given BluetoothDevice
try {
// MY_UUID is the app's UUID string, also used by the server code
tmp = device.createRfcommSocketToServiceRecord(myUUID);
} catch (IOException e) { }
mmSocket = tmp;
}
public void run() {
// Cancel discovery because it will slow down the connection
bluetooth.cancelDiscovery();
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mmSocket.connect();
} catch (IOException connectException) {
// Unable to connect; close the socket and get out
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) { }
}
2 problems I see in your code:
You don't instantiate the Btmanager object, it is still null when you call run. (Will cause a NullPointerException - your app will crash).
You call the run method instead of the start method of the Btmanager. If you want the code in the run method to run in a new thread, you have to call start. Calling run will cause it to run in the same thread. This blocks your UI thread which may cause your app to crash, if it blocks for too long.
For test purporses, I don't use BTmanager class - in onStart() method I add new thread with connection implentation, but still without any results - app crash.
public void onStart()
{
super.onStart();
if (!bluetooth.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, 2);
}
new Thread(new Runnable()
{
public void run()
{
try {
//Create a Socket connection: need the server's UUID number of registered
socket = device.createRfcommSocketToServiceRecord(myUUID);
socket.connect();
Log.d("EF-BTBee", "Connectted");
}
catch (IOException e)
{
Log.e("EF-BTBee", "Error : ", e);
}
}
}).start();
}

Problem connecting to a bluetooth device

I'm trying to connect to a device with the code below... basically modified from the BTchat source. Everything seems to go fine, but the device is not responding to commands, my phone still says it's paired but not connected, and the device says it's not connected. That makes me pretty sure that it's indeed not connected, but no errors are happening.
Could I have the wrong UUID?
the log says:
04-30 18:51:10.116: DEBUG/BluetoothService(1228): uuid(application): 00001101-0000-1000-8000-00805f9b34fb 1
04-30 18:51:10.116: DEBUG/BluetoothService(1228): Making callback for 00001101-0000-1000-8000-00805f9b34fb with result 1
04-30 18:51:10.131: VERBOSE/BluetoothEventRedirector(31561): Received android.bleutooth.device.action.UUID
and my code is printing to the log that it's connected:
04-30 18:53:21.210: DEBUG/BTComm(1044): connect to: K4500-620963
04-30 18:53:21.225: INFO/BTComm(1044): BEGIN ConnectThread
04-30 18:53:26.272: DEBUG/BTComm(1044): connected to: K4500-620963
04-30 18:53:26.272: DEBUG/BTComm(1044): create ConnectedThread
04-30 18:53:26.280: DEBUG/BTComm(1044): setState() 0 -> 3
04-30 18:53:26.280: INFO/BTComm(1044): BEGIN ConnectedThread
Here is my whole code:
p
ublic class BTCom {
// Debugging
private static final String TAG = "BTComm";
private static final boolean D = true;
private static final UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
// Member fields
private final BluetoothAdapter adapter;
private final Handler handler;
private ConnectThread connectThread;
private ConnectedThread connectedThread;
private int state;
private Context context;
private BluetoothDevice BTDevice;
// Constants that indicate the current connection state
public static final int STATE_NONE = 0; // we're doing nothing
public static final int STATE_LISTEN = 1; // now listening for incoming connections
public static final int STATE_CONNECTING = 2; // now initiating an outgoing connection
public static final int STATE_CONNECTED = 3; // now connected to a remote device
public BTCom(Context context, Handler handler) {
adapter = BluetoothAdapter.getDefaultAdapter();
state = STATE_NONE;
this.handler = handler;
this.context = context;
}
private void checkBluetooth(){
// check if device supports bluetooth
if (adapter == null) {
Toast.makeText(context, "ERROR: This device does not support Bluetooth communication"
, Toast.LENGTH_LONG).show();
return;
}
// now make sure bluetooth is enabled
if (!adapter.isEnabled()) {
// if not, then prompt the user
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
context.startActivity(enableBtIntent);
}
}
public BluetoothDevice getBTDevice(){
Set<BluetoothDevice> pairedDevices = adapter.getBondedDevices();
BluetoothDevice foundDevice = null;
BTDevice = null;
// If there are paired devices
if (pairedDevices.size() > 0) {
// Loop through paired devices
for (BluetoothDevice device : pairedDevices) {
// check if the name fits the pattern K4xxx-xxxxxx
if (device.getName().matches("K4\\d\\d\\d-\\d\\d\\d\\d\\d\\d")){
foundDevice = device;
break;
}
}
if (foundDevice == null){ // if we didn't find any
Toast.makeText(context,
"ERROR: No paired BTDevice device was found, please pair a BTDevice device to continue"
, Toast.LENGTH_LONG).show();
return null;
}
}
return foundDevice; // found a BTDevice!
}
/**
* Set the current state of the chat connection
* #param state An integer defining the current connection state
*/
private synchronized void setState(int state) {
if (D) Log.d(TAG, "setState() " + this.state + " -> " + state);
this.state = state;
}
/**
* Start the ConnectThread to initiate a connection to a remote device.
* #param device The BluetoothDevice to connect
*/
public synchronized void connect(BluetoothDevice device) {
Log.d(TAG, "connect to: " + device.getName());
// Cancel any thread attempting to make a connection
if (connectThread != null) {connectThread.cancel(); connectThread = null;}
// Cancel any thread currently running a connection
if (connectedThread != null) {connectedThread.cancel(); connectedThread = null;}
// Start the thread to connect with the given device
connectThread = new ConnectThread(device);
connectThread.start();
}
/**
* Start the ConnectedThread to begin managing a Bluetooth connection
* #param socket The BluetoothSocket on which the connection was made
* #param device The BluetoothDevice that has been connected
*/
public synchronized void connected(BluetoothSocket socket, BluetoothDevice device) {
Log.d(TAG, "connected to: " + device.getName());
// Cancel the thread that completed the connection
if (connectThread != null) {connectThread.cancel(); connectThread = null;}
// Cancel any thread currently running a connection
if (connectedThread != null) {connectedThread.cancel(); connectedThread = null;}
// Start the thread to manage the connection and perform transmissions
connectedThread = new ConnectedThread(socket);
connectedThread.start();
setState(STATE_CONNECTED);
}
/**
* Stop all threads
*/
public synchronized void stop() {
if (D) Log.d(TAG, "stop");
if (connectThread != null) {
connectThread.cancel();
connectThread = null;
}
if (connectedThread != null) {
connectedThread.cancel();
connectedThread = null;
setState(STATE_NONE);
}
}
/**
* Write to the ConnectedThread in an unsynchronized manner
* #param out The bytes to write
* #see ConnectedThread#write(byte[])
*/
public void write(byte[] out) {
// Create temporary object
ConnectedThread r;
// Synchronize a copy of the ConnectedThread
synchronized (this) {
if (state != STATE_CONNECTED) return;
r = connectedThread;
}
// Perform the write unsynchronized
r.write(out);
}
private class ConnectThread extends Thread {
private final BluetoothSocket socket;
private final BluetoothDevice device;
public ConnectThread(BluetoothDevice device) {
this.device = device;
BluetoothSocket tmp = null;
// Get a BluetoothSocket for a connection with the
// given BluetoothDevice
try {
tmp = device.createRfcommSocketToServiceRecord(uuid);
} catch (IOException e) {
Log.e(TAG, "Socket create failed", e);
}
socket = tmp;
}
public void run() {
Log.i(TAG, "BEGIN ConnectThread");
// Make a connection to the BluetoothSocket
try {
// This is a blocking call and will only return on a
// successful connection or an exception
socket.connect();
} catch (IOException e) {
// Close the socket
try {
socket.close();
} catch (IOException e2) {
Log.e(TAG, "unable to close() socket during connection failure", e2);
}
return;
}
// Reset the ConnectThread because we're done
synchronized (BTCom.this) {
connectThread = null;
}
// Start the connected thread
connected(socket, this.device);
}
public void cancel() {
try {
socket.close();
} catch (IOException e) {
Log.e(TAG, "close() of connect socket failed", e);
}
}
}
/**
* This thread runs during a connection with a remote device.
* It handles all incoming and outgoing transmissions.
*/
private class ConnectedThread extends Thread {
private final BluetoothSocket socket;
private final InputStream inStream;
private final OutputStream outStream;
public ConnectedThread(BluetoothSocket socket) {
Log.d(TAG, "create ConnectedThread");
this.socket = 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);
}
inStream = tmpIn;
outStream = tmpOut;
}
public void run() {
Log.i(TAG, "BEGIN ConnectedThread");
byte[] buffer = new byte[1024];
int bytes;
// Keep listening to the InputStream while connected
while (true) {
try {
// Read from the InputStream
bytes = inStream.read(buffer);
// Send the obtained bytes to the UI Activity
handler.obtainMessage(KestrelTest.MESSAGE_READ, bytes, -1, buffer)
.sendToTarget();
} catch (IOException e) {
Log.e(TAG, "disconnected", e);
// Start the service over to restart listening mode
break;
}
}
}
/**
* Write to the connected OutStream.
* #param buffer The bytes to write
*/
public void write(byte[] buffer) {
try {
outStream.write(buffer);
Log.i(TAG, "Sending " + buffer.length + " bytes");
Log.i(TAG, "Sending: " + new String(buffer));
} catch (IOException e) {
Log.e(TAG, "Exception during write", e);
}
}
public void cancel() {
try {
socket.close();
} catch (IOException e) {
Log.e(TAG, "close() of connect socket failed", e);
}
}
}
}
I'm stumped as to why is't not connecting... Any ideas? Thanks!
What is the device you are connecting to? Perhaps the device requires certain profiles to be supported by the host (Android) system, like A2DP, BIP, BPP etc.
The Bluetooth Chat program creates a basic client-server connection, and does not require Bluetooth Profiles support.
For Bluetooth profile support to be implemented on Android, there is a project called “Sybase-iAnywhere-Blue-SDK-for-Android”, which replaces Android's version, and provides all interfaces into the underlying Bluetooth profiles and protocols. Using this, printing over bluetooth using your Android phone will be possible using the BPP profile provided by this SDK.
See links below for more details: link 1: http://www.sybase.com/detail?id=1064424 Link 2: http://www.sybase.com/products/allproductsa-z/mobiledevicesdks/bluetoothsdks
Application profiles supported by the iAnywhere Blue SDK for Android are said to include:
Handsfree (HFP)
Advanced Audio Distribution (A2DP)
A/V Remote Control (AVRCP)
File Transfer Protocol (FTP)
Object Push Protocol (OPP)
SIM Access (SAP)
Phone Book Access (PBAP)
Message Access Profile (MAP)
Human Interface (HID)
Basic Printing (BPP)
Basic Imaging (BIP)

Categories

Resources