Android Question Problems with SQL, external storage and Android 14

jjveloso

Member
Licensed User
Longtime User
Hello everyone
My name is Juanjo, I've been using B4A since a long time (I started with b4ppc) but at an amateur level.
I hope you understand my sort knowledge on this.
Since the beggining y made a program that uses SQlite database to adquire data manually, only with the keyboard, I've been upgrading the program as Android grows and as BHA grow too. (I moved my program from b4ppc to B4A as it started).
Along the years I had no problems but now i'm crashed against the Android 14 wall.
Trying to simplify mi problem, and using the demo program that version 12.8 creates when you say NEW. I have reproduced the problem.
I'M using B4A 12.8, over Android 14 recently instaled by OTA on a Samsung Galaxy tablet S6 lite, I am using "android-34" resources
Libraries used are XUI, CORE and SQL, no more
The program is as follows
programa.jpg

Quite simple.
The problem is that even when it is suposed that I have external access available (see the two logs sentences), when I try to create a database, the error appears as UNABLE TO OPEN DATABASE.
Surprisingly the instruction Makedir gives no error (but the folder is not created ) I cannot see it on "storage/emulated/0"), but even if I create the folder manually in the tablet, the error remains the same
Here is the general log while running the app.
error.jpg

and here are the manifest that the program have, exactly the default one.
Manifest.jpg

Is obvious that I'm doing, at least, one thing bad (or many). Where?
May I have some help from you people?. Thanks a lot

Sorry ofr all this long text.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
 
Upvote 0

jjveloso

Member
Licensed User
Longtime User
Hello
First of all, sorry for duplucating threads,
Sincerely I thought it was an Android 14 problem.
The program I am working with, has been running fine for years without any problem. Right know there are at least 5 or s6 tables runnig it "as is" , even under Android 13.
That's the reason I blamed the problem to Androi14, Sorry again.

I will check again the threads and I think one of them will help to modify the program for the future. I only need to create, write or delete databases in the standard memory of the tablets, not in SD's or any other place outside it.

I'm sure I'll find the way.

Thanks again.
 
Upvote 0

Computersmith64

Well-Known Member
Licensed User
Longtime User
Hello
First of all, sorry for duplucating threads,
Sincerely I thought it was an Android 14 problem.
The program I am working with, has been running fine for years without any problem. Right know there are at least 5 or s6 tables runnig it "as is" , even under Android 13.
That's the reason I blamed the problem to Androi14, Sorry again.

I will check again the threads and I think one of them will help to modify the program for the future. I only need to create, write or delete databases in the standard memory of the tablets, not in SD's or any other place outside it.

I'm sure I'll find the way.

Thanks again.
Despite the flow chart Erel pointed you to saying otherwise, there are legitimate reasons for wanting to use shared storage - but you can't access it in the same way you did before. If your use case is simply providing a database for your app, you might be better off using app specific storage & then you don't have to worry about working around the restrictions on shared storage.

If you're worried about the database being deleted if the user uninstalls / reinstalls the app, you can create backups in shared storage & then copy them back to app specific storage if needed. That's what I do with one of my apps. The way I do that is with a ContentResolver. The downside is that you have to ask the user to choose where they want to keep the backup, but you only have to do that once as their choice is remembered so you can subsequently read & write the file without asking them again.

- Colin.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
If you're worried about the database being deleted if the user uninstalls / reinstalls the app, you can create backups in shared storage & then copy them back to app specific storage if needed
You can provide a backup / restore function. It is quite simple to implement with the "SaveAs code" + ContentChooser.
No reason to force the user to save it in any specific folder. Let the user choose the destination. It can be Google Drive or any other online storage service.
 
Upvote 0

jjveloso

Member
Licensed User
Longtime User
Hello

After reading some threads , I think that a good way to do the things as follows

