Android Question KeyValueStore2 no luck

Discussion in 'Android Questions' started by MitchBu, May 7, 2019.

  1. MitchBu

    MitchBu Active Member Licensed User

    KVS seems to be exactly what I need. In another language, all my apps use a "dictionary" which supports all settings through key value pairs.

    I am trying to implement it in a small test project.

    Code:
    Sub Globals
        
    'These global variables will be redeclared each time the activity is created.
        'These variables can only be accessed from this module.
        Dim Diko As KeyValueStore
    End Sub
    Code:
    Sub Activity_Create(FirstTime As Boolean)
        
    'Do not forget to load the layout file created with the visual designer. For example:
        'Activity.LoadLayout("Layout1")
        Activity.LoadLayout("Main")
      
        
    'Initialize Diko
        If FirstTime Then
            Diko.Initialize(
    File.DirDefaultExternal, "datastore")
        
    End If
    I get the error below. Apparently SQL complains that it cannot open it's database. Please forget my ignorance, I was under the impression that initialize was all that was needed. What must I do to create that SQL file ? Or is it something I left out ?

    Any help will be appreciated.

    TIA.


    --------- beginning of system
    --------- beginning of main
    *** Service (starter) Create ***
    ** Service (starter) Start **
    ** Activity (main) Create, isFirst = true **
    Error occurred on line: 37 (Main)
    android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (Sqlite code 14): Could not open database, (OS error - 2:No such file or directory)
    at android.database.sqlite.SQLiteConnection.nativeOpen(Native Method)
    at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:223)
    at android.database.sqlite.SQLiteConnection.open(SQLiteConnection.java:207)
    at android.database.sqlite.SQLiteConnectionPool.openConnectionLocked(SQLiteConnectionPool.java:511)
    at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:194)
    at android.database.sqlite.SQLiteConnectionPool.open(SQLiteConnectionPool.java:183)
    at android.database.sqlite.SQLiteDatabase.openInner(SQLiteDatabase.java:880)
    at android.database.sqlite.SQLiteDatabase.open(SQLiteDatabase.java:864)
    at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:767)
    at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:742)
    at anywheresoftware.b4a.sql.SQL.Initialize(SQL.java:44)
    at b4a.example3.keyvaluestore._initialize(keyvaluestore.java:362)
    at b4a.example.main._activity_create(main.java:394)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:351)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
    at java.lang.reflect.Method.invoke(Native Method)
    at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:144)
    at b4a.example.main.afterFirstLayout(main.java:104)
    at b4a.example.main.access$000(main.java:17)
    at b4a.example.main$WaitForLayout.run(main.java:82)
    at android.os.Handler.handleCallback(Handler.java:808)
    at android.os.Handler.dispatchMessage(Handler.java:101)
    at android.os.Looper.loop(Looper.java:166)
    at android.app.ActivityThread.main(ActivityThread.java:7529)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)

    ** Activity (main) Resume **
     
  2. jimmyF

    jimmyF Active Member Licensed User

    MitchBu and BillMeyer like this.
  3. Computersmith64

    Computersmith64 Well-Known Member Licensed User

  4. jimmyF

    jimmyF Active Member Licensed User

    Good point!

    Maybe use RuntimePermissions.GetSafeDirDefaultExternal("") instead?

    -j
     
    MitchBu likes this.
  5. MitchBu

    MitchBu Active Member Licensed User

    I will for sure study it in detail tomorrow. But, since obviously you are using that class, can you please confirm there is no need to crate the database beforehand, and that the initialize command suffices ?

    Thank you in advance.
     
  6. jimmyF

    jimmyF Active Member Licensed User

    That's it, exactly. Just give the db a name when initializing the class instance. And best to declare the class, " Public kvs As KeyValueStore ", and do the initialzation in the Starter service module.
    Very important! Be sure, of course, that you have the correct permissions for the directory in which you create the db, as mentioned by @Computersmith64.
     
  7. Erel

    Erel Administrator Staff Member Licensed User

    Several mistakes:

    1. Best to use File.DirInternal.
    2. Never use File.DirDefaultExternal.
    3. You can use Runtime.GetSafeDirDefaultExternal though option #1 is better.
    4. Only use Sub Globals for UI related objects. You should declare 'diko' in Process_Globals or better in Process_Globals of the starter service (and initialize it in Service_Create).
     
    jimmyF likes this.
  8. MitchBu

    MitchBu Active Member Licensed User

    Thank you jimmyF and Erel. With your help, I was able to make it work :)

    I could not declare and initialize in the Starter service, diko was not available in Main. So I declare and initiliaze in Main, that works just fine.

    I post what I did so someone searching later will have the solution.

    Code:
    Sub Process_Globals
        
    'These global variables will be declared once when the application starts.
        'These variables can be accessed from all modules.
           Public Diko As KeyValueStore
    End Sub


    Sub Activity_Create(FirstTime As Boolean)
        
    'Do not forget to load the layout file created with the visual designer. For example:
        'Activity.LoadLayout("Layout1")
        Activity.LoadLayout("Main")
       
        
    'Initialize value pairs
        If FirstTime Then
            Diko.Initialize(
    File.DirInternal, "datastore")
        
    End If
    I had thought of using Map, but I did not see where to save it when the app quits. With kvs, I won't have to worry about that.
     
  9. Erel

    Erel Administrator Staff Member Licensed User

    You should access it with:
    Code:
    Starter.diko.Put(...)
     
  10. MitchBu

    MitchBu Active Member Licensed User

    Oh, I see. Thank you Erel :)
     
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