일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 막내의 막무가내 알고리즘
- 막내의막무가내 플러터
- 안드로이드 Sunflower 스터디
- 막무가내
- 프래그먼트
- 프로그래머스 알고리즘
- 안드로이드 sunflower
- 주택가 잠실새내
- 막내의막무가내 목표 및 회고
- 막내의막무가내 코볼 COBOL
- 막내의막무가내 플러터 flutter
- 부스트코스에이스
- 안드로이드
- flutter network call
- 막내의 막무가내
- 막내의막무가내 일상
- 막내의막무가내 알고리즘
- 막내의막무가내 안드로이드
- 막내의막무가내 코틀린 안드로이드
- 막내의막무가내 프로그래밍
- 막내의막무가내 SQL
- 막내의막무가내
- 막내의막무가내 rxjava
- 부스트코스
- 2022년 6월 일상
- 막내의막무가내 안드로이드 에러 해결
- 주엽역 생활맥주
- 막내의막무가내 안드로이드 코틀린
- Fragment
- 막내의막무가내 코틀린
- Today
- Total
막내의 막무가내 프로그래밍 & 일상
[안드로이드] 카카오링크 API 구현 방법 (feat. 카카오톡 공유하기 기능, 피드형 메시지) 본문
[안드로이드] 카카오링크 API 구현 방법 (feat. 카카오톡 공유하기 기능, 피드형 메시지)
막무가내막내 2021. 4. 8. 17:14
안녕하세요 카카오링크를 구현해보고 싶어 기존 프로젝트에 기능을 구현해보았습니다.
이에 대해 포스팅을 해보겠습니다. ㅎㅎ
[카카오링크란?]
카카오링크는 사용자가 카카오톡 메시지로 친구에게 메시지에 담긴 정보를 공유하는 기능입니다. 사용자는 카카오링크가 적용된 웹 페이지 또는 특정 정보를 자신의 카카오톡 친구에게 공유할 수 있습니다.
[어플리케이션 등록]
카카오 링크를 구현하기전에 애플리케이션 등록을 진행해주어야 합니다. 밑 링크들을 참고해주세요.
카카오링크 관련만 집중해서 포스팅하고 기본 세팅같은건 공식문서 URL로 남기도록 하겠습니다. !
developers.kakao.com/docs/latest/ko/getting-started/app
youngest-programming.tistory.com/93
[시작하기전 기본 모듈 세팅]
카카오 기본 모듈들 설치도 필요합니다. 밑 링크를 꼭 참고해서 세팅해주세요 :) 제가 적은거 말고도 키해시등록 등이 필요해요 !
developers.kakao.com/docs/latest/ko/getting-started/sdk-android
[ 프로젝트 수준 builde.gradle]
프로젝트의 Gradle 설정을 통해 Android SDK를 간편하게 연동할 수 있습니다. Android SDK를 적용할 프로젝트의 build.gradle(Project) 파일에 다음과 같이 Android SDK 레파지토리(Repository)를 설정합니다.
maven { url 'https://devrepo.kakao.com/nexus/content/groups/public/' }
[ 앱 수준 bulilde.gradle]
build.gradle(Module) 파일에 필요한 모듈을 설정합니다. 저는 RxKotlin을 활용했습니다.
dependencies {
implementation "com.kakao.sdk:v2-user:2.4.2" // 카카오 로그인
implementation "com.kakao.sdk:v2-talk:2.4.2" // 친구, 메시지(카카오톡)
implementation "com.kakao.sdk:v2-story:2.4.2" // 카카오스토리
implementation "com.kakao.sdk:v2-link:2.4.2" // 메시지(카카오링크)
implementation "com.kakao.sdk:v2-navi:2.4.2" // 카카오내비
}
//RxKotlin
dependencies {
implementation "com.kakao.sdk:v2-user-rx:2.4.2" // 카카오 로그인
implementation "com.kakao.sdk:v2-talk-rx:2.4.2" // 친구, 메시지(카카오톡)
implementation "com.kakao.sdk:v2-story-rx:2.4.2" // 카카오스토리
implementation "com.kakao.sdk:v2-link-rx:2.4.2" // 메시지(카카오링크)
implementation "com.kakao.sdk:v2-navi:2.4.2" // 카카오내비
}
[manifest 권한]
<!-- 인터넷 사용 권한 설정-->
<uses-permission android:name="android.permission.INTERNET" />
[Java8 사용설정 필요]
// Java 8 사용을 위한 build.gradle 설정
android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
}
[Application 클래스 생성 및 KakaoSdk 초기화]
class GlobalApplication : Application() {
override fun onCreate() {
super.onCreate()
// 다른 초기화 코드들
// Kakao SDK 초기화
KakaoSdk.init(this, "{NATIVE_APP_KEY}")
}
}
<application
<!-- android:name 설정 -->
android:name=".GlobalApplication"
...
>
[나의 구현]
카카오로그인과 Koin도 함께 있어서 위 코드처럼 카카오링크에 필요한 부분만 추가해주면 됩니다.
package com.mtjin.nomoneytrip.di
import android.app.Application
import android.content.res.Resources
import com.kakao.auth.*
import com.kakao.sdk.common.KakaoSdk
import com.mtjin.nomoneytrip.BuildConfig
import com.mtjin.nomoneytrip.module.*
import org.koin.android.ext.koin.androidContext
import org.koin.android.ext.koin.androidLogger
import org.koin.core.context.startKoin
import org.koin.core.logger.Level
class KoinApplication : Application() {
override fun onCreate() {
super.onCreate()
instance = this
// Kakao Sdk 초기화
KakaoSDK.init(KakaoSDKAdapter())
//카카오링크
KakaoSdk.init(this, "발급받은 해시키")
startKoin {
if (BuildConfig.DEBUG) {
androidLogger()
} else {
androidLogger(Level.NONE)
}
androidContext(this@KoinApplication)
modules(
repositoryModule,
localDataModule,
remoteDataModule,
viewModelModule,
apiModule,
firebaseModule
)
}
}
override fun onTerminate() {
super.onTerminate()
instance = null
}
class KakaoSDKAdapter : KakaoAdapter() {
override fun getSessionConfig(): ISessionConfig {
return object : ISessionConfig {
override fun getAuthTypes(): Array<AuthType> {
return arrayOf(AuthType.KAKAO_LOGIN_ALL)
}
override fun isUsingWebviewTimer(): Boolean {
return false
}
override fun isSecureMode(): Boolean {
return false
}
override fun getApprovalType(): ApprovalType? {
return ApprovalType.INDIVIDUAL
}
override fun isSaveFormData(): Boolean {
return true
}
}
}
// Application이 가지고 있는 정보를 얻기 위한 인터페이스
override fun getApplicationConfig(): IApplicationConfig {
return IApplicationConfig { getGlobalApplicationContext() }
}
}
companion object {
private var instance: KoinApplication? = null
fun getGlobalApplicationContext(): KoinApplication? {
checkNotNull(instance) { "This Application does not inherit com.kakao.GlobalApplication" }
return instance
}
}
}
[구현 방법]
이제 카카오링크 구현방법에 대해 살펴보겠습니다.
저는 밑 공식문서를 참고하여 구현했으며 문서도 꼭 읽어보시길 추천드립니다. 매우 잘되어있습니다. ㅎㅎ
developers.kakao.com/docs/latest/ko/message/android-link
먼저 카카오링크 API는 다음과 같은 로직으로 구성으로 되어있습니다.
카카오링크 구현을 앞서 세팅말고도 카카오링크 관련 추가 세팅이 필요합니다.
1. 패키지 쿼리 및 상호작용 설정해야합니다.
Android SDK 2.4.0 이상을 사용할 경우, 해당 설정은 필요하지 않습니다.
Android 11에서는 카카오톡 앱을 통해 메시지를 보내기 위해 패키지 쿼리 및 상호작용 설정이 필요합니다.
앱이 Android 11을 타겟팅하는 경우, AndroidManifest.xml에 아래와 같이 queries 요소를 추가해야 합니다. 자세한 내용은 Android 11의 패키지 공개 상태를 참고합니다.
<manifest package="com.example.sample">
<!--queries에 카카오톡 패키지 추가-->
<queries>
<package android:name="com.kakao.talk" />
</queries>
...
</manifest>
2. 커스텀 스킴(Custom scheme) 설정하기
사용자가 카카오톡 메시지의 버튼을 통해 앱을 실행할 수 있도록 하려면 AndroidManifest.xml 파일에 앱 실행 스킴 설정을 해야 합니다.
[문서]
<activity android:name=".{YOUR_ACTIVITY_NAME}">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- "kakao{YOUR_NATIVE_APP_KEY}://kakaolink" 형식의 앱 실행 스킴을 설정하는데 사용 -->
<data android:host="kakaolink"
android:scheme="kakao{YOUR_NATIVE_APP_KEY}" />
</intent-filter>
</activity>
[나의 구현]
가장 먼저 시작하는 화면인 스플래쉬 액티비티에 추가했습니다.
<activity android:name=".views.splash.SplashActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<!-- "kakao{YOUR_NATIVE_APP_KEY}://kakaolink" 형식의 앱 실행 스킴을 설정하는데 사용 -->
<data
android:host="@string/kakao_link"
android:scheme="@string/kakao_scheme" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
@string/ 은 다음과 같이 발급받은 키를 등록해주면 됩니다. kakao_scheme는 카카오 애플리케이션 키에서 앞에 "kakao"만 덧붙여 주면 됩니다.
// values/strings.xml
<string name="kakao_app_key">541c8caff279뒤에보안상생략</string>
<string name="kakao_scheme">kakao541c8caff279뒤에보안상생략</string>
<string name="kakao_link">kakaolink.com</string>
추가로 카카오톡 메시지의 앱 실행 버튼에는 androidExecutionParams과 iosExecutionParams로 앱 실행 시 앱에 전달할 파라미터를 설정할 수 있습니다. 이 파라미터는 앱 실행 스킴에 다음과 같은 형식으로 추가됩니다.
kakao{YOUR_NATIVE_APP_KEY}://kakaolink${androidExecutionParams}
kakao{YOUR_NATIVE_APP_KEY}://kakaolink${iosExecutionParams}
3. 카카오링크 구현(메시지만들기 및 전송)
이제 설정은 끝났고 구현을 해야합니다.
카카오링크의 핵심 구현은 크게 메시지만들기 -> 메시지전송(공유)로 되어 있습니다.
순서대로 살펴보겠습니다. :)
3-1. 메시지만들기
카카오링크와 카카오톡 메시지 API는 카카오톡 메시지를 구성할 때 com.kakao.sdk.template에 정의된 클래스들을 공통적으로 사용합니다. 메시지 템플릿 > 기본 메시지 템플릿 구성 요소를 참고하여 원하는 메시지 템플릿에서 지원하는 객체들을 포함하여 메시지를 구성합니다.
카카오에서 Feed, List, Location, Commerece, Text 형과 같이 각각의 목적에 맞는 기본 메시지 템플릿들을 제공합니다. 이것들을 활용하면 아주 쉽게 메시지를 만들 수 있습니다. (각각의 메시지유형에 대한 설명은 메시지 템플릿 > 기본 메시지 템플릿 구성 요소 에서 자세히 보실 수 있습니다.)
저같은 경우는 Feed가 적절하겠다고 느껴 Feed 형으로 구현했습니다.
[공식문서 Feed 형 예시]
val defaultFeed = FeedTemplate(
content = Content(
title = "딸기 치즈 케익",
description = "#케익 #딸기 #삼평동 #카페 #분위기 #소개팅",
imageUrl = "http://mud-kage.kakao.co.kr/dn/Q2iNx/btqgeRgV54P/VLdBs9cvyn8BJXB3o7N8UK/kakaolink40_original.png",
link = Link(
webUrl = "https://developers.kakao.com",
mobileWebUrl = "https://developers.kakao.com"
)
),
social = Social(
likeCount = 286,
commentCount = 45,
sharedCount = 845
),
buttons = listOf(
Button(
"웹으로 보기",
Link(
webUrl = "https://developers.kakao.com",
mobileWebUrl = "https://developers.kakao.com"
)
),
Button(
"앱으로 보기",
Link(
androidExecParams = mapOf("key1" to "value1", "key2" to "value2"),
iosExecParams = mapOf("key1" to "value1", "key2" to "value2")
)
)
)
)
[나의 구현]
공유하기 버튼 클릭 시 실행되는 함수를 만들었습니다.
url은 모바일 url만 적용했으며 앱 다운로드로 가게끔 설정했습니다.
더 고차원적으로 개발하려면 노티피케이션 pendingIntent 처리하듯이 앱이 다운되어있는 상태면 앱이 켜지게 스키마를 설정하고 Link 객체의 androidExecParams 파라미터를 활용하여 해당 게시글 상세화면으로 가게하는게 좋을겁니다. (저는 실제 상용화된 앱도 아니여서 여기까지만 구현했습니다. ㅎㅎ )
그리고 위의 기본예시에서 필요없는 것들은 제거했습니다.
private fun sendKakaoLink(userReview: UserReview) {
// 메시지 템플릿 만들기 (피드형)
val defaultFeed = FeedTemplate(
content = Content(
title = userReview.product.title,
description = userReview.review.content,
imageUrl = userReview.review.image,
link = Link(
mobileWebUrl = "https://play.google.com/store/apps/details?id=com.mtjin.nomoneytrip"
)
), social = Social(
likeCount = userReview.review.recommendList.size
),
buttons = listOf(
Button(
"앱으로 보기",
Link(
androidExecParams = mapOf(
"key1" to "value1",
"key2" to "value2"
) // 내 앱에서 파라미터보낼건 필요없음 (앱 다운로드만 유도할것이다)
)
)
)
)
//메시지 보내기 (뒤에서 살펴볼것)
3-2. 기본 템플릿으로 메시지 보내기
다양한 메시지 보내기 종류 중 저는 기본 제공되는 피드를 사용했고 추가적인 커스텀한 기능이 필요 없어서 기본 템플릿으로 메시지 보내기를 선택하였습니다.
[공식문서 구현 예시]
코틀린만 사용시
// 피드 메시지 보내기
LinkClient.instance.defaultTemplate(context, defaultFeed) { linkResult, error ->
if (error != null) {
Log.e(TAG, "카카오링크 보내기 실패", error)
}
else if (linkResult != null) {
Log.d(TAG, "카카오링크 보내기 성공 ${linkResult.intent}")
startActivity(linkResult.intent)
// 카카오링크 보내기에 성공했지만 아래 경고 메시지가 존재할 경우 일부 컨텐츠가 정상 동작하지 않을 수 있습니다.
Log.w(TAG, "Warning Msg: ${linkResult.warningMsg}")
Log.w(TAG, "Argument Msg: ${linkResult.argumentMsg}")
}
}
Rx 사용시
var disposables = CompositeDisposable()
// 피드 메시지 보내기
LinkClient.rx.defaultTemplate(context, defaultFeed)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ linkResult ->
Log.d(TAG, "카카오링크 보내기 성공 ${linkResult.intent}")
startActivity(linkResult.intent)
// 카카오링크 보내기에 성공했지만 아래 경고 메시지가 존재할 경우 일부 컨텐츠가 정상 동작하지 않을 수 있습니다.
Log.w(TAG, "Warning Msg: ${linkResult.warningMsg}")
Log.w(TAG, "Argument Msg: ${linkResult.argumentMsg}")
}, { error ->
Log.e(TAG, "카카오링크 보내기 실패 ", error)
})
.addTo(disposables)
[나의 구현 - Rx사용, //피드메시지 보내기 주석 밑 코드]
private fun sendKakaoLink(userReview: UserReview) {
// 메시지 템플릿 만들기 (피드형)
val defaultFeed = FeedTemplate(
content = Content(
title = userReview.product.title,
description = userReview.review.content,
imageUrl = userReview.review.image,
link = Link(
mobileWebUrl = "https://play.google.com/store/apps/details?id=com.mtjin.nomoneytrip"
)
), social = Social(
likeCount = userReview.review.recommendList.size
),
buttons = listOf(
Button(
"앱으로 보기",
Link(
androidExecParams = mapOf(
"key1" to "value1",
"key2" to "value2"
) // 내 앱에서 파라미터보낼건 필요없음 (앱 다운로드만 유도할것이다)
)
)
)
)
// 피드 메시지 보내기
LinkClient.rx.defaultTemplate(thisContext, defaultFeed)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ linkResult ->
Log.d(TAG, "카카오링크 보내기 성공 ${linkResult.intent}")
startActivity(linkResult.intent)
// 카카오링크 보내기에 성공했지만 아래 경고 메시지가 존재할 경우 일부 컨텐츠가 정상 동작하지 않을 수 있습니다.
Log.w(TAG, "Warning Msg: ${linkResult.warningMsg}")
Log.w(TAG, "Argument Msg: ${linkResult.argumentMsg}")
}, { error ->
Log.e(TAG, "카카오링크 보내기 실패 ", error)
})
.addTo(compositeDisposable)
}
[구현한 전체 코드]
참고로 compositDisaposable 은 BaseFragment에 선언해놨습니다.
package com.mtjin.nomoneytrip.views.community
import android.graphics.Color
import android.util.Log
import android.view.View
import android.widget.AdapterView
import android.widget.TextView
import androidx.lifecycle.Observer
import androidx.navigation.fragment.findNavController
import com.kakao.sdk.link.LinkClient
import com.kakao.sdk.link.rx
import com.kakao.sdk.template.model.*
import com.mtjin.nomoneytrip.R
import com.mtjin.nomoneytrip.base.BaseFragment
import com.mtjin.nomoneytrip.data.community.UserReview
import com.mtjin.nomoneytrip.databinding.FragmentCommunityBinding
import com.mtjin.nomoneytrip.utils.TAG
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.rxkotlin.addTo
import io.reactivex.schedulers.Schedulers
import org.koin.androidx.viewmodel.ext.android.viewModel
class CommunityFragment : BaseFragment<FragmentCommunityBinding>(R.layout.fragment_community) {
private val viewModel: CommunityViewModel by viewModel()
override fun init() {
binding.vm = viewModel
initViewModelCallback()
initAdapter()
initView()
}
private fun initView() {
binding.spCities.setBackgroundColor(Color.TRANSPARENT)
binding.spCities.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(
parent: AdapterView<*>,
view: View?,
position: Int,
id: Long
) {
view?.let {
viewModel.requestReviews((parent.getChildAt(0) as TextView).text.toString())
}
}
override fun onNothingSelected(parent: AdapterView<*>) {}
}
}
private fun initAdapter() {
binding.rvReviews.adapter = CommunityAdapter(context = thisContext, recommendClick = {
viewModel.updateReviewRecommend(it)
}, productClick = {
findNavController().navigate(
CommunityFragmentDirections.actionBottomNav2ToLodgmentDetailFragment(
it.product
)
)
}, shareClick = {
sendKakaoLink(it)
})
}
private fun initViewModelCallback() {
with(viewModel) {
goTourHistory.observe(this@CommunityFragment, Observer {
findNavController().navigate(
CommunityFragmentDirections.actionBottomNav2ToTourHistoryFragment(it.toTypedArray())
)
})
goTourNoHistory.observe(this@CommunityFragment, Observer {
findNavController().navigate(CommunityFragmentDirections.actionBottomNav2ToTourNoHistoryFragment())
})
}
}
private fun sendKakaoLink(userReview: UserReview) {
// 메시지 템플릿 만들기 (피드형)
val defaultFeed = FeedTemplate(
content = Content(
title = userReview.product.title,
description = userReview.review.content,
imageUrl = userReview.review.image,
link = Link(
mobileWebUrl = "https://play.google.com/store/apps/details?id=com.mtjin.nomoneytrip"
)
), social = Social(
likeCount = userReview.review.recommendList.size
),
buttons = listOf(
Button(
"앱으로 보기",
Link(
androidExecParams = mapOf(
"key1" to "value1",
"key2" to "value2"
) // 내 앱에서 파라미터보낼건 필요없음 (앱 다운로드만 유도할것이다)
)
)
)
)
// 피드 메시지 보내기
LinkClient.rx.defaultTemplate(thisContext, defaultFeed)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ linkResult ->
Log.d(TAG, "카카오링크 보내기 성공 ${linkResult.intent}")
startActivity(linkResult.intent)
// 카카오링크 보내기에 성공했지만 아래 경고 메시지가 존재할 경우 일부 컨텐츠가 정상 동작하지 않을 수 있습니다.
Log.w(TAG, "Warning Msg: ${linkResult.warningMsg}")
Log.w(TAG, "Argument Msg: ${linkResult.argumentMsg}")
}, { error ->
Log.e(TAG, "카카오링크 보내기 실패 ", error)
})
.addTo(compositeDisposable)
}
}
[구현 결과]
이상 카카오링크 구현방법에 대해 알아봤습니다.
댓글과 공감은 큰 힘이 됩니다. 감사합니다. !!