반년만에 블로그 ㅎㅎ
반년만에 조금은 재미있는 스프린트를 진행해서 기억하기 위해 블로그를 써본다.
먼저 앞서 제목에서 알 수 있다. RN앱에서 바로 위젯을 추가할 수 있는 기능을 만들어야했다.
유저의 리텐션을 높히기 위해선 위젯의 존재를 알려야하고 더 쉽게 앱에 진입할 수 있는 경로라고 생각했다.
처음엔 아무것도 모르는 미지의 영역이고 불확실한 상황이었지만 팀에서 계속 연습했던 불확실한 상황에서 살아남기(?)를 연습할 수 있는 좋은 기회였다.
⛔️주의⛔️
아쉽지만 위젯을 만드는 법이 아니라 이미 있는 위젯을 더 효과적으로
나타낼 수 있는 블로그이기 때문에 관련이 없을 수도 있는 점 양해부탁드립니다.
다들 코드를 Android Studio에서 코드를 조금이라도 쳐봤다면 Intent와 PendingIntent를 한번쯤은 봤을 것이다.
PendingIntent는 현재 내가 갖고 있는 intent를 바로 실행을 시키는게 아니라 특정 시점, 특정 액션에 수행할 수 있는 특징을 갖고 있다.
@ReactMethod
public fun createWidgetInApp() {
val context: Context = reactApplicationContext
val appWidgetManager = AppWidgetManager.getInstance(context)
val intent = Intent()
val provider = ComponentName(context, Widget::class.java)
// SDK > 26 (android 8.0)
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && appWidgetManager.isRequestPinAppWidgetSupported){
val intent = Intent(context, AndroidAppWidget::class.java)
val successCallback = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
appWidgetManager.requestPinAppWidget(provider, null, successCallback)
}
}
우선 react-native에서 nativeModules로 사용할 것이기 때문에 상단에 @ReactMethod를 적어준다.
ConponentName은 내가 가진 위젯을 import 해주면 되고
이번에 사용할 requestPinAppWidget
이 친구는 안타깝게도 android 8.0 이상만 지원해주기 때문에 if문에서 SDK 버전별로 걸러줘야한다.
PendingIntent에 파라미터로
이렇게 4가지 넣어주면 된다. 1번과 2번은 어느정도 알 수 있겠지만
내 경우엔 3번 Intent엔 데이터 트래킹을 위한 amplitude 코드를 넣어줬어야했다.
class AndroidAppWidget: BroadcastReceiver() {
private val amplitude = Amplitude.getInstance()
override fun onReceive(context: Context?, intent: Intent?) {
amplitude.logEvent(AmplitudeEvents.이벤트_네임)
}
}
successCallback이 성공적으로 실행이 되었을 때 트래킹을 위해 직접 만들어서 넣어줬다.
4번 flag는 아래와 같이 몇가지가 있다.
FLAG_CANCEL_CURRENT
: 사용할 Intent에 대해 한 번에 하나만 활성화해야 하는 경우 사용하며, 이전에 생성한 PendingIntent를 취소한 후 새로 생성한다.FLAG_IMMUTABLE
: 생성된 PendingIntent가 불변(변경될 수 없음)이라는 것을 나타낸다.FLAG_MUTABLE
: 생성된 PendingIntent가 변경 가능해야한다는 것을 나타낸다.FLAG_NO_CREATE
: PendingIntent가 아직 존재하지 않는 경우 생성하는 대신 단순 null을 반환함을 나타낸다.FLAG_ONE_SHOT
: 해당 PendingIntent를 한 번만 사용할 수 있음을 나타낸다.FLAG_UPDATE_CURRENT
: 기존에 생성된 PendingIntent가 있다면 새로운 값으로 업데이트한다.
굳이 내가 사용한 FLAG_UPDATE_CURRENT
가 아니더라도 상황에 맞게 사용하면 될 것 같다 !
라고 했지만
targeting s+ (version 31 and above) requires that one of flag_immutable or flag_mutable be specified when creating a pendingintent.
이라는 에러가 나왔다 ㅎㅎ.....
PendingIntent를 생성할 때 s+(버전 31 이상)를 타겟팅하려면 flag_immutable 또는 flag_mutable 중 하나를 지정해야 한다고 한다..
허허..
그리고 추가적으로 에러의 내용을 보면 google docs에서 일부 변경이 가능한 PendingIntent에 의존하는 경우에만 FLAG_MUTABLE을 사용하고, 다른 경우에는 FLAG_IMMUTABLE 사용을 강력히 권고한다고 한다.
이번에 앱에서 위젯 추가하면서 자연스럽게 유저들에게 위젯을 온보딩해주는 기능을 만들어봤다.
이걸 만듦으로써 좋은 데이터와 좋은 결과가 나와서 유저들이 앱을 더 잘 사용했으면 좋겠다 :)