androidアプリの作成についておたずねします。
foreground serviceを起動させるActivity のコードのうち、
BroadcastReceiverの部分について
次のように記述してあるのですが、
private val timerReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
if (intent?.action == MyTimerService.ACTION_UPDATE) {
val timeRemaining = intent
.getLongExtra(MyTimerService.EXTRA_TIME, 0)
textView.text = "Remaining: $timeRemaining sec"
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
/*
ui要素の設定をここに記述
*/
registerReceiver(
timerReceiver,
IntentFilter(MyTimerService.ACTION_UPDATE))
startForegroundService()
}
}
registerReceiverメソッドの箇所で
次のようなエラーが表示されてしまいます。
`timerReceiver` is missing `RECEIVER_EXPORTED`
or `RECEIVER_NOT_EXPORTED` flag
for unprotected broadcasts registered for ACTION_UPDATE
このエラーはどういった種類のものなのかと、
どのようにすれば改善できるのかを
教えていただけないでしょうか?
とてもよい質問です!
このエラーは **Android 14(APIレベル 34)以降** で導入された
**BroadcastReceiverのセキュリティ強化** に関係しています。
---
### 🔍 エラーの意味:
```
'timerReceiver' is missing 'RECEIVER_EXPORTED'
or 'RECEIVER_NOT_EXPORTED' flag
for unprotected broadcasts registered for ACTION_UPDATE
```
これは、
> アプリが **保護されていないブロードキャスト**
(= 誰でも送れるインテント)を **registerReceiver()** で受信しようとしたけど、
> その受信の「公開範囲」(外部アプリからのインテントを受け入れるかどうか)を
明示するフラグが指定されていない!
という警告/エラーです。
---
### 🛠 改善方法(registerReceiverにフラグを追加)
Android 14 からは、**registerReceiver()** に
`flags` パラメータを追加する必要があります。
つまり、次のように変更します:
```kotlin
registerReceiver(
timerReceiver,
IntentFilter(MyTimerService.ACTION_UPDATE),
Context.RECEIVER_NOT_EXPORTED // ← これを追加
)
```
または、`RECEIVER_EXPORTED` を使う場合もありますが、
**基本的にアプリ内通信(同じアプリ内だけでやり取り)なら
`NOT_EXPORTED` にすべきです**。
---
### ✅ 変更後のコードイメージ(抜粋)
```kotlin
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
registerReceiver(
timerReceiver,
IntentFilter(MyTimerService.ACTION_UPDATE),
Context.RECEIVER_NOT_EXPORTED // Android 14 以降に必須
)
startForegroundService()
}
```
---
### 💡補足:どのバージョンから必要か?
- Android 13 以前 → フラグ指定は不要
- **Android 14(API 34)以降**
→ `RECEIVER_EXPORTED` or `RECEIVER_NOT_EXPORTED` 必須
---
### 🔐 なぜこの仕様が導入された?
セキュリティ上の理由です。
悪意あるアプリが、他のアプリにブロードキャストを送り込む攻撃を防ぐため、
**受信側が「誰から受け取るか」を明示的に決める**必要が出てきました。
---
もし希望があれば、
`startForegroundService()` の実装例や
`MyTimerService` の書き方もサンプル付きでお手伝いできます!
何か他にも引っかかっているところがあれば、お気軽にどうぞ 😊
コメント
コメントを投稿