蓝牙在 Android ViewPager 应用程序中断开连接

问题描述 投票:0回答:1

我目前正在使用 Kotlin 编写的移动应用程序,该应用程序使用户能够通过蓝牙远程控制机器人。我有 MainActivity 类,该类托管 3 个片段:定义蓝牙接口的 FragmentMain、FragmentCamera 和 FragmentDisplayText。 这是我的寻呼机适配器类:

class MyPagerAdapter(fragmentManager: FragmentManager) : FragmentStatePagerAdapter(fragmentManager) {
    override fun getItem(position: Int): Fragment {
        return when (position) {
            0 -> FragmentMain()
            1 -> FragmentCamera()
            2 -> FragmentDisplayText()
            else -> FragmentMain()
        }
    }

    override fun getCount(): Int {
        return 3
    }
}

我的问题是,当我在屏幕之间滑动并到达第三个屏幕时,蓝牙连接关闭。我不知道为什么会这样。

这是我的 MainActivity,我在其中为 ViewPager 设置适配器:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val tabLayout = findViewById<TabLayout>(R.id.tabLayout)
        val viewPager = findViewById<ViewPager>(R.id.viewPager)
        val adapter = MyPagerAdapter(supportFragmentManager)

        viewPager.adapter = adapter
        tabLayout.setupWithViewPager(viewPager)
    }
}

这就是我的蓝牙接口的工作原理:

/* ============================ Thread to Create Bluetooth Connection =================================== */

    inner class CreateConnectThread(private val activity: Activity, private val context: Context, private val bluetoothAdapter: BluetoothAdapter, private val address: String) :
        Thread() {

        init {
            val bluetoothDevice = bluetoothAdapter.getRemoteDevice(address)
            var tmp: BluetoothSocket? = null
            var uuid: UUID? = null

            if (ContextCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH) == PackageManager.PERMISSION_GRANTED
                && ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
                && ContextCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_CONNECT) == PackageManager.PERMISSION_GRANTED
                && ContextCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_SCAN) == PackageManager.PERMISSION_GRANTED) {
                uuid = bluetoothDevice.uuids[0].uuid
            } else {
                ActivityCompat.requestPermissions(
                    activity,
                    arrayOf(
                        Manifest.permission.BLUETOOTH,
                        Manifest.permission.BLUETOOTH_CONNECT,
                        Manifest.permission.ACCESS_FINE_LOCATION,
                        Manifest.permission.BLUETOOTH_SCAN
                    ), PERMISSION_REQUEST_CODE
                )
            }

            try {
                tmp = bluetoothDevice.createInsecureRfcommSocketToServiceRecord(uuid)
            } catch (e: IOException) {
                Log.e(TAG, "Socket's create() method failed", e)
            }
            if (tmp != null) {
                mmSocket = tmp
            }
        }

        override fun run() {
            if (ContextCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH) == PackageManager.PERMISSION_GRANTED
                && ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
                && ContextCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_CONNECT) == PackageManager.PERMISSION_GRANTED
                && ContextCompat.checkSelfPermission(context, Manifest.permission.BLUETOOTH_SCAN) == PackageManager.PERMISSION_GRANTED) {
                bluetoothAdapter.cancelDiscovery()
                try {
                    mmSocket.connect()
                    Log.e("Status", "Device connected")
                    handler.obtainMessage(CONNECTING_STATUS, 1, -1).sendToTarget()
                } catch (connectException: IOException) {
                    try {
                        mmSocket.close()
                        Log.e("Status", "Cannot connect to device")
                        handler.obtainMessage(CONNECTING_STATUS, -1, -1).sendToTarget()
                    } catch (closeException: IOException) {
                        Log.e(TAG, "Could not close the client socket", closeException)
                    }
                    return
                }
            } else {
                ActivityCompat.requestPermissions(
                    activity,
                    arrayOf(
                        Manifest.permission.BLUETOOTH,
                        Manifest.permission.BLUETOOTH_CONNECT,
                        Manifest.permission.ACCESS_FINE_LOCATION,
                        Manifest.permission.BLUETOOTH_SCAN
                    ), PERMISSION_REQUEST_CODE
                )
            }
            bluetoothAdapter.cancelDiscovery()
            connectedThread = ConnectedThread(mmSocket)
            connectedThread.start()
        }

        fun cancel() {
            try {
                mmSocket.close()
            } catch (e: IOException) {
                Log.e(TAG, "Could not close the client socket", e)
            }
        }
    }

    /* =============================== Thread for Data Transfer =========================================== */

    inner class ConnectedThread(socket: BluetoothSocket) : Thread() {
        private val mmSocket: BluetoothSocket = socket
        private val mmInStream: InputStream
        private val mmOutStream: OutputStream

        init {
            var tmpIn: InputStream? = null
            var tmpOut: OutputStream? = null
            try {
                tmpIn = socket.inputStream
                tmpOut = socket.outputStream
            } catch (_: IOException) {
            }
            mmInStream = tmpIn!!
            mmOutStream = tmpOut!!
        }

        override fun run() {
            val buffer = ByteArray(1024)
            var bytes = 0
            while (true) {
                try {
                    buffer[bytes] = mmInStream.read().toByte()
                    var readMessage: String
                    if (buffer[bytes] == '\n'.toByte()) {
                        readMessage = String(buffer, 0, bytes)
                        Log.e("Arduino Message", readMessage)
                        handler.obtainMessage(MESSAGE_READ, readMessage).sendToTarget()
                        bytes = 0
                    } else {
                        bytes++
                    }
                } catch (e: IOException) {
                    e.printStackTrace()
                    break
                }
            }
        }

        fun write(input: String) {
            val bytes = input.toByteArray()
            try {
                mmOutStream.write(bytes)
            } catch (e: IOException) {
                Log.e("Send Error", "Unable to send message", e)
            }
        }

        fun cancel() {
            try {
                mmSocket.close()
            } catch (e: IOException) {
            }
        }
    }

有人知道可能做错了什么吗?预先感谢您的帮助!

我尝试交换 FragmentCamera 和 FragmentDisplayText 但结果是相同的,蓝牙连接已建立,当我滑动到第二个屏幕时它可以工作,当我滑动到最后一个屏幕时它崩溃。

android android-fragments arduino bluetooth android-viewpager
1个回答
0
投票

我认为发生这种情况可能是因为您的蓝牙活动连接到屏幕,因此当您从该屏幕导航时,蓝牙功能会终止。解决方案是在服务中管理蓝牙活动。

一些参考:-

© www.soinside.com 2019 - 2024. All rights reserved.