Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to move Bluetooth activity into a Service

Tags:

The application gives the users 2 connection options, USB and Bluetooth. USB works fine. I have obtained sample codes for Bluetooth connection, however they are designed to work as activity. I tried to do it in a Service but failed.

BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); startService(new Intent(this, MyService.class));  <service android:enabled="true" android:name=".MyService" /> enter code here 

I need to establish Bluetooth communication with a device that is already paired and its MAC address is known. So I can skip discovery and pairing phases. The device I am trying to connect is always discoverable and awaiting connection. Is there a way to do this from a Service Class and keep that connection up through other activities?

I am using BluetoothChatService and DeviceListActivity

like image 1000
wervdon Avatar asked Feb 22 '13 13:02

wervdon


People also ask

What is Bluetooth API?

The Web Bluetooth API provides the ability to connect and interact with Bluetooth Low Energy peripherals.

How to integrate Bluetooth in Android?

In order to enable the Bluetooth of your device, call the intent with the following Bluetooth constant ACTION_REQUEST_ENABLE. Its syntax is. Intent turnOn = new Intent(BluetoothAdapter. ACTION_REQUEST_ENABLE); startActivityForResult(turnOn, 0);


1 Answers

I have written a Bluetooth services which runs in the background and can communicate to any Activity in the application using Messenger http://developer.android.com/guide/components/bound-services.html.

