Kotlinを使用したナビゲーショングローブIOTアプリケーションにおけるBluetoothを用いたスマートグローブへの接続—第5部


導入


この記事では、どのようにペアのデバイスからスマート手袋を接続する方法を学びます.プロセスは、スマート手袋のアプリケーションです.スマートグローブアプリケーションは、すべてのペアのBluetoothデバイスを示しています.ユーザーは手袋を選択し、Bluetoothデバイスに接続する必要があります.
あなたが記事のシリーズに新しい場合は、記事に従ってください.
Beginner: Integration of Huawei Account kit in Navigation Glove IoT application Using Kotlin - Part 1
Beginner: Integration of Huawei Map kit in Navigation Glove IoT application Using Kotlin - Part 2
Beginner: Integration of Huawei Site kit in Navigation Glove IoT application Using Kotlin - Part 3
Beginner: Integration of Huawei Direction API in Navigation Glove IoT application Using Kotlin - Part 4
この記事では、アプリケーション内のすべてのペアデバイスを表示する方法を学びます.また、どのようにAndroidでのリサイクルReviewを統合する方法を学びます.確認してくださいデバイスはすでに電話に対するペアです.
注:AndroidX古いアプリケーションでは、アプリケーションを開発している場合は、RemoteerView依存関係を追加する必要がありますアンドロイドで構築されています.
AndroidManifestで次のアクセス許可を追加します.XML
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
手順に従う
ステップ1 : ActivityThank ConnectRenSmartSense手袋にリサイクルのビューを追加します.XML
<androidx.recyclerview.widget.RecyclerView
    android:id="@+id/recyclerView"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_above="@+id/pairedDeviceBtn"
    android:layout_below="@id/messageTv"
    tools:listitem="@layout/paired_device_list_item"/>
ステップ2:あなたがアイテムを表示する場合は、1つのXMLファイルを作成することができます.
PairedRange DeviceLachy ListchenアイテムXML
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="80dp"
    android:layout_margin="10dp"
    app:cardElevation="6dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center"
        android:gravity="center|start"
        android:orientation="horizontal"
        android:padding="5dp"
        android:id="@+id/rootLayout">

        <ImageView
            android:id="@+id/imageview"
            android:layout_width="50dp"
            android:layout_height="50dp"
            android:layout_marginStart="5dp"
            android:src="@drawable/gloves_ic"
            android:visibility="visible" />

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginStart="5dp"
            android:orientation="vertical">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:layout_weight="1"
                android:gravity="center|start"
                android:orientation="horizontal">

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginStart="10dp"
                    android:layout_marginLeft="15dp"
                    android:text="@string/name"
                    android:textSize="16sp"
                    android:textStyle="bold" />

                <TextView
                    android:id="@+id/deviceName"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginStart="10dp"
                    android:layout_marginLeft="15dp"
                    android:textSize="16sp"
                    android:textStyle="bold" />
            </LinearLayout>

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:layout_weight="1"
                android:gravity="center|start"
                android:orientation="horizontal">

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginStart="10dp"
                    android:layout_marginLeft="15dp"
                    android:text="@string/mac_address"
                    android:textSize="16sp"
                    android:textStyle="bold" />

                <TextView
                    android:id="@+id/macAddress"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginStart="10dp"
                    android:layout_marginLeft="15dp"
                    android:textSize="16sp"
                    android:textStyle="bold" />
            </LinearLayout>
        </LinearLayout>
    </LinearLayout>

</androidx.cardview.widget.CardView>
ステップ3 :デバイスモデル( DeviceModel . kt )のデータクラスを作成する
package com.huawei.navigationglove.model

data class DeviceModel(val name: String, val macAddress: String)
Step 4 :レイアウトマネージャーを宣言します.
private lateinit var linearLayoutManager: LinearLayoutManager
ステップ5 :デバイスモデル変数とペアデバイスリストを宣言します.
private var pairedDeviceList = ArrayList<DeviceModel>()
var deviceModel: DeviceModel? = null
Step 6 :レイアウトマネージャを初期化し、oncreate ()で再表示します.
linearLayoutManager = LinearLayoutManager(this)
recyclerView.layoutManager = linearLayoutManager
ステップ7 : paireddevicelistAdapterを作成します.リサイクルのためのKTビュー.
package com.huawei.navigationglove.ui.adapters

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.huawei.navigationglove.R
import com.huawei.navigationglove.callbacks.OnDeviceClickCallback
import com.huawei.navigationglove.model.DeviceModel

