Android functions

Android platform features could be used with PyJNIus and Plyer libraries.

%load_ext pythonhere
%connect-there
%%there
from pathlib import Path
from kivy.logger import Logger
from android.permissions import Permission, check_permission, request_permission
import plyer
%there -b log

Show notification

%%there
plyer.notification.notify(title='Python', message='Here')

Read accelerometer value

%%there
print(plyer.accelerometer.acceleration)
plyer.accelerometer.enable()
(None, None, None)
%%there --delay 1
print("x: {}, y: {}, z: {}".format(*plyer.accelerometer.acceleration))
x: 0.1305999755859375, y: -0.060272216796875, z: 9.93914794921875
%%there
plyer.accelerometer.disable()
print(plyer.accelerometer.acceleration)
(None, None, None)

Write to external storage

Writing to eternal storage is a restricted action.
If WRITE_EXTERNAL_STORAGE permission was not granted to application, access to “/sdcard” will raise PermissionError:

%%there
def write_to_sdcard():
    with open("/sdcard/test_python_here.txt", "w") as f:
        f.write("Python everywhere!")
        
write_to_sdcard()
Traceback (most recent call last):
  File "<string>", line 6, in <module>
  File "<string>", line 3, in write_to_sdcard
PermissionError: [Errno 13] Permission denied: '/sdcard/test_python_here.txt'
%%there shell
touch /sdcard/test_python_here
touch: '/sdcard/test_python_here': Permission denied

Request runtime permission

%%there
def permissions_callback(permissions, grant_results):
    if permissions and all(grant_results):
        Logger.info("Runtime permissions: granted %s", permissions)
    else:
        Logger.error("Runtime permissions: not granted, %s", permissions)

def ask_permission(permission):
    if check_permission(permission):
        print(f"{permission} is already granted")
    else:
        request_permission(permission, callback=permissions_callback)
%%there
ask_permission(Permission.WRITE_EXTERNAL_STORAGE)

The system permission prompt should appear at this point.

Use external storage

After WRITE_EXTERNAL_STORAGE permission was granted:

%%there
write_to_sdcard()
%%there shell
touch /sdcard/test_python_here.txt
cat /sdcard/test_python_here.txt
rm /sdcard/test_python_here.txt
Python everywhere!

Application-specific directories

Previous example will not work on Android >= 10,

because of privacy changes: https://developer.android.com/about/versions/10/privacy/changes#scoped-storage

In this case, it is possible to use directories that owned by the application:

%%there
from jnius import autoclass, cast
PythonActivity = autoclass('org.kivy.android.PythonActivity')
Environment = autoclass('android.os.Environment')
context = cast('android.content.Context', PythonActivity.mActivity)
print(context.getExternalFilesDir(None).getAbsolutePath())
print(context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS).getAbsolutePath())
print(context.getExternalFilesDir(Environment.DIRECTORY_PICTURES).getAbsolutePath())
/storage/emulated/0/Android/data/me.herethere.pythonhere_dev/files
/storage/emulated/0/Android/data/me.herethere.pythonhere_dev/files/Documents
/storage/emulated/0/Android/data/me.herethere.pythonhere_dev/files/Pictures

Take picture with a camera

Camera could be displayed and captured with the Kivy Camera widget.

%%there
ask_permission(Permission.CAMERA)
%%there kv
Camera:
    play: True
%%there
root.export_to_png(filename=str(Path("camera.png").resolve()))
root.play = False
%%there  shell
file camera.png
rm camera.png
camera.png: PNG image data, 720 x 1296, 8-bit/color RGBA, non-interlaced