Android - Quick Settings에 Custom Tile 추가하는 방법 (kotlin)

JS · 08 Jun 2020

Android 7.0 (API 24)부터 Quick Settings Tiles를 지원합니다. 이 기능은 Quick Settings에 Custom Tile을 추가할 수 있는 기능입니다.

Android Quick settings

내 앱에 TileService를 구현하면, Quick Settings가 그 서비스를 찾아서 Tile로 등록해 줍니다. Tile은 예를 들어 Quick Settings에 보이는 WIFI 아이콘과 같은 것들을 말하는 것입니다.

Tile은 Activity를 실행하거나 팝업을 뛰우는 것보다, WIFI 처럼 on/off로 어떤 기능을 켜고 끄는 동작이 필요할 때 사용하면 좋습니다.

Custom Tile 등록하기 위해 내 앱에 구현해야 할 것은 TileService 서비스를 구현하고 Manifest에 선언하는 것 뿐입니다.

샘플 앱을 만들어보면서 Custom Tile을 추가하는 방법에 대해서 알아보겠습니다.

이 글은 kotlin으로 작성되었습니다. 완성된 샘플은 GitHub - TileService에서 확인할 수 있습니다.

TileService 구현하기

내 앱에 다음과 같이 TileService를 상속받는 서비스를 생성합니다.

@RequiresApi(api = Build.VERSION_CODES.N)
class MyTileService : TileService() {

    override fun onTileAdded() {
    }

    override fun onTileRemoved() {
    }

    override fun onStartListening() {
    }

    override fun onStopListening() {
    }

    override fun onClick() {
    }

    companion object {
        val TAG = MyTileService::class.java.simpleName
    }
}

각각의 메소드에 대한 설명은 다음과 같습니다.

  • onTileAdded() : Quick Settings에 Tile이 추가될 때 호출됩니다.
  • onTileRemoved() : Quick Settings에 Tile이 제거될 때 호출됩니다.
  • onClick() : Tile을 클릭했을 때 호출 됩니다.
  • onStartListening() : Tile에 대한 변화가 있을 때 호출됩니다. onClick() 이전에 호출됩니다.
  • onStartListening() : Tile에 대한 변화가 있을 때 호출됩니다. onClick() 이후에 호출됩니다.

Manifest에 TileService 등록

앱의 AndroidManifest.xml에 다음과 같이 서비스를 등록합니다.

<service
    android:name=".MyTileService"
    android:label="Cloud"
    android:icon="@drawable/ic_cloud"
    android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
    <intent-filter>
        <action android:name="android.service.quicksettings.action.QS_TILE" />
    </intent-filter>
</service>

각각의 속성의 역할은 다음과 같습니다.

  • android:label : Quick Settings에 보이는 이름입니다.
  • android:icon : Quick Settings에 보이는 아이콘입니다.
  • android:permission : Quick Settings만 내 서비스를 사용할 수 있도록 퍼미션을 설정해줘야 합니다.
  • intent-filterandroid:name : Quick Settings이 TileService를 찾을 때 이 action으로 찾습니다. android.service.quicksettings.action.QS_TILE을 Action으로 설정하지 않으면 Quick Settings가 내 앱의 TileService를 찾을 수 없습니다.

Icon은 흰색으로 만드는 것이 좋습니다. Tile을 활성화하거나 비활성화할 때 Quick Settings가 Tint로 색을 변경하기 때문입니다. 기본적인 아이콘들은 File -> New -> Image Asset에서 쉽게 만들 수 있습니다.

Tile을 Quick Settings에 추가하기

지금까지 TileService를 생성하고 앱에 등록도 하였습니다.

이제 Quick Settings에 내 앱의 Tile을 추가할 수 있습니다.

아래 화면에서 왼쪽 하단의 Pen 모양의 아이콘을 누릅니다. Android Quick settings

그럼 내 앱의 Tile이 보입니다. 이것을 드래그해서 Quick Settings에 추가하면 됩니다. Android Quick settings

다시 Quick Settings 화면으로 돌아가면 추가된 것을 볼 수 있습니다. Android Quick settings

이 때 Tile을 클릭해도 On/Off 되는 것처럼 아이콘 색이 변경되지 않습니다.

Tile이 클릭될 때 상태를 변경해줘야 아이콘의 색이 변경됩니다.

Tile 상태 변경

Tile의 상태는 3가지 입니다.

  • STATE_ACTIVE : 활성화된 상태입니다. On 또는 Enable과 같습니다.
  • STATE_INACTIVE : 비활성화된 상태입니다. Off 또는 Disable과 같습니다.
  • STATE_UNAVAILABLE : 사용 불가능한 상태입니다. 이 상태에서는 클릭할 수 없습니다.

왼쪽부터 ACTIVE, INACTIVE, UNAVAILABLE 상태에 따른 Tile의 아이콘입니다. Android Quick settings

Tile이 Quick Settings에 추가되면 onTileAdded()이 호출되며 이 때 다음과 같이 초기값을 설정할 수 있습니다.

override fun onTileAdded() {
    qsTile.state = Tile.STATE_INACTIVE
    qsTile.updateTile()
}

Tile의 state를 변경하면 꼭 updateTile()를 호출해야 합니다. 그렇지 않으면 Tile의 아이콘 색이 변하지 않습니다.

Tile Click 이벤트 처리

Tile을 클릭하면 onClick()이 호출되며, 이 때 Tile의 state를 변경할 수 있습니다.

다음과 같이 클릭할 때마다 Tile의 상태가 Toggle되도록 하였습니다.

override fun onClick() {
    when (qsTile.state) {
        Tile.STATE_ACTIVE -> {
            Log.d(TAG, "Current State is STATE_ACTIVE. change to STATE_INACTIVE")
            qsTile.state = Tile.STATE_INACTIVE
        }
        Tile.STATE_INACTIVE -> {
            Log.d(TAG, "Current State is STATE_INACTIVE. change to STATE_ACTIVE")
            qsTile.state = Tile.STATE_ACTIVE
        }
    }
    qsTile.updateTile()
}

또한, Tile의 State를 변경하는 것 외에 다른 작업을 수행하도록 코드를 추가할 수 있습니다.

Lockscreen에서 Quick Settings가 열렸는지 확인

isLocked는 Lockscreen이 화면에 보이는 상태인지 알려줍니다. 만약 true를 리턴한다면 현재 Lockscreen에서 Quick settings를 열었다고 생각할 수 있습니다.

Lockscreen에서 다른 동작을 수행해야 한다면 다음과 같이 구현할 수 있습니다.

override fun onClick() {
    Log.d(TAG, "isLocked: $isLocked")
    if (isLocked) {
      // ...
    }
}

정리

내 앱에서 TileService를 구현한다면 Quick Settings에 Tile을 등록할 수 있습니다. 특별히 어려운 것은 없고 Manifest에 약속된 형태로 정의를 하면 됩니다. Tile이 클릭되었을 때 상태를 변경해주고, 필요한 작업을 처리하도록 구현하면 됩니다.

이 글에서 사용된 예제는 GitHub - TileService에서 확인할 수 있습니다.

참고

댓글을 보거나 쓰려면 이 버튼을 눌러주세요.
codechachaCopyright ©2019 codechacha