使 android Python 服务在挂起状态下运行

Posted

技术标签:

【中文标题】使 android Python 服务在挂起状态下运行【英文标题】:Making an android Python service to run in suspend state 【发布时间】:2011-01-05 18:59:11 【问题描述】:

这是我使用 android-scripting 编写的 Python 脚本:

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)

它基本上每分钟都在振动(如motivator)。但是,当手机在屏幕空白的情况下锁定时,我感觉不到任何振动。也许Android正在冻结脚本(因此是while循环)?请注意,我确实将此脚本作为服务运行(长按并单击“作为服务启动”)。

有没有办法让这个脚本在手机挂起状态下一直工作?

更新 1:我偶尔会听到振动,不是每分钟 .. 而是随机每 5-10 分钟一次。

更新 2:如果我正常运行脚本(而不是作为服务),则会出现此问题。似乎“time.sleep”没有在指定时间内休眠。

【问题讨论】:

【参考方案1】:

我也面临同样的问题。

当您的 android 设备处于“锁定”模式时,time.sleep() 不可靠:

这是我在三星 Galaxy S 上的 SL4A release4 + pythonForAndroid_r5 + android 2.3.3 上尝试过的一些东西

在 droid.wakeLockAcquirePartial() 和 droid.wakeLockRelease() 中包裹一个 time.sleep(interval) 循环。 这将防止 CPU 变慢。 使用 eventWaitFor(eventName, timeOutInMilliSeconds) 调用:

droid.eventWaitFor("ThisEventCannotHappen", interval*60000)

threading.Timer() 对象似乎也能按预期工作,在我的设备上进行了几次测试后(需要确认...)

我不确定,但您最好记住,在真正的“锁定/睡眠”模式下,这些技巧可能会比预期消耗更多的电量,从而缩短设备的运行时间。

更新: eventWaitFor() 在很长的时间间隔内也不可靠。 这是一个显示 Timer() 工作原理的 sn-p:

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)

【讨论】:

【参考方案2】:

脚本环境绝对是二等公民。您想要的称为 AlarmManager,使用 ELAPSED_REALTIME。如果这不适用于脚本环境,那么您将陷入困境。

脚本环境至少目前不打算完全替代开发工具包环境,您可以在其中创建完整的应用程序。它旨在允许您执行一些简单的脚本任务,但代价是无法执行更复杂的事情。对不起。

【讨论】:

【参考方案3】:

在不支持 AlertManager 的情况下,这不太可能在 ASE 中工作。您最好的选择是提交功能请求并等待。或者,如果您有雄心壮志,请自行扩展 ASE 并提交补丁!

【讨论】:

【参考方案4】:

我对 Python 绑定了解不多,所以我将作为一般的 Android 问题来回答。见Power Management。

PARTIAL_WAKE_LOCK 听起来很有趣:“唤醒锁确保 CPU 正在运行。屏幕可能没有打开。”

探索唤醒锁示例

所有电源管理调用都遵循相同的 基本格式:

    获取 PowerManager 的句柄 服务。 创建唤醒锁并 指定电源管理标志 屏幕、超时等。 获取唤醒锁。 执行操作(播放 MP3、 打开 html 页面等)。 释放唤醒锁。下面的 sn-p 说明了 这个过程。
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();

【讨论】:

【参考方案5】:

可能的解决方案:使用一些调度软件并定期启动您的脚本。这样你就不需要调用 time.sleep()。

也许脚本不是此类周期性任务的最佳解决方案。如果您编写一个简单的 Java 应用程序,您将不会遇到这个问题。

【讨论】:

以上是关于使 android Python 服务在挂起状态下运行的主要内容,如果未能解决你的问题,请参考以下文章

已安排本地通知,但未在挂起和未运行模式下传递

原生 Android 应用程序在挂起时是不是应该释放 OpenGL 资源?

NSURLSessionDownloadTask 在挂起时继续下载

使用 pthreads 在挂起模式下创建线程

所有 iOS 配置文件都停留在挂起 [关闭]

应用程序在挂起时静默终止。 (用户在我的应用程序上按下锁定按钮)