2024年1月2日 星期二

ANDROID STUDIO & KT & BLE

ANDROID STUDIO

版本giraffe 2022.3.1 patch 3--> 安裝
( JETPACK 連結 完全不知道是什麼 )
開新專案不成功,因為要先安裝SDK才能開專案--> 安裝
編譯不成功,因為要安裝gradle--> 安裝

程式不能編譯,因為KT的環境沒弄好--> 安裝
終於編譯成功。到這個階段覺得,新版IDE功能雖然強大但安裝門檻實在很高,佩服一般開發者都能走到這步。

安裝程式


軟體模擬器:安裝失敗(加速顯示不能用,AVD不能用,應該是這台筆電沒有專業顯卡)
實體手機執行:找了舊SONY XPERIA(ANDROID 8.0最高版本,已設為開發模式)-->安裝成功

螢幕截圖和錄影
logcat->有螢幕截圖功能。(連結)
logcat->有螢幕錄影功能。可以錄製三分鐘影片。

LOG資訊
Log.d("KAYJEAN", "get name " + device.name)
出現在logcat

KT(kotlin)語法

新程式語法(感覺是介於PYTHON和JAVA兩者之間),

KT APP專屬設定

入口架構

AndroidManifest.xml資料
設定activity : 
        <activity
            android:name="com.elegant.access.NavActivity"
            android:label="@string/app_name"
            android:theme="@style/Theme.Elegant.Access.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
設定service : 
        <service android:name="com.elegant.access.service.BluetoothLeService" android:enabled="true"/>

桌面按鈕

Fragment為主

    新的UI設計概念,以fragment為主當中各頁面透過navigator切換到其他activity

第一頁:起始動畫(SPLASH)
NAVACTIVITY裡面使用 activity_nav_main ( nav_graph.xml  )

第二頁:開始畫面(StartFragment)  StartContent->LogoCard 按下button跳到下一頁
第三頁:資料出現在DeviceListContent,資料來源為DeviceListBoardCast會將資訊發佈,如果在這邊設定過濾條件,應該就可以過濾想要看到的那類裝置。


每個項目可被點擊
fun BleDeviceCard(bleDevice: BleDevice, navigateToLogin: (BleDevice) -> Unit) {
    Column(
        modifier = Modifier
            .clickable(onClick = { navigateToLogin(bleDevice) })

Jetpack compose

新的版面設計概念,不依靠XML,物件由程式依序寫入而生成。
基礎教學 連結,image 連結,progress bar  連結 連結

BLE

文章說明( 連結 ) 程式( 連結 ) 進度為:用KT連結PIXART,

log 1 2 3 4 5  這邊已經進行 device.connectGatt 完畢

log 10 BluetoothProfile.STATE_CONNECTED 進入這個狀態

從log看狀況

Timber.i("Connected to GATT server.")

Timber.i("Attempting to start service discovery: %s", bluetoothGatt?.discoverServices())  這會自動進行後面動作

log 50 52 BluetoothGatt.GATT_SUCCESS  應該可以繼續發展,傳送資料 但是因為沒有後續,之後就進入 log 11 BluetoothProfile.STATE_DISCONNECTED

log 10 > 後面重複循環 (應是系統自行connect)

過程中基礎知識薄弱,又參考(連結 github位置)

write的功能已經驗證,write完畢會收到onXXX,但是只是結果正確與否,而不是BLE裝置送出的項目
取得部分方式一read,只是BLE這邊沒有對應程式,先跳過
取得部分方式二notification
A.先設定enableIndicateNotification(APP自行設計 setCharacteristicNotification)
會啟動系統gatt.writeDescriptor
B.這裡應該是會收到訊息的地方
override fun onCharacteristicChanged(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic) {
        val content = ByteUtils.bytesToHexString(characteristic.value)
        uiCallback.state("特性改变: 收到内容:$content")
}




DeviceListFragment

BluetoothAdapter.startDiscovery() -> 掃描經典藍芽和BLE藍芽兩種(  目前範例使用這個 )
BluetoothAdapter.startLeScan() -> 用來掃描低功耗藍芽 —- 已被棄用
BluetoothLeScanner.startScan() -> 新的BLE掃描方法
理論上,可以限定要搜尋的service,帶入代表該service的UUID
有四件事情
1.繼承一個BroadcastReceiver 然後使用receiver type的形式返回結果bleDevice
private val receiver = DeviceListBoardCast { bleDevice ->deviceViewModel.addDevice(bleDevice)}
這個在下一個
2.註冊監聽BluetoothDevice.ACTION_FOUND
val filter = IntentFilter(BluetoothDevice.ACTION_FOUND)
    requireContext().registerReceiver(receiver, filter)
掃描的結果會返回DeviceListBoardCast {}內,根據專案調整
3.private val bluetoothAdapter: BluetoothAdapter? = BluetoothAdapter.getDefaultAdapter()
4.bluetoothAdapter!!.startDiscovery()

DeviceListBroadcast

取得資料的運作
val device: BluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)!!
val rssi = intent.getShortExtra(BluetoothDevice.EXTRA_RSSI, Short.MIN_VALUE).toInt()
val uuidExtra = intent.getParcelableArrayExtra(BluetoothDevice.EXTRA_UUID)

BlueToothLEService

找到藍芽裝置
建好service,當跟藍芽綁定時,就能互相溝通,並建立Binder,用來onBind時返回實例給fragment去調用。
準備幾個返回的callback
onConnectionStateChange新的連接狀態改變
onServicesDiscovered新的服務被發現
onCharacteristicRead新的東西讀到後
重要功能是啟動connect
進入點是前面DeviceListFragment
執行service中的connect
要跟裝置內的GATT Server連線mBluetoothGatt = device.connectGatt(this, false, mGattCallback);這會連線到藍芽裝置host的GATT Server。
bluetoothGatt = device.connectGatt(this, false, gattCallback)
把要連線的adress丟進去
拿到想要連線的BluetoothDevice
再用device內的方法connectGatt去綁定Gatt裝置
當然同時要丟入前面寫好的gattCallback

讀取資料

displayGattServices
藍芽最重要的就是終端之間的通訊
所以如果想要收送資料
必需要找出service與characteristic
這個範例並沒有提到如何讀取資料,如果真的要進行
gattServices.forEach { gattService ->
    取得各個charxxxx  有sample但實際code沒看到
fun readCharacteristic(characteristic: BluetoothGattCharacteristic) {
        bluetoothGatt?.let { gatt ->
            gatt.readCharacteristic(characteristic)
    這是取得characteristic內容 
private val bluetoothGattCallback = object : BluetoothGattCallback() {
        override fun onCharacteristicRead(
            gatt: BluetoothGatt,
            characteristic: BluetoothGattCharacteristic,
            status: Int
            ) {
                if (status == BluetoothGatt.GATT_SUCCESS) {
                broadcastUpdate(BluetoothService.ACTION_DATA_AVAILABLE, characteristic)
            }
        }
    }
其他類似範例(連結)

其他

理論:Android BT API(連結)。

基本character:範例

  1. 對應ADAFRUIT IOS 有幾個不同的  連結 連結
  2. 落落長非常專業說明 連結 連結

進階HID:PIXART的範例聚集在HID(連結  連結)。


沒有留言:

張貼留言