class PairedDevicesAdapter(
    private val mList: List<DeviceModel>,
    private val onDeviceClickCallback: OnDeviceClickCallback
) :
    RecyclerView.Adapter<PairedDevicesAdapter.ViewHolder>() {

    // create new views
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context)
            .inflate(R.layout.paired_device_list_item, parent, false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val deviceModel = mList[position]
        holder.deviceName.text = deviceModel.name
        holder.macAddress.text = deviceModel.macAddress
        holder.rootLayout.setOnClickListener { onDeviceClickCallback.onDeviceClick(deviceModel) }
    }

    // return the number of the items in the list
    override fun getItemCount(): Int {
        return mList.size
    }

    // Holds the views for adding it to image and text
    class ViewHolder(ItemView: View) : RecyclerView.ViewHolder(ItemView) {
        val deviceName: TextView = itemView.findViewById(R.id.deviceName)
        val macAddress: TextView = itemView.findViewById(R.id.macAddress)
        val rootLayout: LinearLayout = itemView.findViewById(R.id.rootLayout)
    }
}
ステップ8:今すべてのペアデバイスを取得し、アダプタのデバイスのリストを設定します.
private fun pairedDevicesList() {
    pairedDeviceList = ArrayList<DeviceModel>()
    pairedDevices = myBluetooth!!.bondedDevices
    val list: ArrayList<String> = ArrayList<String>()
    if ((pairedDevices as MutableSet<BluetoothDevice>?)!!.size > 0) {
        for (bt in (pairedDevices as MutableSet<BluetoothDevice>?)!!) {
            Log.e(TAG, bt.name + "\n" + bt.address)
            list.add(bt.name + "\n" + bt.address) //Get the device's name and the address
            deviceModel = DeviceModel(bt.name, bt.address)
            pairedDeviceList.add(deviceModel!!)
        }
        val adapter = PairedDevicesAdapter(pairedDeviceList, this)
        recyclerView.adapter = adapter
    } else {
        Toast.makeText(
            applicationContext,
            "No Paired Bluetooth Devices Found.",
            Toast.LENGTH_LONG
        ).show()
    }
}
ステップ9:今すぐリサイクルerviewはペアデバイスのリストが表示されます.今、ユーザーが接続しているデバイス上でクリックします.だから今ではCreonerViewのonclickを作成できます.そのためにはインターフェイスコールバックを使用します.
Create OnDeviceClickCallback.kt interface.


package com.huawei.navigationglove.callbacks

import com.huawei.navigationglove.model.DeviceModel
interface OnDeviceClickCallback {
fun onDeviceClick(deviceModel: DeviceModel)
}
手順9 :このインターフェイスをアクティビティで実装します.
class ConnectSmartGlovesActivity : AppCompatActivity(), OnDeviceClickCallback {
関数をオーバーライドします.
override fun onDeviceClick(deviceModel: DeviceModel) {
address = deviceModel.macAddress
ConnectBT(this).execute()
}
Step 10 :次の変数を作成します.
private var progress: ProgressDialog? =null //This progress dialog box while connecting to bluetooth
private var isBtConnected = false
var btSocket: BluetoothSocket? = null //Bridge which sends data to bluetooth from Android app
var myBluetooth: BluetoothAdapter? = null
val myUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB") //Unique
var address: String? = null
ステップ11 :接続のための非同期クラスを作成します.
//このクラスには、HC - 05モジュールに接続するために必要な関数が含まれます
open class ConnectBT(val context: Context) : AsyncTask<Void?, Void?, Void?>() // UI thread
{
    private var ConnectSuccess = true //if it's here, it's almost connected
    override fun onPreExecute() {
        progress = ProgressDialog.show(
            context,
            "Connecting...",
            "Please wait!!!"
        ) //show a progress dialog
    }


