diff --git a/software/android/app/src/main/AndroidManifest.xml b/software/android/app/src/main/AndroidManifest.xml index c721c7d..3517895 100644 --- a/software/android/app/src/main/AndroidManifest.xml +++ b/software/android/app/src/main/AndroidManifest.xml @@ -12,6 +12,10 @@ android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.Hexapod"> + ? = 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(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(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 = bluetoothManager!!.adapter.bondedDevices + + // If there are paired devices, add each one to the ArrayAdapter + if (pairedDevices.isNotEmpty()) { + findViewById(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.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" + } +} \ No newline at end of file diff --git a/software/android/app/src/main/java/com/rookiedev/hexapod/MainActivity.kt b/software/android/app/src/main/java/com/rookiedev/hexapod/MainActivity.kt index 8284d2f..bf640d0 100644 --- a/software/android/app/src/main/java/com/rookiedev/hexapod/MainActivity.kt +++ b/software/android/app/src/main/java/com/rookiedev/hexapod/MainActivity.kt @@ -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(R.id.port_input_layout) val deviceList = findViewById(R.id.paired_devices) + val selectedDevice = findViewById(R.id.selected) + val deviceName = findViewById(R.id.textView_device_name) + val deviceAddress = findViewById(R.id.textView_device_address) val sourceLink = findViewById(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(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(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 = 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(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) { diff --git a/software/android/app/src/main/res/layout/activity_device_list.xml b/software/android/app/src/main/res/layout/activity_device_list.xml new file mode 100644 index 0000000..ebacdde --- /dev/null +++ b/software/android/app/src/main/res/layout/activity_device_list.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/software/android/app/src/main/res/layout/activity_main.xml b/software/android/app/src/main/res/layout/activity_main.xml index e4a5daa..f9ad9a8 100644 --- a/software/android/app/src/main/res/layout/activity_main.xml +++ b/software/android/app/src/main/res/layout/activity_main.xml @@ -6,11 +6,13 @@ android:layout_height="match_parent" tools:context=".MainActivity"> - + android:paddingEnd="16dp" + android:orientation="vertical" + android:gravity="center_horizontal"> + app:layout_constraintTop_toBottomOf="@+id/tab"> + app:layout_constraintTop_toBottomOf="@id/ip_input_layout"> - - - - - - +