This repository was archived by the owner on Jul 10, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Expand file tree
/
Copy pathBluetoothChatFragment.kt
More file actions
135 lines (114 loc) · 4.63 KB
/
Copy pathBluetoothChatFragment.kt
File metadata and controls
135 lines (114 loc) · 4.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
* Copyright (C) 2020 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.bluetoothlechat.chat
import android.bluetooth.BluetoothDevice
import android.content.Context
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.bluetoothlechat.R
import com.example.bluetoothlechat.bluetooth.ChatServer
import com.example.bluetoothlechat.bluetooth.Message
import com.example.bluetoothlechat.databinding.FragmentBluetoothChatBinding
import com.example.bluetoothlechat.gone
import com.example.bluetoothlechat.visible
private const val TAG = "BluetoothChatFragment"
class BluetoothChatFragment : Fragment() {
private var _binding: FragmentBluetoothChatBinding? = null
// this property is valid between onCreateView and onDestroyView.
private val binding: FragmentBluetoothChatBinding
get() = _binding!!
private val deviceConnectionObserver = Observer<DeviceConnectionState> { state ->
when (state) {
is DeviceConnectionState.Connected -> {
val device = state.device
Log.d(TAG, "Gatt connection observer: have device $device")
chatWith(device)
}
is DeviceConnectionState.Disconnected -> {
showDisconnected()
}
}
}
private val connectionRequestObserver = Observer<BluetoothDevice> { device ->
Log.d(TAG, "Connection request observer: have device $device")
ChatServer.setCurrentChatConnection(device)
}
private val messageObserver = Observer<Message> { message ->
Log.d(TAG, "Have message ${message.text}")
adapter.addMessage(message)
}
private val adapter = MessageAdapter()
private val inputMethodManager by lazy {
requireContext().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentBluetoothChatBinding.inflate(inflater, container, false)
Log.d(TAG, "chatWith: set adapter $adapter")
binding.messages.layoutManager = LinearLayoutManager(context)
binding.messages.adapter = adapter
showDisconnected()
binding.connectDevices.setOnClickListener {
findNavController().navigate(R.id.action_find_new_device)
}
return binding.root
}
override fun onStart() {
super.onStart()
requireActivity().setTitle(R.string.chat_title)
ChatServer.connectionRequest.observe(viewLifecycleOwner, connectionRequestObserver)
ChatServer.deviceConnection.observe(viewLifecycleOwner, deviceConnectionObserver)
ChatServer.messages.observe(viewLifecycleOwner, messageObserver)
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
private fun chatWith(device: BluetoothDevice) {
binding.connectedContainer.visible()
binding.notConnectedContainer.gone()
val chattingWithString = resources.getString(R.string.chatting_with_device, device.address)
binding.connectedDeviceName.text = chattingWithString
binding.sendMessage.setOnClickListener {
val message = binding.messageText.text.toString()
// only send message if it is not empty
if (message.isNotEmpty()) {
ChatServer.sendMessage(message)
// clear message
binding.messageText.setText("")
}
}
}
private fun showDisconnected() {
hideKeyboard()
binding.notConnectedContainer.visible()
binding.connectedContainer.gone()
}
private fun hideKeyboard() {
inputMethodManager.hideSoftInputFromWindow(binding.root.windowToken, 0)
}
}