Создание Android-службы Python для запуска в состоянии ожидания - PullRequest
15 голосов
/ 16 января 2010

Вот мой скрипт на Python, написанный с использованием android-scripting :

import android, time

droid = android.Android()
interval = 1 # every 1 minute

while True:
    # define your own vibrate pattern here
    droid.vibrate(200)
    time.sleep(0.3)
    droid.vibrate(300)

    time.sleep(60*interval)

Он в основном вибрирует каждую минуту (как мотиватор ).Однако, когда телефон заблокирован с отключенным экраном, я не чувствую никакой вибрации.Возможно, Android замораживает скрипт (и, следовательно, цикл while)?Обратите внимание, что я действительно запускаю этот сценарий как службу (нажмите и удерживайте кнопку «Запуск от имени службы»).

Существует ли способ заставить этот сценарий работать постоянно, независимо от состояния приостановки телефона?

Обновление 1 : Я слышу вибрации время от времени, не каждую минуту ... а скорее, как каждые 5-10 минут случайно.

Обновление 2 : Эта проблема возникает, если я запускаю скрипт нормально (не как сервис).Похоже, "time.sleep" не спит в течение указанного времени.

Ответы [ 5 ]

10 голосов
/ 05 февраля 2010

Среда для написания сценариев определенно является гражданином второго сорта.То, что вы хотите, называется AlarmManager, используя ELAPSED_REALTIME.Если это не доступно для среды сценариев, вы застряли.

Среда сценариев, по крайней мере в настоящее время, не предназначена для полной замены среды комплекта разработки, где можно создавать полноценные приложения.Он предназначен для того, чтобы позволить вам выполнять некоторые простые задачи сценариев за счет невозможности делать более сложные вещи.К сожалению.

2 голосов
/ 13 ноября 2011

У меня такая же проблема.

time.sleep () не является надежным, когда ваше устройство Android находится в «заблокированном» режиме:

Вот несколько вещей, которые я пробовал на SL4A release4 + pythonForAndroid_r5 + android 2.3.3 на samsung galaxy S

  • оберните цикл time.sleep (интервал) внутри droid.wakeLockAcquirePartial () и droid.wakeLockRelease (). Это предотвратит замедление процессора.
  • использовать вызов eventWaitFor (eventName, timeOutInMilliSeconds):

droid.eventWaitFor ("ThisEventCannotHappen", интервал * 60000)

  • threading.Timer () объект, кажется, также работает как ожидалось, после нескольких тестов на моем устройстве (требуется подтверждение ...)

Я не уверен, но вам лучше иметь в виду, что эти приемы могут потреблять больше энергии, чем ожидалось, в истинном «заблокированном / спящем» режиме и, следовательно, сокращать время работы вашего устройства.

Обновление: eventWaitFor () также не является надежным для длительных интервалов. Вот фрагмент, показывающий, как работает Timer ():

import android
import threading
import logging


def doStuff():
    logging.info("testTimer.py: Stuff DONE")
    droid.notify('testTimer.py',"doStuff() has been called")
    droid.vibrate(500)

def createLog(path):
    logging.basicConfig(filename=path,
                        level=logging.INFO,
                        format='%(asctime)s %(message)s')

DELAY=600

droid=android.Android()
logpath="/mnt/sdcard/testTimer.py.log"
createLog(logpath)
timer=threading.Timer(DELAY,doStuff)
logging.info("timer starting now")
timer.start()
logging.info("doStuff() will be called by timer...Delay=%d" % DELAY)
1 голос
/ 04 февраля 2010

Вряд ли это будет работать в ASE без поддержки AlertManager. Лучше всего подать запрос на функцию и дождаться этого. Или, если вы чувствуете себя амбициозно, расширьте ASE и отправьте патч!

0 голосов
/ 26 января 2010

Я не очень разбираюсь в связывании Python, поэтому собираюсь ответить на него как на общую проблему с Android. См. Управление питанием .

PARTIAL_WAKE_LOCK звучит интересно: «Wake Lock, который гарантирует, что процессор работает. Экран может быть не включен.»

Пример использования Wake Lock

Все вызовы управления питанием выполняются одинаково Базовый формат:

  1. Получить дескриптор PowerManager сервис.
  2. Создать блокировку от пробуждения и указать флаги управления питанием для экран, время ожидания и т. д.
  3. Получите блокировку от пробуждения.
  4. Выполнение операции (воспроизведение MP3, открыть HTML-страницу и т. д.).
  5. Снять блокировку. Фрагмент ниже иллюстрирует этот процесс.
PowerManager pm = (PowerManager)mContext.getSystemService(
                                          Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(
                                      PowerManager.SCREEN_DIM_WAKE_LOCK
                                      | PowerManager.ON_AFTER_RELEASE,
                                      TAG);
wl.acquire();
 // ...
wl.release();
0 голосов
/ 24 января 2010

Возможное решение: использовать программное обеспечение планировщика и регулярно запускать сценарий. Таким образом, вам не нужно вызывать time.sleep ().

Возможно, сценарии не лучшее решение для таких периодических задач. Вы не столкнетесь с этой проблемой, если напишите простое Java-приложение.

...