android_foregroundService_と_broadcast receiverに関するエラー

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` の書き方もサンプル付きでお手伝いできます!


何か他にも引っかかっているところがあれば、お気軽にどうぞ 😊


コメント