Foggy day

[Android] Android launcher basic 본문

Android

[Android] Android launcher basic

jinhan38 2023. 8. 27. 16:40

이번 포스팅에서는 안드로이드 런처앱을 만들어보겠습니다. 

런처앱을 만들게 된 계기는 참여했던 프로젝트에서 디바이스가 켜졌을 때 아무것도 없는 화면을 보여줘야 했기 때문입니다. 기본적으로 Android Os가 제공하는 런처에는 시스템 앱들을 보여주고 있습니다. 하지만 프로젝트에서는 디바이스를 실행시켰을 때 기본적으로 설치된 시스템 앱들은 숨기고, 비어있는 화면만 보여줘야 했습니다. 그리고 해당 비즈니스에서 사용할 애플리케이션은 Boot App으로 만들어서 실행시켜야 했습니다. 이때 아무것도 없이 비어있는 화면을 보여주기 위해서는 런처앱을 만들어야 했습니다. 

참여했던 프로젝트에서는 앱 목록을 보여주는 기능은 없었지만, 예제에서는 설치된 앱 목록들을 보여주고, 클릭했을 때 앱을 실행시키는 기능도 추가했습니다. 

 

 

1. 기본 화면

2. 설치된 앱 목록 화면

3. Manifest 설정

 

 

이번 런처앱에서 할 작업은 크게 3가지입니다. 먼저 기본적으로 화면에 보여줄 화면을 구성한 다음에, 앱이 설치된 목록을 보여줄 화면을 만들겠습니다. 그리고 Manifest에서 기본앱/홈앱으로 만들어주고, theme을 변경해줍니다. 

 

 

 

1. 기본 화면

기본 화면이 될 MainActivity에서는 버튼 하나만 추가하겠습니다. 버튼을 클릭했을 때 앱 목록을 볼 수 있는 화면으로 이동할 예정입니다. 

 

MainActivity

class MainActivity : Activity() {
    
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        findViewById<Button>(R.id.apps_button).setOnClickListener {
            val i = Intent(this, AppsListActivity::class.java)
            startActivity(i)
        }
    }

}

 

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/apps_button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_alignParentEnd="true"
        android:background="@android:color/holo_purple"
        android:padding="20dp"
        android:text="앱 목록"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:ignore="HardcodedText" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

 

 

2. 설치된 앱 목록 화면

디바이스에 설치된 앱 목록을 불러오고, 해당 항목을 클릭했을 때 앱을 실행시키는 로직을 구현하겠습니다. 

핵심은 설치된 앱 정보들을 불러오는 것과 클릭했을 때 앱을 실행시키는 것입니다.(RecyclerView를 활용한 UI 구성은 화면 하단에 있는 깃허브 코드를 참조해 주세요)

 

- 앱 목록 불러오기

설치된 앱 목록을 불러오기 위해서는 Intent와 PacakgeManager를 사용해야 합니다. 이렇게 불러온 정보들은 AppInfo 데이터 클래스에 담아주겠습니다. 

    private fun loadApps(): ArrayList<AppInfo> {
        val dataList = ArrayList<AppInfo>()
        val manager = packageManager
        val i = Intent(Intent.ACTION_MAIN, null)
        i.addCategory(Intent.CATEGORY_LAUNCHER)
        val apps = manager!!.queryIntentActivities(i, 0)

        for (app in apps) {
            dataList.add(
                AppInfo(
                    appName = app.loadLabel(manager).toString(),
                    packageName = app.activityInfo.packageName,
                    icon = app.activityInfo.loadIcon(manager)
                )
            )
        }
        return dataList
    }
data class AppInfo(
    val appName: String,
    val packageName: String,
    var icon: Drawable
)

 

- 앱 실행

앱을 실행시키는 것 또한 intent와 pacakgeManaer로 작업해 줍니다. getLaunchIntentForPackage 함수에 패키지명을 넣어준 후 startActivity 함수를 실행시켜 주세요.

val i = context.packageManager!!.getLaunchIntentForPackage(dataList[position].packageName)
context.startActivity(i)

 

 

3. Manifest

Manifest에서는 홈앱 설정과 테마를 변경해 주겠습니다.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.Launcher"
        tools:targetApi="31">
        <!--
        android:launchMode="singleTask" 시스템이 한 개의 인스턴스만 생성한다.
        싱글톤과 같다고 보면 된다.
        -->
        <activity
            android:name=".MainActivity"
            android:exported="true"
            android:launchMode="singleTask">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />

                <!-- 홈 버튼을 눌렀을 때 홈 앱처럼 됨 -->
                <category android:name="android.intent.category.HOME" />
                <category android:name="android.intent.category.DEFAULT" />
                <!---->
            </intent-filter>

            <meta-data
                android:name="android.app.lib_name"
                android:value="" />
        </activity>

        <!--설치된 앱의 목록을 보여주기 위한 화면-->
        <activity
            android:name=".AppsListActivity"
            android:exported="false" />

    </application>

</manifest>

 

themes.xml

parent 에서 Theme.AppCompat 가 나오지 않는다면 

build.gradle(Module:android.app)에 implementation 'androidx.appcompat:appcompat:1.6.1' 를 추가해주세요.

<resources>
    <style name="Theme.Launcher" parent="Theme.AppCompat">
        <!--배경색 투명으로 변경-->
        <item name="android:windowBackground">@android:color/transparent</item>
        <item name="android:colorBackgroundCacheHint">@null</item>
        <!--시스템의 배경화면을 보여줄지 말지 설정 -->
        <item name="android:windowShowWallpaper">true</item>
        <!--상태바 컬러 변경-->
        <item name="android:statusBarColor">@android:color/transparent</item>
        <!--하단 네비게이션바 컬러 변경-->
        <item name="android:navigationBarColor">@android:color/transparent</item>
        <!--윈도우에서 보여지는 컨텐츠의 Overlay(그림자) 제거-->
        <item name="android:windowContentOverlay">@null</item>
        <!--앱 실행 시 보이는 초기 로딩 화면 보여줄지 여부, true로 설정하면 안 보여줌 -->
		<!-- <item name="android:windowDisablePreview">true</item> -->
    </style>
</resources>

 

 

 

최종 화면

 

 

 

 

예제 소스코드 

https://github.com/jinhan38/launcher_android