public class PrinterService extends Service { private BluetoothAdapter mBluetoothAdapter; public static final String BT_DEVICE = "btdevice"; public static final String SPP_UUID = "00001101-0000-1000-8000-00805F9B34FB"; 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 private ConnectThread mConnectThread; private static ConnectedThread mConnectedThread; // public mInHangler mHandler = new mInHangler(this); private static Handler mHandler = null; public static int mState = STATE_NONE; public static String deviceName; public Vector<Byte> packdata = new Vector<Byte>(2048); public static Device device = null;  @Override public void onCreate() {     Log.d("PrinterService", "Service started");     super.onCreate(); }  @Override public IBinder onBind(Intent intent) {     mHandler = ((MyAplication) getApplication()).getHandler();     return mBinder; }  public class LocalBinder extends Binder {     PrinterService getService() {         return PrinterService.this;     } }    private final IBinder mBinder = new LocalBinder();  @Override public int onStartCommand(Intent intent, int flags, int startId) {     Log.d("PrinterService", "Onstart Command");     mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();     if (mBluetoothAdapter != null) {         device = (Device) intent.getSerializableExtra(BT_DEVICE);         deviceName = device.getDeviceName();         String macAddress = device.getMacAddress();         if (macAddress != null && macAddress.length() > 0) {             connectToDevice(macAddress);         } else {             stopSelf();             return 0;         }     }     String stopservice = intent.getStringExtra("stopservice");     if (stopservice != null && stopservice.length() > 0) {         stop();     }     return START_STICKY; }  private synchronized void connectToDevice(String macAddress) {     BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(macAddress);     if (mState == STATE_CONNECTING) {         if (mConnectThread != null) {             mConnectThread.cancel();             mConnectThread = null;         }     }      // Cancel any thread currently running a connection     if (mConnectedThread != null) {         mConnectedThread.cancel();         mConnectedThread = null;     }     mConnectThread = new ConnectThread(device);     mConnectThread.start();     setState(STATE_CONNECTING); }  private void setState(int state) {     PrinterService.mState = state;     if (mHandler != null) {         mHandler.obtainMessage(AbstractActivity.MESSAGE_STATE_CHANGE, state, -1).sendToTarget();     } }  public synchronized void stop() {     setState(STATE_NONE);     if (mConnectThread != null) {         mConnectThread.cancel();         mConnectThread = null;     }      if (mConnectedThread != null) {         mConnectedThread.cancel();         mConnectedThread = null;     }     if (mBluetoothAdapter != null) {         mBluetoothAdapter.cancelDiscovery();     }     stopSelf(); }  @Override public boolean stopService(Intent name) {     setState(STATE_NONE);     if (mConnectThread != null) {         mConnectThread.cancel();         mConnectThread = null;     }      if (mConnectedThread != null) {         mConnectedThread.cancel();         mConnectedThread = null;     }     mBluetoothAdapter.cancelDiscovery();     return super.stopService(name); }  private void connectionFailed() {     PrinterService.this.stop();     Message msg = mHandler.obtainMessage(AbstractActivity.MESSAGE_TOAST);     Bundle bundle = new Bundle();     bundle.putString(AbstractActivity.TOAST, getString(R.string.error_connect_failed));     msg.setData(bundle);     mHandler.sendMessage(msg); }  private void connectionLost() {     PrinterService.this.stop();     Message msg = mHandler.obtainMessage(AbstractActivity.MESSAGE_TOAST);     Bundle bundle = new Bundle();     bundle.putString(AbstractActivity.TOAST, getString(R.string.error_connect_lost));     msg.setData(bundle);     mHandler.sendMessage(msg); }  private static Object obj = new Object();  public static void write(byte[] out) {     // Create temporary object     ConnectedThread r;     // Synchronize a copy of the ConnectedThread     synchronized (obj) {         if (mState != STATE_CONNECTED)             return;         r = mConnectedThread;     }     // Perform the write unsynchronized     r.write(out); }  private synchronized void connected(BluetoothSocket mmSocket, BluetoothDevice mmDevice) {     // Cancel the thread that completed the connection     if (mConnectThread != null) {         mConnectThread.cancel();         mConnectThread = null;     }      // Cancel any thread currently running a connection     if (mConnectedThread != null) {         mConnectedThread.cancel();         mConnectedThread = null;     }      mConnectedThread = new ConnectedThread(mmSocket);     mConnectedThread.start();      // Message msg =     // mHandler.obtainMessage(AbstractActivity.MESSAGE_DEVICE_NAME);     // Bundle bundle = new Bundle();     // bundle.putString(AbstractActivity.DEVICE_NAME, "p25");     // msg.setData(bundle);     // mHandler.sendMessage(msg);     setState(STATE_CONNECTED);  }  private class ConnectThread extends Thread {     private final BluetoothSocket mmSocket;     private final BluetoothDevice mmDevice;      public ConnectThread(BluetoothDevice device) {         this.mmDevice = device;         BluetoothSocket tmp = null;         try {             tmp = device.createRfcommSocketToServiceRecord(UUID.fromString(SPP_UUID));         } catch (IOException e) {             e.printStackTrace();         }         mmSocket = tmp;     }      @Override     public void run() {         setName("ConnectThread");         mBluetoothAdapter.cancelDiscovery();         try {             mmSocket.connect();         } catch (IOException e) {             try {                 mmSocket.close();             } catch (IOException e1) {                 e1.printStackTrace();             }             connectionFailed();             return;          }         synchronized (PrinterService.this) {             mConnectThread = null;         }         connected(mmSocket, mmDevice);     }      public void cancel() {         try {             mmSocket.close();         } catch (IOException e) {             Log.e("PrinterService", "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) {         mmSocket = socket;         InputStream tmpIn = null;         OutputStream tmpOut = null;         try {             tmpIn = socket.getInputStream();             tmpOut = socket.getOutputStream();         } catch (IOException e) {             Log.e("Printer Service", "temp sockets not created", e);         }         mmInStream = tmpIn;         mmOutStream = tmpOut;     }      @Override     public void run() {         while (true) {             try {                 if (!encodeData(mmInStream)) {                     mState = STATE_NONE;                     connectionLost();                     break;                 } else {                 }                 // mHandler.obtainMessage(AbstractActivity.MESSAGE_READ,                 // bytes, -1, buffer).sendToTarget();             } catch (Exception e) {                 e.printStackTrace();                 connectionLost();                 PrinterService.this.stop();                 break;             }          }     }      private byte[] btBuff;       public void write(byte[] buffer) {         try {             mmOutStream.write(buffer);              // Share the sent message back to the UI Activity             mHandler.obtainMessage(AbstractActivity.MESSAGE_WRITE, buffer.length, -1, buffer).sendToTarget();         } catch (IOException e) {             Log.e("PrinterService", "Exception during write", e);         }     }      public void cancel() {         try {             mmSocket.close();          } catch (IOException e) {             Log.e("PrinterService", "close() of connect socket failed", e);         }     }  }  public void trace(String msg) {     Log.d("AbstractActivity", msg);     toast(msg); }  public void toast(String msg) {     Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show(); }  @Override public void onDestroy() {     stop();     Log.d("Printer Service", "Destroyed");     super.onDestroy(); }  private void sendMsg(int flag) {     Message msg = new Message();     msg.what = flag;     handler.sendMessage(msg); }  private Handler handler = new Handler() {     @Override     public void handleMessage(Message msg) {//         if (!Thread.currentThread().isInterrupted()) {             switch (msg.what) {             case 3:                  break;              case 4:                  break;             case 5:                 break;              case -1:                 break;             }         }         super.handleMessage(msg);     }  }; } 

UPDATE

you need to use Handler in your MyApplication Class

Handler.Callback realCallback = null; Handler handler = new Handler() {     public void handleMessage(android.os.Message msg) {         if (realCallback != null) {             realCallback.handleMessage(msg);         }     }; }; public Handler getHandler() {     return handler; } public void setCallBack(Handler.Callback callback) {     this.realCallback = callback; } 
like image 173
Kapil Vats Avatar answered Oct 19 '22 08:10

Kapil Vats