eliasdorneles / beeware-android-template

Template for starting a native Android app using Python and the BeeWare tools
MIT License
36 stars 5 forks source link

python for android documentation - read/write files #2

Closed vanous closed 6 years ago

vanous commented 7 years ago

Thanks for all this work, it is just great! Is there any source or documentation about the python for android, where i could figure out how to use all the import android stuff? I am trying to read a file on android from python but it doesn't work by trial/error. I used the tictactoe examples for widgets and layout understanding but now have hit a road block...

thank you very much

edit: in fact, i will try to read sqlite, so your upcoming todo app looks very promising to me :)))

eliasdorneles commented 7 years ago

Hello @vanous ! Thanks, cool to know you're trying out this stuff! :)

There really isn't much documentation just yet, I've been writing these example apps with the goal of both dogfooding VOC for Android apps and bootstrapping documentation for this approach.

Essentially, what exists so far are these example apps I've been building (besides the template) and Toga-Android's source code.

VOC doesn't have much documentation on this Java-interoperability stuff yet, I've just opened a ticket for it: https://github.com/pybee/voc/issues/689

About your specific problem: to use a sqlite database within Android, instead of managing creating/opening the file in your code, I think you'd be better using the SQLiteOpenHelper class which does that for you, you just provide a name for the DB -- that's what I intend to do for that little todo app.

vanous commented 7 years ago

Thank you very much. I will try this.

vanous commented 7 years ago

I have to admit, i have no idea what i am even attempting... :) :(

I can imagine i must create a new class to extend the SQLiteOpenHelper, then create methods top onCreate or onOpen but... :/

class DBHelper(implements=android.database.sqlite.SQLiteOpenHelper):
    def __init__(self, callback, *args, **kwargs):
        self.callback = callback
        self.args = args
        self.kwargs = kwargs

    def onOpen(self,db:android.database.sqlite.SQLiteDatabase) -> db:

i have been searching for some docs, examples etc... but I will probably have to wait for your todo app :)))

eliasdorneles commented 7 years ago

Hey @vanous -- haha, yeah, I'm very familiar with that feeling, as you might imagine! :)

You're in the right direction, but there are some things missing:

1) SQLiteOpenHelper is an abstract class, not an interface, so you have to use extend instead of implements

2) To generate the proper constructor, you gotta used the @super trick that generates a Java-compatible constructor. This trick is maybe best documented currently in a comment section in the code.

Essentially, you'll want something looking like this:

class DBHelper(extends=android.database.sqlite.SQLiteOpenHelper):

    # use the @super trick to create a Java constructor that passes
    # some hardcoded values to the parent constructor
    @super({
        context: android.content.Context,
        "com.example.vanous": java.lang.String,
        None: android.database.sqlite.SQLiteDatabase[CursorFactory],
        1: int
    })
    def __init__(self, context):
        print('starting DBHelper')

You'll also want to implement the onCreate and onUpgrade methods that are required by that abstract class:

def onCreate(self, db: android.database.sqlite.SQLiteDatabase) -> void:
    # some code here...

def onUpgrade(self, db: android.database.sqlite.SQLiteDatabase,
              oldVersion: int, newVersion: int) -> void:
    pass

I'll try to incorporate something like this to that todo app, but you can keep digging this if you want. =)

To have a look what the implementations of those methods may look like, if you're not scared of a little Java, you may have a look at this tutorial: https://www.sitepoint.com/starting-android-development-creating-todo-app/

eliasdorneles commented 7 years ago

I've just commited a working example to the todo app: https://github.com/eliasdorneles/todoapp-voc/blob/aa9794cf5e93174d932751808a3789309e8bec42/todoapp/app.py#L88-L156

Let me know how it goes for you!

vanous commented 7 years ago

Thank you very much! now i am tempted not to look at the todo and try it myself first :))

eliasdorneles commented 7 years ago

now i am tempted not to look at the todo and try it myself first :))

it'll be a valid learning experience, go for it!

If you do that, it would really awesome if you could also take notes of the problems you face and register here later. It would be great for documentation. :)

Here, I'll start, two problems I run into often are:

1) forgetting to put the self in the method declaration and then getting an error saying the method doesn't exist or something weird like that -- this is because the signatures didn't match, so Java doesn't find the method

2) forgetting to pass the AndroidContext (self._activity) to a class that needs it, and then getting a fun error like Caused by: RuntimeError: No candidate constructor found for signature (); tried []

vanous commented 7 years ago

do you always have to rerun gradle and install apk or can you somehow run python code directly? (i can imagine you have to re-voc-transpile, but i rather ask)...

eliasdorneles commented 7 years ago

Sadly there is no way to eval Python code directly in Android, no.

What I do is, after I run python setup.py android the first time (which builds the android/ directory and everything), I just run yes N | python setup.py android --start the next times. With the --start flag, it will run gradle for you.

vanous commented 7 years ago

Nice trick with the --start, i just run gradlew, but had to tweak some stuff around. One more question please: is it possible to use any python imports in briefcase converted app? Not even compiled ones, but stuff like json or requests? Obviously it doesn't work for me so perhaps there is a trick for this? Thank you very much.

eliasdorneles commented 7 years ago

Hi there! Currently the list of imports that you can use is seriously limited, because VOC still doesn't support the full standard library (tbh, i think not even half of it). So at the moment, your best bet would be to do requests and JSON handling through Java libraries and Android APIs -- at least until we can compile and run more of the stdlib with VOC.

vanous commented 7 years ago

Thank you very much! This explains what role briefcase plays in the packaging and voc, included in by briefcase, in compiling :)

eliasdorneles commented 7 years ago

@vanous you got it :)

rsemenoff commented 6 years ago

I just discovered this, sorry if this is a naive question...but is there a way to know what has yet to be implemented? I'm using Sympy and Numpy intended to be incorporate into an android studio project rather than create whole app in python. Will VOC as it stands now, work for me ?

eliasdorneles commented 6 years ago

@rsemenoff Numpy would not work w/ VOC, because it's not pure Python. VOC needs pure Python code to compile into JVM bytecode.

eliasdorneles commented 6 years ago

@vanous I'm going to close this ticket, since there is a complete working example for sqlite in the Todo app. Thanks!