私はアーティストで、いくつかの Android スマートフォンを使ったインスタレーションに取り組んでいます。私は Java/Android プログラミングの専門家ではありません。私はやることで学んでいるだけで、stackoverflow はとても役に立ちます。異なる Android バージョン (2.3-4.4) の異なるデバイスを使用しています。デバイスは常に USB 経由で給電されます。アプリは展示会とリゾートの営業時間中にのみ実行され、翌日には自動的に実行されます。スケジューリングには、AlarmManager を使用しています。現在、一部のデバイスで自動再起動に問題がありますが、他のデバイスでは期待どおりに動作します。
以下は、スケジューリングの重要な一部の抜粋です。
AndroidManifest.xml には、次の権限が設定されています。
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
特に WAKE_LOCK パーミッションが設定されています。
onCreate は次のように始まります。
@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_start);
pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
if (android.os.Build.VERSION.SDK_INT > 12) {
if (pm != null) {
wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK| PowerManager.ACQUIRE_CAUSES_WAKEUP
| PowerManager.ON_AFTER_RELEASE, "MyWakeLock");
}
}else {
// unlock screen and switch screen back light on
// for Android 2.3 - disable for higher Versions
KeyguardManager km = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
final KeyguardManager.KeyguardLock kl;
if (km != null) {
kl = km.newKeyguardLock("MyKeyguardLock");
kl.disableKeyguard();
}
if (pm != null) {
wakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK| PowerManager.ACQUIRE_CAUSES_WAKEUP
| PowerManager.ON_AFTER_RELEASE, "MyWakeLock");
}
}
wakeLock.acquire();
Thread.setDefaultUncaughtExceptionHandler(new MyExceptionHandler(this));
PowerManager.ACQUIRE_CAUSES_WAKEUP が使用されています。私の理解では、状態に関係なく画面を表示する必要があります。
onDestroy で私は使用しています:
PendingIntent pendingIntent = PendingIntent.getActivity(MyApplication.getInstance().getBaseContext(),0,intent,PendingIntent.FLAG_ONE_SHOT );
AlarmManager alarmManager = (AlarmManager) MyApplication.getInstance().getBaseContext().getSystemService(Context.ALARM_SERVICE);
if (alarmManager != null) {
alarmManager.set(AlarmManager.RTC_WAKEUP , System.currentTimeMillis()+delayInMillis,pendingIntent);
Date date = new Date(System.currentTimeMillis()+delayInMillis);
SimpleDateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy ' 'HH:mm:ss.SSS");
Log.i("** restart at **",dateFormat.format(date));
}
このスニペットは、「展示会の終了時間に達した」ために finish() が呼び出されたときに実行されます。前述のように、これはほとんどのデバイスで機能します。アプリが自動的に再起動しないように見えるデバイスでは、たとえば電源ボタンを押すか、USB を切断することによって画面が表示されるとすぐにアプリが起動します (たとえば、ラップトップを接続して logcat を読み取るため)。次のようなものを見つけます (LG P-875 Android 4.1.3 は 14:00:xx に開始する必要があります)
03-25 14:00:53.516 677-748/? I/ActivityManager: START {flg=0x14000004 cmp=eu.karin_daum.daum.reality/.Start (has extras) u=0} from pid -1
03-25 14:00:53.546 677-748/? I/ActivityManager: Start proc eu.karin_daum.daum.reality for activity eu.karin_daum.daum.reality/.Start: pid=31324 uid=10099 gids={3003, 1015, 1028}
私にはこれで問題ないように見えますが、PowerManager は反応しませんでした。この例では、数分後にラップトップを接続するために USB を切断した瞬間に PowerManager が反応しました。
03-25 14:04:13.986 677-691/? D/PowerManagerService: userActivity mLastEventTime=201702573 time=201861160 mUserActivityAllowed=true mUserState=0x0 mWakeLockState=0x0 mProximitySensorActive=false timeoutOverride=-1 force=false
03-25 14:04:13.986 677-691/? D/PowerManagerService: setPowerState: mPowerState=0x0 newState=0x7 noChangeLights=false reason=2
03-25 14:04:13.986 677-691/? D/PowerManagerService: setPowerState: mPowerState=0 newState=7 noChangeLights=false
03-25 14:04:13.996 677-691/? D/PowerManagerService: setTimeoutLocked now=201861160 timeoutOverride=-1 nextState=3 when=201862660
03-25 14:04:14.006 677-747/? D/PowerManagerService: Perflock acquired: 7, 1
03-25 14:04:14.006 677-750/? D/PowerManagerService: offMask=0x0 dimMask=0x0 onMask=0x0 difference=0x1 realDifference=0x0 forceState=0x1
03-25 14:04:14.096 677-1038/? D/PowerManagerService: pid=31324 tag=MyWakeLock mAcquireCausesWakeupTime=201861278 diffTime=149932030
03-25 14:04:14.096 677-1038/? D/PowerManagerService: setPowerState: mPowerState=0x7 newState=0x7 noChangeLights=false reason=3
最後の 2 行目では、onCreate で送信したリクエストが処理されているようです (tag=MyWakeLock)
執筆中、次のテストで PowerManager が自動的に反応したが、AlarmManager アクションから約 10 分の遅延しかなかったことに気付きました。
私は何を間違っていますか?onDestroy で WakeLock を解放する必要がありますか? 問題の解決策はありますか?