15


3

中断状態で実行するAndroid Pythonサービスの作成

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)

基本的には毎分振動します(http://www.reddit.com/r/Android/comments/ag6b6/periodic_reminder_app/[motivator]など)。 ただし、画面がブランクになった状態で電話がロックされている場合、振動は感じません。 おそらく、Androidはスクリプトをフリーズしているのでしょうか(そしてwhileループです)? このスクリプトを実際にサービスとして実行していることに注意してください(ロングタップして[サービスとして開始]をクリックします)。

電話のサスペンド状態に関係なく、このスクリプトを常に機能させる方法はありますか?

*更新1 *:毎分ではなく、時々振動が聞こえます。 むしろ5-10分ごとにランダムに好きです。

*更新2 *:この問題は、スクリプトを(サービスとしてではなく)通常実行した場合に発生します。 「time.sleep」が指定された時間スリープしていないようです。

5 Answer


10


スクリプト環境は間違いなく二流市民です。 必要なものは、ELAPSED_REALTIMEを使用したAlarmManagerと呼ばれます。 スクリプト環境でそれが利用できない場合は、行き詰まっています。

スクリプト環境は、少なくとも現時点では、完全なアプリケーションを作成できる開発キット環境を完全に置き換えることを意図したものではありません。 これは、より複雑なことを実行できないという犠牲を払って、いくつかの単純なスクリプト作成タスクを実行できるようにすることを目的としています。 ごめんなさい。


2


私は同じような問題に直面しています。

Androidデバイスが「ロック」モードの場合、time.sleep()は信頼できません。

SL4A release4 + pythonForAndroid_r5 + samsung galaxy Sのandroid 2.3.3で試したことをいくつか紹介します。

  • time.sleep(interval)ループをdroid.wakeLockAcquirePartial()内にラップします およびdroid.wakeLockRelease()。 これにより、CPUの速度が低下しなくなります。

  • eventWaitFor(eventName、timeOutInMilliSeconds)呼び出しを使用します。

droid.eventWaitFor( "ThisEventCannotHappen"、interval * 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


AlertManagerをサポートしていなくても、ASEでこれが機能することはまずありません。 あなたの最善の策は、機能要求を提出し、それを待つことです。 または、野心的であれば、ASEを自分で拡張してパッチを提出してください!


-1


Pythonバインディングについてはあまり知らないので、一般的なAndroidの問題として回答します。 http://pdk.android.com/online-pdk/guide/power_management.html [電源管理]を参照してください。

`PARTIAL_WAKE_LOCK`はおもしろそうです:「CPUが実行されていることを保証するウェイクロック。 画面がオンになっていない可能性があります。」

_ _ === ウェイクロックの例の調査

すべての電源管理呼び出しは、同じ基本形式に従います。

  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();


-2


考えられる解決策:スケジューラソフトウェアを使用して、スクリプトを定期的に開始します。 この方法では、time.sleep()を呼び出す必要はありません。

たぶん、スクリプトはそのような定期的なタスクに最適なソリューションではありません。 単純なJavaアプリを作成する場合、この問題に直面することはありません。