Skip to content

bitinerant/flutter_with_python_android

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

26 Commits
 
 
 
 

Repository files navigation

Flutter with Python on Android

Instructions on how to generate one APK, containing Flutter UI as a frontend, and a Python Service as a backend.

Using the p4a project for bundling python scripts and cross-compiling python libraries with native components (like numpy/scipy/pandas/tflite-runtime).

NOTE: This tutorial requres at minimum p4a version v2022.07.20 and buildozer version 1.4.0

Install buildozer:

https://buildozer.readthedocs.io/en/latest/installation.html

Generate empty buildozer config

cd libapp
buildozer init

Edit a sample python file called srv.py

import time
while True:
    time.sleep(1)
    print('hello world')

Edit buildozer.spec

package.domain = org.domain

# kivy introduces conflicting dependencies and is not needed
requirements = python3

# select service bootstrap 
p4a.bootstrap = service_library 

# ask p4a to output aar instead of apk 
android.release_artifact = aar

# specify your runtime python package dependencies here (comma separated)
requirements = python3

# foreground : so that OS does not kill us (optional)
# sticky : so that OS restarts us on exit/crash  (optional)
services = Srv:srv.py:foreground:sticky  

# pick ABI(s) - NOTE: listing more than needed here grows the final .apk size
android.archs = arm64-v8a, x86

Compile the aar

buildozer android release

Setup a flutter project

cd ..\
flutter create -i objc -a java testapp

Edit testapp/android/app/build.gradle


# change minSdkVersion to match p4a aar library. 

minSdkVersion 21 

# add aar as a dependency 

dependencies { 
   implementation files('../../../libapp/bin/myapp-0.1-arm64-v8a_x86-release.aar') 
} 

Start services on app startup

Here we assume you wish to start the service when your app starts and you are using a sticky foreground service.

edit testapp/android/app/src/main/java/com/example/testapp/MainActivity.java

package com.example.testapp; 
import io.flutter.embedding.android.FlutterActivity; 
import android.os.Bundle; 
import  org.domain.myapp.ServiceSrv; 

public class MainActivity extends FlutterActivity { 

   @Override 
   protected void onCreate(Bundle savedInstanceState) { 
       super.onCreate(savedInstanceState); 
       ServiceSrv.prepare(this); 
       ServiceSrv.start(this, ""); 
       } 
} 

Optionally, you can add a hook when the app exits to stop the python service with ServiceSrv.stop(this) API

Add Foreground Service Permission

Optional if you selected foreground when specifying the service in buildozer.

Edit testapp/android/app/src/main/AndroidManifest.xml write to <manifest>

<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

Build and run the flutter app

flutter run

At this point, you should see 'hello world' printed if you adb locat , while the flutter demo app running. Communicating between the two is an excercse to the user, you can use raw sockets, ZeroMQ, Nanomsg-NG libraries to name a few.

Some useful projects:

  • Access Android Java API from Python: pyjnius
  • Cross platform API for common tasks: plyer

Proguard rules for pyjnius

-keep public class org.kivy.android.** {
    *;
}
-keep public class org.jnius.** {
    *;
}

About

Build a Flutter APK with a builtin Python Service backend

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published