i played around with creating a ContentProvider ....
I came out with a small and simple Library which provides a simple ContenProvider.
The small library b4aContentProvider is basically only returning some Constants which you need to use when using contentResolver to get Data from the DatacontentProvider.
It also contains the ContentProvider itself for sure (more or less hidden).
The Database schema behind the ContentProvider is based on the b4xcloudkvs Database. I´m just playing around and i thougth it may be a good idea.
This all may be something for you if you have multiple apps on one Device for which you want to store Data accessible by all your apps.
The plus: No additional permissions are needed. No need to share a file or something, no need for Runtimepermissions.
One App, i name it the ContentProvider Host, must implement the ContentProvider. All your other apps only need to use the contentResolver Library.
To make your app the Host add this to your Manifest
You´ll find two Example Apps attached.
Code to write a Dataset to the Provider:
Code to read the last Data from the Provider:
Here i am limiting the results to 1 Item. Sorted by time value DESCending. And the id must be 815 and the USER field must be "b4a.example"
Hope to give some inspiration for you to use it.
As the VALUE is saved using b4xserializator your are Limited to the follwing types:
The following types are supported as values:
Lists, Maps, Strings, primitives (numbers), user defined types and arrays (only arrays of bytes and arrays of objects are supported).
Custom types should be declared in the main module.
Including combinations of these types (a list that holds maps for example).
Though i did not tried to use the same Customtype in two apps and try to write/access them later... Not sure it it works because the two Types are defined in two different Apps... I´ll investigate ;-)
I came out with a small and simple Library which provides a simple ContenProvider.
The small library b4aContentProvider is basically only returning some Constants which you need to use when using contentResolver to get Data from the DatacontentProvider.
It also contains the ContentProvider itself for sure (more or less hidden).
The Database schema behind the ContentProvider is based on the b4xcloudkvs Database. I´m just playing around and i thougth it may be a good idea.
This all may be something for you if you have multiple apps on one Device for which you want to store Data accessible by all your apps.
The plus: No additional permissions are needed. No need to share a file or something, no need for Runtimepermissions.
One App, i name it the ContentProvider Host, must implement the ContentProvider. All your other apps only need to use the contentResolver Library.
To make your app the Host add this to your Manifest
B4X:
AddApplicationText(
<provider
android:name="de.donmanfred.dataprovider"
android:authorities="de.donmanfred.dataprovider"
android:enabled="true"
android:exported="true" />)
You´ll find two Example Apps attached.
Code to write a Dataset to the Provider:
B4X:
Sub Globals
'These global variables will be redeclared each time the activity is created.
'These variables can only be accessed from this module.
Private prov As DataProvider
Private cr As ContentResolver
End Sub
B4X:
Dim m As Map = CreateMap("January": 1, "February": 2)
Dim jgen As JSONGenerator
jgen.Initialize(m)
Dim val As ContentValues
val.Initialize
val.PutString(prov.KEY,GUID)
val.PutString(prov.USER,Application.PackageName)
val.PutLong(prov.TIME,DateTime.Now)
val.PutInteger(prov.ID,815)
val.PutBytes(prov.VALUE,serializator.ConvertObjectToBytes(m)) ' I am usind b4xserializator so the content is limited to the understood content...
Dim resUri As Uri = cr.Insert(prov.CONTENT_URI,val)
Dim contentID As Int = resUri.ParseId
Log($"contentID of created content: ${contentID}"$)
Code to read the last Data from the Provider:
Here i am limiting the results to 1 Item. Sorted by time value DESCending. And the id must be 815 and the USER field must be "b4a.example"
B4X:
Dim projection() As String = Array As String(prov.ID,prov.KEY,prov.VALUE,prov.TIME,prov.USER)
cr.QueryAsync(prov.CONTENT_URI,projection, $"${prov.ID}=815 AND ${prov.USER}="b4a.example" "$,Null,prov.TIME&" DESC LIMIT 1")
wait for CR_QueryCompleted(Success As Boolean, Crsr As Cursor)
Log($"QueryCompleted(${Success})"$)
If Crsr.IsInitialized Then
If Crsr.RowCount > 0 Then
Log($"CR --------------------------------------"$)
Dim Cursor As Cursor
Cursor = Crsr
For i = 0 To Cursor.RowCount - 1
Cursor.Position = i
'calcon.ACCOUNT_TYPE,calcon.OWNER_ACCOUNT)
Log($"$time{Cursor.GetLong(prov.TIME)}: ${Cursor.GetInt(prov.ID)}: ${Cursor.GetString(prov.KEY)}:${Cursor.GetString(prov.USER)}: ${serializator.ConvertBytesToObject(Cursor.GetBlob(prov.VALUE))} "$ ) ' You can use the constants you used for the projection. But remember: only the ones you defined in the projection are available in the Result.
Next
Cursor.Close
Log($"CR --------------------------------------"$)
Else
' No rows
End If
End If
Hope to give some inspiration for you to use it.
As the VALUE is saved using b4xserializator your are Limited to the follwing types:
The following types are supported as values:
Lists, Maps, Strings, primitives (numbers), user defined types and arrays (only arrays of bytes and arrays of objects are supported).
Custom types should be declared in the main module.
Including combinations of these types (a list that holds maps for example).
Though i did not tried to use the same Customtype in two apps and try to write/access them later... Not sure it it works because the two Types are defined in two different Apps... I´ll investigate ;-)
Attachments
Last edited: