初めてのバックグラウンドジョブデバッグ on Android

## ChatGPTさんにお世話になりながらアプリ開発
うちの親の監視（いや、生存確認）のために歩数計測みたいなアプリを入れていたが全然動かなくなったので、勉強かねて自作しようと、この素人が思い立った。

### バックグラウンドで動かすことの難易度を知る
WindowsやLinuxサーバでの定期処理はたくさん作ってきたので行ける気がしてた。けど、ちょっと進めただけで、Androidはアプリがバックグラウンドの場合、スリープ状態の場合、とか、結構考えなきゃいけないことがいっぱいあることが分かった。

### デバッグを制するものが開発を制する！
というわけで、バッテリー消費を抑えるとかいろいろな観点から、ChatGPTさんからはWorkManagerを使いなさいと言われその通りに実装。でも、動いている実感（と、動かなかった場合の理由の納得感）がなく、やっぱりデバッグしたい！となったが、ChatGPTさんからの回答はスマートすぎる？のかよくわからないかったので自分なりのまとめ。

### adbコマンドでの可視化２通り
３つめ以降もあるのだろうけど、見つかれば追記。
```bash
#1
adb shell am broadcast -a "androidx.work.diagnostics.REQUEST_DIAGNOSTICS" -p "com.skacyba.mimamori"

#2
adb shell dumpsys jobscheduler > job_mimamori.txt
```

#### #1：adbコマンドで診断した結果をlogcatで見る
下記コマンドを実行し、
```bash:
$ adb shell am broadcast -a "androidx.work.diagnostics.REQUEST_DIAGNOSTICS" -p "com.skacyba.mimamori"
Broadcasting: Intent { act=androidx.work.diagnostics.REQUEST_DIAGNOSTICS flg=0x400000 pkg=com.skacyba.mimamori }
Broadcast completed: result=0
```
AndroidStudioからlogcatを見る。出ていない場合はリフレッシュボタン押す。
```java:AndroidStudioのlogcatの内容。package:mimamoriでフィルタしている。
2025-03-07 11:02:35.996 27273-28004 WM-DiagnosticsWrkr      com.skacyba.mimamori                 I  Recently completed work:
2025-03-07 11:02:36.019 27273-28004 WM-DiagnosticsWrkr      com.skacyba.mimamori                 I   Id 	 Class Name	 Job Id	 State	 Unique Name	 Tags	
                                                                                                    631595f4-5eae-4fc9-81f1-9a323cc2596b	 androidx.work.impl.workers.DiagnosticsWorker	 null	 SUCCEEDED	 	 androidx.work.impl.workers.DiagnosticsWorker	
                                                                                                    bd5b5e16-6e95-4c8c-b8bb-497b207562df	 androidx.work.impl.workers.DiagnosticsWorker	 76	 SUCCEEDED	 	 androidx.work.impl.workers.DiagnosticsWorker	
                                                                                                    b5fe8230-88e2-4fd9-b1cd-4f47d05d6f64	 androidx.work.impl.workers.DiagnosticsWorker	 73	 SUCCEEDED	 	 androidx.work.impl.workers.DiagnosticsWorker	
                                                                                                    fdfffb45-0967-4595-ab88-dc85039687e6	 androidx.work.impl.workers.DiagnosticsWorker	 72	 SUCCEEDED	 	 androidx.work.impl.workers.DiagnosticsWorker	
                                                                                                    78fb5847-7ea8-4076-aeb8-858f6ee06e00	 androidx.work.impl.workers.DiagnosticsWorker	 64	 SUCCEEDED	 	 androidx.work.impl.workers.DiagnosticsWorker	
                                                                                                    85367655-683d-4bb9-9141-323219cc2563	 androidx.work.impl.workers.DiagnosticsWorker	 63	 SUCCEEDED	 	 androidx.work.impl.workers.DiagnosticsWorker	
                                                                                                    a6ca30e1-8b8d-48c5-886e-8ec7190b44d2	 androidx.work.impl.workers.DiagnosticsWorker	 62	 SUCCEEDED	 	 androidx.work.impl.workers.DiagnosticsWorker	
                                                                                                    3e91cd21-3783-43cb-9d8c-83e3464a097c	 androidx.work.impl.workers.DiagnosticsWorker	 61	 SUCCEEDED	 	 androidx.work.impl.workers.DiagnosticsWorker	
2025-03-07 11:02:36.019 27273-28004 WM-DiagnosticsWrkr      com.skacyba.mimamori                 I  Running work:
2025-03-07 11:02:36.022 27273-28004 WM-DiagnosticsWrkr      com.skacyba.mimamori                 I   Id 	 Class Name	 Job Id	 State	 Unique Name	 Tags	
                                                                                                    21879892-0194-4f1c-916b-a5c006d7e82a	 androidx.work.impl.workers.DiagnosticsWorker	 132	 RUNNING	 	 androidx.work.impl.workers.DiagnosticsWorker	
2025-03-07 11:02:36.022 27273-28004 WM-DiagnosticsWrkr      com.skacyba.mimamori                 I  Enqueued work:
2025-03-07 11:02:36.028 27273-28004 WM-DiagnosticsWrkr      com.skacyba.mimamori                 I   Id 	 Class Name	 Job Id	 State	 Unique Name	 Tags	
                                                                                                    fad0bf36-54c0-4576-9748-efe14eac4c46	 com.skacyba.mimamori.LocationBatteryWorker	 130	 ENQUEUED	 LocationBatteryWork	 com.skacyba.mimamori.LocationBatteryWorker	
                                                                                                    b9164eb4-4794-43dd-855d-02fb43f6e417	 com.skacyba.mimamori.LocationBatteryWorker	 131	 ENQUEUED	 MimamoriWorker	 com.skacyba.mimamori.LocationBatteryWorker	
2025-03-07 11:02:36.031 27273-27312 WM-WorkerWrapper        com.skacyba.mimamori                 I  Worker result SUCCESS for Work [ id=21879892-0194-4f1c-916b-a5c006d7e82a, tags={ androidx.work.impl.workers.DiagnosticsWorker } ]
```
##### ↑ Recently completed work:から続く行
最近のジョブみたいだが、androidx.work.impl.workers.DiagnosticsWorkerなので、このadbコマンド自体を表していると一旦理解。気にしない。

