DATA STORE

Android guide : https://developer.android.com/topic/libraries/architecture/datastore

We all know that Jetpack Data Store is new, it would mature soon. I want to highlight few things which are not documented in Android developer portal

There are two concept in DataStore

  1. Preferences DataStore : This a replacement for legacy shared preference

  2. Proto DataStore : This is used to write data to a file in predefined format.

    • predefined format : These are called proto files, think this file like a schema file.

In this blog I would explain about Proto Datastore and How i used it.

My Requirement: Create a New File (JSON) every time the Data Connection state changes and capture the cell id, network name, mnc & mcc from the registered cell . Yes Information of the Cell tower with which Mobile is connected although there may be multiple towers where the device is getting signals.

I could have captured cell id, network name, mnc & mcc in Database Table and Could have iterated the table rows and converted each row to json file. Now this is where Proto DataStore shines.

With DataStore i can capture the Data and write to file directly. I can send this data (a.k.a PB files) to server.

Server would not understand every random file you send, it has to be in a format it can parse. So we need to have a contract of format. This is defined in Proto file.
you can read more : https://developers.google.com/protocol-buffers

I want to focus on creating a PB files, there are two ways to do so

Type 1 : Using Flow

  • create a datastore object

    • val cellInfoDataStore: DataStore<CellInfo> by dataStore(
        fileName = "cellInfo_file1.pb",
        serializer = CellInfoSerializer
      )
  • Use DataStore.data to expose a Flow

    • cellInfoDataStore.data.map { cellInfo ->
          // read the file
          print(cellInfo.cellid)
        }
    • cellInfoDataStore.data.updateData { cellInfo ->
          cellInfo.toBuilder()
            .setCellID(7621255169)
            .build()
          }

Type 2 : Basic File Stream

  • lateinit var cellInfoProtoBuilder: CellInfoProto.Builder
                try {
                    cellInfoProtoBuilder = CellInfoProto.newBuilder()
                        .mergeFrom(FileInputStream(context.dataStoreFile("cellInfo_file1.pb")))
                } catch (ex: FileNotFoundException) {
                    cellInfoProtoBuilder = CellInfoProto.newBuilder()
                }
  • cellInfoProtoBuilder.cellID = 7621255169 // Do all you need with builder
  • cellInfoProtoBuilder.build().writeTo(FileOutputStream(context.dataStoreFile("cellInfo_file1.pb")))

Lesson Learnt

  • Never have more than one object of DataStore for one pb file. This has to be one to one mapping

  • I feel the read and write directly using File Stream was more atomic and predictable. but never try to mix these two types

Bipin Ayetra