0

我正在尝试以编程方式启动 DFU 模式,以更新使用北欧硬件的 ble 设备的固件。这是我的完整代码:

package fr.digitalblend.dfu

import android.annotation.SuppressLint
import android.bluetooth.le.ScanFilter
import android.bluetooth.le.ScanSettings
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.telecom.Call
import android.view.View
import androidx.annotation.RequiresApi
import androidx.core.net.toUri

import no.nordicsemi.android.dfu.DfuProgressListenerAdapter
import no.nordicsemi.android.dfu.DfuServiceController
import no.nordicsemi.android.dfu.DfuServiceInitiator
import no.nordicsemi.android.dfu.DfuServiceListenerHelper
import no.nordicsemi.android.dfu.DfuBaseService
import okhttp3.Callback
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import org.json.JSONObject
import java.io.*
import java.io.FileOutputStream
import java.io.File

class MainActivity : AppCompatActivity() {
    
    private val mDfuProgressListener = object : DfuProgressListenerAdapter() {

        override fun onDeviceConnecting(deviceAddress: String) {
            println("CONNECTING")
        }

        override fun onDfuProcessStarting(deviceAddress: String) {
            println("WE START")
        }

        override fun onProgressChanged (
            deviceAddress: String,
            percent: Int,
            speed: Float,
            avgSpeed: Float,
            currentPart: Int,
            partsTotal: Int
        ) {
            super.onProgressChanged (
                deviceAddress,
                percent,
                speed,
                avgSpeed,
                currentPart,
                partsTotal
            )
        }

        override fun onDfuCompleted(deviceAddress: String) {

            println("UPDATE COMPLETE")
            super.onDfuCompleted(deviceAddress)

        }

        override fun onDfuAborted(deviceAddress: String) {
            println("!!!! onDfuAborted !!!!!")
        }

        override fun onError(deviceAddress: String, error: Int, errorType: Int, message: String?) {
            println("!!!! onError !!!!! ==> " + message)
        }

    }

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

        DfuServiceListenerHelper.registerProgressListener(this, mDfuProgressListener)
        getFlowKeyVersion()
    }
    
    private fun getFlowKeyVersion(){
        val request = Request
            .Builder()
            .url("https://xxxxxx/api/firmware/27/")
            .addHeader("Authorization", "Token xxxxx")
            .addHeader("Content-Type", "application/json")
            .build()

        val client = OkHttpClient()
        client.newCall(request).enqueue(object : Callback {
            @SuppressLint("UseCompatLoadingForDrawables")
            override fun onFailure(call: okhttp3.Call, e: IOException) {
                runOnUiThread {

                }
            }

            @SuppressLint("UseCompatLoadingForDrawables")
            override fun onResponse(call: okhttp3.Call, response: Response) {
                // Handle this
                if (response.code == 200) {
                    val rep = response.body?.string()

                    val jsonResponse = JSONObject(rep!!)
                    val version = jsonResponse.getString("version")

                    val jsonFile = jsonResponse.getJSONObject("file")
                    val url = jsonFile.getString("url")
                    val name = jsonFile.getString("name")
                    val size = jsonFile.getInt("size")
                    println(url)
                    println(name)
                    println(size)
                    println(version)

                    if(version != "1") {
                        runOnUiThread {
                            getFlowKeyFile(url, name, size)
                        }
                    }
                } else {
                    runOnUiThread {

                    }
                }
            }
        })
    }

    private fun getFlowKeyFile(url: String, name: String, size: Int) {
        val request = Request
            .Builder()
            .url(url)
            .addHeader("Authorization", "Token xxxxxxxx")
            .build()

        val client = OkHttpClient()
        client.newCall(request).enqueue(object : Callback {
            @SuppressLint("UseCompatLoadingForDrawables")
            override fun onFailure(call: okhttp3.Call, e: IOException) {
                runOnUiThread {

                }
            }

            @RequiresApi(Build.VERSION_CODES.O)
            @SuppressLint("UseCompatLoadingForDrawables")
            override fun onResponse(call: okhttp3.Call, response: Response) {
                // Handle this
                if (response.code == 200) {
                    var inputStream: InputStream? = null
                    try {
                        inputStream = response.body?.byteStream()
                        val buff = ByteArray(1024 * 4)
                        var downloaded: Long = 0
                        val target: Long = response.body?.contentLength()!!
                        val file = File(this@MainActivity.cacheDir, name)
                        val output: OutputStream = FileOutputStream(file)
                        while (true) {
                            val readed: Int = inputStream?.read(buff)!!
                            if (readed == -1) {
                                break
                            }
                            output.write(buff, 0, readed)
                            //write buff
                            downloaded += readed.toLong()
                        }
                        output.flush()
                        output.close()
                        if(size.toLong() == target){
                            if (file.exists()) {
                                println(file.absoluteFile)
                                dfuFlowKey(file)

                            } else {
                                println( "le fichier zip n'est pas disponible")
                            }
                        }
                    } catch (ignore: IOException) {

                    } finally {
                        inputStream?.close()
                    }

                } else {
                    runOnUiThread {

                    }
                }
            }
        })
    }

    @RequiresApi(Build.VERSION_CODES.O)
    fun dfuFlowKey(file: File) {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            DfuServiceInitiator.createDfuNotificationChannel(this)
        }

        var starter : DfuServiceInitiator? = null

            starter = DfuServiceInitiator("DF:27:D8:15:EE:42")

                .setUnsafeExperimentalButtonlessServiceInSecureDfuEnabled(true)
                .setKeepBond(false)
                .setZip(
                    file.toUri()
                )

            starter.start(this, DfuBaseService::class.java)


    }
}

我阅读了许多示例,当然还有官方文档,但都没有成功。开始后DfuServiceInitiator没有附加任何内容,我从不输入DfuProgressListenerAdapter函数......我的项目只有这个活动,没有别的。

任何想法 ?

谢谢你的帮助!

4

0 回答 0