Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package com.moonlightcheese.btsrv;
- import java.lang.*;
- import java.io.*;
- import java.util.*;
- import android.app.*;
- import android.os.*;
- import android.bluetooth.*;
- import android.content.*;
- import android.util.Log;
- //service that dies when completely unbound
- public class ScannerService extends Service
- {
- //instance of the Binder we define in this Service
- private final IBinder mBinder = new ScannerBinder();
- //local variable needed for bluetooth connectivity
- BluetoothAdapter btAdapter; //the local Bluetooth adapter
- BluetoothDevice mScanner; //the scanner we are connecting to
- boolean isDiscoveringLocal = false; //a boolean value that we set/unset to tell if this service initiated discovery, this avoids listing devices if another application initiated the discovery
- List<BluetoothDevice> scannerList; //the list of bluetooth scanners found during discovery
- public static final UUID BLUETOOTH_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); //the UUID. magic.
- ReconnectThread mRCT;
- //message ids and constants
- public final static int MESSAGE_BT_READ = 21;
- public final static int MESSAGE_SOCKET_ERROR = 22;
- public final static int REQUEST_ENABLE_BT = 10;
- public final static String ACTION_SELECT_SCANNER = "com.conceptualsystems.scannerservice.selectscanner";
- public final static String ACTION_READ_SCANNER = "com.conceptualsystems.scannerservice.readscanner";
- public final static String ACTION_REQUEST_RECONNECT = "com.conceptualsystems.scannerservice.request_reconnect";
- public final static String ACTION_RECONNECT = "com.conceptualsystems.scannerservice.reconnect";
- public final static String LOG_TAG = "btsrv - ScannerService.java";
- // Class that extends Binder
- ////////////////////////////
- public class ScannerBinder extends Binder {
- ScannerService getService () {
- //return this instance
- return ScannerService.this;
- }
- }
- @Override
- public IBinder onBind(Intent intent) {
- return mBinder;
- }
- @Override
- public void onCreate()
- {
- super.onCreate();
- scannerList = new ArrayList<BluetoothDevice>();
- }
- @Override
- public void onDestroy() {
- super.onDestroy();
- unregisterReceiver(mReceiver);
- }
- private class ReconnectThread extends Thread {
- //Members
- BluetoothDevice mDevice;
- BluetoothConnectThread mBCT;
- //Constructor
- public ReconnectThread(BluetoothDevice device) {
- this.mDevice=device;
- }
- public void reconnect() {
- try {
- mBCT = new BluetoothConnectThread(mScanner, btHandler);
- mBCT.start();
- } catch(Exception e) {
- Log.i(LOG_TAG, e.getMessage());
- }
- }
- public void run() {
- //try to reconnect one time
- this.reconnect();
- //loop until an interrupt has been received
- while(true) {
- try {
- Thread.sleep(1000);
- } catch(InterruptedException e) {
- return;
- }
- }
- }
- }
- // Create a BroadcastReceiver for ACTION_FOUND, ACTION_STATE_CHANGED, ACTION_DISCOVERY_FINISHED
- private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (BluetoothDevice.ACTION_FOUND.equals(action) && isDiscoveringLocal) {
- BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
- boolean newEntry = true;
- Log.i(LOG_TAG, "found device: "+device.getName());
- for(BluetoothDevice storedDevice : scannerList) {
- if(device.getAddress().equals(storedDevice.getAddress())) {
- newEntry = false;
- }
- }
- if(newEntry) {
- scannerList.add(device);
- }
- }
- if(BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
- isDiscoveringLocal = false;
- Log.i(LOG_TAG, "discovery finished.");
- //TODO: broadcast an intent to interested applications so they can choose the device to use
- if(!scannerList.isEmpty()) {
- Intent i = new Intent(ACTION_SELECT_SCANNER);
- List<String> scannerLabels = new ArrayList<String>(scannerList.size());
- for(BluetoothDevice device : scannerList) {
- scannerLabels.add(device.getName()+"\n"+device.getBluetoothClass().toString());
- }
- i.putExtra("scannerArray", scannerLabels.toArray(new String[1]));
- sendBroadcast(i);
- Log.i(LOG_TAG, "sent broadcast with array elements: " + scannerList.toString());
- Log.i(LOG_TAG, "size of scannerList: " + scannerList.size());
- Log.i(LOG_TAG, "size of scannerLabels: " + scannerLabels.size());
- } else {
- Intent i = new Intent(ACTION_SELECT_SCANNER);
- sendBroadcast(i);
- Log.i(LOG_TAG, "sent broadcast with empty intent (no extras)");
- }
- }
- if(BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
- if(BluetoothAdapter.STATE_ON == btAdapter.getState()) {
- initialize(); //make a call to initialize when the adapter turns on to perform the discovery process
- }
- }
- ////////////////////////////
- //TODO: may need to rebond sometimes. initiate rebonding if device becomes unpaired here.
- if(BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {
- int bondState = -1;
- int oldBondState = -1;
- BluetoothDevice device = null;
- try {
- bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.BOND_NONE);
- oldBondState = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, BluetoothDevice.BOND_NONE);
- device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
- } catch (Exception e) {
- //
- }
- Log.i(LOG_TAG, "bond state changed.");
- Log.i(LOG_TAG, "device name: "+device.getName());
- Log.i(LOG_TAG, "device addr: "+device.getAddress());
- switch(bondState) {
- case BluetoothDevice.BOND_NONE:
- Log.i(LOG_TAG, "now unbonded");
- break;
- case BluetoothDevice.BOND_BONDED:
- Log.i(LOG_TAG, "now bonded");
- break;
- case BluetoothDevice.BOND_BONDING:
- Log.i(LOG_TAG, "now bonding");
- break;
- }
- switch(oldBondState) {
- case BluetoothDevice.BOND_NONE:
- Log.i(LOG_TAG, "was unbonded");
- break;
- case BluetoothDevice.BOND_BONDED:
- Log.i(LOG_TAG, "was bonded");
- break;
- case BluetoothDevice.BOND_BONDING:
- Log.i(LOG_TAG, "was bonding");
- break;
- }
- }
- if(BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {
- Log.i(LOG_TAG, "connected.");
- if(mRCT!=null && mRCT.getState() != Thread.State.NEW) {
- mRCT.destroy();
- }
- }
- if(BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) {
- Log.i(LOG_TAG, "disconnected.");
- //TODO: check the pref stored device in addition to the local, last used device in memory
- Intent reconnectIntent = new Intent();
- reconnectIntent.setAction(ScannerService.ACTION_REQUEST_RECONNECT);
- sendBroadcast(reconnectIntent);
- }
- if(BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED.equals(action)) {
- Log.i(LOG_TAG, "disconnect requested.");
- }
- if(ScannerService.ACTION_RECONNECT.equals(action)) {
- if(mScanner!=null) {
- mRCT = new ReconnectThread(mScanner);
- mRCT.start();
- }
- }
- }
- };
- public void selectBluetoothDevice(int selection) {
- //
- if(scannerList.isEmpty()) {
- //TODO: NullPointerException needs to go here
- Log.i(LOG_TAG+":ssbt", "NullPointerException?");
- } else {
- if(selection > scannerList.size()-1 || selection < 0) {
- //TODO: IllegalArgumentException needs to go here
- Log.i(LOG_TAG+"ssbt", "IllegalArgumentException");
- } else {
- //argument should be good, use this selection to select the BluetoothDevice to connect to
- mScanner = scannerList.get(selection);
- scannerList.clear(); //clear the list after selection
- BluetoothConnectThread bct = new BluetoothConnectThread(mScanner, btHandler);
- bct.start();
- }
- }
- }
- public boolean initialize() {
- btAdapter = BluetoothAdapter.getDefaultAdapter();
- if(btAdapter == null) {
- //no bluetooth adapter available. do not run bluetooth code.
- return false;
- } else {
- // Register the BroadcastReceiver
- IntentFilter filter = new IntentFilter();
- filter.addAction(BluetoothDevice.ACTION_FOUND);
- filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
- filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
- filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
- filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
- filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
- filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED);
- filter.addAction(ScannerService.ACTION_RECONNECT);
- //TODO: unregister receiver onDestroy()
- registerReceiver(mReceiver, filter);
- if(!btAdapter.isEnabled()) { //enable bluetooth if disabled.
- btAdapter.enable();
- return false;
- } else {
- isDiscoveringLocal = true;
- scannerList.clear();
- Log.i(LOG_TAG, "starting discovery process...");
- btAdapter.startDiscovery();
- }
- }
- return true;
- }
- private class BluetoothServerThread extends Thread {
- private BluetoothServerSocket btServerSocket;
- public BluetoothServerThread() {
- BluetoothServerSocket tmp = null;
- try {
- tmp = btAdapter.listenUsingRfcommWithServiceRecord("smsmobile", BLUETOOTH_UUID);
- } catch (IOException e) {}
- btServerSocket = tmp;
- }
- public void run() {
- BluetoothSocket socket = null;
- while(true) {
- try {
- socket = btServerSocket.accept();
- } catch (IOException e) {
- break;
- }
- if(socket != null) {
- BluetoothSocketThread socketThread = new BluetoothSocketThread(socket, btHandler);
- socketThread.start();
- try {
- btServerSocket.close();
- } catch (IOException e) {
- Log.e(LOG_TAG+":bst", "could not close the server socket? i mean srsly, wtf?");
- }
- break;
- }
- }
- }
- public void cancel() {
- try {
- btServerSocket.close();
- } catch (IOException e) {}
- }
- };
- private class BluetoothConnectThread extends Thread {
- private BluetoothSocket mSocket;
- private BluetoothDevice mDevice;
- private Handler mHandler;
- public BluetoothConnectThread(BluetoothDevice device, Handler handler) {
- BluetoothSocket tmp = null;
- mDevice = device;
- mHandler = handler;
- try {
- tmp = device.createRfcommSocketToServiceRecord(BLUETOOTH_UUID);
- } catch (IOException e) {
- Log.e(LOG_TAG, "could not create rfcomm socket as client");
- }
- mSocket = tmp;
- }
- public synchronized void run() {
- btAdapter.cancelDiscovery();
- BluetoothSocketThread btsThread = null;
- try {
- mSocket.connect();
- btsThread = new BluetoothSocketThread(mSocket, btHandler);
- btsThread.start();
- } catch (Exception e) {
- if(mSocket == null) {
- Log.e(LOG_TAG, "device socket was never initiated, socket is null");
- }
- Log.e(LOG_TAG, "connection failed");
- Log.e(LOG_TAG, e.toString());
- Message m = Message.obtain(mHandler, MESSAGE_SOCKET_ERROR);
- mHandler.sendMessage(m);
- }
- }
- public void cancel() {
- try {
- mSocket.close();
- } catch(IOException e) {
- Log.i(LOG_TAG, "client connection closed");
- }
- }
- };
- private class BluetoothSocketThread extends Thread {
- private final BluetoothSocket mSocket;
- private final LineNumberReader mInStream;
- private final OutputStream mOutStream;
- private final Handler mHandler;
- public BluetoothSocketThread(BluetoothSocket socket, Handler handler) {
- mSocket = socket;
- LineNumberReader tmpIn = null;
- OutputStream tmpOut = null;
- mHandler = handler;
- try {
- tmpIn = new LineNumberReader(new InputStreamReader(socket.getInputStream()));
- tmpOut = socket.getOutputStream();
- } catch(IOException e) {
- Log.e(LOG_TAG, "could not capture input/output stream");
- //Message m = Message.obtain(mHandler, MESSAGE_SOCKET_ERROR);
- //mHandler.sendMessage(m);
- }
- mInStream = tmpIn;
- mOutStream = tmpOut;
- }
- public void run() {
- //Message m = Message.obtain(mHandler, MESSAGE_SOCKET_SEND, mSocket);
- //mHandler.sendMessage(m);
- Log.i(LOG_TAG, "socket successfully connected... starting listener loop");
- while(true) {
- try {
- Message m = Message.obtain(mHandler, MESSAGE_BT_READ, mInStream.readLine());
- mHandler.sendMessage(m);
- } catch(IOException e) {
- Log.e(LOG_TAG, "read or handling error");
- break;
- }
- }
- }
- public void write(byte[] bytes) {
- try {
- mOutStream.write(bytes);
- } catch (IOException e) {
- Log.e(LOG_TAG+":bst", "write error");
- }
- }
- public void cancel() {
- try {
- mSocket.close();
- } catch (IOException e) { }
- }
- };
- private final Handler btHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- switch(msg.what) {
- case MESSAGE_BT_READ:
- //a read was requested
- ////broadcast an intent containing the string read from the scanner
- Intent i = new Intent(ACTION_READ_SCANNER);
- i.putExtra("scannerRead", (String)msg.obj);
- sendBroadcast(i);
- //Log.i(LOG_TAG+":bth", "read a message" + (String)msg.obj);
- break;
- case MESSAGE_SOCKET_ERROR:
- //error. if the reconnect thread is up and running, attempt a reconnect.
- Log.e(LOG_TAG, "a socket error occurred when trying to connect");
- if(mRCT!=null) {
- Log.i(LOG_TAG, "attempting reconnect...");
- mRCT.reconnect();
- }
- break;
- }
- }
- };
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement