Kotlin

블루투스통신하기_(2)

아이코씨 2020. 1. 21. 14:31

3. ApplicationClass.kt (Activity만들기) app\src\main\java\com\()\프로젝트명\Application.kt 파일


import android.app.Application
import android.content.Context
import org.json.JSONArray
import org.json.JSONObject
import java.io.File


class ApplicationClass : Application() {
companion object {
lateinit var context: Context
lateinit var LoginID:String
lateinit var Area:String
lateinit var Device:String

fun getAppContext(): Context {
return context
}


var objFileSensor: JSONArray = JSONArray()
fun putPhotoData(gpsData:String, file:String){

var inputObject=JSONObject()
inputObject.put("Sensor",gpsData)
inputObject.put("FileName",file)
this.objFileSensor.put(inputObject)

}



이제 기본적인 준비는 끝났다.

이제 실제로 블루투스 통신을 할 Activity에 코드를 추가하면 됨.


통신을 시작할 activity에 통신에 필요한 변수들을 선언한다


private val mBtHandler = BluetoothHandler()
private val mBluetoothManager: BluetoothManager = BluetoothManager.getInstance()
private var mPrevUpdateTime = 0L
private var mIsConnected = false


onCreate 함수 안에

if(!checkBluetooth()) {
btn_scan.isEnabled = false
val enableIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
startActivityForResult(enableIntent, Const.REQUEST_ENABLE_BT)

} else {
btn_scan.isEnabled = true
}


mBluetoothManager.setHandler(mBtHandler)

// Register for broadcasts when a device is discovered
var filter = IntentFilter(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED)
this.registerReceiver(mReceiver, filter)

initialize()

 위의 코드를 추가한다.


btn_scan 변수는 xml에서 추가한 버튼인데 이 버튼을 누르면 연결 가능한 페어링 된 블루투스 장비 목록을 보여주는 화면이 뜬다(Dialog).

처음에 이 Activity를 로딩하면서 블루투스 장비를 스캔 할 버튼을 셋팅해주는 부분인듯.


private fun initialize() {

btn_scan.setOnClickListener {
if(mIsConnected)
disconnect()
else
doScan()
}

}


이 초기화 함수는 버튼이나 텍스트 박스 등.. 초기화 할 UI들을 초기화 해주는 함수.


override fun onBackPressed() {
// Exit dialog
val alertDiag = AlertDialog.Builder(this)
alertDiag.setMessage("Exit app?")
alertDiag.setPositiveButton("OK") { _: DialogInterface, _: Int ->
// finish app
finishApp()
}
alertDiag.setNegativeButton("Cancel") { _: DialogInterface, _: Int -> }

val alert = alertDiag.create()
alert.setTitle("Warning")
alert.show()
}


override fun onDestroy() {
super.onDestroy()
finalizeActivity()
}

override fun onLowMemory() {
super.onLowMemory()
finalizeActivity()
}


private fun finalizeActivity() {

// Close bluetooth connection
mBluetoothManager.stop()
// Unregister broadcast listeners
this.unregisterReceiver(mReceiver)
}

private fun finishApp() {
ActivityCompat.finishAffinity(this);
System.runFinalizersOnExit(true);
System.exit(0);
}

private fun checkBluetooth(): Boolean {
return mBluetoothManager.isBluetoothEnabled()
}

/**
* Launch the DeviceListActivity to see devices and do scan
*/
private fun doScan() {
val intent = Intent(this, DeviceListActivity::class.java)
startActivityForResult(intent, Const.REQUEST_CONNECT_DEVICE)
}

앱 종료나.. 뒤로 버튼 눌렀을 때나 기타 등등 기본적인 셋팅을 해주는 함수들....



/**
* Ensure this device is discoverable by others
*/


private fun setConnected(connected: Boolean) {
mIsConnected = connected
if(connected) {
btn_scan.text = resources.getText(R.string.disconnect)
btn_Camera.isEnabled=true
} else {
btn_scan.text = resources.getText(R.string.button_scan)
}
}

private fun disconnect() {
mBluetoothManager.stop()
}

이건 연결하고 연결 끊고...


이제부터가 핵심 데이터 받아서 텍스트박스에 뿌려주는부분..

// The BroadcastReceiver that listens for discovered devices and
// changes the title when discovery is finished
private val mReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val action = intent.action

// When discovery finds a device
if (BluetoothAdapter.ACTION_SCAN_MODE_CHANGED == action) {
val scanMode = intent.getIntExtra(BluetoothAdapter.EXTRA_SCAN_MODE, -1)
when(scanMode) {
BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE -> {
btn_scan.isEnabled = false
textView.append("\nSCAN_MODE_CONNECTABLE_DISCOVERABLE")
textView.append("\nMake server socket")

mBluetoothManager.start()
}
BluetoothAdapter.SCAN_MODE_CONNECTABLE -> {
btn_scan.isEnabled = true
textView.append("\nSCAN_MODE_CONNECTABLE")
}
BluetoothAdapter.SCAN_MODE_NONE -> {
// Bluetooth is not enabled
btn_scan.isEnabled = false
textView.append("\nBluetooth is not enabled!!")
}
}
}
}
}

inner class BluetoothHandler : Handler() {
//메시지 수신
override fun handleMessage(msg: Message) {
when (msg.what) {
BluetoothManager.MESSAGE_READ -> {
if (msg.obj != null)
{
val currentTime = System.currentTimeMillis()
if(mPrevUpdateTime + 1000 < currentTime) {
textView.append("\n")
mPrevUpdateTime = currentTime
}
if(textView.text.length > 10000) {
textView.text = ""
}

val string=(msg.obj as ByteArray).toString(Charset.defaultCharset())
var scrollAmount=textView.getLayout().getLineTop(textView.lineCount)-textView.height
if(scrollAmount>0)
textView.scrollTo(0,scrollAmount)
else
textView.scrollTo(0,0)

                    textView.append(string)


}
}
BluetoothManager.MESSAGE_STATE_CHANGE -> {
when(msg.arg1) {
BluetoothManager.STATE_NONE -> { // we're doing nothing
text_status.text = resources.getString(R.string.bt_title) + ": " + resources.getString(R.string.bt_state_init)

setConnected(false)
}
BluetoothManager.STATE_LISTEN -> { // now listening for incoming connections
text_status.text = resources.getString(R.string.bt_title) + ": " + resources.getString(R.string.bt_state_wait)

setConnected(false)
}
BluetoothManager.STATE_CONNECTING -> { // connecting to remote
text_status.text = resources.getString(R.string.bt_title) + ": " + resources.getString(R.string.bt_state_connect)

}
BluetoothManager.STATE_CONNECTED -> { // now connected to a remote device
text_status.text = resources.getString(R.string.bt_state_connected)

setConnected(true)
}
}
}
BluetoothManager.MESSAGE_DEVICE_NAME -> {
if(msg.data != null) {
val deviceName = msg.data.getString(BluetoothManager.MSG_DEVICE_NAME)
val deviceAddr = msg.data.getString(BluetoothManager.MSG_DEVICE_ADDRESS)
text_status.append(" to ")
text_status.append(deviceName)
text_status.append(", ")
text_status.append(deviceAddr)
}
}
}

super.handleMessage(msg)
}
}

이부분은 더 공부해봐야 알겠지만 아마도 외부에서 오는 응답을 처리하는 부분인가보다..

블루투스 장비를 검색하는 다른 다이얼로그에서 어떤 장비가 선택되었을 떄나 그럴 경우,,


/**
* Receives result from external activity
*/
public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {

when (requestCode) {
Const.REQUEST_CONNECT_DEVICE -> {
// When DeviceListActivity returns with a device to connect
if (resultCode == Activity.RESULT_OK) {
// Get the device MAC address
val address = data?.extras?.getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS)
// Attempt to connect to the device
mBluetoothManager.connect(address)
}
}
Const.REQUEST_ENABLE_BT -> {
// When the request to enable Bluetooth returns
if (resultCode == Activity.RESULT_OK) {
// Bluetooth is now enabled, so set up a BT session
btn_scan.isEnabled = true
} else {
// User did not enable Bluetooth or an error occured
Toast.makeText(this, R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show()
btn_scan.isEnabled = false
}
}
Const.REQUEST_DISCOVERABLE -> {
// resultCode is always false
}
} // End of switch(requestCode)
}



코드를 뜯어보면 do Scan이라는 버튼으로 다이얼로그를 별도로 열어서 페이링 된 블루투스 장비 목록을 보고 거기서 선택하여 연결하는 부분이 있는데 그 부분은 다음 포스팅에 xml와 엑티비티 전문을 업로드 할 예정