플러터 개발 초기에는 ios때문에 머리터질 것 같았는데요.. 이제 안드로이드가 말썽입니다. 🤔
그럼 이제 안드로이드와 친해져볼 시간입니다.
아래는 저의 삽질의 기록이기 때문에 해결방법은 여기서 요약 정리해둘게요
1번 해결방법
Manifest merger failed : Apps targeting Android 12 and higher are required to specify an explicit value for `android:exported` when the corresponding component has an intent filter defined
해결방법: android:exported의 값을 true로 설정한다.
여기서 해결이 되지 않는다면 혹시 앱을 빌드하신 지 오래되셨나요? 그럼 2번을 확인해봅니다.
2번 해결방법
androidstudio를 사용해 앱을 빌드하고 있었다면 vscode나 다른 환경으로 변경해봅니다.
(이유: 더 구체적인 다른 에러를 제공받을 가능성있음)
다른 환경이 없다면 그냥 외부 패키지의 업데이트 버전을 한번 더 확인해보세요
버전이 충돌난 경우 위와 같은 에러가 발생하기 때문에 버전이 충돌하지 않을 때까지 맞춰나가시면 됩니다.
아래는 저의 삽질의 기록입니다.
에러는 아래와 같이 발생했습니다.
안드로이드 12이상을 타켓팅하는 앱은 android:exported에 값을 줘야 한다는 것입니다. android:exported는 앱을 다른 앱에서 사용할 수 있도록 설정하는 기능이었고 만약 원한다면 true, 원하지않는다면 false를 줘야 합니다. 그리고 공식문서를 참고해보니 애뮬레이터를 사용하는 경우에도 true값을 줘야한다고 합니다.
안드로이드스튜디오가 지시하는 대로 intent값을 true로 설정합니다. 하지만 여전히 에러가 해결되지 않습니다.? 제가 뭘 빠뜨렸겠죠
그럼 이제 구글링의 시간입니다.
Execution failed for task ':app:processReleaseMainManifest' even after having android:exported defined before all <intent-filter
Execution failed for task ':app:processReleaseMainManifest' Manifest merger failed : Apps targeting Android 12 and higher are required to specify an explicit value for android:exported when the
stackoverflow.com
저와 똑같은 상황에 처한 플러터 뉴비를 발견합니다. 반갑네용
하지만 해결되지 않아용 지나갈게용
유튜브에서 똑같은 상황에 처하신 분을 발견했어용
https://www.youtube.com/watch?v=fma_umbAe6A&ab_channel=ProgrammersLab
그리고 켜진 이 화면.
내가 true로 설정한 값이 부분적으로 적용되고 있는게 보여용 바꿔볼게용
이런 몇 몇 친구들이 true를 적용하지 않았네용 직접 고쳐줄게용
안되네용 열받으니까 한번 껐다켜봅시당 🤔
아까 만났던 뉴비의 답변들을 천천히 읽어볼게용
선언이 중복인 경우에도 해당 에러가 발생한다고 해용 그럼 내 코드에 중복이 있는지 한번 볼게용
찬찬히 살펴봤는데 없는것 같아용 그럼 다른 해결방법을 찾아볼게용
아무래도 제가 본질에 대해 파악하고 있지 못한다는 생각이 듭니다. 그럼 이럴 때 필요한 건 공식문서 시간입니다.
https://developer.android.com/guide/components/intents-filters
매니페스트 파일이 어떻게 구성되어있는지 그리고 문제를 일으키는 intent 파일이 도대체 뭐하는 친구들인지 알아볼게용
모든 앱 프로젝트는 프로젝트 소스 세트의 루트에 AndroidManifest.xml 파일(정확히 이 이름)이 있어야 합니다. 매니페스트 파일은 Android 빌드 도구, Android 운영체제 및 Google Play에 앱에 관한 필수 정보를 설명합니다.
매니페스트 파일은 다른 여러 가지도 설명하지만 특히 다음과 같은 내용을 선언해야 합니다.
- 앱의 패키지 이름(일반적으로 코드의 네임스페이스와 일치). Android 빌드 도구는 프로젝트를 빌드할 때 이 이름으로 코드 엔터티의 위치를 확인합니다. 앱을 패키징할 때 빌드 도구가 이 값을 Gradle 빌드 파일의 애플리케이션 ID로 대체합니다. 이는 시스템과 Google Play에서 고유한 앱 식별자로 사용됩니다. 패키지 이름과 앱 ID에 대해 자세히 알아보세요.
- 앱의 구성 요소(모든 액티비티, 서비스, Broadcast Receiver, 콘텐츠 제공자 포함). 각 구성 요소는 Kotlin이나 Java 클래스의 이름과 같은 기본 속성을 정의해야 합니다. 또한 자신이 처리할 수 있는 기기 구성의 종류, 그리고 구성 요소가 어떻게 시작되는지 설명하는 인텐트 필터와 같은 기능을 선언할 수도 있습니다. 앱 구성 요소에 대해 자세히 알아보세요.
- 앱이 시스템 또는 다른 앱의 보호된 부분에 액세스하기 위해 필요한 권한. 이것은 다른 앱이 이 앱의 콘텐츠에 액세스하고자 하는 경우 반드시 있어야 하는 모든 권한도 선언합니다. 권한에 대해 자세히 알아보세요.
- 앱에 필요한 하드웨어 및 소프트웨어 기능으로, 이에 따라 앱을 Google Play에서 설치할 수 있는 기기의 종류가 달라집니다. 기기 호환성에 대해 자세히 알아보세요.
Android Studio를 사용하여 앱을 빌드하고 있다면 매니페스트 파일이 생성되고, 앱을 빌드하는 동안(특히, 코드 템플릿을 사용하는 시점에서) 대부분의 기본적인 매니페스트 요소가 추가될 것입니다.
공식문서의 내용에 따르면 앱의 패키지와 프로젝트를 빌드할 때 구성되는 모든 액티비티, 서비스, 권한 등의 내용을 구성하고 있네요
가장 먼저 manifest의 정보와 패키지 정보가 담겨있습니다. 여기까진 참 쉽죠?
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp"
android:versionCode="1"
android:versionName="1.0" >
...
</manifest>
현재 문제는 intent-filter입니다.
Manifest merger failed : Apps targeting Android 12 and higher are required to specify an explicit value for `android:exported` when the corresponding component has an intent filter defined.
다 설정을 해줬는데 안되는 건
1.빠진 부분이 있다.
2.설정이 애초에 잘못되었다. (manifest 파일 내부, 안드로이드 버전, 타겟 sdk 버전)
3.그냥 캐시다 캐시를 빡빡 밀어라
3번이었으면 좋겠지만 아닐 가능성이 더 크기때문에 더 찾아볼게용
먼저 인텐트에 대한 개요입니당.
앱 액티비티, 서비스, Broadcast Receiver는 인텐트로 활성화됩니다. 인텐트는 실행할 작업을 설명하는 Intent 객체로 정의되는 메시지입니다. 여기에는 작업할 데이터, 작업을 수행해야 하는 구성 요소의 카테고리 및 기타 지침이 포함됩니다.
앱이 인텐트를 시스템에 발행하면 시스템은 각 앱의 매니페스트 파일에 선언된 인텐트 필터에 기초하여 인텐트를 처리할 수 있는 앱 구성 요소를 찾습니다. 시스템은 일치하는 구성 요소의 인스턴스를 시작하고 해당 구성 요소에 Intent 객체를 전달합니다. 두 개 이상의 앱이 인텐트를 처리할 경우 사용자는 어느 앱을 사용할지 선택할 수 있습니다.
앱 구성 요소는 인텐트 필터(<intent-filter> 요소로 정의)를 몇 개든 가질 수 있으며, 각 인텐트 필터는 해당 구성 요소의 각 기능을 설명합니다.
자세한 내용은 인텐트 및 인텐트 필터 문서를 참조하세요.
그러니까 앱이 실행할 작업을 정의하는 메시지라고 보면 되용 매니페스트 파일 안에 선언되어 시스템을 실행할 때 intent 객체에 필요한 인스턴스를 전달하는 거에용 인텐트 필터는 갯수는 제한이 없다고 나와있어용
인텐트에는 두가지 종류가 있어용 암시적 인텐트와 명시적 인텐트에용
- 명시적 인텐트는 인텐트를 충족하는 애플리케이션이 무엇인지 지정합니다. 이를 위해 대상 앱의 패키지 이름 또는 완전히 자격을 갖춘 구성 요소 클래스 이름을 제공합니다. 명시적 인텐트는 일반적으로 앱 안에서 구성 요소를 시작할 때 씁니다. 시작하고자 하는 액티비티 또는 서비스의 클래스 이름을 알고 있기 때문입니다. 예를 들어, 사용자 작업에 응답하여 새로운 액티비티를 시작하거나 백그라운드에서 파일을 다운로드하기 위해 서비스를 시작하는 것 등이 여기에 해당됩니다.
- 암시적 인텐트는 특정 구성 요소의 이름을 대지 않지만, 그 대신 수행할 일반적인 작업을 선언하여 다른 앱의 구성 요소가 이를 처리할 수 있도록 해줍니다. 예를 들어 사용자에게 지도에 있는 한 위치를 표시하고자 하는 경우, 암시적 인텐트를 사용하여 해당 기능을 갖춘 다른 앱이 지정된 위치를 지도에 표시하도록 요청할 수 있습니다.
아무리 뒤져봐도 알수없는 에러.. 그러다가 문득 에러가 부족하다는 생각이 들었습니다. 저는 원래 vscode를 사용해서 플러터 개발을 진행하고 있었는데 회사에서 안드로이드 스튜디오를 사용하면서 집에서도 안드로이드 스튜디오와 더 친해지기 위해 환경을 맞춰뒀는데 익숙한 환경으로 돌아가기 위해 vscode를 켰고 다른 에러를 발견했습니다..!
쿡쿡 덕분에 에러를 해결할 수 있었고 제 에러의 원인은 외부 라이브러리 버전이 충돌나고 있었습니다. 안스에서는 그냥 intent-filter라고만 명시둔 것을 확인할 수 있었습니다. 1년 동안 업데이트를 하지 않았다보니 그걸 먼저 확인했어야했는데 제가 놓쳤던 부분은 라이브러리였습니다. (개-운)
이번에 배운 건 한가지 환경에서 안되면 환경을 바꿔보는 것도 답입니다.
혹시나.. 잠들려다가 한번만 다시 vscode로 해보자 라고 한 게 이렇게 풀리네요 에러를 정확하게 주었습니다. 고마워요 vscode
버전 수정하고나니 빌드 잘 됩니다.ㅠ 으앙 이걸로 업데이트 2주 밀렸지만 너무 좋네요 감사합니다😭
'Flutter' 카테고리의 다른 글
[flutter] flutter앱에 cloud_firestore 연결 / 예제코드 (0) | 2023.01.25 |
---|---|
[flutter] 플러터의기본 BuildContext를 설명하세요 [정의/사용방법] (0) | 2023.01.21 |
[flutter] chatgpt로 Flutter 로그인 앱을 만드는 예제 (0) | 2023.01.11 |
[상태관리 패키지 사용하지 않고] 플러터 앱 만들기 (0) | 2022.09.06 |
[Flutter Favorite] device_preview 예시코드 (0) | 2022.08.09 |