Foggy day

[Flutter] Flutter 앱 Android Launcher(런처) 설정, 상태바와 네비게이션 바 숨기기 본문

Flutter/Flutter 앱

[Flutter] Flutter 앱 Android Launcher(런처) 설정, 상태바와 네비게이션 바 숨기기

jinhan38 2023. 3. 13. 18:44

 

 

이번 포스팅에서는 Flutter로 만든 Android 앱을 런처앱으로(기본앱)으로 설정하는 방법을 알아보겠습니다.

 

 

요구 조건은 아래와 같습니다.

  • 실행된 앱에서 Recent 버튼 비활성화
  • 상태바(Status bar, 상단)와 네비게이션 바(Navigation bar, 하단) 숨김 처리
  • 실행된 앱에서 Back 버튼 비활성화(Back 버튼으로 앱 종료 못하도록 설정)
  • Android 홈 버튼을 눌렀을 때 해당 앱 실행

 

첫번째 기능은 Android Native 코드에서

두번째, 세번째 기능은 Flutter 코드에서

네번째 기능은 핸드폰의 설정 앱에서 변경할 수 있습니다. 

 

 

 

1. Android Native code

 

 

MainActivity.kt

먼저 Android의 MainActivity 파일에서 아래 코드를 추가해주세요.

Recent 버튼을 클릭했을 경우 onPause 생명주기를 타게 됩니다. 이때 백그라운드에 있는 앱에서 최상단에 있는 앱을 다시 실행시키는 코드입니다. 

package com.example.launcher

import android.app.ActivityManager
import android.content.Context
import android.os.Build
import androidx.annotation.RequiresApi
import io.flutter.embedding.android.FlutterActivity

class MainActivity: FlutterActivity() {

    // Recent button click
    @RequiresApi(Build.VERSION_CODES.M)
    override fun onPause() {
        super.onPause()
        val activityManager: ActivityManager = applicationContext
            .getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
        activityManager.moveTaskToFront(taskId, 0)
    }
}

 

 

AndroidManifest.xml

해당 앱을 기본앱으로(런처앱)으로 만들기 위해 설정을 해줘야 합니다. 

프로젝트를 처음 만들면 AndroidManifest의 launchMode는 singleTop으로 기본 설정됩니다. 이것을 singleTask로 변경해주세요. 

 

그리고 상단에는 permission 추가

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

 

intent-filter에는 category를 추가해주세요

<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.HOME"/>

 

AndroidManifest full code 

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.launcher">

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

    <application
        android:name="${applicationName}"
        android:icon="@mipmap/ic_launcher"
        android:label="launcher">
        <activity
            android:name=".MainActivity"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
            android:exported="true"
            android:hardwareAccelerated="true"
            android:launchMode="singleTask"
            android:theme="@style/LaunchTheme"
            android:windowSoftInputMode="adjustResize">
            <meta-data
                android:name="io.flutter.embedding.android.NormalTheme"
                android:resource="@style/NormalTheme" />
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />

                <category android:name="android.intent.category.DEFAULT"/>
                <category android:name="android.intent.category.HOME"/>

            </intent-filter>
        </activity>
        <meta-data
            android:name="flutterEmbedding"
            android:value="2" />
    </application>
</manifest>

 

 

 

 

2. Flutter code

Back 버튼 기능을 컨트롤하기 위해서 WillPopScope 위젯을 사용했고, 

상태바와 네비게이션바를 숨김처리하기 위해서는 main함수에서 SystemUI를 설정해줬습니다.

앱을 종료하기 위해서는 SystemNavigator.pop(); 를 호출했습니다. 

 

main.dart

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

void main() {

  /// Binding 위해 추가 
  WidgetsFlutterBinding.ensureInitialized();

  /// 상태바와 네비게이션바 숨김 처리
  SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: []);

  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
  
    /// 백버튼 기능 비활성화
    return WillPopScope(
      onWillPop: () async => false,
      child: Scaffold(
        appBar: AppBar(
          title: Text(widget.title),
        ),
        body: Center(
          child: ElevatedButton(
            onPressed: () {
            
              /// 앱 종료 
              SystemNavigator.pop();
              
            },
            child: const SizedBox(
              width: 200,
              height: 100,
              child: Center(
                child: Text(
                  "앱 종료",
                  style: TextStyle(fontSize: 40),
                ),
              ),
            ),
          ),
        ),
      ),
    );
  }
}

 

 

 

 

3. 홈 버튼 눌렀을 때 특정 앱 실행 

안드로이드의 홈 버튼을 누르면 일반적으로 볼 수 있는 홈앱이 실행됩니다. 

이때 홈 앱이 아니라 다른 앱을 실행시키고 싶다면 홈앱 설정을 변경해줘야 합니다. 

설정 -> 애플리케이션 -> 기본앱 -> 홈 앱-> 원하는 앱 선택 

(기본앱이 되기 위해서는 AndroidManifest 설정 절차를 거쳐야합니다.)

 

기본앱 설정하는 과정 

 

 

 


 

 

 

1, 2, 3번의 과정을 거치면 

특정 앱을 홈 앱으로 만들 수 있습니다.

그리고 백, 앱목록 버튼을 비활성화 함으로써 홈앱에서 벗어나지 않도록 할 수 있습니다. 

만약 이러한 상태의 앱을 만들었다면 사용자가 앱 종료할 수 있도록 버튼을 추가해주는 것을 추천합니다. 

 

 

Github

https://github.com/jinhan38/launcher