핀수로그
  • [Android] 부팅 시 앱 실행하기 2 | Application startup on BOOT
    2024년 09월 01일 15시 27분 31초에 업로드 된 글입니다.
    작성자: 핀수
    728x90
    반응형

    들어가며

    이전에 부팅 시 앱 실행하기 기능을 검토해서 그 내용을 공유했었다.

    버전 10부터 변경사항이 생겨 다른 방법으로 구현해었어야 했는데,

    부팅 후 앱이 실행될 때까지 1분에서 1분 30초가량이 걸리는 문제가 있었다.

    해당 기능을 구현하려는 목적이 구현된 결과와는 부합하지 않는 것 같아, 검토를 중단했었다.

    이후, 다른 곳에서 또 이 기능을 검토할 기회가 있었고

    이번에는 1분처럼 긴 시간이 아닌 조금은 즉각적으로 부팅 후 앱을 실행할 수 있도록 구현할 수 있는 코드를 찾았다.

    여기에서 참고하여 구현했다. 

     

    구현하기

    1. BootReceiver 만들기

    디바이스가 부팅되었을 때 이를 알 수 있도록 브로드캐스트 리시버를 상속한 부트 리시버를 만든다.

    class BootReceiver : BroadcastReceiver() {
    
        override fun onReceive(context: Context, intent: Intent) {
            Toast.makeText(context, "부트 리시버 실행", Toast.LENGTH_SHORT).show()
    
            val action = intent.action
            action?.let {
                if (action == Intent.ACTION_BOOT_COMPLETED) {
                    try {
                        val appIntent = Intent(context, BootActivity::class.java)
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                            appIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
                            val pendingIntent = PendingIntent.getActivity(
                                context,
                                0,
                                appIntent,
                                PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
                            )
    
                            try {
                                pendingIntent.send()
                            } catch (e: PendingIntent.CanceledException) {
                                e.printStackTrace()
                            }
                        } else {
                            appIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                            context.startActivity(appIntent)
                        }
                    } catch (e: Exception) {
                        e.printStackTrace()
                    }
                }
            }
        }
    }

    이전 코드와 달라진 점은 PendingIntent를 사용해 앱을 실행시킨다는 점이다.

    PendingIntent

    앱이 다른 구성 요소 (예: 알림, 위젯 등)에게 실행할 수 있는 작업을 전달하는 데 사용되는 객체

    이 객체는 Intent를 포함하며, 나중에 발생할 작업을 나타냄

     

    FLAG_IMMUTABLE

    생성된 PendingIntent가 변경되지 않도록 함

    안전하고 예상 가능한 작동을 보장하기 위한 것

    보안상의 이유로 대부분의 경우 이 플래그를 사용하는 것이 좋음

     

    FLAG_MUTABLE

    생성된 PendingIntent를 변경할 수 있음

    특정 상황에서 유연성이 필요할 때 유용할 수 있지만, 변경 가능성 때문에 보안상의 위험이 발생할 수 있음

     

    FLAG_UPDATE_CURRENT

    설명된 PendingIntent가 이미 존재하는 경우 이를 유지하되

    추가 데이터를 이 새 Intent에 있는 내용으로 대체함을 나타내는 플래그

     

    2. 권한 설정하기

    AndroidManifext.xml

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

    3. Receiver 등록하기

    AndroidManifext.xml

    <receiver
        android:name=".utils.BootReceiver"
        android:enabled="true"
        android:exported="true" >
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"/>
            <category android:name="android.intent.category.DEFAULT"/>
        </intent-filter>
    </receiver>

    4. 권한 부여받기

    마찬가지로 다른 앱 위에 표시 권한을 부여받아야 한다. (안드로이드 6버전 이상부터)

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        if (!Settings.canDrawOverlays(this)) {
            val intent = Intent(
                Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse(
                    "package:$packageName"
                )
            )
            startActivity(intent)
        }
    }

     

    결과

    이전에는 1분~1분 30초 정도 걸리던 것이 8~10초 정도로 줄어든 것을 확인할 수 있다.

     


    공부하며 작성된 글이라 잘못된 정보가 있을 수 있습니다.

    말씀해주시면 수정하겠습니다. 감사합니다.

    References

    아래 글을 참고하여 작성 되었습니다.

     

    [Android] 재부팅 시 앱 자동 실행

    📌 개요 OS 부팅 시 프로그램이 자동실행 되도록 할 수 있도록 사용중이였다. Android 10 버전 이후의 기기에선 동작하지 않았다. 이유를 알아보자. 📌 원인파악 부팅 시 자동 실행에 관하여 검색

    velog.io

     

    728x90
    반응형
    댓글