##### ↑ Running work:から続く行
知りたい情報のうち、実行中のものがここに表示される。下記参照。

##### ↑ Enqueued work:から続く行
これが知りたい情報。アプリはcom.skacyba.mimamori.LocationBatteryWorkerでジョブを登録する作りにしているので、登録されていることが分かる。「MimamoriWorker」というのは、ジョブ登録時にTagがつけられるのでそれをこの名前にしており、それが表示されている。30分おきに実行とか詳しい情報は出ない。


#### #2：adbコマンドでジョブの詳細をテキスト化して読み解く
下記でテキストファイルに書き出して、エディタで頑張って見る。
```
$ adb shell dumpsys jobscheduler > job_mimamori.txt
```

##### ↑ テキストをmimamoriで検索
下記のような一節がヒットするので、見て、頑張っていろいろ解釈する。
→解釈の仕方はまだ勉強中。コードと照らし合わせると、下記文言から何となく設定内容はわかる（多分コードの意図通り設定されているなーとかいう）レベルでいったん納得している。
>  JOB #u0a499/131: 4e46736 com.skacyba.mimamori/androidx.work.impl.background.systemjob.SystemJobService
    u0a499 tag=*job*/com.skacyba.mimamori/androidx.work.impl.background.systemjob.SystemJobService
    Source: uid=u0a499 user=0 pkg=com.skacyba.mimamori
    JobInfo:
      Service: com.skacyba.mimamori/androidx.work.impl.background.systemjob.SystemJobService
      Requires: charging=false batteryNotLow=false deviceIdle=false
      Extras: mParcelledData.dataSize=248
      Minimum latency: +29m59s953ms
      Backoff: policy=1 initial=+30s0ms
      Has early constraint
    Required constraints: TIMING_DELAY [0x80000000]
    Dynamic constraints:
    Satisfied constraints: DEVICE_NOT_DOZING BACKGROUND_NOT_RESTRICTED WITHIN_QUOTA [0x3400000]
    Unsatisfied constraints: TIMING_DELAY [0x80000000]
    Tracking: TIME QUOTA
    Implicit constraints:
      readyNotDozing: true
      readyNotRestrictedInBg: true
      readyDynamicSatisfied: false
    Standby bucket: FREQUENT
    Enqueue time: -9m55s696ms
    Run time: earliest=+20m4s257ms, latest=none, original latest=none
    Restricted due to: none.
    Ready: false (job=false user=true !restricted=true !pending=true !active=true !backingup=true comp=true)

##### 見ているポイント

Satisfied constraints: DEVICE_NOT_DOZING BACKGROUND_NOT_RESTRICTED WITHIN_QUOTA 
で、スリープ（Dozeモード）周りをなんとかしようとしているな、とか

Enqueue time: -9m55s696ms
Run time: earliest=+20m4s257ms, latest=none, original latest=none
9分55秒前に登録して、次回は20分4秒後なのでちゃんと30分サイクルで実行されそうだな、とか

### まだまだ中途半端だけど今後
頑張って追記予定！