How to move Bluetooth activity into a Service

匿名 (未验证) 提交于 2019-12-03 02:08:02

问题:

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

回答1:

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; } 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!