Android프로그래밍

[Android] 안드로이드 14 타켓팅시 발생하는 One of RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED should be specified when a receiver isn’t being registered exclusively for system broadcasts 리시버 등록 오류 해결하기

안드로이드 스튜디오에서 build.gradle(:app) 파일 설정에서 targetSdkVersion을 33에서 34로 상향 후 테스트 폰을 연결 후 실행하였다.

android {
    compileSdk 34
    defaultConfig {
        applicationId "com.test"
        minSdkVersion 19
        targetSdkVersion 34
        versionCode 836
        versionName "8.1.6"
.....이하생략

이전까지는 발생하지 않았던 오류가 발생되었다. 오류내용은 다음과 같다.

FATAL EXCEPTION: main
Process: com.test, PID: 18923
java.lang.RuntimeException: Unable to start service com.test.TestService@ec532b3 with Intent { cmp=com.test/.TestService }: java.lang.SecurityException: com.test: One of RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED should be specified when a receiver isn't being registered exclusively for system broadcasts
                                                                                                    	at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:5286)
                                                                                                    	at android.app.ActivityThread.-$$Nest$mhandleServiceArgs(Unknown Source:0)
                                                                                                    	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2531)
                                                                                                    	at android.os.Handler.dispatchMessage(Handler.java:106)
                                                                                                    	at android.os.Looper.loopOnce(Looper.java:230)
                                                                                                    	at android.os.Looper.loop(Looper.java:319)
                                                                                                    	at android.app.ActivityThread.main(ActivityThread.java:8893)
                                                                                                    	at java.lang.reflect.Method.invoke(Native Method)
                                                                                                    	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:608)
                                                                                                    	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)
                                                                                                    Caused by: java.lang.SecurityException: com.test: One of RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED should be specified when a receiver isn't being registered exclusively for system broadcasts
                                                                                                    	at android.os.Parcel.createExceptionOrNull(Parcel.java:3069)
                                                                                                    	at android.os.Parcel.createException(Parcel.java:3053)
                                                                                                    	at android.os.Parcel.readException(Parcel.java:3036)
                                                                                                    	at android.os.Parcel.readException(Parcel.java:2978)
                                                                                                    	at android.app.IActivityManager$Stub$Proxy.registerReceiverWithFeature(IActivityManager.java:6137)
                                                                                                    	at android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:1913)
                                                                                                    	at android.app.ContextImpl.registerReceiver(ContextImpl.java:1853)
                                                                                                    	at android.app.ContextImpl.registerReceiver(ContextImpl.java:1841)
                                                                                                    	at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:772)
                                                                                                    	at com.test.TestService.regisiterReceiver(TestService.java:272)
                                                                                                    	at com.test.TestService.onStartCommand(TestService.java:196)
                                                                                                    	at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:5268)
                                                                                                    	at android.app.ActivityThread.-$$Nest$mhandleServiceArgs(Unknown Source:0) 
                                                                                                    	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2531) 
                                                                                                    	at android.os.Handler.dispatchMessage(Handler.java:106) 
                                                                                                    	at android.os.Looper.loopOnce(Looper.java:230) 
                                                                                                    	at android.os.Looper.loop(Looper.java:319) 
                                                                                                    	at android.app.ActivityThread.main(ActivityThread.java:8893) 
                                                                                                    	at java.lang.reflect.Method.invoke(Native Method) 
                                                                                                    	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:608) 
                                                                                                    	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103) 
                                                                                                    Caused by: android.os.RemoteException: Remote stack trace:
                                                                                                    	at com.android.server.am.ActivityManagerService.registerReceiverWithFeature(ActivityManagerService.java:16580)
                                                                                                    	at android.app.IActivityManager$Stub.onTransact$registerReceiverWithFeature$(IActivityManager.java:11530)
                                                                                                    	at android.app.IActivityManager$Stub.onTransact(IActivityManager.java:2928)
                                                                                                    	at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:3195)
                                                                                                    	at android.os.Binder.execTransactInternal(Binder.java:1375)



오류가 발생한 코드의 위치는 다음과 같다.

registerReceiver(testReceiver, intentFilter);

Android 14 이상(U+)에서 실행되는 앱의 경우 리시버 등록시 반드시  RECEIVER_EXPORTED / RECEIVER_NOT_EXPORTED 플래그 중에 하나를 지정해주어야한다. 만약 다른 앱의 송신을 수신할수 있도록 하려면 RECEIVER_EXPORTED 플래그를 사용하면 되고, 다른 앱의 송신을 수신하지 않는 리시버를 등록하려면 RECEIVER_NOT_EXPORTED 플래그를 설정하여 사용하면 된다.

오류가 해결된 코드는 다음과 같다.

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {  //if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
    registerReceiver(testReceiver, intentFilter, RECEIVER_NOT_EXPORTED); //다른 앱의 송신을 수신 하지 않음
}else{
    registerReceiver(testReceiver, intentFilter);
}

ContextCompat을 사용하면 Android 버전에 대해 분기하지 않고 Broadcast Receiver를 등록할 수 있다.

ContextCompat.registerReceiver(getApplicationContext(), testReceiver, intentFilter, ContextCompat.RECEIVER_EXPORTED);


reference : https://stackoverflow.com/questions/77235063/one-of-receiver-exported-or-receiver-not-exported-should-be-specified-when-a-rec

error: Content is protected !!