ソースを参照

能扫到蓝牙了

Changpeng Duan 5 年 前
コミット
99303356ce

+ 21 - 8
app/src/main/java/com/example/watch/ui/activity/MainActivity.kt

@@ -20,6 +20,7 @@ import android.widget.TextView
 import android.widget.Toast
 import androidx.appcompat.app.AlertDialog
 import androidx.appcompat.app.AppCompatActivity
+import androidx.fragment.app.FragmentManager
 import androidx.fragment.app.FragmentPagerAdapter
 import androidx.viewpager.widget.ViewPager
 import com.android.chileaf.WearManager
@@ -74,15 +75,27 @@ class MainActivity : AppCompatActivity(), ScannerFragment.OnDeviceSelectedListen
     private fun linkHeartBand() {
         val chainBtn = findViewById<Button>(R.id.chainBtn)
         chainBtn.setOnClickListener {
-            if (isBLEEnabled()) {
-                if (!mDeviceConnected) {
-                    showDeviceScanningDialog()
-                } else {
-                    mManager!!.disConnect()
-                }
-            } else {
-                showBLEDialog()
+
+            val dialog = ScannerFragment.getInstance()
+            if(dialog == null){
+                println("1122")
+            }else{
+                dialog.show(supportFragmentManager, "scan_fragment")
             }
+
+//            val fragmentManager: FragmentManager = this.supportFragmentManager
+//            val dialog = ScannerFragment.getInstance()
+//            dialog.show(fragmentManager, "scanFragment");
+
+//            if (isBLEEnabled()) {
+//                if (!mDeviceConnected) {
+//                    showDeviceScanningDialog()
+//                } else {
+//                    mManager!!.disConnect()
+//                }
+//            } else {
+//                showBLEDialog()
+//            }
         }
     }
 

+ 0 - 458
app/src/main/java/com/example/watch/ui/activity/ScannerFragment.kt

@@ -1,458 +0,0 @@
-package com.example.watch.ui.activity
-
-import android.Manifest
-import android.app.Dialog
-import android.bluetooth.BluetoothAdapter
-import android.bluetooth.BluetoothDevice
-import android.bluetooth.BluetoothManager
-import android.content.Context
-import android.content.DialogInterface
-import android.content.pm.PackageManager
-import android.os.Bundle
-import android.os.Handler
-import android.text.TextUtils
-import android.view.Gravity
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import android.widget.*
-import androidx.appcompat.app.AlertDialog
-import androidx.core.app.ActivityCompat
-import androidx.core.content.ContextCompat
-import androidx.fragment.app.DialogFragment
-import com.android.chileaf.WearManager
-import com.android.chileaf.bluetooth.scanner.ScanCallback
-import com.android.chileaf.bluetooth.scanner.ScanResult
-import com.example.watch.R
-import com.example.watch.ui.activity.ScannerFragment.OnDeviceSelectedListener
-import timber.log.Timber
-import java.util.*
-
-/**
- * ScannerFragment class scan required BLE devices and shows them in a list. This class scans and filter
- * devices with standard BLE Service UUID and devices with custom BLE Service UUID. It contains a
- * list and a button to scan/cancel. There is a interface [OnDeviceSelectedListener] which is
- * implemented by activity in order to receive selected device. The scanning will continue to scan
- * for 5 seconds and then stop.
- */
-class ScannerFragment : DialogFragment() {
-    private var mBluetoothAdapter: BluetoothAdapter? = null
-    private var mListener: OnDeviceSelectedListener? = null
-    private var mAdapter: DeviceListAdapter? = null
-    private val mHandler = Handler()
-    private var mScanButton: Button? = null
-    private var mPermissionRationale: View? = null
-    private var mIsScanning = false
-    
-    fun getInstance(): ScannerFragment? {
-        val fragment = ScannerFragment()
-        val args = Bundle()
-        fragment.arguments = args
-        return fragment
-    }
-
-    /**
-     * Interface required to be implemented by activity.
-     */
-    interface OnDeviceSelectedListener {
-        /**
-         * Fired when user selected the device.
-         *
-         * @param device the device to connect to
-         * @param name   the device name. Unfortunately on some devices [BluetoothDevice.getName]
-         * always returns `null`, i.e. Sony Xperia Z1 (C6903) with Android 4.3.
-         * The name has to be parsed manually form the Advertisement packet.
-         */
-        fun onDeviceSelected(device: BluetoothDevice?, name: String?)
-
-        /**
-         * Fired when scanner dialog has been cancelled without selecting a device.
-         */
-        fun onDialogCanceled() {}
-    }
-
-    /**
-     * This will make sure that [OnDeviceSelectedListener] interface is implemented by activity.
-     */
-    override fun onAttach(context: Context) {
-        super.onAttach(context)
-        try {
-            mListener = context as OnDeviceSelectedListener
-        } catch (e: ClassCastException) {
-            throw ClassCastException("$context must implement OnDeviceSelectedListener")
-        }
-    }
-
-    override fun onCreate(savedInstanceState: Bundle?) {
-        super.onCreate(savedInstanceState)
-        val manager =
-            requireContext().getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
-        if (manager != null) {
-            mBluetoothAdapter = manager.adapter
-        }
-    }
-
-    override fun onDestroyView() {
-        stopScan()
-        super.onDestroyView()
-    }
-
-    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
-        val builder = AlertDialog.Builder(requireContext())
-        val dialogView: View =
-            LayoutInflater.from(activity).inflate(R.layout.fragment_device_scan, null)
-        val listview = dialogView.findViewById<ListView>(R.id.list)
-        listview.emptyView = dialogView.findViewById(R.id.empty)
-        listview.adapter = activity?.let {
-            DeviceListAdapter(it)
-                .also({ mAdapter = it })
-        }
-        builder.setTitle(R.string.scanner_title)
-        val dialog = builder.setView(dialogView).create()
-        listview.onItemClickListener =
-            AdapterView.OnItemClickListener { parent: AdapterView<*>?, view: View?, position: Int, id: Long ->
-                stopScan()
-                dialog.dismiss()
-                val d: ExtendedBluetoothDevice =
-                    mAdapter?.getItem(position) as ExtendedBluetoothDevice
-                mListener?.onDeviceSelected(d.device, d.name)
-            }
-        mPermissionRationale =
-            dialogView.findViewById(R.id.permission_rationale) // this is not null only on API23+
-        mScanButton = dialogView.findViewById(R.id.action_cancel)
-        mScanButton?.setOnClickListener(View.OnClickListener { v: View ->
-            if (v.id == R.id.action_cancel) {
-                if (mIsScanning) {
-                    dialog.cancel()
-                } else {
-                    startScan()
-                }
-            }
-        })
-        addBoundDevices()
-        if (savedInstanceState == null) startScan()
-        return dialog
-    }
-
-    override fun onCancel(dialog: DialogInterface) {
-        super.onCancel(dialog)
-            mListener?.onDialogCanceled()
-    }
-
-    override fun onRequestPermissionsResult(
-        requestCode: Int,
-        permissions: Array<String>,
-        grantResults: IntArray
-    ) {
-        when (requestCode) {
-            REQUEST_PERMISSION_REQ_CODE -> {
-                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
-                    // We have been granted the Manifest.permission.ACCESS_COARSE_LOCATION permission. Now we may proceed with scanning.
-                    startScan()
-                } else {
-                    mPermissionRationale!!.visibility = View.VISIBLE
-                    Toast.makeText(activity, R.string.no, Toast.LENGTH_SHORT)
-                        .show()
-                }
-            }
-        }
-    }
-
-    /**
-     * Scan for 5 seconds and then stop scanning when a BluetoothLE device is found then mLEScanCallback
-     * is activated This will perform regular scan for custom BLE Service UUID and then filter out.
-     * using class ScannerServiceParser
-     */
-    private fun startScan() {
-        // Since Android 6.0 we need to obtain either Manifest.permission.ACCESS_COARSE_LOCATION or Manifest.permission.ACCESS_FINE_LOCATION to be able to scan for
-        // Bluetooth LE devices. This is related to beacons as proximity devices.
-        // On API older than Marshmallow the following code does nothing.
-        if (ContextCompat.checkSelfPermission(
-                requireContext(),
-                Manifest.permission.ACCESS_COARSE_LOCATION
-            ) != PackageManager.PERMISSION_GRANTED
-        ) {
-            // When user pressed Deny and still wants to use this functionality, show the rationale
-            if (ActivityCompat.shouldShowRequestPermissionRationale(
-                    requireActivity(),
-                    Manifest.permission.ACCESS_COARSE_LOCATION
-                ) && mPermissionRationale!!.visibility == View.GONE
-            ) {
-                mPermissionRationale!!.visibility = View.VISIBLE
-                return
-            }
-            requestPermissions(
-                arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION),
-                REQUEST_PERMISSION_REQ_CODE
-            )
-            return
-        }
-
-        // Hide the rationale message, we don't need it anymore.
-        if (mPermissionRationale != null) mPermissionRationale!!.visibility = View.GONE
-        mAdapter?.clearDevices()
-        mScanButton?.setText(R.string.scanner_action_cancel)
-        WearManager.getInstance(activity).startScan(scanCallback)
-        mIsScanning = true
-        mHandler.postDelayed({
-            if (mIsScanning) {
-                stopScan()
-            }
-        }, SCAN_DURATION)
-    }
-
-    /**
-     * Stop scan if user tap Cancel button
-     */
-    private fun stopScan() {
-        if (mIsScanning) {
-            mScanButton?.setText(R.string.scanner_action_scan)
-            WearManager.getInstance(activity).stopScan()
-            mIsScanning = false
-        }
-    }
-
-    private val scanCallback: ScanCallback = object : ScanCallback() {
-        override fun onBatchScanResults(results: List<ScanResult>) {
-            mAdapter?.update(results)
-        }
-    }
-
-    private fun addBoundDevices() {
-        val devices = mBluetoothAdapter!!.bondedDevices
-        mAdapter?.addBondedDevices(devices)
-    }
-
-    private class DeviceListAdapter(private val mContext: Context) :
-        BaseAdapter() {
-        private val mListBondedValues: ArrayList<com.example.watch.ui.activity.ScannerFragment.ExtendedBluetoothDevice> =
-            ArrayList<com.example.watch.ui.activity.ScannerFragment.ExtendedBluetoothDevice>()
-        private val mListValues: ArrayList<com.example.watch.ui.activity.ScannerFragment.ExtendedBluetoothDevice> =
-            ArrayList<com.example.watch.ui.activity.ScannerFragment.ExtendedBluetoothDevice>()
-
-        /**
-         * Sets a list of bonded devices.
-         *
-         * @param devices list of bonded devices.
-         */
-        fun addBondedDevices(devices: Set<BluetoothDevice>) {
-            val bondedDevices: MutableList<com.example.watch.ui.activity.ScannerFragment.ExtendedBluetoothDevice> =
-                mListBondedValues
-            for (device in devices) {
-                if (matchDeviceName(device.name)) {
-                    bondedDevices.add(
-                        com.example.watch.ui.activity.ScannerFragment.ExtendedBluetoothDevice(
-                            device
-                        )
-                    )
-                }
-            }
-            notifyDataSetChanged()
-        }
-
-        private fun matchDeviceName(name: String?): Boolean {
-            if (name != null && !TextUtils.isEmpty(name)) {
-                for (filterName in FILTER_NAMES) {
-                    if (name.toUpperCase().startsWith(filterName)) {
-                        return true
-                    }
-                }
-            }
-            return false
-        }
-
-        /**
-         * Updates the list of not bonded devices.
-         *
-         * @param results list of results from the scanner
-         */
-        fun update(results: List<ScanResult>) {
-            for (result in results) {
-                Timber.e(result.toString())
-                val device: com.example.watch.ui.activity.ScannerFragment.ExtendedBluetoothDevice? =
-                    findDevice(result)
-                if (device == null) {
-                    if (hasPairAddress(result)) {
-                        mListValues.add(
-                            com.example.watch.ui.activity.ScannerFragment.ExtendedBluetoothDevice(
-                                result
-                            )
-                        )
-                    }
-                } else if (result.scanRecord != null) {
-                    device.name = result.scanRecord!!.deviceName
-                    device.rssi = result.rssi
-                }
-            }
-            notifyDataSetChanged()
-        }
-
-        private fun hasPairAddress(result: ScanResult): Boolean {
-            val record = result.scanRecord
-            val name = if (record != null) record.deviceName else ""
-            return matchDeviceName(name)
-        }
-
-        private fun findDevice(result: ScanResult): com.example.watch.ui.activity.ScannerFragment.ExtendedBluetoothDevice? {
-            for (device in mListBondedValues) if (device.matches(result) && hasPairAddress(result)) return device
-            for (device in mListValues) if (device.matches(result)) return device
-            return null
-        }
-
-        fun clearDevices() {
-            mListValues.clear()
-            notifyDataSetChanged()
-        }
-
-        override fun getCount(): Int {
-            val bondedCount = mListBondedValues.size + 1 // 1 for the title
-            val availableCount =
-                if (mListValues.isEmpty()) 2 else mListValues.size + 1 // 1 for title, 1 for empty text
-            return if (bondedCount == 1) availableCount else bondedCount + availableCount
-        }
-
-        override fun getItem(position: Int): Any {
-            val bondedCount = mListBondedValues.size + 1 // 1 for the title
-            return if (mListBondedValues.isEmpty()) {
-                if (position == 0) R.string.scanner_subtitle_not_bonded else mListValues[position - 1]
-            } else {
-                if (position == 0) return R.string.scanner_subtitle_bonded
-                if (position < bondedCount) return mListBondedValues[position - 1]
-                if (position == bondedCount) R.string.scanner_subtitle_not_bonded else mListValues[position - bondedCount - 1]
-            }
-        }
-
-        override fun getViewTypeCount(): Int {
-            return 3
-        }
-
-        override fun areAllItemsEnabled(): Boolean {
-            return false
-        }
-
-        override fun isEnabled(position: Int): Boolean {
-            return getItemViewType(position) == com.example.watch.ui.activity.ScannerFragment.DeviceListAdapter.Companion.TYPE_ITEM
-        }
-
-        override fun getItemViewType(position: Int): Int {
-            if (position == 0) return com.example.watch.ui.activity.ScannerFragment.DeviceListAdapter.Companion.TYPE_TITLE
-            if (!mListBondedValues.isEmpty() && position == mListBondedValues.size + 1) return com.example.watch.ui.activity.ScannerFragment.DeviceListAdapter.Companion.TYPE_TITLE
-            return if (position == count - 1 && mListValues.isEmpty()) com.example.watch.ui.activity.ScannerFragment.DeviceListAdapter.Companion.TYPE_EMPTY else com.example.watch.ui.activity.ScannerFragment.DeviceListAdapter.Companion.TYPE_ITEM
-        }
-
-        override fun getItemId(position: Int): Long {
-            return position.toLong()
-        }
-
-        override fun getView(position: Int, oldView: View, parent: ViewGroup): View {
-            val inflater = LayoutInflater.from(mContext)
-            val type = getItemViewType(position)
-            var view = oldView
-            when (type) {
-                com.example.watch.ui.activity.ScannerFragment.DeviceListAdapter.Companion.TYPE_EMPTY -> if (view == null) {
-                    view = TextView(mContext)
-                    val empty = view
-                    empty.gravity = Gravity.CENTER_HORIZONTAL
-                    empty.text = mContext.getString(R.string.scanner_empty)
-                }
-                com.example.watch.ui.activity.ScannerFragment.DeviceListAdapter.Companion.TYPE_TITLE -> {
-                    if (view == null) {
-                        view = TextView(mContext)
-                    }
-                    val title = view as TextView
-                    title.gravity = Gravity.CENTER_HORIZONTAL
-                    title.setText((getItem(position) as Int))
-                }
-                else -> {
-//                    if (view == null) {
-//                        view = inflater.inflate(R.layout.item_device_list, parent, false)
-//                        val holder: com.example.watch.ui.activity.ScannerFragment.DeviceListAdapter.ViewHolder =
-//                            com.example.watch.ui.activity.ScannerFragment.DeviceListAdapter.ViewHolder()
-//
-//                        holder.name = view.findViewById<TextView>(R.id.name)
-//                        holder.address = view.findViewById<TextView>(R.id.address)
-//                        holder.signal = view.findViewById<TextView>(R.id.rssi)
-//                        view.tag = holder
-//                    }
-                    val device: com.example.watch.ui.activity.ScannerFragment.ExtendedBluetoothDevice =
-                        getItem(position) as com.example.watch.ui.activity.ScannerFragment.ExtendedBluetoothDevice
-                    val holder: com.example.watch.ui.activity.ScannerFragment.DeviceListAdapter.ViewHolder =
-                        view.tag as com.example.watch.ui.activity.ScannerFragment.DeviceListAdapter.ViewHolder
-                    val name: String? = device.name
-                    holder.name?.setText(name ?: mContext.getString(R.string.not_available))
-                    holder.address?.setText(device.device.getAddress())
-                    if (!device.isBonded || device.rssi != com.example.watch.ui.activity.ScannerFragment.ExtendedBluetoothDevice.Companion.NO_RSSI) {
-                        holder.signal?.setText(device.rssi.toString() + "dBm")
-                        holder.signal?.setVisibility(View.VISIBLE)
-                    } else {
-                        holder.signal?.setVisibility(View.GONE)
-                    }
-                }
-            }
-            return view
-        }
-
-        private inner class ViewHolder {
-            var name: TextView? = null
-            var address: TextView? = null
-            var signal: TextView? = null
-        }
-
-        companion object {
-            private const val TYPE_TITLE = 0
-            private const val TYPE_ITEM = 1
-            private const val TYPE_EMPTY = 2
-        }
-    }
-
-    private class ExtendedBluetoothDevice {
-        var name: String?
-        var rssi: Int
-        var isBonded: Boolean
-        val device: BluetoothDevice
-
-        constructor(scanResult: ScanResult) {
-            device = scanResult.device
-            name = if (scanResult.scanRecord != null) scanResult.scanRecord!!.deviceName else null
-            rssi = scanResult.rssi
-            isBonded = false
-        }
-
-        constructor(device: BluetoothDevice) {
-            this.device = device
-            name = device.name
-            rssi =
-                com.example.watch.ui.activity.ScannerFragment.ExtendedBluetoothDevice.Companion.NO_RSSI
-            isBonded = true
-        }
-
-        fun matches(scanResult: ScanResult): Boolean {
-            return device.address == scanResult.device.address
-        }
-
-        companion object {
-            const val NO_RSSI = -1000
-        }
-    }
-
-    companion object {
-        @JvmName("getInstance1")
-        fun getInstance(): ScannerFragment {
-            val fragment = ScannerFragment()
-            val args = Bundle()
-            fragment.arguments = args
-            return fragment
-        }
-
-        private const val SCAN_DURATION: Long = 5000
-        private const val REQUEST_PERMISSION_REQ_CODE = 34
-        private val FILTER_NAMES = arrayOf("CL831", "SE2")
-        val instance: ScannerFragment
-            get() {
-                val fragment = ScannerFragment()
-                val args = Bundle()
-                fragment.arguments = args
-                return fragment
-            }
-    }
-}

+ 1 - 1
app/src/main/res/layout/fragment_device_scan.xml

@@ -17,7 +17,7 @@
         android:visibility="gone" />
 
     <ListView
-        android:id="@+id/list"
+        android:id="@android:id/list"
         android:layout_width="match_parent"
         android:layout_height="0dp"
         android:layout_weight="1"