MMS 및 URI 처리

semin8990·2024년 4월 4일

안드로이드

목록 보기
4/10

웹 이미지 주소를 가지고 MMS 를 보내는 경우가 있었음.
해당 사항 구현 도중 문제 사항들이 많아서 한번 정리함

  1. 인터넷 url 을 URL로 바꿈
  2. URL 로 바꾼 것을 bitmap 으로 생성
  3. bitmap을 캐시에 저장한뒤 uri 를 생성 (content:// 형태)

Android 7.0 (API 레벨 24)부터 애플리케이션 간에 file:// URI를 통한 파일 접근이 금지되어, 이를 대체하기 위해 FileProvider 를 사용 해야함

우선 Manifest 의 설정을 추가 해야함

<provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="${applicationId}.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>

파일의 저장을 위해 프로바이더 추가 (경로설정을 위해)

xml 폴더에 file_paths.xml 를 추가함

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <files-path name="files" path="." />
    <external-files-path name="external_files" path="." />
    <external-path name="external_files" path="." />
    <cache-path name="cached_files" path="." />
    <external-cache-path name="cached_files" path="." />
    <root-path name="root" path="." />
</paths>

path 를 지정 해줘도 되지만 현재 디렉토리로 설정 해줌

bitmap 에서 Uri 추출 하는 내용

private suspend fun getImageUri(bitmap: Bitmap): Uri = withContext(Dispatchers.IO) {
        val storage = context.requireContext().externalCacheDir
        val timeStamp = System.currentTimeMillis().toString()
        val fileName = "cache_"+timeStamp+".png"
        val tempFile = File(storage ,fileName )
        try {
            tempFile.createNewFile()
            val outputStream = FileOutputStream(tempFile)
            bitmap.compress(Bitmap.CompressFormat.PNG , 100 , outputStream)
            outputStream.close()
        }catch (e : Exception){
            throw e
        }
        return@withContext  FileProvider.getUriForFile(context.requireContext() , "lgt.call.fileprovider" ,tempFile)
    }

변환 내용은 위와 같음

어떻게 사용 하였는지 전문을 보자면

suspend fun sendMMS(
        isDualNumber: Boolean,
        message: String,
        phoneNumber: String,
        url: List<String>,
        callback: suspend () -> Unit
    ) {
        val resultCode = setRunCatching {
            block = callback
            val arrays = ArrayList<Uri>()
            url.forEach { uri ->
                val bitmap = getBitmap(URL(uri))
                val bitmapUri = bitmap?.let {
                    if (isHigherThanAndroid7NamelySdk24()) {
                        getImageUri(it)
                    } else {
                        getImageUriM(it)
                    }
                }
                if (bitmapUri != null) {
                    arrays.add(bitmapUri)
                }
            }
            val replaceNumber = phoneNumber.replace('#', ' ', false)
            val number = if (isDualNumber) "$replaceNumber#" else replaceNumber
            val intent = Intent(Intent.ACTION_SEND_MULTIPLE)
            intent.putExtra(Intent.EXTRA_TEXT, message)
            intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, arrays)
            intent.type = "image/png"
            intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
            if (phoneNumber.isBlank().not()) {
                intent.putExtra("address", number)
            }
            startActivityResult.launch(intent)
        }
    }

( setRunCatching 그냥 try-catch 문을 조금 쓰기 편하게 커스텀 한것 )




내용에 문제가 있거나 다른 의견이 있으시다면 댓글 부탁드립니다.

profile
안드로이드 개발자

0개의 댓글