Skip to main content

PPG2 / BioZ / Accelerometer / ECG transfer & export

Location of the files: PPG2, EmoGraphy, BioZ, Accelerometer

All the files are saved in the internal app folder on the phone.

The folders are not accessible externally, here is the list of the folders per type:

enum class RawFileType(val directory: String) {  
UNKNOWN(""),

SLEEP("sleep"),

PPG2("ppg2"),

ECG("ecg"),

BIOZ("bioz"),

ACC("acc");
}

The list of files is accessible in the table RawFileChunk

Exportable files have the type <type>_FULL, example for PPG2: PPG2_FULL

Once exported, the files are deleted

  • Get the exportable files

Use the following code:

DataSdk.getInstance().getManager().rawFileRepository?.getExportabledWiffFiles(watchAddress, RawFileType.PPG2)
  • Get notified when a new .wiff file is ready (starting SDK 0.8.0)
private val fullWiffFileListener = object : ValueUpdated.Listener<RawFileChunk> {
override fun onValueUpdated(model: RawFileChunk) {
if (model.type.contains(type.name, true)) {
this@DataMeasurementFragment.view?.findViewById<TextView>(R.id.action_result)?.text =
"New File saved: ${model.fileName} size ${model.size / 1024} ko at ${Date(model.timestamp)}"
}
}
}

override fun onStart() {
super.onStart()

dataSdkManager?.wiffFileUpdated?.addListener(fullWiffFileListener)
}

override fun onStop() {

// Unsubscribe updated listener.
dataSdkManager?.wiffFileUpdated?.removeListener(fullWiffFileListener)
super.onStop()
}
  • Export of the files

    • Method 1: export to the phone’s internal storage (Document, Download, etc)

      The user selects the directory, and then the files are copied to the directory. The directory is a folder from the phone’s internal storage, for exemple the Download folder.

    After the export, the files are deleted from the app.

Code example (DataMeasurementFragment.kt in the sample app):

    val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)  
val mainActivity = requireActivity() as MainActivity
mainActivity.startActivityForResult(intent) { a, b ->
b?.data?.also { uri -> val docFile = DocumentFile.fromTreeUri(requireContext(), uri) ?: return@startActivityForResult dataSdkManager?.wiffFileExporter?.exportWiffFiles(address, type, docFile, {

DocFile is obtained by asking the user to select a local folder and give access to the app.

  • Method 2: export to the app folder (hidden from the user)

    It is possible to export the files to the hidden app folder using the method exportWiffFilesToAppDirectory

    Files will be copied to Android/data/<your.application.id>/files (in the sample app, Android/data/com.corsano.sdk.sample/files)

Example using the sample app with “My_directory”

Export to the app directory

Code example (DataMeasurementFragment.kt in the sample app):

    val directory =  
mainActivity.getExternalFilesDir("My_directory") ?: return@setOnClickListener
if (!directory.exists())
directory.mkdir()

dataSdkManager?.wiffFileExporter?.exportWiffFilesToAppDirectory(
watchAddress, RawFileType.PPG2,
directory

Export behaviour

exportWiffFiles copies the .wiff chunks recorded for a device to a folder the user has granted access to.

fun exportWiffFiles(
address: String,
type: RawFileType,
documentFile: DocumentFile,
onSuccess: ((ArrayList<RawFileChunk>) -> Unit)? = null,
onError: ((Throwable) -> Unit)? = null
)
ParameterTypeDescription
addressStringMAC address of the bracelet whose files are exported
typeRawFileTypePPG2, ACC, BIOZ, ECG or SLEEP
documentFileDocumentFileDestination folder, from the system folder picker
onSuccess((ArrayList<RawFileChunk>) -> Unit)?The chunks that were copied
onError((Throwable) -> Unit)?Called when nothing could be copied

Points worth knowing when you build a UI around it:

  • Having nothing to export is a success, not an error. onSuccess is called with an empty list. Do not present that as a failure to the user.
  • A file that cannot be copied does not abort the batch. Every other file is still exported; the failure is logged per file.
  • Files that failed stay eligible. They are returned to the pending state and retried on the next export, rather than being stuck as permanently in-progress.
  • Chunks whose .wiff file no longer exists on disk are removed from the database before the export starts, so they cannot make every later export fail.
  • A destination folder that is no longer writable is reported through onError with a readable message.

Export therefore either copies what it can and reports it through onSuccess, or reports a real problem through onError — a partial batch is not treated as a total failure.

  • Data interpretation

The exported files can be parsed using our sample code, available in Python or PHP.

Please request access via our contact page.