Beta Playground ContentProvider (simple database for all your apps (call it a devicekvs))

Discussion in 'Android Questions' started by DonManfred, Jan 27, 2019.

  1. DonManfred

    DonManfred Expert Licensed User

    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. :D

    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
    Code:
    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:

    Code:
    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
    Code:
    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"

    Code:
    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 ;-)
     

    Attached Files:

    Last edited: Jan 31, 2019
    peacemaker, asales, Xicu and 10 others like this.
  2. DonManfred

    DonManfred Expert Licensed User

    It does work :D
     
  3. Peter Simpson

    Peter Simpson Expert Licensed User

    Hiya Manfred,
    This looks great. I have to create an example of an issue that I'm having for @klaus, once I have done that I will be testing your Playground ContentProvider.

    Your dedication for this forum really is excellent, plus now and again @DonManfred you put a smile on my face.

    Anyway yo yo yo keep rapping, oops wrong type of wrapping ;)

    Thank you Don
     
    DonManfred likes this.
  4. moster67

    moster67 Expert Licensed User

    Good one, hehe
     
  5. rboeck

    rboeck Well-Known Member Licensed User

    Hi,

    i tried to test your contentprovider and was not able to find a solution for this problem:

    When i open the sample file DataContentProviderEx in line 45/main:
    prov.USER <- here i get: Unknown Member: user

    I dont find any definition of user as member of provider; i am using B4A 9.0. Something on my side seems out of order?
     
  6. DonManfred

    DonManfred Expert Licensed User

    I just opened the example i have on HDD

    [​IMG]
     
  7. rboeck

    rboeck Well-Known Member Licensed User

    I am sure, that the problem is on my computer, but at which position are the members of contentprovider defined? Some part of my software is outdated, but which one?
    prov.png
     
  8. DonManfred

    DonManfred Expert Licensed User

    Just to make sure.
    I´ve changed the version of the lib i am using to 1.01.
    Maybe i uploaded an outdated lib

    Try it with 1.01
     

    Attached Files:

    asales and Erel like this.
  9. rboeck

    rboeck Well-Known Member Licensed User

    Bingo! There was a difference in file size and now i get all members!

    Thanks!
     
    DonManfred likes this.
  10. DonManfred

    DonManfred Expert Licensed User

    To give an explanation. The members like ID, USER, TIME, VALUE are just placeholders for the Strings
    "ID", "USER", "TIME" and "VALUE"

    You can for sure define your own fields with your own names. The above are only to demonstrate the principle and to give some help.
    I could have used constants in B4A too instead.
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice