update
This commit is contained in:
		@@ -12,6 +12,10 @@
 | 
			
		||||
        android:roundIcon="@mipmap/ic_launcher_round"
 | 
			
		||||
        android:supportsRtl="true"
 | 
			
		||||
        android:theme="@style/Theme.Hexapod">
 | 
			
		||||
        <activity
 | 
			
		||||
            android:name=".DeviceListActivity"
 | 
			
		||||
            android:exported="false"
 | 
			
		||||
            android:theme="@style/Theme.MaterialComponents.DayNight.Dialog"/>
 | 
			
		||||
        <activity
 | 
			
		||||
            android:name=".ControlActivity"
 | 
			
		||||
            android:exported="false"
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,184 @@
 | 
			
		||||
package com.rookiedev.hexapod
 | 
			
		||||
 | 
			
		||||
import android.annotation.SuppressLint
 | 
			
		||||
import android.app.Activity
 | 
			
		||||
import android.bluetooth.BluetoothAdapter
 | 
			
		||||
import android.bluetooth.BluetoothDevice
 | 
			
		||||
import android.bluetooth.BluetoothManager
 | 
			
		||||
import android.content.BroadcastReceiver
 | 
			
		||||
import android.content.Context
 | 
			
		||||
import android.content.Intent
 | 
			
		||||
import android.content.IntentFilter
 | 
			
		||||
import android.os.Bundle
 | 
			
		||||
import android.view.View
 | 
			
		||||
import android.view.Window
 | 
			
		||||
import android.widget.AdapterView.OnItemClickListener
 | 
			
		||||
import android.widget.ArrayAdapter
 | 
			
		||||
import android.widget.Button
 | 
			
		||||
import android.widget.ListView
 | 
			
		||||
import android.widget.TextView
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This Activity appears as a dialog. It lists any paired devices and
 | 
			
		||||
 * devices detected in the area after discovery. When a device is chosen
 | 
			
		||||
 * by the user, the MAC address of the device is sent back to the parent
 | 
			
		||||
 * Activity in the result Intent.
 | 
			
		||||
 */
 | 
			
		||||
class DeviceListActivity : Activity() {
 | 
			
		||||
    /**
 | 
			
		||||
     * Member fields
 | 
			
		||||
     */
 | 
			
		||||
    private var mBtAdapter: BluetoothAdapter? = null
 | 
			
		||||
 | 
			
		||||
    private var mContext: Context? = null
 | 
			
		||||
    private var bluetoothManager: BluetoothManager? = null
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Newly discovered devices
 | 
			
		||||
     */
 | 
			
		||||
    private var mNewDevicesArrayAdapter: ArrayAdapter<String>? = null
 | 
			
		||||
 | 
			
		||||
    @SuppressLint("MissingPermission")
 | 
			
		||||
    override fun onCreate(savedInstanceState: Bundle?) {
 | 
			
		||||
        super.onCreate(savedInstanceState)
 | 
			
		||||
 | 
			
		||||
        // Setup the window
 | 
			
		||||
//        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS)
 | 
			
		||||
        setContentView(R.layout.activity_device_list)
 | 
			
		||||
 | 
			
		||||
        mContext = applicationContext
 | 
			
		||||
 | 
			
		||||
        // Set result CANCELED in case the user backs out
 | 
			
		||||
        setResult(RESULT_CANCELED)
 | 
			
		||||
 | 
			
		||||
        // Initialize array adapters. One for already paired devices and
 | 
			
		||||
        // one for newly discovered devices
 | 
			
		||||
        val pairedDevicesArrayAdapter = ArrayAdapter<String>(this, R.layout.device_name)
 | 
			
		||||
        mNewDevicesArrayAdapter = ArrayAdapter(this, R.layout.device_name)
 | 
			
		||||
 | 
			
		||||
        // Find and set up the ListView for paired devices
 | 
			
		||||
        val pairedListView: ListView = findViewById<ListView>(R.id.paired_devices)
 | 
			
		||||
        pairedListView.adapter = pairedDevicesArrayAdapter
 | 
			
		||||
        pairedListView.onItemClickListener = mDeviceClickListener
 | 
			
		||||
 | 
			
		||||
        // Find and set up the ListView for newly discovered devices
 | 
			
		||||
//        val newDevicesListView: ListView = findViewById(R.id.new_devices)
 | 
			
		||||
//        newDevicesListView.adapter = mNewDevicesArrayAdapter
 | 
			
		||||
//        newDevicesListView.onItemClickListener = mDeviceClickListener
 | 
			
		||||
 | 
			
		||||
        // Register for broadcasts when a device is discovered
 | 
			
		||||
//        var filter = IntentFilter(BluetoothDevice.ACTION_FOUND)
 | 
			
		||||
//        this.registerReceiver(mReceiver, filter)
 | 
			
		||||
 | 
			
		||||
        // Register for broadcasts when discovery has finished
 | 
			
		||||
//        filter = IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)
 | 
			
		||||
//        this.registerReceiver(mReceiver, filter)
 | 
			
		||||
 | 
			
		||||
        // Get the local Bluetooth adapter
 | 
			
		||||
        bluetoothManager =
 | 
			
		||||
            mContext!!.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
 | 
			
		||||
        bluetoothManager!!.adapter
 | 
			
		||||
 | 
			
		||||
        // Get a set of currently paired devices
 | 
			
		||||
        val pairedDevices: Set<BluetoothDevice> = bluetoothManager!!.adapter.bondedDevices
 | 
			
		||||
 | 
			
		||||
        // If there are paired devices, add each one to the ArrayAdapter
 | 
			
		||||
        if (pairedDevices.isNotEmpty()) {
 | 
			
		||||
            findViewById<View>(R.id.title_paired_devices).visibility = View.VISIBLE
 | 
			
		||||
            for (device in pairedDevices) {
 | 
			
		||||
                pairedDevicesArrayAdapter.add(
 | 
			
		||||
                    """
 | 
			
		||||
                        ${device.name}
 | 
			
		||||
                        ${device.address}
 | 
			
		||||
                        """.trimIndent()
 | 
			
		||||
                )
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            val noDevices = "No device"
 | 
			
		||||
            pairedDevicesArrayAdapter.add(noDevices)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @SuppressLint("MissingPermission")
 | 
			
		||||
    override fun onDestroy() {
 | 
			
		||||
        super.onDestroy()
 | 
			
		||||
 | 
			
		||||
        // Make sure we're not doing discovery anymore
 | 
			
		||||
//        if (mBtAdapter != null) {
 | 
			
		||||
//            mBtAdapter!!.cancelDiscovery()
 | 
			
		||||
//        }
 | 
			
		||||
//        bluetoothManager!!.adapter.cancelDiscovery()
 | 
			
		||||
 | 
			
		||||
        // Unregister broadcast listeners
 | 
			
		||||
//        unregisterReceiver(mReceiver)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The on-click listener for all devices in the ListViews
 | 
			
		||||
     */
 | 
			
		||||
    @SuppressLint("MissingPermission")
 | 
			
		||||
    private val mDeviceClickListener =
 | 
			
		||||
        OnItemClickListener { av, v, arg2, arg3 -> // Cancel discovery because it's costly and we're about to connect
 | 
			
		||||
//            bluetoothManager!!.adapter.cancelDiscovery()
 | 
			
		||||
 | 
			
		||||
            // Get the device MAC address, which is the last 17 chars in the View
 | 
			
		||||
            val info = (v as TextView).text.toString()
 | 
			
		||||
            val address = info.substring(info.length - 17)
 | 
			
		||||
 | 
			
		||||
            // Create the result Intent and include the MAC address
 | 
			
		||||
            val intent = Intent()
 | 
			
		||||
            intent.putExtra(EXTRA_DEVICE_ADDRESS, address)
 | 
			
		||||
 | 
			
		||||
            // Set result and finish this Activity
 | 
			
		||||
            setResult(RESULT_OK, intent)
 | 
			
		||||
            finish()
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The BroadcastReceiver that listens for discovered devices and changes the title when
 | 
			
		||||
     * discovery is finished
 | 
			
		||||
     */
 | 
			
		||||
    private val mReceiver: BroadcastReceiver = object : BroadcastReceiver() {
 | 
			
		||||
        @SuppressLint("MissingPermission")
 | 
			
		||||
        override fun onReceive(context: Context?, intent: Intent) {
 | 
			
		||||
            val action = intent.action
 | 
			
		||||
 | 
			
		||||
            // When discovery finds a device
 | 
			
		||||
            if (BluetoothDevice.ACTION_FOUND == action) {
 | 
			
		||||
                // Get the BluetoothDevice object from the Intent
 | 
			
		||||
                val device =
 | 
			
		||||
                    intent.getParcelableExtra<BluetoothDevice>(BluetoothDevice.EXTRA_DEVICE)
 | 
			
		||||
                // If it's already paired, skip it, because it's been listed already
 | 
			
		||||
                if (device != null && device.bondState != BluetoothDevice.BOND_BONDED) {
 | 
			
		||||
                    mNewDevicesArrayAdapter!!.add(
 | 
			
		||||
                        """
 | 
			
		||||
                            ${device.name}
 | 
			
		||||
                            ${device.address}
 | 
			
		||||
                            """.trimIndent()
 | 
			
		||||
                    )
 | 
			
		||||
                }
 | 
			
		||||
                // When discovery is finished, change the Activity title
 | 
			
		||||
//            } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED == action) {
 | 
			
		||||
//                setProgressBarIndeterminateVisibility(false)
 | 
			
		||||
//                setTitle(R.string.select_device)
 | 
			
		||||
//                if (mNewDevicesArrayAdapter!!.count == 0) {
 | 
			
		||||
//                    val noDevices = resources.getText(R.string.none_found).toString()
 | 
			
		||||
//                    mNewDevicesArrayAdapter!!.add(noDevices)
 | 
			
		||||
//                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    companion object {
 | 
			
		||||
        /**
 | 
			
		||||
         * Tag for Log
 | 
			
		||||
         */
 | 
			
		||||
        private const val TAG = "DeviceListActivity"
 | 
			
		||||
 | 
			
		||||
        /**
 | 
			
		||||
         * Return Intent extra
 | 
			
		||||
         */
 | 
			
		||||
        var EXTRA_DEVICE_ADDRESS = "device_address"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -1,8 +1,7 @@
 | 
			
		||||
package com.rookiedev.hexapod
 | 
			
		||||
 | 
			
		||||
import android.Manifest
 | 
			
		||||
import android.bluetooth.BluetoothDevice
 | 
			
		||||
import android.bluetooth.BluetoothManager
 | 
			
		||||
import android.app.Activity
 | 
			
		||||
import android.content.Context
 | 
			
		||||
import android.content.Intent
 | 
			
		||||
import android.content.pm.PackageManager
 | 
			
		||||
@@ -13,10 +12,15 @@ import android.text.Editable
 | 
			
		||||
import android.text.TextWatcher
 | 
			
		||||
import android.text.method.LinkMovementMethod
 | 
			
		||||
import android.view.View
 | 
			
		||||
import android.widget.*
 | 
			
		||||
import android.widget.AdapterView.OnItemClickListener
 | 
			
		||||
import android.widget.Button
 | 
			
		||||
import android.widget.ListView
 | 
			
		||||
import android.widget.TextView
 | 
			
		||||
import android.widget.Toast
 | 
			
		||||
import androidx.activity.result.contract.ActivityResultContracts
 | 
			
		||||
import androidx.annotation.RequiresApi
 | 
			
		||||
import androidx.appcompat.app.AppCompatActivity
 | 
			
		||||
import androidx.constraintlayout.widget.ConstraintLayout
 | 
			
		||||
import androidx.core.app.ActivityCompat
 | 
			
		||||
import com.google.android.material.tabs.TabLayout
 | 
			
		||||
import com.google.android.material.textfield.TextInputEditText
 | 
			
		||||
@@ -28,6 +32,11 @@ class MainActivity : AppCompatActivity() {
 | 
			
		||||
        private const val BLUETOOTH_PERMISSION_CODE = 100
 | 
			
		||||
        private const val INTERNET_PERMISSION_CODE = 101
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private val REQUEST_CONNECT_DEVICE_SECURE = 1
 | 
			
		||||
    private val REQUEST_CONNECT_DEVICE_INSECURE = 2
 | 
			
		||||
    private val REQUEST_ENABLE_BT = 3
 | 
			
		||||
 | 
			
		||||
    private val SHAREDPREFSNAME = "com.rookiedev.hexapod_preferences"
 | 
			
		||||
    private val SHAREDPREFSIP = "IP"
 | 
			
		||||
    private val SHAREDPREFSPORT = "PORT"
 | 
			
		||||
@@ -51,6 +60,9 @@ class MainActivity : AppCompatActivity() {
 | 
			
		||||
        val portLayout = findViewById<TextInputLayout>(R.id.port_input_layout)
 | 
			
		||||
 | 
			
		||||
        val deviceList = findViewById<ListView>(R.id.paired_devices)
 | 
			
		||||
        val selectedDevice = findViewById<ConstraintLayout>(R.id.selected)
 | 
			
		||||
        val deviceName = findViewById<TextView>(R.id.textView_device_name)
 | 
			
		||||
        val deviceAddress = findViewById<TextView>(R.id.textView_device_address)
 | 
			
		||||
 | 
			
		||||
        val sourceLink = findViewById<TextView>(R.id.textView_github)
 | 
			
		||||
        sourceLink.movementMethod = LinkMovementMethod.getInstance()
 | 
			
		||||
@@ -65,72 +77,12 @@ class MainActivity : AppCompatActivity() {
 | 
			
		||||
                        ipLayout.visibility = View.VISIBLE
 | 
			
		||||
                        portLayout.visibility = View.VISIBLE
 | 
			
		||||
                        deviceList.visibility = View.GONE
 | 
			
		||||
                        selectedDevice.visibility = View.GONE
 | 
			
		||||
                    } else if (tab.text == "Bluetooth") {
 | 
			
		||||
                        checkPermission(Manifest.permission.BLUETOOTH_CONNECT, BLUETOOTH_PERMISSION_CODE)
 | 
			
		||||
                        if (ActivityCompat.checkSelfPermission(
 | 
			
		||||
                                mContext!!,
 | 
			
		||||
                                Manifest.permission.BLUETOOTH_CONNECT
 | 
			
		||||
                            ) != PackageManager.PERMISSION_GRANTED
 | 
			
		||||
                        ) {
 | 
			
		||||
                            // TODO: Consider calling
 | 
			
		||||
                            //    ActivityCompat#requestPermissions
 | 
			
		||||
                            // here to request the missing permissions, and then overriding
 | 
			
		||||
                            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
 | 
			
		||||
                            //                                          int[] grantResults)
 | 
			
		||||
                            // to handle the case where the user grants the permission. See the documentation
 | 
			
		||||
                            // for ActivityCompat#requestPermissions for more details.
 | 
			
		||||
                            return
 | 
			
		||||
                        }
 | 
			
		||||
                        ipLayout.visibility = View.GONE
 | 
			
		||||
                        portLayout.visibility = View.GONE
 | 
			
		||||
                        deviceList.visibility = View.VISIBLE
 | 
			
		||||
 | 
			
		||||
                        // Initialize array adapters. One for already paired devices and
 | 
			
		||||
                        // one for newly discovered devices
 | 
			
		||||
 | 
			
		||||
                        // Initialize array adapters. One for already paired devices and
 | 
			
		||||
                        // one for newly discovered devices
 | 
			
		||||
                        val pairedDevicesArrayAdapter =
 | 
			
		||||
                            ArrayAdapter<kotlin.String>(mContext!!, R.layout.device_name)
 | 
			
		||||
 | 
			
		||||
                        // Find and set up the ListView for paired devices
 | 
			
		||||
 | 
			
		||||
                        // Find and set up the ListView for paired devices
 | 
			
		||||
                        val pairedListView = findViewById<ListView>(R.id.paired_devices)
 | 
			
		||||
                        pairedListView.adapter = pairedDevicesArrayAdapter
 | 
			
		||||
                        pairedListView.onItemClickListener = mDeviceClickListener
 | 
			
		||||
 | 
			
		||||
                        // Get the local Bluetooth adapter
 | 
			
		||||
 | 
			
		||||
                        // Get the local Bluetooth adapter
 | 
			
		||||
//                        mBtAdapter = BluetoothAdapter.getDefaultAdapter()
 | 
			
		||||
                        val bluetoothManager = mContext!!.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
 | 
			
		||||
                        bluetoothManager.adapter
 | 
			
		||||
 | 
			
		||||
                        // Get a set of currently paired devices
 | 
			
		||||
 | 
			
		||||
                        // Get a set of currently paired devices
 | 
			
		||||
                        val pairedDevices: Set<BluetoothDevice> = bluetoothManager.adapter.bondedDevices
 | 
			
		||||
 | 
			
		||||
                        // If there are paired devices, add each one to the ArrayAdapter
 | 
			
		||||
 | 
			
		||||
                        // If there are paired devices, add each one to the ArrayAdapter
 | 
			
		||||
                        if (pairedDevices.isNotEmpty()) {
 | 
			
		||||
//                            findViewById<View>(R.id.title_paired_devices).visibility = View.VISIBLE
 | 
			
		||||
                            for (device in pairedDevices) {
 | 
			
		||||
                                pairedDevicesArrayAdapter.add(
 | 
			
		||||
                                    """
 | 
			
		||||
                                    ${device.name}
 | 
			
		||||
                                    ${device.address}
 | 
			
		||||
                                    """.trimIndent()
 | 
			
		||||
                                )
 | 
			
		||||
                            }
 | 
			
		||||
                            pairedListView.layoutParams.height = 153*6
 | 
			
		||||
                        }
 | 
			
		||||
//                        else {
 | 
			
		||||
//                            val noDevices = resources.getText(R.string.none_paired).toString()
 | 
			
		||||
//                            pairedDevicesArrayAdapter.add(noDevices)
 | 
			
		||||
//                        }
 | 
			
		||||
                        selectedDevice.visibility = View.VISIBLE
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@@ -142,6 +94,13 @@ class MainActivity : AppCompatActivity() {
 | 
			
		||||
            }
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
        selectedDevice.setOnClickListener{
 | 
			
		||||
            checkPermission(Manifest.permission.BLUETOOTH_CONNECT, BLUETOOTH_PERMISSION_CODE)
 | 
			
		||||
            val serverIntent = Intent(this, DeviceListActivity::class.java)
 | 
			
		||||
            resultLauncher.launch(serverIntent)
 | 
			
		||||
//            startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE_INSECURE)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        readSharedPref()
 | 
			
		||||
 | 
			
		||||
        buttonConnect.setOnClickListener {
 | 
			
		||||
@@ -184,6 +143,14 @@ class MainActivity : AppCompatActivity() {
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    var resultLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
 | 
			
		||||
        if (result.resultCode == Activity.RESULT_OK) {
 | 
			
		||||
            // There are no request codes
 | 
			
		||||
            val data: Intent? = result.data
 | 
			
		||||
//            doSomeOperations()
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Function to check and request permission.
 | 
			
		||||
    private fun checkPermission(permission: String, requestCode: Int) {
 | 
			
		||||
        if (ActivityCompat.checkSelfPermission(this@MainActivity, permission) == PackageManager.PERMISSION_DENIED) {
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,42 @@
 | 
			
		||||
<?xml version="1.0" encoding="utf-8"?>
 | 
			
		||||
<!-- Copyright (C) 2014 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.
 | 
			
		||||
-->
 | 
			
		||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 | 
			
		||||
    android:layout_width="match_parent"
 | 
			
		||||
    android:layout_height="match_parent"
 | 
			
		||||
    android:orientation="vertical"
 | 
			
		||||
    >
 | 
			
		||||
 | 
			
		||||
    <TextView
 | 
			
		||||
        android:id="@+id/title_paired_devices"
 | 
			
		||||
        android:layout_width="match_parent"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        android:padding="24dp"
 | 
			
		||||
        android:textAppearance="?attr/textAppearanceHeadline6"
 | 
			
		||||
        android:text="Select Device"
 | 
			
		||||
        android:visibility="visible"
 | 
			
		||||
        />
 | 
			
		||||
 | 
			
		||||
    <View
 | 
			
		||||
        android:id="@+id/divider"
 | 
			
		||||
        android:layout_width="match_parent"
 | 
			
		||||
        android:layout_height="1dp"
 | 
			
		||||
        android:background="?android:attr/listDivider" />
 | 
			
		||||
 | 
			
		||||
    <ListView
 | 
			
		||||
        android:id="@+id/paired_devices"
 | 
			
		||||
        android:layout_width="match_parent"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        android:stackFromBottom="false"
 | 
			
		||||
        />
 | 
			
		||||
 | 
			
		||||
</LinearLayout>
 | 
			
		||||
@@ -6,11 +6,13 @@
 | 
			
		||||
    android:layout_height="match_parent"
 | 
			
		||||
    tools:context=".MainActivity">
 | 
			
		||||
 | 
			
		||||
    <androidx.constraintlayout.widget.ConstraintLayout
 | 
			
		||||
    <LinearLayout
 | 
			
		||||
        android:layout_width="match_parent"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        android:paddingStart="16dp"
 | 
			
		||||
        android:paddingEnd="16dp">
 | 
			
		||||
        android:paddingEnd="16dp"
 | 
			
		||||
        android:orientation="vertical"
 | 
			
		||||
        android:gravity="center_horizontal">
 | 
			
		||||
 | 
			
		||||
        <ImageView
 | 
			
		||||
            android:id="@+id/hexapod_logo"
 | 
			
		||||
@@ -48,15 +50,15 @@
 | 
			
		||||
 | 
			
		||||
        <com.google.android.material.textfield.TextInputLayout
 | 
			
		||||
            android:id="@+id/ip_input_layout"
 | 
			
		||||
            android:layout_width="0dp"
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:layout_marginBottom="4dp"
 | 
			
		||||
            android:visibility="visible"
 | 
			
		||||
            app:errorEnabled="true"
 | 
			
		||||
            app:layout_constraintBottom_toTopOf="@id/port_input_layout"
 | 
			
		||||
            app:layout_constraintEnd_toEndOf="parent"
 | 
			
		||||
            app:layout_constraintStart_toStartOf="parent"
 | 
			
		||||
            app:layout_constraintTop_toBottomOf="@+id/tab"
 | 
			
		||||
            android:visibility="visible">
 | 
			
		||||
            app:layout_constraintTop_toBottomOf="@+id/tab">
 | 
			
		||||
 | 
			
		||||
            <com.google.android.material.textfield.TextInputEditText
 | 
			
		||||
                android:id="@+id/ip_input"
 | 
			
		||||
@@ -70,15 +72,15 @@
 | 
			
		||||
 | 
			
		||||
        <com.google.android.material.textfield.TextInputLayout
 | 
			
		||||
            android:id="@+id/port_input_layout"
 | 
			
		||||
            android:layout_width="0dp"
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:layout_marginBottom="4dp"
 | 
			
		||||
            android:visibility="visible"
 | 
			
		||||
            app:errorEnabled="true"
 | 
			
		||||
            app:layout_constraintBottom_toTopOf="@id/paired_devices"
 | 
			
		||||
            app:layout_constraintEnd_toEndOf="parent"
 | 
			
		||||
            app:layout_constraintStart_toStartOf="parent"
 | 
			
		||||
            app:layout_constraintTop_toBottomOf="@id/ip_input_layout"
 | 
			
		||||
            android:visibility="visible">
 | 
			
		||||
            app:layout_constraintTop_toBottomOf="@id/ip_input_layout">
 | 
			
		||||
 | 
			
		||||
            <com.google.android.material.textfield.TextInputEditText
 | 
			
		||||
                android:id="@+id/port_input"
 | 
			
		||||
@@ -100,27 +102,30 @@
 | 
			
		||||
            app:layout_constraintEnd_toEndOf="parent"
 | 
			
		||||
            app:layout_constraintStart_toStartOf="parent"
 | 
			
		||||
            app:layout_constraintTop_toBottomOf="@id/port_input_layout"
 | 
			
		||||
            app:layout_constraintBottom_toTopOf="@id/button_connect"
 | 
			
		||||
            app:layout_constraintBottom_toTopOf="@id/selected"
 | 
			
		||||
            android:visibility="visible"/>
 | 
			
		||||
 | 
			
		||||
<!--        <include-->
 | 
			
		||||
<!--            layout="@layout/device_name"-->
 | 
			
		||||
<!--            app:layout_constraintEnd_toEndOf="parent"-->
 | 
			
		||||
<!--            app:layout_constraintHorizontal_bias="1.0"-->
 | 
			
		||||
<!--            app:layout_constraintStart_toStartOf="parent"-->
 | 
			
		||||
<!--            app:layout_constraintTop_toBottomOf="@+id/paired_devices" />-->
 | 
			
		||||
        <include
 | 
			
		||||
            android:id="@+id/selected"
 | 
			
		||||
            android:visibility="visible"
 | 
			
		||||
            layout="@layout/selected_device"
 | 
			
		||||
            app:layout_constraintBottom_toTopOf="@+id/button_connect"
 | 
			
		||||
            app:layout_constraintEnd_toEndOf="parent"
 | 
			
		||||
            app:layout_constraintStart_toStartOf="parent"
 | 
			
		||||
            app:layout_constraintTop_toBottomOf="@+id/port_input_layout" />
 | 
			
		||||
 | 
			
		||||
        <Button
 | 
			
		||||
            android:id="@+id/button_connect"
 | 
			
		||||
            android:layout_width="0dp"
 | 
			
		||||
            android:layout_width="match_parent"
 | 
			
		||||
            android:layout_height="wrap_content"
 | 
			
		||||
            android:layout_marginTop="16dp"
 | 
			
		||||
            android:paddingTop="16dp"
 | 
			
		||||
            android:paddingBottom="16dp"
 | 
			
		||||
            android:text="Connect"
 | 
			
		||||
            app:layout_constraintBottom_toTopOf="@+id/textView_github"
 | 
			
		||||
            app:layout_constraintEnd_toEndOf="parent"
 | 
			
		||||
            app:layout_constraintStart_toStartOf="parent"
 | 
			
		||||
            app:layout_constraintTop_toBottomOf="@id/paired_devices" />
 | 
			
		||||
            app:layout_constraintTop_toBottomOf="@id/selected" />
 | 
			
		||||
 | 
			
		||||
        <TextView
 | 
			
		||||
            android:id="@+id/textView_github"
 | 
			
		||||
@@ -133,5 +138,5 @@
 | 
			
		||||
            app:layout_constraintStart_toStartOf="parent"
 | 
			
		||||
            app:layout_constraintTop_toBottomOf="@+id/button_connect" />
 | 
			
		||||
 | 
			
		||||
    </androidx.constraintlayout.widget.ConstraintLayout>
 | 
			
		||||
    </LinearLayout>
 | 
			
		||||
</ScrollView>
 | 
			
		||||
@@ -3,44 +3,48 @@
 | 
			
		||||
    xmlns:app="http://schemas.android.com/apk/res-auto"
 | 
			
		||||
    xmlns:tools="http://schemas.android.com/tools"
 | 
			
		||||
    android:layout_width="match_parent"
 | 
			
		||||
    android:layout_height="match_parent">
 | 
			
		||||
    android:layout_height="wrap_content"
 | 
			
		||||
    android:clickable="true"
 | 
			
		||||
    android:focusable="true"
 | 
			
		||||
    android:background="?android:attr/selectableItemBackground">
 | 
			
		||||
 | 
			
		||||
    <ImageView
 | 
			
		||||
        android:id="@+id/imageView"
 | 
			
		||||
        android:layout_width="40dp"
 | 
			
		||||
        android:layout_height="40dp"
 | 
			
		||||
        android:padding="8dp"
 | 
			
		||||
        android:layout_width="64dp"
 | 
			
		||||
        android:layout_height="64dp"
 | 
			
		||||
        android:padding="16dp"
 | 
			
		||||
        app:layout_constraintBottom_toBottomOf="parent"
 | 
			
		||||
        app:layout_constraintStart_toStartOf="parent"
 | 
			
		||||
        app:layout_constraintTop_toTopOf="parent"
 | 
			
		||||
        app:layout_constraintEnd_toStartOf="@+id/textView"
 | 
			
		||||
        app:layout_constraintEnd_toStartOf="@+id/textView_device_name"
 | 
			
		||||
        app:srcCompat="@drawable/ic_baseline_bluetooth_24" />
 | 
			
		||||
 | 
			
		||||
    <TextView
 | 
			
		||||
        android:id="@+id/textView"
 | 
			
		||||
        android:id="@+id/textView_device_name"
 | 
			
		||||
        android:layout_width="wrap_content"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        android:textAppearance="?attr/textAppearanceHeadline6"
 | 
			
		||||
        android:text="TextView"
 | 
			
		||||
        app:layout_constraintBottom_toTopOf="@+id/textView2"
 | 
			
		||||
        app:layout_constraintBottom_toTopOf="@+id/textView_device_address"
 | 
			
		||||
        app:layout_constraintStart_toEndOf="@+id/imageView"
 | 
			
		||||
        app:layout_constraintTop_toTopOf="parent"
 | 
			
		||||
        app:layout_constraintVertical_chainStyle="packed" />
 | 
			
		||||
 | 
			
		||||
    <TextView
 | 
			
		||||
        android:id="@+id/textView2"
 | 
			
		||||
        android:id="@+id/textView_device_address"
 | 
			
		||||
        android:layout_width="wrap_content"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        android:textAppearance="?attr/textAppearanceBody2"
 | 
			
		||||
        android:text="TextView"
 | 
			
		||||
        app:layout_constraintBottom_toBottomOf="parent"
 | 
			
		||||
        app:layout_constraintStart_toEndOf="@+id/imageView"
 | 
			
		||||
        app:layout_constraintTop_toBottomOf="@+id/textView" />
 | 
			
		||||
        app:layout_constraintTop_toBottomOf="@+id/textView_device_name" />
 | 
			
		||||
 | 
			
		||||
    <ImageView
 | 
			
		||||
        android:id="@+id/imageView2"
 | 
			
		||||
        android:layout_width="wrap_content"
 | 
			
		||||
        android:layout_height="wrap_content"
 | 
			
		||||
        android:layout_width="64dp"
 | 
			
		||||
        android:layout_height="64dp"
 | 
			
		||||
        android:padding="16dp"
 | 
			
		||||
        app:layout_constraintBottom_toBottomOf="parent"
 | 
			
		||||
        app:layout_constraintEnd_toEndOf="parent"
 | 
			
		||||
        app:layout_constraintTop_toTopOf="parent"
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user