    @SuppressLint("MissingPermission")
    override fun doInBackground(vararg devices: Void?): Void? //while the progress dialog is shown, the connection is done in background
    {
        try {
            if (btSocket == null || !isBtConnected) {
                myBluetooth =
                    BluetoothAdapter.getDefaultAdapter() //get the mobile bluetooth device
                val dispositivo: BluetoothDevice = myBluetooth!!.getRemoteDevice(address) //connects to the device's address and checks if it's available
                Log.e(TAG,"Device: "+Gson().toJson(dispositivo))
                btSocket = dispositivo.createInsecureRfcommSocketToServiceRecord(myUUID) //create a RFCOMM (SPP) connection
                Log.e(TAG,"Device: "+Gson().toJson(btSocket))
                BluetoothAdapter.getDefaultAdapter().cancelDiscovery()
                btSocket!!.connect() //start connection
            }
        } catch (e: IOException) {
            ConnectSuccess = false //if the try failed, you can check the exception here
            Log.e("MapsActivity","Device not connected" +e.message)
        }
        return null
    }

    override fun onPostExecute(result: Void?) //after the doInBackground, it checks if everything went fine
    {
        super.onPostExecute(result)
        if (!ConnectSuccess) {
            val toast =
                Toast.makeText(context, "Failure", Toast.LENGTH_LONG)
            toast.show()
            val handler = Handler()
            handler.postDelayed({ toast.cancel() }, 300)
            //TODO need to check this
            //finish()
        } else {
            val toast = Toast.makeText(context, "Success.", Toast.LENGTH_LONG)
            toast.show()
            val handler = Handler()
            handler.postDelayed({ toast.cancel() }, 300)

            //msg("Connected.");
            SystemClock.sleep(1000)
            isBtConnected = true
        }
        progress!!.dismiss()
    }
}
ステップ12 :接続と切断状態を取得するには、oncreate ()でレジスタブロードキャスト受信を作成します.
val filter = IntentFilter()
filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED)
filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED)
filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED)
this.registerReceiver(nReceiver, filter)
ステップ13:作成放送受信機.
//This BroadcastReceiver finds listens the status of bluetooth
private val nReceiver: BroadcastReceiver? = object : BroadcastReceiver() {
    @RequiresApi(Build.VERSION_CODES.M)
    override fun onReceive(context: Context, intent: Intent) {
        val action = intent.action
        val device = intent.getParcelableExtra<BluetoothDevice>(BluetoothDevice.EXTRA_DEVICE)
        if (BluetoothDevice.ACTION_FOUND == action) {
        } else if (BluetoothDevice.ACTION_ACL_CONNECTED == action) {
            co = true
            Log.e("mode:", "Connected")
            requestLocationUpdatesWithCallback()
        } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED == action) {
        } else if (BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED == action) {
            Log.e("mode:", "disConnected")
        } else if (BluetoothDevice.ACTION_ACL_DISCONNECTED == action) {
            co = false
            Log.e("mode:", "disConnected1")
            val vib = context.getSystemService(Vibrator::class.java)
            Log.e("Vibe", "" + vib.hasVibrator())
            //t1.speak("Your Bluetooth Has Been Disconnected", TextToSpeech.QUEUE_FLUSH, null);
            for (i in 0..4) {
                vib.vibrate(700)
                SystemClock.sleep(1000)
            }
            i = 0
        }
    }
}

結果



ヒントとトリック

  • AndroidManifestでBluetoothアクセス許可を追加したことを確認します.XML
  • 電話ブルートゥースが有効になっていることを確認します.
  • AndroidXの下にアプリケーションを構築している場合は、buildの依存性を追加してください.Gradleファイル.
  • 結論


    この記事では、我々はどのようにAndroidのアプリケーションでは、スマート手袋のアプリケーションでペアデバイスのリストが表示されていると一緒にRecrutionerViewを使用する方法を学んだ.また、スマートグローブアプリケーションからデバイスを接続する方法を学んだ.

    リファレンス


    Bluetooth Official document
    Recyclerview Document