polarofficial / polar-ble-sdk

Repository includes SDK and code examples. More info https://polar.com/en/developers
Other
447 stars 147 forks source link

fetching files on to my desktop computer from h10 - android 14 breaks WRITE_EXTERNAL_STORAGE #426

Open smyffanon opened 6 months ago

smyffanon commented 6 months ago

Platform your question concerns:

Device:

Description:

I think I missed a change in the API and need to re write my code to use

downloadRecordingButton( EDIT: when this happened I read the code too fast, and mistakenly thought the verity code applied to the h10)

, but for the next couple of weeks while I'm working on this, is there some temporary work around for this?

What is the standard way with android 14 to get files off my h10 and on to my desktop computer?

Files don't need to go on the phone, although that is the way I've been doing it.

I was using the API calls related to these:

mainactivity.rkt in function fetchExerciseButton val path = getExternalFilesDir(null)

AndroidManifest.xml

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

and this seems broken with the update to android 14.

I cannot now create a directory Internal\ shared\ storage/Android/data/com.polar.rr_004/files/

even using the files app on stock android 14, the app says it cannot create the directory.

Question TWO: can we not use whatever method Polar Sensor Logger is using?
That seems unaffected by the upgrade to 14.

smyffanon commented 6 months ago

(December 12 update) For the moment I have downgraded my phone to Android 13,

trying to figure out how to get my r-r exercise recordings on to the phone, can't see any way to do it (I'm not an Android developer, in case you're wondering, I'm just trying to mod the code as best I can)

smyffanon commented 6 months ago

Working in android 13 to get the RR intervals to the Download directory, this code supposedly works on Android 14.

So what to do now? if this doesn't work on Android 14 it's 4 hours round-trip to updating to 14, testing this app, then downgrading to 13 if it doesn't work out.

I'll wait on that for a bit.

    fetchExerciseButton.setOnClickListener {
        val fileName = "rr_" + deviceId

        val context = getApplicationContext()
        val outputStream: OutputStream? = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            val values = ContentValues()
            values.put(MediaStore.MediaColumns.DISPLAY_NAME, fileName)
            values.put(MediaStore.MediaColumns.MIME_TYPE, "text/plain")
            values.put(MediaStore.MediaColumns.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS)
            val extVolumeUri: Uri = MediaStore.Files.getContentUri("external")

            val fileUri: Uri? = context.contentResolver.insert(extVolumeUri, values)
            context.contentResolver.openOutputStream(fileUri!!)
        } else {
            val path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).toString()
            val file = File(path, "$fileName")
            FileOutputStream(file)
        }

        val isDisposed = fetchExerciseDisposable?.isDisposed ?: true
        if (isDisposed) {
            if (exerciseEntries.isNotEmpty()) {
                toggleButtonDown(fetchExerciseButton, R.string.reading_exercise)
                // just for the example purpose read the entry which is first on the exerciseEntries list
                fetchExerciseDisposable = api.fetchExercise(deviceId, exerciseEntries.first())
                    .observeOn(AndroidSchedulers.mainThread())
                    .doFinally {
                        toggleButtonUp(fetchExerciseButton, R.string.read_exercise)
                    }
                    .subscribe(
                        { polarExerciseData: PolarExerciseData ->
                            Log.d(TAG, "Exercise data count: ${polarExerciseData.hrSamples.size} samples: ${polarExerciseData.hrSamples}")
                            var onComplete = "Exercise has ${polarExerciseData.hrSamples.size} hr samples.\n\n"
                            if (polarExerciseData.hrSamples.size >= 3)
                                onComplete += "HR data {${polarExerciseData.hrSamples[0]}, ${polarExerciseData.hrSamples[1]}, ${polarExerciseData.hrSamples[2]} ...}"
                            showDialog("Exercise data read", onComplete)

                            try {
                                val itr = polarExerciseData.hrSamples.listIterator()
                                val p = PrintWriter(outputStream)
                                while(itr.hasNext()){
                                    p.println(itr.next())
                                }
                                p.close()
                            } catch (e: IOException) {
                                e.printStackTrace()
                            }

                        },
                        { error: Throwable ->
                            val errorDescription = "Failed to read exercise. Reason: $error"
                            Log.e(TAG, errorDescription)
                            showSnackbar(errorDescription)
                        }
                    )
            } else {
                val helpTitle = "Reading exercise is not possible"
                val helpMessage = "Either device has no exercise entries or you haven't list them yet. Please, create an exercise or use the \"LIST EXERCISES\" " +
                        "button to list exercises on device."
                showDialog(helpTitle, helpMessage)
            }
        } else {
            Log.d(TAG, "Reading of exercise is in progress at the moment.")
        }
    }