gdsqlite-native icon indicating copy to clipboard operation
gdsqlite-native copied to clipboard

Android support?

Open snakeskinsalamander opened this issue 6 years ago • 40 comments

Hi there,

Can we be able to recompile it to support Android?

snakeskinsalamander avatar May 30 '18 05:05 snakeskinsalamander

Email me if Android support available : [email protected]

salihkallai avatar May 31 '18 16:05 salihkallai

Please, make it work for Android :)

disemq avatar Apr 11 '19 16:04 disemq

Is there support for Android?

danielkotzer avatar Aug 11 '19 08:08 danielkotzer

I don't have any experience with Android compilation, but I could give it a whack.

TGRCdev avatar Aug 11 '19 14:08 TGRCdev

For a long time I worked on the Adobe Air platform (Flex/Flesh), it was good for my needs. Not long ago, I moved from flash/flex to Godot, and it is really a great game engine, I think I should be using it for all kinds of applications, not only games, but one feature that I really miss is communication with a local Sqlite database which I had in flash, and I need it to work on all platforms because I publish on all platforms, if this will be added I'll have everything I need in Godot.

danielkotzer avatar Aug 11 '19 15:08 danielkotzer

I spent about a day diving into this, but unfortunately the C++ bindings for Godot don't support Android yet, so I can only do so much. I've messed around with the NDK compilers and Scons files, but all my outputs fail to link together for one reason or another.

TGRCdev avatar Aug 13 '19 00:08 TGRCdev

I appreciate your effort, thank you. I guess we'll have to wait for it.

danielkotzer avatar Aug 13 '19 08:08 danielkotzer

I may have spoken too soon! After writing an Android.mk and Application.mk, I can confirm that SQLite for Godot is working on Android!

Screenshot from my Galaxy S10E running the high_scores.gd example: Screenshot_20190813-154015_SQLiteTest The text is small, but it's showing that it is accessing the database, and that the db is a valid reference!

Now that I have compilation working, all I've got to do is clean up my godot-cpp SConstruct, merge the commands from ndk-build into GD SQLite's SConstruct file, and put together a beta release, and we'll be right as rain!

TGRCdev avatar Aug 13 '19 22:08 TGRCdev

Great! thank you, have you updated the binary file yet? can I download it from the code section? let me know when it is ready as a binary file for downloading.

danielkotzer avatar Aug 14 '19 06:08 danielkotzer

I'm still cleaning up godot-cpp, but I'll comment when I have the beta binaries ready, along with a link to download.

EDIT: Well, I HAD it, but now I can't reproduce how I compiled the plugin. This is going to take longer than I had expected.

TGRCdev avatar Aug 14 '19 06:08 TGRCdev

Well, I messed up.

After the successful compile, I got too far ahead of myself, and forgot to commit my script changes for godot-cpp and gdsqlite-native. Now, all of my attempts to recompile a working plugin are failing, so I'm practically back at square one.

Sorry to y'all who have been waiting for this. I'm going to keep cracking at it, and I'll notify you when I get a (COMMITTED AND BACKED UP) build working again.

TGRCdev avatar Aug 15 '19 10:08 TGRCdev

I appreciate your effort, and have no doubt that eventually you will get it to work again.

danielkotzer avatar Aug 15 '19 15:08 danielkotzer

It's here!

After a long time compiling and recompiling, the binaries for Android are available.

These binaries were compiled using a modified version of a fork of godot-cpp. I'm now working on editing the original godot-cpp to produce working binaries as well, but progress on that is slow, so I figured I would compile and release the latest SQLite plugin binaries and drop them here.

I have tested these on my S10E (arm64v8) and on a BlueStacks emulator (x86).

I will clean up my SConstruct file for GDSQLite itself and make a PR soon.

TGRCdev avatar Aug 19 '19 05:08 TGRCdev

Thank you, some games like games that teach English, must have a dictionary included, and you need to search the dictionary efficiently, having Sqlite is a savior, and an important milestone in the development of Godot.

danielkotzer avatar Aug 19 '19 10:08 danielkotzer

Tried to use this build (the binaries for Android are available.) by replacing the lib folder on the godot_sqlite-9289ef9 demo project with this new one, but I got an error message: Inavlid call. Nonexistent function 'open_db' in base 'Reference (gdsqlite.gdns)'.

danielkotzer avatar Aug 19 '19 20:08 danielkotzer

These binaries were compiled with the latest commit of SQLite. Some of the methods were changed. https://github.com/khairul169/gdsqlite-native/blob/b1810837f7cb54e6792dfb6ce26fc999db361728/src/gdsqlite.cpp#L251-L262 SQLite.open_db(path) should be replaced with SQLite.open(path)

TGRCdev avatar Aug 19 '19 20:08 TGRCdev

Hey! Does this works on Godot 3.1 Android export? I setted up a simple scene that would change a Label based on the first row of the items.db example. I tried to use it, and it ran fine on the editor, updating the label's text accordingly. But when I exported the APK and ran on my devide (Moto G6) it didn't update the label's text. I DID include the "*.db" on the non-resource export option.

MarcosRRM avatar Sep 10 '19 02:09 MarcosRRM

@MarcosRRM The latest release of this repository doesn't have Android binaries, but I have a beta build that does include Android binaries. Please try these and tell me if it works (you will have to replace any instances of open_db(path) with open(path) in your scripts)

If that doesn't work, please enable USB debugging on your phone and run adb logcat -s godot with your phone connected to your PC, and reply with whatever error it spits out (or if it doesn't spit one out)

TGRCdev avatar Sep 10 '19 03:09 TGRCdev

