Android kotlin을 통해 Gmail API에 연결하여 수신함의 메시지를 가져오는 방법

1 하고 싶은 일


안드로이드 앱으로 Gmail 수신함에서 메시지를 얻고 싶습니다.

2 과거의 보도와 실시 방침(건너뛰어도 된다)


과거 기사는 OAuth2였다.0 인증을 사용할 때 client id와 client secret을 사용하는 방법이 많습니다참고 자료(Qita, @hsn).안드로이드 프로그램은 클라이언트 id로만 실행된다고 해서 사용하고 싶습니다. (실제로는 클라이언트 id를 입력할 곳조차 없습니다.)
따라서 Android 애플리케이션에서 Google 스프레드시트를 사용하는 기사 [참고문(침실계산,karintomania)]를 참조하여 인증 코드를 작성하여 Gmail API에 적용합니다.이 글은 현재 추천하지 않는 startActivityForesult를 사용하고 있기 때문에 이 부분을 [참조 기사(Compose 및 기타 라이브러리, Android)] 참고하여 추천 형식으로 다시 씁니다.

3 사전 준비(Google Cloud Plaatform으로 진행)


Google Developer Constore 검색을 사용해도 GCP로 날아갈 수 있다고 생각합니다.
따라서 API 및 서비스 를 선택하고 인증 정보 를 선택합니다.페이지의 인증 정보 작성에서 OAuth 클라이언트 ID를 선택합니다.지시에 따라 빈칸을 채우다.여기서 응용 프로그램 종류는 안드로이드를 선택해야 합니다.
또 OAuth의 동의 화면도 설정했다.Scope는 Gmail을 통해 목적에 맞는 Scope를 설정합니다.

4 이동 코드


아래로 이동하는 코드는 다음과 같다.
실장 아키텍처는'제팩 컴포지션의 안드로이드 MVM 아키텍처 입문'(오택준 수저)을 참고했다.
먼저 인증 뷰에 대해 설명합니다.
AuthGmailView.kt
@Composable
fun AuthGmailView(mainViewModel: MainViewModel,context: Context, activity: Activity) {
   val uiState: MainViewModel.UiState by mainViewModel.uiState

   lateinit var mGoogleSignInClient: GoogleSignInClient
   lateinit var credential: GoogleAccountCredential
   val scopeGmail: String = "目的に合わせたscopeを入れてください。"

   val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN).requestScopes(
       Scope(scopeGmail)
   ).requestEmail().build()
   mGoogleSignInClient = GoogleSignIn.getClient(activity, gso)
   credential = GoogleAccountCredential.usingOAuth2(activity, Collections.singleton(scopeGmail))

   val signInIntent: Intent = mGoogleSignInClient.signInIntent
   val test = rememberLauncherForActivityResult(contract = ActivityResultContracts.StartActivityForResult(), onResult = {

       if (it.resultCode == Activity.RESULT_OK) {
           val task = GoogleSignIn.getSignedInAccountFromIntent(it.data)
           try {
               val account = task.getResult(ApiException::class.java)
               Log.i("Sign in", "Name : " + account?.displayName.toString())  //Debug用
               Log.i("Sign in", "Email : " + account?.email)  //Debug用
               mainViewModel.initialLoad(context = context)  //Gmailの中身を探すModelを呼んでいます。
           } catch (e: ApiException) {
               Log.w("Sign in fail", "signInResult: failed code = " + e.statusCode)
               mainViewModel.resultAuth()  //失敗したと表示
           }
       } else {
           mainViewModel.resultAuth()  //失敗したと表示
       }
   })
   SideEffect {
       test.launch(signInIntent)   //サインインの画面を出す。
   }
}

그리고 나는 메시지를 부르는 곳에 있었다.여기에 가벼운 애완동물이 표시되어 있다.
   val scopeGmail: String = "目的に合わせたscopeを入れてください。"

   override suspend fun getInboxEmails(context: Context): MessagesGmail {
       val account = GoogleSignIn.getLastSignedInAccount(context)
       val credential: GoogleAccountCredential =
           GoogleAccountCredential.usingOAuth2(context, Collections.singleton(scopeGmail))
       credential?.setSelectedAccount(account?.account) 

   withContext(Dispatchers.Default) {
           val mailService = Gmail.Builder(
               AndroidHttp.newCompatibleTransport(),
               JacksonFactory.getDefaultInstance(), credential
           ).setApplicationName("Test")
               .build()
           val messages = mailService.users().messages().list("me").execute()
           Log.i("size of messages", messages.messages.size.toString())  //Debug用に何個Messageあるかを表示
           var listMessage: MutableList<Message> = mutableListOf()
           var a = 0;
           for (message in messages.messages) {
               val mdata = mailService.users().messages().get("me", message.id).execute()
               listMessage.add(a++, mdata)
           }
           Log.d("Mutable list", listMessage[0].snippet)
           val messagesGmail = MessagesGmail(messsages = listMessage)
           return@withContext messagesGmail
       }
여기
for (message in messages.messages) {
   val mdata = mailService.users().messages().get("me", message.id).execute()
   listMessage.add(a++, mdata)
}
이걸 하지 않으면 메시지를 읽을 수 없으니 주의하세요.
그리고 Gmail API 참조를 바탕으로listMessage에서 원하는 정보를 얻으면 된다.


로그아웃하고 싶을 때 아래 함수를 적당히 만들어서 부르세요.
fun logout() {
       val scopeGmail: String = "目的に合わせたscopeを入れてください。"

       lateinit var mGoogleSignInClient: GoogleSignInClient
       val gso = GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN).requestScopes(
           Scope(scopeGmail)
       ).requestEmail().build()
       mGoogleSignInClient = GoogleSignIn.getClient(this, gso)
       mGoogleSignInClient.signOut()
   }

최후


저는 안드로이드 앱을 개발한 초보자이기 때문에 나쁜 코드의 작성법이나 문제가 있으면 댓글로 남겨주세요.질문에 대답할 수 있는 범위 내에서 당신에게 돌려드리니 반드시 메시지를 남겨 주십시오.
댓글에 쓸 수 없는 질문과 질문이 있다면,akira.kashihara[at]hotmail.메일로 com으로 보내주세요.

참고 문장


여기서 좋은 소식 꼭 봐주세요.

  • Gmail API용 Sample Code(Python) <-Tread에 관한 Sample Code이므로 주의하세요!
  • Gmail API 참조
  • 다음 문장은 조사 시 제시된 문장이다
  • How to handle Activity.onActivityResult() with Jetpack Compose?(stackoverflow)
  • rememberLauncherForActivityResult throws Launcher has not been initialized in Jetpack Compose(stackoverflow)
  • 활동 결과 가져오기(Android)
  • Compose 및 기타 라이브러리(Android)
  • Google/Facebook Sign In in MVVM(stackoverflow)
  • 좋은 웹페이지 즐겨찾기