ITmob-Ly
发布于 2023-04-20 / 86 阅读
0

Android Exception: java.lang.SecurityException: Uid 0 not permitted to force scheduled jobs

Android 开发中常用 WorkManagerJobScheduler 来做定时任务的操作,但是测试时等待它触发执行会给调试带来不便。

adb 提供了命令可以强制执行指定 Job Id 的任务:

adb shell cmd jobscheduler run [-f | --force] [-u | --user USER_ID] PACAGE JOB_ID

但通过命令强制执行任务时可能会遇到 Exception: java.lang.SecurityException: Uid 0 not permitted to force scheduled jobs 异常。

如下是执行包名为 cn.itmob.demo 应用的 job id 为 19 的任务时抛出的异常:

C:\Users\itmob.cn> adb shell cmd jobscheduler run -f cn.itmob.demo 19
Exception: java.lang.SecurityException: Uid 0 not permitted to force scheduled jobs

因为该操作不能以 root 用户执行,切换到非 root 用户重新强制执行任务:

C:\Users\itmob.cn> adb unroot
restarting adbd as non root

C:\Users\itmob.cn> adb shell cmd jobscheduler run -f cn.itmob.demo 19
Running job [FORCED]

扩展:

  1. adb shell cmd jobscheduler 查看帮助文档

    C:\Users\itmob.cn> adb shell cmd jobscheduler
    Job scheduler (jobscheduler) commands:
      help
        Print this help text.
      run [-f | --force] [-s | --satisfied] [-u | --user USER_ID] PACKAGE JOB_ID
        Trigger immediate execution of a specific scheduled job. For historical
        reasons, some constraints, such as battery, are ignored when this
        command is called. If you don't want any constraints to be ignored,
        include the -s flag.
        Options:
          -f or --force: run the job even if technical constraints such as
             connectivity are not currently met. This is incompatible with -f
             and so an error will be reported if both are given.
    ...
    
  2. 查看 WorkManager 的工作状态,查看某个 worker 的 Job ID

    C:\Users\itmob.cn> adb shell am broadcast -a "androidx.work.diagnostics.REQUEST_DIAGNOSTICS" -p "cn.itmob.demo"
    Broadcasting: Intent { act=androidx.work.diagnostics.REQUEST_DIAGNOSTICS flg=0x400000 pkg=cn.itmob.demo }
    Broadcast completed: result=0
    

    查看 logcat, 会输指定包名应用中 WorkManager 的状态,其中包括 Job Id,State 等信息

    C:\Users\itmob.cn> adb logcat
    04-20 01:13:40.437 19855 19948 D WM-GreedyScheduler: Starting work for a12dbcd7-22fc-4ef7-9f6f-29fd3a99a112
    04-20 01:13:40.440 19855 19855 D WM-SystemJobService: onStartJob for WorkGenerationalId(workSpecId=a89dbcd7-3ffc-4ef7-9f6f-29fd3a99a314, generation=0)
    04-20 01:13:40.442 19855 19948 D WM-Processor: Processor: processing WorkGenerationalId(workSpecId=a89dbcd7-3ffc-4ef7-9f6f-29fd3a99a314, generation=0)
    04-20 01:13:40.444 19855 19948 D WM-Processor: Work WorkGenerationalId(workSpecId=a89dbcd7-3ffc-4ef7-9f6f-29fd3a99a314, generation=0) is already enqueued for processing
    04-20 01:13:40.454 19855 19855 D WM-WorkerWrapper: Starting work for androidx.work.impl.workers.DiagnosticsWorker
    04-20 01:13:40.471 19855  8146 I WM-DiagnosticsWrkr: Recently completed work:
    04-20 01:13:40.471 19855  8146 I WM-DiagnosticsWrkr: 
    04-20 01:13:39.270     0     0 I         : c3   8085 google_charger: l=100 vb=4364 vc=4362 c=1 fv=4400000 t=265 s=N/A usb=1 wlc=0
    04-20 01:13:40.487 19855  8146 I WM-DiagnosticsWrkr:  Id 	 Class Name	 Job Id	 State	 Unique Name	 Tags	
    04-20 01:13:40.487 19855  8146 I WM-DiagnosticsWrkr: 4e641fbb-76b2-4a9f-a6e4-d7517e7947de	 cn.itmob.demo.SampleWorker	 null	 SUCCEEDED	 RemoteConfigFetch	 cn.itmob.demo.SampleWorker
    04-20 01:13:40.487 19855  8146 I WM-DiagnosticsWrkr: 9d57a387-1adc-4d2c-937c-00fd445755ea	 cn.itmob.demo.Sample2Worker	 null	 SUCCEEDED	 	 cn.itmob.demo.Sample2Worker	
    04-20 01:13:40.487 19855  8146 I WM-DiagnosticsWrkr: 4851df53-a78d-40e8-b965-180f38616e6e	 cn.itmob.demo.Sample3Worker	 null	 SUCCEEDED	 	 cn.itmob.demo.Sample3Worker	
    4-20 01:13:40.488 19855  8146 I WM-DiagnosticsWrkr: Running work:
    04-20 01:13:40.488 19855  8146 I WM-DiagnosticsWrkr: 
    04-20 01:13:40.489 19855  8146 I WM-DiagnosticsWrkr:  Id 	 Class Name	 Job Id	 State	 Unique Name	 Tags	
    04-20 01:13:40.489 19855  8146 I WM-DiagnosticsWrkr: a89dbcd7-3ffc-4ef7-9f6f-29fd3a99a314	 androidx.work.impl.workers.DiagnosticsWorker	 20	 RUNNING	 	 androidx.work.impl.workers.DiagnosticsWorker	
    04-20 01:13:40.489 19855  8146 I WM-DiagnosticsWrkr: Enqueued work:
    04-20 01:13:40.489 19855  8146 I WM-DiagnosticsWrkr: 
    04-20 01:13:40.491 19855  8146 I WM-DiagnosticsWrkr:  Id 	 Class Name	 Job Id	 State	 Unique Name	 Tags	
    04-20 01:13:40.491 19855  8146 I WM-DiagnosticsWrkr: 97220006-dc58-4005-baa5-b3e1dff70c5e	 cn.itmob.demo.Sample4Worker	 19	 ENQUEUED	 AutoPollCatalog	 cn.itmob.demo.Sample4Worker	
    04-20 01:13:40.491 19855 19952 D WM-WorkerWrapper: androidx.work.impl.workers.DiagnosticsWorker returned a Success {mOutputData=Data {}}.
    04-20 01:13:40.493 19855 19952 I WM-WorkerWrapper: Worker result SUCCESS for Work [ id=a89dbcd7-3ffc-4ef7-9f6f-29fd3a99a314, tags={ androidx.work.impl.workers.DiagnosticsWorker } ]
    04-20 01:13:40.496 19855 19855 D WM-Processor: Processor a89dbcd7-3ffc-4ef7-9f6f-29fd3a99a314 executed; reschedule = false
    04-20 01:13:40.496 19855 19855 D WM-SystemJobService: a89dbcd7-3ffc-4ef7-9f6f-29fd3a99a314 executed on JobScheduler
    

    上面的日志信息中可以看到还未执行的 Sample4Worker 和它的 Job Id, State 等信息。

  3. 根据 Job Id 单独查看某个 Worker 的状态

    C:\Users\itmob.cn> adb shell cmd jobscheduler get-job-state -u 0 cn.itmob.demo 19
    waiting