diff --git a/BluetoothLeChat/app/build.gradle b/BluetoothLeChat/app/build.gradle
index fb7fcbee..b1066143 100644
--- a/BluetoothLeChat/app/build.gradle
+++ b/BluetoothLeChat/app/build.gradle
@@ -1,11 +1,11 @@
/*
- * Copyright 2020 Google LLC
+ * Copyright (C) 2021 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
*
- * https://www.apache.org/licenses/LICENSE-2.0
+ * 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,
@@ -54,13 +54,14 @@ android {
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
- implementation 'androidx.core:core-ktx:1.3.1'
- implementation 'androidx.fragment:fragment-ktx:1.3.0-alpha08'
- implementation 'androidx.activity:activity-ktx:1.2.0-alpha08'
+ implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.1'
+ implementation 'androidx.core:core-ktx:1.3.2'
+ implementation 'androidx.fragment:fragment-ktx:1.3.4'
+ implementation 'androidx.activity:activity-ktx:1.3.0-alpha08'
implementation 'androidx.appcompat:appcompat:1.2.0'
- implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0'
- implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
- implementation 'androidx.recyclerview:recyclerview:1.1.0'
- implementation "androidx.navigation:navigation-fragment-ktx:2.3.0"
- implementation "androidx.navigation:navigation-ui-ktx:2.3.0"
+ implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
+ implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
+ implementation 'androidx.recyclerview:recyclerview:1.2.0'
+ implementation "androidx.navigation:navigation-fragment-ktx:2.3.5"
+ implementation "androidx.navigation:navigation-ui-ktx:2.3.5"
}
\ No newline at end of file
diff --git a/BluetoothLeChat/app/src/main/AndroidManifest.xml b/BluetoothLeChat/app/src/main/AndroidManifest.xml
index 99596546..8a00a879 100644
--- a/BluetoothLeChat/app/src/main/AndroidManifest.xml
+++ b/BluetoothLeChat/app/src/main/AndroidManifest.xml
@@ -8,7 +8,7 @@
tag in the AndroidManifest.xml.
// If the app is installed on an emulator without bluetooth then the app will crash
@@ -258,7 +265,15 @@ object ChatServer {
offset: Int,
value: ByteArray?
) {
- super.onCharacteristicWriteRequest(device, requestId, characteristic, preparedWrite, responseNeeded, offset, value)
+ super.onCharacteristicWriteRequest(
+ device,
+ requestId,
+ characteristic,
+ preparedWrite,
+ responseNeeded,
+ offset,
+ value
+ )
if (characteristic.uuid == MESSAGE_UUID) {
gattServer?.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, 0, null)
val message = value?.toString(Charsets.UTF_8)
@@ -275,7 +290,10 @@ object ChatServer {
super.onConnectionStateChange(gatt, status, newState)
val isSuccess = status == BluetoothGatt.GATT_SUCCESS
val isConnected = newState == BluetoothProfile.STATE_CONNECTED
- Log.d(TAG, "onConnectionStateChange: Client $gatt success: $isSuccess connected: $isConnected")
+ Log.d(
+ TAG,
+ "onConnectionStateChange: Client $gatt success: $isSuccess connected: $isConnected"
+ )
// try to send a message to the other device as a test
if (isSuccess && isConnected) {
// discover services
@@ -303,7 +321,7 @@ object ChatServer {
super.onStartFailure(errorCode)
// Send error state to display
val errorMessage = "Advertise failed with error: $errorCode"
- Log.d(TAG, "Advertising failed")
+ Log.d(TAG, errorMessage)
//_viewState.value = DeviceScanViewState.Error(errorMessage)
}
diff --git a/BluetoothLeChat/app/src/main/java/com/example/bluetoothlechat/bluetooth/Constants.kt b/BluetoothLeChat/app/src/main/java/com/example/bluetoothlechat/bluetooth/Constants.kt
index bf6f1a6e..95fba96f 100644
--- a/BluetoothLeChat/app/src/main/java/com/example/bluetoothlechat/bluetooth/Constants.kt
+++ b/BluetoothLeChat/app/src/main/java/com/example/bluetoothlechat/bluetooth/Constants.kt
@@ -15,6 +15,7 @@
*/
package com.example.bluetoothlechat.bluetooth
+
import java.util.*
/**
@@ -25,7 +26,7 @@ import java.util.*
*
* Bluetooth requires a certain format for UUIDs associated with Services.
* The official specification can be found here:
- * [://www.bluetooth.org/en-us/specification/assigned-numbers/service-discovery][https]
+ * [https://www.bluetooth.org/en-us/specification/assigned-numbers/service-discovery]
*/
val SERVICE_UUID: UUID = UUID.fromString("0000b81d-0000-1000-8000-00805f9b34fb")
@@ -38,5 +39,3 @@ val MESSAGE_UUID: UUID = UUID.fromString("7db3e235-3608-41f3-a03c-955fcbd2ea4b")
* UUID to confirm device connection
*/
val CONFIRM_UUID: UUID = UUID.fromString("36d4dc5c-814b-4097-a5a6-b93b39085928")
-
-const val REQUEST_ENABLE_BT = 1
diff --git a/BluetoothLeChat/app/src/main/java/com/example/bluetoothlechat/bluetooth/EnableBluetoothFragment.kt b/BluetoothLeChat/app/src/main/java/com/example/bluetoothlechat/bluetooth/EnableBluetoothFragment.kt
index e19582a8..2546cf27 100644
--- a/BluetoothLeChat/app/src/main/java/com/example/bluetoothlechat/bluetooth/EnableBluetoothFragment.kt
+++ b/BluetoothLeChat/app/src/main/java/com/example/bluetoothlechat/bluetooth/EnableBluetoothFragment.kt
@@ -22,6 +22,7 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import androidx.activity.result.contract.ActivityResultContracts
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.navigation.fragment.findNavController
@@ -31,6 +32,7 @@ import com.example.bluetoothlechat.databinding.FragmentEnableBluetoothBinding
class EnableBluetoothFragment : Fragment() {
private var _binding: FragmentEnableBluetoothBinding? = null
+
// This property is only valid between onCreateView and onDestroyView.
private val binding
get() = _binding!!
@@ -42,6 +44,13 @@ class EnableBluetoothFragment : Fragment() {
}
}
+ private val startForResultEnableBluetooth =
+ registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
+ if (it.resultCode == Activity.RESULT_OK) {
+ ChatServer.startServer(requireActivity().application)
+ }
+ }
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
ChatServer.requestEnableBluetooth.observe(this, bluetoothEnableObserver)
@@ -51,32 +60,16 @@ class EnableBluetoothFragment : Fragment() {
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
- ): View? {
+ ): View {
_binding = FragmentEnableBluetoothBinding.inflate(inflater, container, false)
binding.errorAction.setOnClickListener {
- // Prompt user to turn on Bluetooth (logic continues in onActivityResult()).
+ // Prompt user to turn on Bluetooth (logic continues in registerForActivityResult()).
val enableBtIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
- startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT)
+ startForResultEnableBluetooth.launch(enableBtIntent)
}
return binding.root
}
- override fun onActivityResult(
- requestCode: Int,
- resultCode: Int,
- data: Intent?
- ) {
- super.onActivityResult(requestCode, resultCode, data)
- when (requestCode) {
- REQUEST_ENABLE_BT -> {
- if (resultCode == Activity.RESULT_OK) {
- ChatServer.startServer(requireActivity().application)
- }
- super.onActivityResult(requestCode, resultCode, data)
- }
- else -> super.onActivityResult(requestCode, resultCode, data)
- }
- }
}
\ No newline at end of file
diff --git a/BluetoothLeChat/app/src/main/java/com/example/bluetoothlechat/bluetooth/LocationRequiredFragment.kt b/BluetoothLeChat/app/src/main/java/com/example/bluetoothlechat/bluetooth/LocationRequiredFragment.kt
index ad48c46b..ec9e2735 100644
--- a/BluetoothLeChat/app/src/main/java/com/example/bluetoothlechat/bluetooth/LocationRequiredFragment.kt
+++ b/BluetoothLeChat/app/src/main/java/com/example/bluetoothlechat/bluetooth/LocationRequiredFragment.kt
@@ -18,19 +18,16 @@ package com.example.bluetoothlechat.bluetooth
import android.Manifest
import android.content.pm.PackageManager
import android.os.Bundle
-import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
+import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import com.example.bluetoothlechat.R
import com.example.bluetoothlechat.databinding.FragmentLocationRequiredBinding
-private const val TAG = "LocationRequiredFrag"
-private const val LOCATION_REQUEST_CODE = 0
-
// Fragment responsible for checking if the app has the ACCESS_FINE_LOCATION permission.
// This permission is required when using the BLE APIs so the user must grant permission
// to the app before viewing the BluetoothChatFragment or DeviceListFragment
@@ -44,7 +41,7 @@ class LocationRequiredFragment : Fragment() {
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
- ): View? {
+ ): View {
_binding = FragmentLocationRequiredBinding.inflate(inflater, container, false)
// hide the error messages while checking the permissions
@@ -64,25 +61,14 @@ class LocationRequiredFragment : Fragment() {
checkLocationPermission()
}
- override fun onRequestPermissionsResult(
- requestCode: Int,
- permissions: Array,
- grantResults: IntArray
- ) {
- super.onRequestPermissionsResult(requestCode, permissions, grantResults)
- Log.d(TAG, "onRequestPermissionsResult: ")
- when(requestCode) {
- LOCATION_REQUEST_CODE -> {
- if (grantResults.isNotEmpty() &&
- grantResults[0] == PackageManager.PERMISSION_GRANTED) {
- // Navigate to the chat fragment
- findNavController().navigate(R.id.action_start_chat)
- } else {
- showError()
- }
+ private val startForResultRequestPermission =
+ registerForActivityResult(ActivityResultContracts.RequestPermission()) {
+ if (it) {
+ findNavController().navigate(R.id.action_start_chat)
+ } else {
+ showError()
}
}
- }
private fun showError() {
binding.locationErrorMessage.visibility = View.VISIBLE
@@ -99,10 +85,7 @@ class LocationRequiredFragment : Fragment() {
// Navigate to the chat fragment
findNavController().navigate(R.id.action_start_chat)
} else {
- requestPermissions(
- arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
- LOCATION_REQUEST_CODE
- )
+ startForResultRequestPermission.launch(Manifest.permission.ACCESS_FINE_LOCATION)
}
}
}
\ No newline at end of file
diff --git a/BluetoothLeChat/app/src/main/java/com/example/bluetoothlechat/chat/BluetoothChatFragment.kt b/BluetoothLeChat/app/src/main/java/com/example/bluetoothlechat/chat/BluetoothChatFragment.kt
index bb5fe4c4..290c058a 100644
--- a/BluetoothLeChat/app/src/main/java/com/example/bluetoothlechat/chat/BluetoothChatFragment.kt
+++ b/BluetoothLeChat/app/src/main/java/com/example/bluetoothlechat/chat/BluetoothChatFragment.kt
@@ -27,9 +27,9 @@ import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
-import com.example.bluetoothlechat.bluetooth.Message
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
@@ -39,12 +39,13 @@ 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 { state ->
- when(state) {
+ when (state) {
is DeviceConnectionState.Connected -> {
val device = state.device
Log.d(TAG, "Gatt connection observer: have device $device")
@@ -54,7 +55,6 @@ class BluetoothChatFragment : Fragment() {
showDisconnected()
}
}
-
}
private val connectionRequestObserver = Observer { device ->
@@ -77,7 +77,7 @@ class BluetoothChatFragment : Fragment() {
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
- ): View? {
+ ): View {
_binding = FragmentBluetoothChatBinding.inflate(inflater, container, false)
Log.d(TAG, "chatWith: set adapter $adapter")
diff --git a/BluetoothLeChat/app/src/main/java/com/example/bluetoothlechat/chat/LocalMessageViewHolder.kt b/BluetoothLeChat/app/src/main/java/com/example/bluetoothlechat/chat/LocalMessageViewHolder.kt
index 3283a556..e454adef 100644
--- a/BluetoothLeChat/app/src/main/java/com/example/bluetoothlechat/chat/LocalMessageViewHolder.kt
+++ b/BluetoothLeChat/app/src/main/java/com/example/bluetoothlechat/chat/LocalMessageViewHolder.kt
@@ -18,8 +18,8 @@ package com.example.bluetoothlechat.chat
import android.view.View
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
-import com.example.bluetoothlechat.bluetooth.Message
import com.example.bluetoothlechat.R
+import com.example.bluetoothlechat.bluetooth.Message
class LocalMessageViewHolder(view: View) : RecyclerView.ViewHolder(view) {
diff --git a/BluetoothLeChat/app/src/main/java/com/example/bluetoothlechat/chat/MessageAdapter.kt b/BluetoothLeChat/app/src/main/java/com/example/bluetoothlechat/chat/MessageAdapter.kt
index 5b38f161..9cb1bf62 100644
--- a/BluetoothLeChat/app/src/main/java/com/example/bluetoothlechat/chat/MessageAdapter.kt
+++ b/BluetoothLeChat/app/src/main/java/com/example/bluetoothlechat/chat/MessageAdapter.kt
@@ -19,9 +19,8 @@ import android.util.Log
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
-import com.example.bluetoothlechat.bluetooth.Message
import com.example.bluetoothlechat.R
-import java.lang.IllegalArgumentException
+import com.example.bluetoothlechat.bluetooth.Message
private const val TAG = "MessageAdapter"
private const val REMOTE_MESSAGE = 0
@@ -33,7 +32,7 @@ class MessageAdapter : RecyclerView.Adapter() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
Log.d(TAG, "onCreateViewHolder: ")
val inflater = LayoutInflater.from(parent.context)
- return when(viewType) {
+ return when (viewType) {
REMOTE_MESSAGE -> {
val view = inflater.inflate(R.layout.item_remote_message, parent, false)
RemoteMessageViewHolder(view)
@@ -50,8 +49,7 @@ class MessageAdapter : RecyclerView.Adapter() {
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
Log.d(TAG, "onBindViewHolder: ")
- val message = messages[position]
- when(message) {
+ when (val message = messages[position]) {
is Message.RemoteMessage -> {
(holder as RemoteMessageViewHolder).bind(message)
}
@@ -68,7 +66,7 @@ class MessageAdapter : RecyclerView.Adapter() {
override fun getItemViewType(position: Int): Int {
Log.d(TAG, "getItemViewType: ")
- return when(messages[position]) {
+ return when (messages[position]) {
is Message.RemoteMessage -> REMOTE_MESSAGE
is Message.LocalMessage -> LOCAL_MESSAGE
}
diff --git a/BluetoothLeChat/app/src/main/java/com/example/bluetoothlechat/chat/RemoteMessageViewHolder.kt b/BluetoothLeChat/app/src/main/java/com/example/bluetoothlechat/chat/RemoteMessageViewHolder.kt
index dc6fa825..94b1d544 100644
--- a/BluetoothLeChat/app/src/main/java/com/example/bluetoothlechat/chat/RemoteMessageViewHolder.kt
+++ b/BluetoothLeChat/app/src/main/java/com/example/bluetoothlechat/chat/RemoteMessageViewHolder.kt
@@ -18,8 +18,8 @@ package com.example.bluetoothlechat.chat
import android.view.View
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
-import com.example.bluetoothlechat.bluetooth.Message
import com.example.bluetoothlechat.R
+import com.example.bluetoothlechat.bluetooth.Message
class RemoteMessageViewHolder(view: View) : RecyclerView.ViewHolder(view) {
diff --git a/BluetoothLeChat/app/src/main/java/com/example/bluetoothlechat/scan/DeviceScanFragment.kt b/BluetoothLeChat/app/src/main/java/com/example/bluetoothlechat/scan/DeviceScanFragment.kt
index a380ba1d..ef9c1b1f 100644
--- a/BluetoothLeChat/app/src/main/java/com/example/bluetoothlechat/scan/DeviceScanFragment.kt
+++ b/BluetoothLeChat/app/src/main/java/com/example/bluetoothlechat/scan/DeviceScanFragment.kt
@@ -35,7 +35,6 @@ import com.example.bluetoothlechat.scan.DeviceScanViewState.*
import com.example.bluetoothlechat.visible
private const val TAG = "DeviceScanFragment"
-const val GATT_KEY = "gatt_bundle_key"
class DeviceScanFragment : Fragment() {
@@ -70,7 +69,7 @@ class DeviceScanFragment : Fragment() {
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
- ): View? {
+ ): View {
_binding = FragmentDeviceScanBinding.inflate(inflater, container, false)
val devAddr = getString(R.string.your_device_address) + ChatServer.getYourDeviceAddress()
binding.yourDeviceAddr.text = devAddr
diff --git a/BluetoothLeChat/app/src/main/java/com/example/bluetoothlechat/scan/DeviceScanViewModel.kt b/BluetoothLeChat/app/src/main/java/com/example/bluetoothlechat/scan/DeviceScanViewModel.kt
index c5a8f0fa..fb9be9cd 100644
--- a/BluetoothLeChat/app/src/main/java/com/example/bluetoothlechat/scan/DeviceScanViewModel.kt
+++ b/BluetoothLeChat/app/src/main/java/com/example/bluetoothlechat/scan/DeviceScanViewModel.kt
@@ -16,9 +16,9 @@
package com.example.bluetoothlechat.scan
import android.app.Application
-import android.bluetooth.*
+import android.bluetooth.BluetoothAdapter
+import android.bluetooth.BluetoothDevice
import android.bluetooth.le.*
-import android.os.Handler
import android.os.ParcelUuid
import android.util.Log
import androidx.lifecycle.AndroidViewModel
@@ -26,9 +26,13 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.example.bluetoothlechat.bluetooth.SERVICE_UUID
import com.example.bluetoothlechat.scan.DeviceScanViewState.*
-
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
private const val TAG = "DeviceScanViewModel"
+
// 30 second scan period
private const val SCAN_PERIOD = 30000L
@@ -66,7 +70,7 @@ class DeviceScanViewModel(app: Application) : AndroidViewModel(app) {
stopScanning()
}
- fun startScan() {
+ private fun startScan() {
// If advertisement is not supported on this device then other devices will not be able to
// discover and connect to it.
if (!adapter.isMultipleAdvertisementSupported) {
@@ -81,8 +85,10 @@ class DeviceScanViewModel(app: Application) : AndroidViewModel(app) {
_viewState.value = ActiveScan
// Stop scanning after the scan period
- Handler().postDelayed({ stopScanning() }, SCAN_PERIOD)
-
+ CoroutineScope(Dispatchers.Main).launch {
+ delay(SCAN_PERIOD)
+ stopScanning()
+ }
// Kick off a new scan
scanCallback = DeviceScanCallback()
scanner?.startScan(scanFilters, scanSettings, scanCallback)
@@ -152,5 +158,4 @@ class DeviceScanViewModel(app: Application) : AndroidViewModel(app) {
}
}
-
}
\ No newline at end of file
diff --git a/BluetoothLeChat/app/src/main/java/com/example/bluetoothlechat/scan/DeviceScanViewState.kt b/BluetoothLeChat/app/src/main/java/com/example/bluetoothlechat/scan/DeviceScanViewState.kt
index f048a7c7..f684b4ec 100644
--- a/BluetoothLeChat/app/src/main/java/com/example/bluetoothlechat/scan/DeviceScanViewState.kt
+++ b/BluetoothLeChat/app/src/main/java/com/example/bluetoothlechat/scan/DeviceScanViewState.kt
@@ -18,8 +18,8 @@ package com.example.bluetoothlechat.scan
import android.bluetooth.BluetoothDevice
sealed class DeviceScanViewState {
- object ActiveScan: DeviceScanViewState()
- class ScanResults(val scanResults: Map): DeviceScanViewState()
- class Error(val message: String): DeviceScanViewState()
- object AdvertisementNotSupported: DeviceScanViewState()
+ object ActiveScan : DeviceScanViewState()
+ class ScanResults(val scanResults: Map) : DeviceScanViewState()
+ class Error(val message: String) : DeviceScanViewState()
+ object AdvertisementNotSupported : DeviceScanViewState()
}
\ No newline at end of file
diff --git a/BluetoothLeChat/app/src/main/res/layout/activity_main.xml b/BluetoothLeChat/app/src/main/res/layout/activity_main.xml
index f279db81..709dabdd 100644
--- a/BluetoothLeChat/app/src/main/res/layout/activity_main.xml
+++ b/BluetoothLeChat/app/src/main/res/layout/activity_main.xml
@@ -14,8 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
@@ -27,4 +26,4 @@
android:layout_height="match_parent"
app:defaultNavHost="true"
app:navGraph="@navigation/nav_graph" />
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/BluetoothLeChat/app/src/main/res/layout/fragment_bluetooth_chat.xml b/BluetoothLeChat/app/src/main/res/layout/fragment_bluetooth_chat.xml
index 685a163a..070a52d3 100644
--- a/BluetoothLeChat/app/src/main/res/layout/fragment_bluetooth_chat.xml
+++ b/BluetoothLeChat/app/src/main/res/layout/fragment_bluetooth_chat.xml
@@ -14,8 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
@@ -23,21 +22,21 @@
android:id="@+id/not_connected_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:orientation="vertical"
- android:layout_gravity="center">
+ android:layout_gravity="center"
+ android:orientation="vertical">
+ android:text="@string/no_connected_device_message" />
+ android:layout_marginTop="@dimen/std_margin"
+ android:text="@string/connect_device_prompt" />
+ android:layout_gravity="center_horizontal"
+ android:padding="@dimen/std_margin"
+ android:textSize="@dimen/txt_size_18" />
+ android:layout_weight="1" />
+ android:layout_height="wrap_content"
+ android:importantForAutofill="no" />
+ android:text="@string/send_message_button" />
\ No newline at end of file
diff --git a/BluetoothLeChat/app/src/main/res/layout/fragment_device_scan.xml b/BluetoothLeChat/app/src/main/res/layout/fragment_device_scan.xml
index 26cec729..756cbd0c 100644
--- a/BluetoothLeChat/app/src/main/res/layout/fragment_device_scan.xml
+++ b/BluetoothLeChat/app/src/main/res/layout/fragment_device_scan.xml
@@ -37,9 +37,9 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
- android:paddingTop="16dp"
+ android:paddingTop="@dimen/std_margin"
android:text="@string/active_scan_message"
- android:textSize="18sp" />
+ android:textSize="@dimen/txt_size_18" />
-
+ android:text="@string/bt_not_enabled" />
+ android:text="@string/enable_bluetooth_prompt" />
\ No newline at end of file
diff --git a/BluetoothLeChat/app/src/main/res/layout/fragment_location_required.xml b/BluetoothLeChat/app/src/main/res/layout/fragment_location_required.xml
index 2e16fc70..2276f3a3 100644
--- a/BluetoothLeChat/app/src/main/res/layout/fragment_location_required.xml
+++ b/BluetoothLeChat/app/src/main/res/layout/fragment_location_required.xml
@@ -14,8 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-
@@ -24,8 +23,8 @@
android:id="@+id/location_error_message"
android:layout_width="0dp"
android:layout_height="wrap_content"
- android:layout_marginStart="16dp"
- android:layout_marginEnd="16dp"
+ android:layout_marginStart="@dimen/std_margin"
+ android:layout_marginEnd="@dimen/std_margin"
android:text="@string/location_required_error"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
@@ -36,7 +35,7 @@
android:id="@+id/grant_permission_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginTop="16dp"
+ android:layout_marginTop="@dimen/std_margin"
android:text="@string/grant_permission_prompt"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
diff --git a/BluetoothLeChat/app/src/main/res/layout/item_device.xml b/BluetoothLeChat/app/src/main/res/layout/item_device.xml
index fb83cb94..a79523c4 100644
--- a/BluetoothLeChat/app/src/main/res/layout/item_device.xml
+++ b/BluetoothLeChat/app/src/main/res/layout/item_device.xml
@@ -23,10 +23,9 @@
android:id="@+id/device_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
- android:layout_marginStart="16dp"
- android:layout_marginTop="16dp"
- android:layout_marginEnd="16dp"
- android:text="Device info here"
+ android:layout_marginStart="@dimen/std_margin"
+ android:layout_marginTop="@dimen/std_margin"
+ android:layout_marginEnd="@dimen/std_margin"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
@@ -35,11 +34,10 @@
android:id="@+id/device_address"
android:layout_width="0dp"
android:layout_height="wrap_content"
- android:layout_marginStart="16dp"
- android:layout_marginTop="16dp"
- android:layout_marginEnd="16dp"
- android:layout_marginBottom="16dp"
- android:text="TextView"
+ android:layout_marginStart="@dimen/std_margin"
+ android:layout_marginTop="@dimen/std_margin"
+ android:layout_marginEnd="@dimen/std_margin"
+ android:layout_marginBottom="@dimen/std_margin"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
diff --git a/BluetoothLeChat/app/src/main/res/layout/item_local_message.xml b/BluetoothLeChat/app/src/main/res/layout/item_local_message.xml
index 9d4a2eb4..beff1197 100644
--- a/BluetoothLeChat/app/src/main/res/layout/item_local_message.xml
+++ b/BluetoothLeChat/app/src/main/res/layout/item_local_message.xml
@@ -24,10 +24,10 @@
android:id="@+id/message_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
- android:layout_marginStart="16dp"
- android:layout_marginTop="8dp"
- android:layout_marginEnd="16dp"
- android:layout_marginBottom="8dp"
+ android:layout_marginStart="@dimen/std_margin"
+ android:layout_marginTop="@dimen/std_margin_half"
+ android:layout_marginEnd="@dimen/std_margin"
+ android:layout_marginBottom="@dimen/std_margin_half"
android:background="@color/local_message_background"
android:padding="8dp"
android:textColor="#000000"
diff --git a/BluetoothLeChat/app/src/main/res/layout/item_remote_message.xml b/BluetoothLeChat/app/src/main/res/layout/item_remote_message.xml
index 782a3ddf..135cfe1b 100644
--- a/BluetoothLeChat/app/src/main/res/layout/item_remote_message.xml
+++ b/BluetoothLeChat/app/src/main/res/layout/item_remote_message.xml
@@ -24,10 +24,10 @@
android:id="@+id/message_text"
android:layout_width="0dp"
android:layout_height="wrap_content"
- android:layout_marginStart="16dp"
- android:layout_marginTop="8dp"
- android:layout_marginEnd="16dp"
- android:layout_marginBottom="8dp"
+ android:layout_marginStart="@dimen/std_margin"
+ android:layout_marginTop="@dimen/std_margin_half"
+ android:layout_marginEnd="@dimen/std_margin"
+ android:layout_marginBottom="@dimen/std_margin_half"
android:background="@color/remote_message_background"
android:padding="8dp"
android:textColor="#ffffff"
diff --git a/BluetoothLeChat/app/src/main/res/values/dimens.xml b/BluetoothLeChat/app/src/main/res/values/dimens.xml
new file mode 100644
index 00000000..7ec7c2db
--- /dev/null
+++ b/BluetoothLeChat/app/src/main/res/values/dimens.xml
@@ -0,0 +1,6 @@
+
+
+ 16dp
+ 18sp
+ 8dp
+
\ No newline at end of file
diff --git a/BluetoothLeChat/app/src/main/res/values/strings.xml b/BluetoothLeChat/app/src/main/res/values/strings.xml
index 280ffd38..86a43fdd 100644
--- a/BluetoothLeChat/app/src/main/res/values/strings.xml
+++ b/BluetoothLeChat/app/src/main/res/values/strings.xml
@@ -23,8 +23,6 @@
Scanning for devices
Please enable Bluetooth in order to scan for devices
Enable Bluetooth
- Bluetooth Advertisements are not supported on this device
- Would you like to chat with %1$s
No
Yes
Not connected to a device
@@ -33,4 +31,5 @@
Chatting with %1$s
Your device address:
Choose a device to chat with:
+ enter message
diff --git a/BluetoothLeChat/build.gradle b/BluetoothLeChat/build.gradle
index 066453de..5f389647 100644
--- a/BluetoothLeChat/build.gradle
+++ b/BluetoothLeChat/build.gradle
@@ -1,11 +1,11 @@
/*
- * Copyright 2020 Google LLC
+ * 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
*
- * https://www.apache.org/licenses/LICENSE-2.0
+ * 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,
@@ -15,13 +15,13 @@
*/
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
- ext.kotlin_version = "1.4.0"
+ ext.kotlin_version = "1.5.0"
repositories {
google()
- jcenter()
+ mavenCentral()
}
dependencies {
- classpath 'com.android.tools.build:gradle:4.0.1'
+ classpath 'com.android.tools.build:gradle:4.2.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
@@ -31,7 +31,7 @@ buildscript {
allprojects {
repositories {
google()
- jcenter()
+ mavenCentral()
}
}
diff --git a/BluetoothLeChat/gradle/wrapper/gradle-wrapper.properties b/BluetoothLeChat/gradle/wrapper/gradle-wrapper.properties
index be3bbac4..e08329cf 100644
--- a/BluetoothLeChat/gradle/wrapper/gradle-wrapper.properties
+++ b/BluetoothLeChat/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Thu Sep 03 12:48:38 EDT 2020
+#Wed May 19 13:24:30 EDT 2021
distributionBase=GRADLE_USER_HOME
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip
distributionPath=wrapper/dists
-zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
+zipStoreBase=GRADLE_USER_HOME