💌 [Android/Kotlin] mailto: url 메일보내기 설정하기

안드로이드 WebView 에서 mailto: 스케마 링크가 url로 인식해서 안먹히는 상황이 생겼다.

net:: ERR_UNKNOWN_URL_SCHEME

💙 해결방법

WebViewClient 클래스의 shouldOverrideUrlLoading 메소드를 오버라이드하여
mailto: 스케마의 링크를 클릭했을 때 Intent.ACTION_SENDTO 를 이용하여 이메일 액티비티를 호출하도록 해준다.

inner class WebViewClientClass : WebViewClient() {

	// 페이지 이동
	override fun shouldOverrideUrlLoading(
		view: WebView,
        url: String
    ): Boolean {
		if (url.startsWith("mailto:")) { // mailto 스케마 링크가 url로 인식해서 안먹히는 상황 분기
			try {
				val emailIntent = Intent(Intent.ACTION_SENDTO,Uri.parse(url)) // 메일 전송 설정

                // 이메일 클라이언트가 설치 되어있는지 확인
                val packageManager = view.context.packageManager
                val activities = packageManager.queryIntentActivities(emailIntent, 0)
                if (activities.isNotEmpty()) {
                	// 설치되어 있다면 인텐트 실행
                    view.context.startActivity(emailIntent)
                } else {
                    // 설치되어 있지 않다면 사용자에게 알림 표시 등의 방법으로 안내
                    Toast.makeText(mContext,"이메일 클라이언트를 설치해야 합니다.",Toast.LENGTH_SHORT).show()
                }
			} catch (e: Exception) {
                    e.printStackTrace()
            }
		} else {
			view.loadUrl(url)
		}
		return true
	}

🚨 android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.SENDTO } 오류

✅ 태블릿이나 해외폰일 경우 전화나 메일 기능을 사용할 수 없을 때 이런 Exception 이 뜬다.
이 오류를 해결하기 위해 이메일 클라이언트가 설치되어 있는지 확인하고, 설치되어 있다면 인텐트를 실행하는 로직을 구현해준다.

💎 'queryIntentActivities(Intent, Int): (Mutable)List<ResolveInfo!>' is deprecated. Deprecated in Java

  • queryIntentActivities 함수가 deprecated 되어서 Android 11부터는 패키지 매니저의 resolveActivity 를 사용하여 인텐트를 처리할 수 있는 액티비티가 있는지 확인.
val intent = Intent(Intent.ACTION_SENDTO,Uri.parse(url))
	// 처리 가능한 앱이 있는지 확인
	if (intent.resolveActivity(packageManager) != null) {
		startActivity(intent)
	} else {
		Utils.Toast(mContext,"이메일 클라이언트 앱을 설치해야 합니다.")
	}

💎 Consider adding a declaration to your manifest when calling this method; see https://g.co/dev/packagevisibility for details

  • 안드로이드 11 이상에서는 앱 간의 패키지 가시성 변경으로 인해 일부 앱이 다른 앱의 컴포넌트를 사용하는 데 제한을 받게됨.
  • 인텐트로 외부 앱을 호출하려면 요소를 AndroidManifest.xml 파일에 추가하여 앱 간의 패키지 가시성을 설정해야 함.

AndroidManifest.xml

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

    <!-- 다른 manifest 선언들 -->

    <!-- <queries> 요소를 추가하여 이메일 클라이언트 앱의 패키지 이름을 지정 -->
    <queries>
        <!-- 이메일 클라이언트 앱 -->
        <package android:name="com.google.android.gm" />
        <!-- 추가적인 이메일 클라이언트 앱들 -->
    </queries>

    <application>
        <!-- 액티비티, 서비스 등의 구성 요소들 -->

    </application>
</manifest>
  • < queries > 요소 내에 사용할 이메일 클라이언트 앱의 패키지 이름을 추가해준다.
  • 여기에 추가된 패키지 이름은 요소를 통해 해당 앱의 컴포넌트에 접근할 수 있는 권한을 부여한다.

참고 :
https://developer.android.com/guide/components/intents-common?hl=ko#Email
https://stackoverflow.com/questions/72289500/passing-new-intentintent-action-sendto-setdatauri-parsemailto-to-inten

profile
Android Developer..+ iOS 슬쩍 🌱 ✏️끄적끄적,,개인 기록용 👩🏻‍💻

0개의 댓글