1 I use an internal database that have the tables emty, to create new databases each time the user need to do that (we have on database for each customer's data. Al this work will be done allways in DirInternal, a app-only work to be done
2 every customer'database will be copied to external storage once created, it will live together with the rest of databases (some times there are up 100 databases (allways accesible to be copied to another computer or sent to some other colleague when needed.)

The process of working with the customer's database will consist of 3 step
#1 The database is copied from external storage to internal stoage where it is fully accesible
#2 The work is done all the time at internal storage.
#3 when the work is done and the database is closed, the database will be copied again to external storage

In this way I do not fill internalstorage with databases (the program only use one each time), and the databases are accesible to external use.

Probably it is the less elegant way of doing the work, but it should work.

I would appreciate any coment about.

Thanks again for your help
 
Upvote 0

jjveloso

Member
Licensed User
Longtime User
Hello again
I have been reading some threads an now I have a way to have acces to external estorage. it is based on
https://www.b4x.com/android/forum/threads/externalstorage-access-sd-cards-and-usb-sticks.90238/

After that I read the extras page
https://www.b4x.com/android/forum/threads/external-storage-extras.143576/
after reading this thread i discovered that the way you can copy file depends on the type of file, or at least this is what it is proposed in the previous thread
Even in this thread there is a routine to copy files form internal to external storage.
Based on this I tryed, unsuccessfully to transform it to tte opposite way (external to internal)

This original code have been copied directly from External Storage Extras example published in the last thread I mention

' Original code
'Copy a file to External Storage.
'Dir: The current input file directory, eg. File.DirAssets etc.
'Name: The current input file name
'Parent: External Storage parent name (Directory where place a file)
'Rename: Optionally rename the output file. Pass "" to mantain original name.
Public Sub CopyFileToExternalStorage (Dir As String, Name As String, Parent As ExternalFile, Rename As String) As Boolean
If File.Exists(Dir, Name) = False Then
Log("File do not exist on DirAssets while copy to External Storage: " & Name)
Return False
End If

Dim iStream As InputStream, oStream As OutputStream
Dim oFile As ExternalFile

If Rename <> "" Then
oFile = FindFileOrCreate(Parent, Rename) ' Optionally rename output file, pass "" to Rename argument will mantain original name
Else
oFile = FindFileOrCreate(Parent, Name)
End If

If oFile.IsInitialized = True Then
iStream = File.OpenInput(Dir, Name)
oStream = OpenOutputStream(oFile)
File.copy2(iStream, oStream)
iStream.Close
oStream.Close
Return True
Else
Log("Cannot create file on External Storage: " & Name)
Return False
End If
End Sub
'End of original code

'JJV code start here


'Copy a file from External Storage.
'Dir: The current output file directory, located at storage.root
'Name: The current output file name
'Parent: External Storage parent name (Directory where a file is)
'Rename: Optionally rename the output file. Pass "" to mantain original name.
Public Sub CopyFilefromExternalStorage (Parent As ExternalFile, extName As String, Dir As String, Rename As String) As Boolean
' If File.Exists(Dir, Name) = False Then
' Log("File do not exist on DirAssets while copy to External Storage: " & Name)
' Return False
' End If

Dim iStream As InputStream, oStream As OutputStream
Dim iFile As ExternalFile

iFile.Initialize
'
' If Rename <> "" Then
' iFile = FindFileOrCreate(Parent, Rename) ' Optionally rename output file, pass "" to Rename argument will mantain original name
' Else
iFile = FindFileOrCreate(Parent, extName)
' End If

If iFile.IsInitialized = True Then
iStream = OpenInputStream(Parent)
oStream = File.OpenOutput(Dir, extName, False)
File.copy2(iStream, oStream)
iStream.Close
oStream.Close
Return True
Else
Log("Cannot create file on internal Storage: " & Rename)
Return False
End If
End Sub

'JJV code ends here

Sincerely I cannot find where the problem is or if its really not possible to move files fron external to internal storage.

NEXT I do not know if it would be better to include this in a new thread or here

Looking on this and another problems around external storage limitation, and assuming this situation will be there forever as android versions grow.
I thnik that it could be a good idea to have something similar y to the FILE object existing at the CORE library. Posibly an XTFILE.object could have similar capabilities to the FILE object but related with the external estorage. allowing a simple way to handle external files and/or moving them to and from internal storage.

I would like to know how to do it, but my programming skills at not so high, sorry.

But my firs question is still there.
What am I doing wrong? or... am I doing anything right there?
is it possible to copy files form external storage to internal storage?. Is there any standard procedure or do we need to have an specific one for databases?.

Thanks a lot for your help
 
Upvote 0

jjveloso

Member
Licensed User
Longtime User
Hello
The error was a stupid mistake
I should have writen
B4X:
iStream =  OpenInputStream(iFile)

instead of
B4X:
iStream =  OpenInputStream(parent)

About the second question (XTFILE. xxxxxx). I wonder what is your opinion (and the rest of the people who want to express it, of course)

Thanks for your help
I'll try to add this instructions to my program ans see what happens

Thanks again
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
About the second question (XTFILE. xxxxxx). I wonder what is your opinion (and the rest of the people who want to express it, of course)
The external resources cannot be treated as local files. There are only disadvantages for taking ExternalStorage class code and putting it inside the core library.
 
Upvote 0
Top