- [Android] 부팅 시 앱 실행하기 | Android 10+ Application startup on BOOT2022년 09월 21일 00시 28분 11초에 업로드 된 글입니다.작성자: 핀수728x90반응형
들어가며
부팅 시 앱이 실행 되었으면 좋겠다는 요구 사항이 들어왔다.
예전에 부팅 되었을 때 관련 데이터를 삭제하는 기능을 잠깐 검토 했던 기억이 있어서
금방 하겠거니 생각했다.
그렇게 영원한 나의 친구이자 스승인 구글에 관련 기능을 검색했다.
1. AndroidManifest.xml 에 권한을 명시하고
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
2. Receiver를 만들고
class DeviceBootReceiver : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { val action = intent?.action if (action.equals(Intent.ACTION_BOOT_COMPLETED)){ val appIntent = Intent(context, SplashActivity::class.java) intent?.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) context.startActivity(appIntent) } } }
3. AndroidManifest.xml 에 리시버를 등록하면
<application> ... <receiver android:name=".util.DeviceBootReceiver" android:exported="true" android:enabled="true" android:directBootAware="true"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED"/> </intent-filter> </receiver> ... </application>
끝나는 간단한 기능이었다.
그렇게 코드를 작성하고 실행을 했는데
안.된.다.Android 10 (API 레벨 29) 이상은 앱이 백그라운드에서 실행될 때 Activity를 시작할 수 있는 시점에 제한이 있습니다
원인은 위와 같았다.
정책이 변경되면서 해당 버전부터는 위의 방식은 통하지 않았다.
직접 Activity를 시작하는 것이 아니라 서비스를 등록하고 그 서비스를 통해 특정 작업을 처리하도록 변경되었다.
그런데 마침 내가 테스트한 기기가 버전 10이었고
또 우리 프로젝트의 주 타겟 버전이 11이기 때문에 해당 문제를 반드시 해결해야만 했다.
그래서 또 내 최고의최고의 스승 공식문서를 찾아보았다.
주 내용은 background에서 activity 실행을 제한하겠다는 내용인데
아래에 해당 제한에 대한 예외 사항들이 나와있었다.이 앱은 사용자로부터 SYSTEM_ALERT_WINDOW 권한을 부여받았습니다.
예외 사항의 마지막 항목이다.
SYSTEM_ALERT_WINDOW 권한
해당 권한을 부여받은 앱은 다른 모든 앱 위에 표시될 수 있다는 의미같다.
시스템 관련 앱들에서 주로 쓰일 것이다.
좀 더 높은 우선순위를 가진 앱들이..
그러므로 대부분의 앱들은 해당 권한을 요청할 일이 없다.
그러나 현재 나의 앱은 성격이 좀 다르므로..
해당 권한을 통해 기능을 구현해보려고 한다.권한 부여 받기
Settings.canDrawOverlays(context) 를 통해 해당 권한을 확인할 수 있다.
권한이 부여되지 않은 상태라면 아래와 같이 해당 화면으로 보낼 수 있다.
버전 10까지는 내 앱의 권한 화면으로 이동할 수 있지만
11부터는 Uri 부분은 무시되고 '다른 앱 위에 표시' 허용 가능 목록이 뜬다.
거기서 직접 찾아 권한을 부여해야한다.if (!Settings.canDrawOverlays(this)){ val intent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:${packageName}")) startActivity(intent) }
*수동으로 권한 주는법
[설정] - [애플리케이션] - 더보기 (점 세개) - 특별한 접근 - 원하는 앱 찾아 권한 부여기능 구현하기
1. 권한 설정
AndroidManifest.xml
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
2. BroadcastReceiver 생성
class DeviceBootReceiver : BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { val action = intent?.action if (action.equals(Intent.ACTION_BOOT_COMPLETED)){ startService(context!!) } } private fun startService(context: Context){ val appIntent = Intent(context, BootService::class.java) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O){ context.startForegroundService(appIntent) } else { context.startService(appIntent) } } }
3. receiver 등록
AndroidManifest.xml
<application> ... <receiver android:name=".util.DeviceBootReceiver" android:exported="true" android:enabled="true" android:directBootAware="true"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED"/> </intent-filter> </receiver> ... </application>
4. Service 생성
class BootService : Service() { private val myChannelId = "ChannelId" private val id = 10 override fun onCreate() { super.onCreate() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { createNotificationChannel() startForeground(id, createNotification()) startApp() } } @RequiresApi(Build.VERSION_CODES.O) private fun createNotificationChannel() { val notificationChannel = NotificationChannel(myChannelId, "MyService", NotificationManager.IMPORTANCE_HIGH) val notificationManager = applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager notificationManager.createNotificationChannel(notificationChannel) } private fun createNotification(): Notification { return NotificationCompat.Builder(this, myChannelId) .setContentTitle("Service is running") .setContentText("Service is running") .build() } @RequiresApi(Build.VERSION_CODES.O) private fun startApp(){ if (Settings.canDrawOverlays(this)){ val intent = Intent(this, SplashActivity::class.java) intent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) this.startActivity(intent) } } override fun onDestroy() { super.onDestroy() stopForeground(true) } override fun onBind(intent: Intent?): IBinder? { return null } }
5. Service 등록
AndroidManifest.xml
<service android:name=".util.BootService"/>
적용화면
그런데 부팅 후 앱이 실행되기까지 꽤나 오랜 시간이 걸린다....
평균 1분 ~ 1분 30초 정도 소요되기 때문에 이부분은 좀 더 고려가 필요해보인다.
References
아래 글을 참고하여 작성 되었습니다.
[Android Tip] 부팅 시 자동으로 앱 실행하기
모바일 용 앱에서는 그럴 일이 거의 없지만, 일반 셋탑용 앱을 만들다보면 부팅되자마자 앱이 자동으로 실...
blog.naver.com
Android 10.0 Application startup on BOOT
We have an android application which we intend to start/launch during phone boot. With some code tries in Android 10, we realized that the launching of app on boot, is not possible after Android 8.0.
stackoverflow.com
[Android] 다른 앱 위에 그리기 샘플코드(android.permission.SYSTEM_ALERT_WINDOW)
다른 앱 위에 팝업창을 뛰우거나 앱을 실행해야할 때 다른 앱 위에 그리기 권한이 필요하다. 일반 권한 및 위험 권한처럼 동작하지 않는 권한이 있다. SYSTEM_ALERT_WINDOW 및 WRITE_SETTINGS는 특히 민감
ddolcat.tistory.com
Android - ACTION_BOOT_COMPLETED 이벤트 받기
안드로이드는 부팅이 완료되면 ACTION_BOOT_COMPLETED 인텐트를 전달하여 앱이 실행되도록 합니다. 앱은 이 인텐트를 받고, 어떤 작업을 처리할 수 있습니다. 또한, BOOT_COMPLETED 인텐트를 받고 내 앱의
codechacha.com
728x90반응형'Android > Android' 카테고리의 다른 글
내 프로젝트와 Firebase 연동하기 (0) 2023.03.06 [Android] Hilt 적용해보기 (0) 2023.01.04 LeakCanary 사용하기 (0) 2022.08.07 fastlane 으로 Android 앱 배포 쉽게 하기 (feat. windows) (0) 2022.07.05 Android Jetpack Compose 맛보기 (0) 2022.07.03 다음글이 없습니다.이전글이 없습니다.댓글