Background Service using P4A android.service

FeralBytes edited this page Sep 5, 2017 · 3 revisions

Note: Last Updated 04SEP2017 in reference to changes for Kivy 1.10 and SDL2 boot strap.

Create your service as normal in the folder service/ as main.py. To make it a foreground service with a touchable notification; use the code below.

    import jnius
    Context = jnius.autoclass('android.content.Context')
    Intent = jnius.autoclass('android.content.Intent')
    PendingIntent = jnius.autoclass('android.app.PendingIntent')
    AndroidString = jnius.autoclass('java.lang.String')
    NotificationBuilder = jnius.autoclass('android.app.Notification$Builder')
    Notification = jnius.autoclass('android.app.Notification')
    service_name = 'S1'
    package_name = 'com.something'
    service = jnius.autoclass('org.kivy.android.PythonService').mService
    # Previous version of Kivy had a reference to the service like below.
    #service = jnius.autoclass('{}.Service{}'.format(package_name, service_name)).mService
    PythonActivity = jnius.autoclass('org.kivy.android' + '.PythonActivity')
    notification_service = service.getSystemService(
        Context.NOTIFICATION_SERVICE)
    app_context = service.getApplication().getApplicationContext()
    notification_builder = NotificationBuilder(app_context)
    title = AndroidString("EzTunes".encode('utf-8'))
    message = AndroidString("Ready to play music.".encode('utf-8'))
    app_class = service.getApplication().getClass()
    notification_intent = Intent(app_context, PythonActivity)
    notification_intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
        Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK)
    notification_intent.setAction(Intent.ACTION_MAIN)
    notification_intent.addCategory(Intent.CATEGORY_LAUNCHER)
    intent = PendingIntent.getActivity(service, 0, notification_intent, 0)
    notification_builder.setContentTitle(title)
    notification_builder.setContentText(message)
    notification_builder.setContentIntent(intent)
    Drawable = jnius.autoclass("{}.R$drawable".format(service.getPackageName()))
    icon = getattr(Drawable, 'icon')
    notification_builder.setSmallIcon(icon)
    notification_builder.setAutoCancel(True)
    new_notification = notification_builder.getNotification()
    #Below sends the notification to the notification bar; nice but not a foreground service.
    #notification_service.notify(0, new_noti)
    service.startForeground(1, new_notification)

When you want your service to no longer run in the foreground, but rather to be a background service just execute this code.

from jnius import autoclass
Service = autoclass('org.renpy.android.PythonService').mService
Service.stopForeground(True)

Just remember this service is removed from foreground state, allowing it to be killed if more memory is needed.

Here is the Java Documentation on stopForeground()

You still start your service as normal from your app.

from jnius import autoclass
service = autoclass('{}.Service{}'.format(package_name, service_name))
mActivity = autoclass('org.kivy.android.PythonActivity').mActivity
argument = ''
service.start(mActivity, argument)

Reference: https://github.com/kivy/python-for-android/issues/267

Clone this wiki locally
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.