Skip to content

Native Android features

Permissions

Declare permissions before running the app:

declare_permissions([
    "android.permission.CAMERA",
    "android.permission.ACCESS_FINE_LOCATION",
])

Request dangerous permissions at runtime:

def permission_result(granted):
    if granted:
        toast("Permission granted")
    else:
        toast("Permission denied")

permissions.request(
    "android.permission.CAMERA",
    on_response=permission_result,
)

Only request permissions when a user action needs them, and explain the reason in the interface.

Notifications and sharing

notify("Download complete", "Midnight Drive is available offline")
share("Listen to Midnight Drive", title="Share track")
clipboard.copy("https://example.com/track/42")

notify creates a system notification. toast is for brief in-app feedback. snackbar is useful when the message belongs to the current screen and may include an action.

def image_selected(success, path):
    if success:
        avatar.set_value(path)

camera.capture(on_result=image_selected)
gallery.pick(on_result=image_selected)

The Previewer uses a file picker to simulate the flow. Android opens the native camera or content picker.

Location

def location_result(success, latitude, longitude, city):
    if success:
        location_label.set_value(city + " ยท " + latitude + ", " + longitude)
    else:
        location_label.set_value("Location unavailable")

location.get_current(on_result=location_result)

Declare and request the appropriate location permission before reading the device position.

Background work

def sync_library():
    https.get(API_URL, on_response=save_library)

service.every(
    run=sync_library,
    minutes=15,
    id="library_sync",
    only_on_wifi=True,
    only_when_charging=True,
)

service.once(run=sync_library, after_minutes=5, id="initial_sync")
service.cancel(id="library_sync")

Android compiles scheduled work to WorkManager. The operating system controls the exact execution time, particularly for periodic jobs.

App inspection

apps.list(on_result=show_apps)
apps.permissions("com.example.app", on_result=show_permissions)
apps.extract("com.example.app", on_result=extracted)
apps.hash("com.example.app", on_result=hashed)

These APIs inspect packages available to the Android device and simulate results where possible in the Previewer.

Google Play package visibility

Broad package visibility, especially QUERY_ALL_PACKAGES, is restricted by Google Play policy. Use it only when the app's core purpose qualifies, and prefer targeted package queries where possible.

Native dialogs

alert("Saved", "Your settings were updated.")

confirm(
    "Delete playlist?",
    "This cannot be undone.",
    on_result=lambda accepted: delete_if_confirmed(accepted),
)

Use Overlays and content states for richer Material sheets, modals, menus, pickers and snackbars.