Improved handling for bluetooth enable/disable.

This commit is contained in:
Felix Ableitner 2014-10-25 22:17:35 +03:00
parent e20804e916
commit b1a55a3d4d
3 changed files with 49 additions and 21 deletions

View file

@ -43,7 +43,7 @@ class ChatService extends Service {
private var ListenThread: ListenThread = _ private var ListenThread: ListenThread = _
private var isDestroyed = false private var cancelDiscovery = false
private val MainHandler: Handler = new Handler() private val MainHandler: Handler = new Handler()
@ -55,14 +55,11 @@ class ChatService extends Service {
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter() bluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
var filter: IntentFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND) registerReceiver(DeviceDiscoveredReceiver, new IntentFilter(BluetoothDevice.ACTION_FOUND))
registerReceiver(mReceiver, filter) registerReceiver(BluetoothStateReceiver, new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED))
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED) if (bluetoothAdapter.isEnabled) {
registerReceiver(mReceiver, filter) startBluetoothConnections()
Log.i(Tag, "Discovery started") }
discover()
ListenThread = new ListenThread(getString(R.string.app_name), bluetoothAdapter, onConnected)
ListenThread.start()
} }
override def onStartCommand(intent: Intent, flags: Int, startId: Int): Int = { override def onStartCommand(intent: Intent, flags: Int, startId: Int): Int = {
@ -76,15 +73,16 @@ class ChatService extends Service {
override def onDestroy(): Unit = { override def onDestroy(): Unit = {
super.onDestroy() super.onDestroy()
ListenThread.cancel() ListenThread.cancel()
isDestroyed = true cancelDiscovery = true
unregisterReceiver(mReceiver) unregisterReceiver(DeviceDiscoveredReceiver)
unregisterReceiver(BluetoothStateReceiver)
} }
/** /**
* Stops any current discovery, then starts a new one, recursively until service is stopped. * Stops any current discovery, then starts a new one, recursively until service is stopped.
*/ */
def discover(): Unit = { def discover(): Unit = {
if (isDestroyed) if (cancelDiscovery)
return return
if (!bluetoothAdapter.isDiscovering()) { if (!bluetoothAdapter.isDiscovering()) {
@ -100,19 +98,47 @@ class ChatService extends Service {
/** /**
* Receives newly discovered devices and connects to them. * Receives newly discovered devices and connects to them.
*/ */
private final def mReceiver: BroadcastReceiver = new BroadcastReceiver() { private val DeviceDiscoveredReceiver: BroadcastReceiver = new BroadcastReceiver() {
override def onReceive(context: Context, intent: Intent) { override def onReceive(context: Context, intent: Intent) {
intent.getAction() match {
case BluetoothDevice.ACTION_FOUND =>
val device: Device = val device: Device =
new Device(intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE), false) new Device(intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE), false)
devices = devices + (device.id -> device) devices = devices + (device.id -> device)
new ConnectThread(device, onConnected).start() new ConnectThread(device, onConnected).start()
}
}
/**
* Starts or stops listening and discovery based on bluetooth state.
*/
private val BluetoothStateReceiver: BroadcastReceiver = new BroadcastReceiver {
override def onReceive(context: Context, intent: Intent): Unit = {
intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1) match {
case BluetoothAdapter.STATE_ON =>
startBluetoothConnections()
case BluetoothAdapter.STATE_TURNING_OFF =>
connections.foreach(d => d._2.close())
case BluetoothAdapter.STATE_OFF =>
Log.d(Tag, "Bluetooth disabled, stopping listening and discovery")
if (ListenThread != null) {
ListenThread.cancel()
}
cancelDiscovery = true
case _ => case _ =>
} }
} }
} }
/**
* Starts to listen for incoming connections, and starts regular active discovery.
*/
private def startBluetoothConnections(): Unit = {
Log.i(Tag, "Listening and discovery started")
cancelDiscovery = false
discover()
ListenThread = new ListenThread(getString(R.string.app_name), bluetoothAdapter, onConnected)
ListenThread.start()
}
/** /**
* Registers a listener that is called whenever a new device is connected. * Registers a listener that is called whenever a new device is connected.
*/ */

View file

@ -32,7 +32,9 @@ class ListenThread(name: String, adapter: BluetoothAdapter,
socket = ServerSocket.accept() socket = ServerSocket.accept()
} catch { } catch {
case e: IOException => case e: IOException =>
Log.e(Tag, "Failed to accept new connection", e) // This happens if Bluetooth is disabled manually.
Log.w(Tag, "Failed to accept new connection", e)
return
} }
val device: Device = new Device(socket.getRemoteDevice, true) val device: Device = new Device(socket.getRemoteDevice, true)

View file

@ -62,7 +62,7 @@ class TransferThread(device: Device, socket: BluetoothSocket,
} }
} }
def cancel(): Unit = { def close(): Unit = {
try { try {
socket.close() socket.close()
} catch { } catch {