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
Preferences DataStore : This a replacement for legacy shared preference
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 aFlow
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