【Java】Caller パッケージ名 needs to hold android.permission.SCHEDULE_EXACT_ALARM to set exact alarms.

タイトルのエラーに出くわしてしまいました。

AndroidManifest.xml内 で以下のように宣言するだけで良いと思っていたので出くわす理由がわかりませんでした…

<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />

公式ドキュメント

AlarmManager を使って正確な時間にアラームを設定してサービスを動かしたかったのでこれで、AlarmManager の setExact() などのexactを含むメソッドを利用できると思っていました。

てか、実際にそう出来る端末がありました。
ただ、他にandroid でタイトルのエラーを起こす機種がいました。

何はともあれ対策です。

どうやら AlarmManager には 正確にスケジューリング出来るか確認できるメソッド canScheduleExactAlarms() があるようです。

android12以上だと使えます。

AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && !alarmManager.canScheduleExactAlarms()) {
    alarmManager.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, triggerAtMillis, pendingIntent);
} else {
    alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, triggerAtMillis, pendingIntent);
}

canScheduleExactAlarms() メソッドのドキュメントを見ると

SCHEDULE_EXACT_ALARM権限を持つ、またはデバイスの省電力除外リストに入っているとtrueを返してくれるみたいです。

つまりエラーが起きたということはどちらともダメだったということです。
上述した実際に出来た端末は元々デバイスの省電力除外リストに入れていたからっぽいですね…

なんにせよユーザー側で設定を変えれるので上記のような分岐は行う必要があります。

Exactを使わせたい場合は、Intentで「Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM 」を指定して設定してもらうか省電力モードから外す必要がありそうです。

12への変更点に書いておいて欲しかったです…

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です