Android 14 디바이스에서 Target SDK API가 34인 앱은 암시적 인텐트로 자신의 Activity를 실행하려고 할 때 아래와 같은 에러가 발생할 수 있습니다.

Android 14에서 암시적 인텐트와 대기 중인 인텐트 제한사항라는 변경사항이 추가되었기 때문인데요, 어떤 경우에 문제가 발생하고 해결 방법은 무엇인지 알아보겠습니다.

Activity 실행:

context.startActivity(Intent("com.example.action.APP_ACTION"))

에러:

08-13 21:43:10.268 10019 10019 D AndroidRuntime: Shutting down VM
08-13 21:43:10.272 10019 10019 E AndroidRuntime: FATAL EXCEPTION: main
08-13 21:43:10.272 10019 10019 E AndroidRuntime: Process: com.example.myapplication, PID: 10019
08-13 21:43:10.272 10019 10019 E AndroidRuntime: android.content.ActivityNotFoundException: No Activity found to handle Intent { act=com.example.action.APP_ACTION }
08-13 21:43:10.272 10019 10019 E AndroidRuntime: 	at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:2238)
08-13 21:43:10.272 10019 10019 E AndroidRuntime: 	at android.app.Instrumentation.execStartActivity(Instrumentation.java:1877)
08-13 21:43:10.272 10019 10019 E AndroidRuntime: 	at android.app.Activity.startActivityForResult(Activity.java:5589)
08-13 21:43:10.272 10019 10019 E AndroidRuntime: 	at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:676)
08-13 21:43:10.272 10019 10019 E AndroidRuntime: 	at android.app.Activity.startActivityForResult(Activity.java:5547)
08-13 21:43:10.272 10019 10019 E AndroidRuntime: 	at androidx.fragment.app.FragmentActivity.startActivityForResult(FragmentActivity.java:663)
08-13 21:43:10.272 10019 10019 E AndroidRuntime: 	at android.app.Activity.startActivity(Activity.java:6045)

1. Android 14의 변경사항

간단히 말하면, Android 14 디바이스에서 Target SDK API가 34 이상인 앱은, 암시적 인텐트로 exported=false로 선언된 Activity는 실행할 수 없습니다.

예를 들어, 아래와 같이 액티비티를 exported=false로 선언했을 때

<activity
    android:name=".AppActivity"
    android:exported="false">
    <intent-filter>
        <action android:name="com.example.action.APP_ACTION" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

아래와 같은 암시적 인텐트로 실행하면 Activity를 찾을 수 없다는 에러와 함께 ActivityNotFoundException이 발생합니다.

val intent = Intent("com.example.action.APP_ACTION")
startActivity(intent)

이 변경사항은 Target SDK API가 34 이상인 앱에만 적용됩니다. API가 33 이하인 앱은 에러가 발생하지 않고 액티비티가 실행됩니다.

암시적 인텐트는 Intent에 Package name이나 Component name이 설정되지 않은 인텐트

2. 해결 방법

명시적 인텐트를 사용하여 실행

명시적 인텐트를 사용하면 exported=false인 Activity도 실행할 수 있습니다.

val intent = Intent("com.example.action.APP_ACTION")
intent.setPackage("com.example.myapplication")
startActivity(intent)

exported=false는 외부 앱에 Activity를 노출하지 않고 내부적으로만 사용, exported=true는 외부 앱에서 실행 가능

exported를 true로 변경

Activity를 exported=true로 선언하여 모든 앱에게 공개를 하면, 암시적 인텐트를 사용하여 실행할 수 있습니다.

<activity
    android:name=".AppActivity"
    android:exported="false">
    <intent-filter>
        <action android:name="com.example.action.APP_ACTION" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

만약 액티비티를 외부에서 실행하지 못하도록 해야한다면, 명시적 인텐트로 실행하는 방법 뿐이 없습니다.