Delete BluetoothService.kt

master
Zhengyu Peng 2 years ago
parent 754c77fc3d
commit a2b5112b7b

@ -1,525 +0,0 @@
package com.rookiedev.hexapod.network
import android.annotation.SuppressLint
import android.bluetooth.*
import android.content.Context
import android.os.Bundle
import android.os.Handler
import java.io.IOException
import java.io.InputStream
import java.io.OutputStream
import java.util.*
/**
* This class does all the work for setting up and managing Bluetooth
* connections with other devices. It has a thread that listens for
* incoming connections, a thread for connecting with a device, and a
* thread for performing data transmissions when connected.
*/
class BluetoothService(context: Context?) {
// Member fields
private var bluetoothManager: BluetoothManager? = null
private var mContext: Context? = null
// private val mAdapter: BluetoothAdapter
// private val mHandler: Handler
private var mSecureAcceptThread: AcceptThread? = null
private var mInsecureAcceptThread: AcceptThread? = null
private var mConnectThread: ConnectThread? = null
private var mConnectedThread: ConnectedThread? = null
/**
* Return the current connection state.
*/
@get:Synchronized
var mState: Int
private set
private var mNewState: Int
/**
* Update UI title according to the current state of the chat connection
*/
@Synchronized
private fun updateUserInterfaceTitle() {
mState = mState
// Log.d(TAG, "updateUserInterfaceTitle() " + mNewState + " -> " + state)
mNewState = mState
// Give the new state to the Handler so the UI Activity can update
// mHandler.obtainMessage(Constants.MESSAGE_STATE_CHANGE, mNewState, -1).sendToTarget()
}
/**
* Start the chat service. Specifically start AcceptThread to begin a
* session in listening (server) mode. Called by the Activity onResume()
*/
@Synchronized
fun start() {
// Log.d(TAG, "start")
// Cancel any thread attempting to make a connection
if (mConnectThread != null) {
mConnectThread!!.cancel()
mConnectThread = null
}
// Cancel any thread currently running a connection
if (mConnectedThread != null) {
mConnectedThread!!.cancel()
mConnectedThread = null
}
// Start the thread to listen on a BluetoothServerSocket
if (mSecureAcceptThread == null) {
mSecureAcceptThread = AcceptThread(true)
mSecureAcceptThread!!.start()
}
if (mInsecureAcceptThread == null) {
mInsecureAcceptThread = AcceptThread(false)
mInsecureAcceptThread!!.start()
}
// Update UI title
updateUserInterfaceTitle()
}
/**
* Start the ConnectThread to initiate a connection to a remote device.
*
* @param device The BluetoothDevice to connect
* @param secure Socket Security type - Secure (true) , Insecure (false)
*/
@Synchronized
fun connect(device: BluetoothDevice, secure: Boolean) {
// Log.d(TAG, "connect to: $device")
// Cancel any thread attempting to make a connection
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
}
// Start the thread to connect with the given device
mConnectThread = ConnectThread(device, secure)
mConnectThread!!.start()
// Update UI title
updateUserInterfaceTitle()
}
/**
* 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
*/
@SuppressLint("MissingPermission")
@Synchronized
fun connected(socket: BluetoothSocket?, device: BluetoothDevice, socketType: String) {
// Log.d(TAG, "connected, Socket Type:$socketType")
// 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
}
// Cancel the accept thread because we only want to connect to one device
if (mSecureAcceptThread != null) {
mSecureAcceptThread!!.cancel()
mSecureAcceptThread = null
}
if (mInsecureAcceptThread != null) {
mInsecureAcceptThread!!.cancel()
mInsecureAcceptThread = null
}
// Start the thread to manage the connection and perform transmissions
mConnectedThread = ConnectedThread(socket, socketType)
mConnectedThread!!.start()
// Send the name of the connected device back to the UI Activity
// val msg = mHandler.obtainMessage(Constants.MESSAGE_DEVICE_NAME)
val bundle = Bundle()
bundle.putString(Constants.DEVICE_NAME, device.name)
// msg.data = bundle
// mHandler.sendMessage(msg)
// Update UI title
updateUserInterfaceTitle()
}
/**
* Stop all threads
*/
@Synchronized
fun stop() {
// Log.d(TAG, "stop")
if (mConnectThread != null) {
mConnectThread!!.cancel()
mConnectThread = null
}
if (mConnectedThread != null) {
mConnectedThread!!.cancel()
mConnectedThread = null
}
if (mSecureAcceptThread != null) {
mSecureAcceptThread!!.cancel()
mSecureAcceptThread = null
}
if (mInsecureAcceptThread != null) {
mInsecureAcceptThread!!.cancel()
mInsecureAcceptThread = null
}
mState = STATE_NONE
// Update UI title
updateUserInterfaceTitle()
}
/**
* Write to the ConnectedThread in an unsynchronized manner
*
* @param out The bytes to write
* @see ConnectedThread.write
*/
fun write(out: ByteArray?) {
// Create temporary object
var r: ConnectedThread?
// Synchronize a copy of the ConnectedThread
synchronized(this) {
if (mState != STATE_CONNECTED) return
r = mConnectedThread
}
// Perform the write unsynchronized
r!!.write(out)
}
/**
* Indicate that the connection attempt failed and notify the UI Activity.
*/
private fun connectionFailed() {
// Send a failure message back to the Activity
// val msg = mHandler.obtainMessage(Constants.MESSAGE_TOAST)
val bundle = Bundle()
bundle.putString(Constants.TOAST, "Unable to connect device")
// msg.data = bundle
// mHandler.sendMessage(msg)
mState = STATE_NONE
// Update UI title
updateUserInterfaceTitle()
// Start the service over to restart listening mode
start()
}
/**
* Indicate that the connection was lost and notify the UI Activity.
*/
private fun connectionLost() {
// Send a failure message back to the Activity
// val msg = mHandler.obtainMessage(Constants.MESSAGE_TOAST)
val bundle = Bundle()
bundle.putString(Constants.TOAST, "Device connection was lost")
// msg.data = bundle
// mHandler.sendMessage(msg)
mState = STATE_NONE
// Update UI title
updateUserInterfaceTitle()
// Start the service over to restart listening mode
start()
}
/**
* This thread runs while listening for incoming connections. It behaves
* like a server-side client. It runs until a connection is accepted
* (or until cancelled).
*/
@SuppressLint("MissingPermission")
private inner class AcceptThread(secure: Boolean) : Thread() {
// The local server socket
private val mmServerSocket: BluetoothServerSocket?
private val mSocketType: String
override fun run() {
// Log.d(
// TAG, "Socket Type: " + mSocketType +
// "BEGIN mAcceptThread" + this
// )
name = "AcceptThread$mSocketType"
var socket: BluetoothSocket?
// Listen to the server socket if we're not connected
while (mState != STATE_CONNECTED) {
socket = try {
// This is a blocking call and will only return on a
// successful connection or an exception
mmServerSocket!!.accept()
} catch (e: IOException) {
// Log.e(TAG, "Socket Type: " + mSocketType + "accept() failed", e)
break
}
// If a connection was accepted
if (socket != null) {
synchronized(this@BluetoothService) {
when (mState) {
STATE_LISTEN, STATE_CONNECTING -> // Situation normal. Start the connected thread.
connected(
socket, socket.remoteDevice,
mSocketType
)
STATE_NONE, STATE_CONNECTED -> // Either not ready or already connected. Terminate new socket.
try {
socket.close()
} catch (e: IOException) {
// Log.e(
// TAG,
// "Could not close unwanted socket",
// e
// )
}
}
}
}
}
// Log.i(
// TAG,
// "END mAcceptThread, socket Type: $mSocketType"
// )
}
fun cancel() {
// Log.d(TAG, "Socket Type" + mSocketType + "cancel " + this)
try {
mmServerSocket!!.close()
} catch (e: IOException) {
// Log.e(TAG, "Socket Type" + mSocketType + "close() of server failed", e)
}
}
init {
var tmp: BluetoothServerSocket? = null
mSocketType = if (secure) "Secure" else "Insecure"
// Create a new listening server socket
try {
tmp = if (secure) {
bluetoothManager!!.adapter.listenUsingRfcommWithServiceRecord(
NAME_SECURE,
MY_UUID_SECURE
)
} else {
bluetoothManager!!.adapter.listenUsingInsecureRfcommWithServiceRecord(
NAME_INSECURE, MY_UUID_INSECURE
)
}
} catch (e: IOException) {
// Log.e(TAG, "Socket Type: " + mSocketType + "listen() failed", e)
}
mmServerSocket = tmp
mState = STATE_LISTEN
}
}
/**
* This thread runs while attempting to make an outgoing connection
* with a device. It runs straight through; the connection either
* succeeds or fails.
*/
@SuppressLint("MissingPermission")
private inner class ConnectThread(private val mmDevice: BluetoothDevice, secure: Boolean) :
Thread() {
private val mmSocket: BluetoothSocket?
private val mSocketType: String
override fun run() {
// Log.i(
// TAG,
// "BEGIN mConnectThread SocketType:$mSocketType"
// )
name = "ConnectThread$mSocketType"
// Always cancel discovery because it will slow down a connection
bluetoothManager!!.adapter.cancelDiscovery()
// Make a connection to the BluetoothSocket
try {
// This is a blocking call and will only return on a
// successful connection or an exception
mmSocket!!.connect()
} catch (e: IOException) {
// Close the socket
try {
mmSocket!!.close()
} catch (e2: IOException) {
// Log.e(
// TAG, "unable to close() " + mSocketType +
// " socket during connection failure", e2
// )
}
connectionFailed()
return
}
// Reset the ConnectThread because we're done
synchronized(this@BluetoothService) { mConnectThread = null }
// Start the connected thread
connected(mmSocket, mmDevice, mSocketType)
}
fun cancel() {
try {
mmSocket!!.close()
} catch (e: IOException) {
// Log.e(
// TAG,
// "close() of connect $mSocketType socket failed", e
// )
}
}
init {
var tmp: BluetoothSocket? = null
mSocketType = if (secure) "Secure" else "Insecure"
// Get a BluetoothSocket for a connection with the
// given BluetoothDevice
try {
tmp = if (secure) {
mmDevice.createRfcommSocketToServiceRecord(
MY_UUID_SECURE
)
} else {
mmDevice.createInsecureRfcommSocketToServiceRecord(
MY_UUID_INSECURE
)
}
} catch (e: IOException) {
// Log.e(TAG, "Socket Type: " + mSocketType + "create() failed", e)
}
mmSocket = tmp
mState = STATE_CONNECTING
}
}
/**
* This thread runs during a connection with a remote device.
* It handles all incoming and outgoing transmissions.
*/
private inner class ConnectedThread(socket: BluetoothSocket?, socketType: String) :
Thread() {
private val mmSocket: BluetoothSocket? = socket
private val mmInStream: InputStream?
private val mmOutStream: OutputStream?
override fun run() {
// Log.i(TAG, "BEGIN mConnectedThread")
val buffer = ByteArray(1024)
var bytes: Int
// Keep listening to the InputStream while connected
while (mState == STATE_CONNECTED) {
try {
// Read from the InputStream
bytes = mmInStream!!.read(buffer)
// Send the obtained bytes to the UI Activity
// mHandler.obtainMessage(Constants.MESSAGE_READ, bytes, -1, buffer)
// .sendToTarget()
} catch (e: IOException) {
// Log.e(TAG, "disconnected", e)
connectionLost()
break
}
}
}
/**
* Write to the connected OutStream.
*
* @param buffer The bytes to write
*/
fun write(buffer: ByteArray?) {
try {
mmOutStream!!.write(buffer)
// Share the sent message back to the UI Activity
// mHandler.obtainMessage(Constants.MESSAGE_WRITE, -1, -1, buffer)
// .sendToTarget()
} catch (e: IOException) {
// Log.e(TAG, "Exception during write", e)
}
}
fun cancel() {
try {
mmSocket!!.close()
} catch (e: IOException) {
// Log.e(TAG, "close() of connect socket failed", e)
}
}
init {
// Log.d(TAG, "create ConnectedThread: $socketType")
var tmpIn: InputStream? = null
var tmpOut: OutputStream? = null
// Get the BluetoothSocket input and output streams
try {
tmpIn = socket!!.inputStream
tmpOut = socket.outputStream
} catch (e: IOException) {
// Log.e(TAG, "temp sockets not created", e)
}
mmInStream = tmpIn
mmOutStream = tmpOut
mState = STATE_CONNECTED
}
}
companion object {
// Debugging
private const val TAG = "BluetoothChatService"
// Name for the SDP record when creating server socket
private const val NAME_SECURE = "BluetoothChatSecure"
private const val NAME_INSECURE = "BluetoothChatInsecure"
// Unique UUID for this application
private val MY_UUID_SECURE = UUID.fromString("fa87c0d0-afac-11de-8a39-0800200c9a66")
private val MY_UUID_INSECURE = UUID.fromString("8ce255c0-200a-11e0-ac64-0800200c9a66")
// Constants that indicate the current connection state
const val STATE_NONE = 0 // we're doing nothing
const val STATE_LISTEN = 1 // now listening for incoming connections
const val STATE_CONNECTING = 2 // now initiating an outgoing connection
const val STATE_CONNECTED = 3 // now connected to a remote device
}
/**
* Constructor. Prepares a new BluetoothChat session.
*
* @param context The UI Activity Context
* @param handler A Handler to send messages back to the UI Activity
*/
init {
mContext = context
// mAdapter = BluetoothAdapter.getDefaultAdapter()
bluetoothManager =
mContext!!.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
bluetoothManager!!.adapter
mState = STATE_NONE
mNewState = mState
// mHandler = handler
}
}
Loading…
Cancel
Save