-
Notifications
You must be signed in to change notification settings - Fork 1
How to Schedule Notification
In android to schedule tasks when app isn't open either a WorkManger or AlarmManager is needed.
An AlarmManager is more specific, here's how to go about creating it
With this pattern:
- From your
main.pyschedule the AlarmManager with time you want - Then you can close your app.
- After time specified your AlarmManager calls your service.py
I recommend this way because it involves less java and allows you to run other python things for max 15 mins allowed by Android.
In your buildozer.spec
Specify needed files and permissions
services = Shorttask:./services/shorttask.py
android.add_src = ./src
android.permissions = POST_NOTIFICATIONS, USE_EXACT_ALARM, SCHEDULE_EXACT_ALARM
p4a.hook = ./hook.pyCreate src/TheReceiver.java
The java file starts your python service.
- Change
org.wally.wallervariable with values in yourbuildozer.spec->"package.domain.package.name" - Edit first and second line
package org.wally.waller;
import org.wally.waller.ServiceShorttask;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class TheReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String msg = intent.getStringExtra("message");
if (msg == null) msg = "No message";
Log.d("TheReceiver", "Broadcast received: " + msg);
try {
ServiceShorttask.start(context, msg);
Log.d("TheReceiver", "Shorttask service start requested");
} catch (Exception e) {
Log.e("TheReceiver", "Failed to start Shorttask", e);
}
}
}From p4a/hook.py
Inserts your receiver to AndroidManifest.xml
- Change
packagevariable with values in yourbuildozer.spec->"package.domain.package.name"
package = "org.wally.waller"
from pathlib import Path
from pythonforandroid.toolchain import ToolchainCL
def after_apk_build(toolchain: ToolchainCL):
manifest_file = Path(toolchain._dist.dist_dir) / "src" / "main" / "AndroidManifest.xml"
text = manifest_file.read_text(encoding="utf-8")
receiver_xml = f"""
<receiver
android:name="{package}.TheReceiver"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="ALARM_ACTION" />
</intent-filter>
</receiver>
"""
text = text.replace("</application>", f"{receiver_xml}\n</application>")
manifest_file.write_text(text, encoding="utf-8")
print("Manifest update completed successfully!\n", text)From ./services/shorttask.py
Send notification and run some task for 15 mins if needed.
import os, time
from android_notify import Notification
receiver_arg = os.environ.get('PYTHON_SERVICE_ARGUMENT', "")
print("python Shorttask arg", receiver_arg)
fmt = lambda s: f"{int((s % 3600) // 60)}m {int(s % 60)}s"
n = Notification(title="Service runtime: --:--")
n.send()
mins = 60 * 15
for i in range(0, mins):
n.updateTitle(f"Service runtime: {fmt(i)}")
time.sleep(1)Lastly from your main.py
Choose the seconds later you want and argument
def schedule_alarm(secs=10):
import time
from android_notify.config import get_python_activity_context, get_package_name
from android_notify.internal.java_classes import autoclass, String, PendingIntent, Intent
AlarmManager = autoclass('android.app.AlarmManager')
Context = autoclass('android.content.Context')
context = get_python_activity_context()
alarm = context.getSystemService(Context.ALARM_SERVICE)
intent = Intent(context, autoclass(f"{get_package_name()}.TheReceiver"))
intent.setAction(String("ALARM_ACTION"))
intent.putExtra(String("message"), String("Arg from Python!"))
pending = PendingIntent.getBroadcast(
context, 1234, intent, PendingIntent.FLAG_IMMUTABLE
)
trigger_time = int((time.time() + secs) * 1000)
alarm.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, trigger_time, pending)
# setExactAndAllowWhileIdle ensures the alarm triggers even if the device is in Doze mode, unlike set() which may be delayed.To see logs on console run adb logcat | grep -E "python|TheReceiver|Shorttask or n.setBigText("large log")
This repo was very helpful: RedsTooN/kivy-java-alarmmanager-bridge