Hey! Thanks for the help. I was actually talking about your binaries. I tried what you said and the log was:

09-10 00:11:33.563 18179 18208 I godot   : Cannot open database!
09-10 00:11:33.563 18179 18208 I godot   : SQL Error: unable to open database file
09-10 00:11:33.563 18179 18208 E godot   : **SCRIPT ERROR**: Invalid get index '0' (on base: 'Array').
09-10 00:11:33.563 18179 18208 E godot   :    At: res://examples/item_database.gdc:16:_ready() - Invalid get index '0' (on base: 'Array').

Aparently it cannot open the DB on Android. The DB is located on the root folder and I'm opening it using: db.open("res://items.db") It works perfectly when I run on the editor.

Again, thanks for the help and the android binaries. If this works it will help IMMENSELLY with my college graduation project.

MarcosRRM avatar Sep 10 '19 03:09 MarcosRRM

@MarcosRRM I exported the demo and it ran fine on my end (Galaxy S10E). The only thing I can think of is to double-check which line you added *.db to in the Resources tab. image

TGRCdev avatar Sep 10 '19 07:09 TGRCdev

I created a project from 0, rechecked every step and it still didn't work. Not on 3 smartphones I have at home (Samsung, Motorola and Xiaomi). I must be missing a step. I just need to place the DB inside the project's root folder, add the "*.db" to the "Filters to export non-resource" and I should be able to access it just by "db.open("res://myDB.db")" right? Should I export the PCK? I'm just exporting the APK. Do I need one of those permissions on the Options Tab? Again, it worked when running the scene in the editor.

Anyway, I tried to create a DB programatically with the File class and saved it to the "user://" directory, and it worked PERFECTLY! Right now, that's enough for me! Thanks, again, for the Android binaries!

MarcosRRM avatar Sep 11 '19 12:09 MarcosRRM

EDIT: Actually, I'm experiencing a weird bug where a database will not always open under res://, and Godot will occasionally crash when de-referencing a database handle. Maybe just use user:// for now


Ah, I just realized what was wrong.

In the item_database.gd example, the database under res:// is opened like so:

if (path.begins_with("res://")):
	# Open packed database
	var file = File.new()
	if (file.open(path, file.READ) != OK):
		return false;
	var size = file.get_len()
	var buffers = file.get_buffer(size)
	return db.open_buffered(path, buffers, size)

This is because, when a game is exported, all files under res:// are zipped up into the .pck file (or the .apk in this instance). The actual file doesn't exist, which usually is not a problem because Godot has a virtual file system built in for files under res://.

SQLite doesn't use that, it opens files directly. It has no concept of res://.

For now, a workaround for opening databases under res:// looks like this:

var file = File.new()
file.open("res://myDB.db", file.READ)
var size = file.get_len()
db.open_buffered("res://myDB.db", file.get_buffer(size), size)

Which should open a read-only database with the handle db.

Also, I'm glad that I could help with my beta binaries! I'll try to keep them up to date, and maybe set up a nightly build.

TGRCdev avatar Sep 11 '19 13:09 TGRCdev

@TGRCdev with the instructions of your latest comment it worked well for me. Thank you!

samuelpedrajas avatar Sep 26 '19 14:09 samuelpedrajas

@TGRCdev Thanks for your efforts getting this to work. I also was able to get SQLite working on my android app. Is there a way to get the database open in a read/write mode?

file.open("res://myDB.db", file.WRITE); ...perhaps?

grymjack avatar Oct 20 '19 14:10 grymjack

@grymjack You should be able to open a database under the user:// directory, and that database should be read/writable. If not, let me know.

TGRCdev avatar Oct 20 '19 14:10 TGRCdev

@TGRCdev Well I am noobish coder, so I could be doing something stupid. I am using your latest beta binaries you linked above. I have an existing table with data that opens and displays the data just fine on the android side, in the user:// space. I tried to install new data in the table for display. This worked fine on the GoDot IDE, but did not work on the Android app. One of the annoying side problems I am having is getting ADB working (different versions server/client?), so not able to get a debug console on the phone is an issue.

grymjack avatar Oct 20 '19 15:10 grymjack

@grymjack No worries, we all have to start somewhere!

Databases under the res:// directory are compressed into the .pck file when the game is exported. As such, any databases under res:// should be treated as read-only.

One solution is to copy your pre-made database from res:// into the user:// directory when the game starts for the first time, then use that for write access.

Example code:

var db

func _ready():
    var dir = Directory.new()
    if not dir.file_exists("user://save_db.db"):
        dir.copy("res://readonly.db", "user://save_db.db")
    db = SQLite.new()
    db.open("user://save_db.db")
    # db can now be used to write data

TGRCdev avatar Oct 20 '19 15:10 TGRCdev

@TGRCdev Thanks, I'll give that a try. If the database you will be making a copy of is very large, will that double the resources needed on the phone for the app?

grymjack avatar Oct 20 '19 15:10 grymjack

I believe so. It could be slightly less depending on what compression the .pck uses, but the worst case is that it uses double the space on the phone.

TGRCdev avatar Oct 20 '19 15:10 TGRCdev

@TGRCdev Once the app has created a copy of this database at runtime, does the database delete itself once the app closes? If this is the case, how would I connect to a full read/write database that will have persistent records added to it over the course of time? The database is very large and could grow up to 1GB+. If the user space read/write database remains after app restart, I could create an empty database, copy that, do a one-time import of the needed data and avoid the double resource problem and have a database that would grow over time. Is this feasible?

grymjack avatar Oct 20 '19 16:10 grymjack