안드로이드 개발 팁 #92 - assets 폴더의 PDF 파일을 외부 앱으로 열기

assets 폴더의 PDF 파일을 외부 앱으로 열기

No. 92
2025. 01. 31 (금) | Written by @dorian-mobileapp

개요

  • PDF 파일을 assets 폴더로부터 외부 저장소에 복사
  • PDF 파일 URI 생성 코드 작성
  • Intent 활용하여 PDF 파일 여는 코드 작성
  • PDF 파일을 외부 앱으로 여는 함수 작성
  • 액티비티 또는 컴포저블 함수에서 PDF 파일 열기

PDF 파일을 assets 폴더로부터 외부 저장소에 복사

  • asset 폴더의 파일을 앱의 cache 폴더로 복사
fun Context.copyFileToCacheDir(fileName: String) {
    val file = File(this.cacheDir, fileName)
    this.assets.open(fileName).use { inputStream ->
        FileOutputStream(file).use { outputStream ->
            inputStream.copyTo(outputStream)
        }
    }
}
  • PDF 파일이 cache 폴더에 복사되었는지 확인하는 확장 함수도 추가
fun Context.isFileCopiedToCacheDir(fileName: String): Boolean {
    val file = File(this.cacheDir, fileName)
    return file.exists()
}

PDF 파일 URI 생성 코드 작성

  • AndroidManifest.xml 파일의 application 요소 안에 provider 요소 추가
<provider
    android:name="androidx.core.content.FileProvider"
    android:authorities="${applicationId}.provider"
    android:exported="false"
    android:grantUriPermissions="true">
    <meta-data
        android:name="android.support.FILE_PROVIDER_PATHS"
        android:resource="@xml/file_paths" />
</provider>
  • {모듈}/src/main/res/xml/file_paths.xml 파일 추가
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <cache-path name="cache" path="." />
</paths>
  • PDF 파일 URI 생성 코드 작성
val fileUri: Uri = FileProvider.getUriForFile(
    context,
    "${context.packageName}.provider", // FileProvider authority
    File(context.cacheDir, pdfFileName)
)

Intent 활용하여 PDF 파일 여는 코드 작성

  • 필수 플래그
    • FLAG_GRANT_READ_URI_PERMISSION:
context.startActivity(Intent(Intent.ACTION_VIEW).apply {
    data = fileUri    // 위에서 정의한 fileUri
    flags = Intent.FLAG_GRANT_READ_URI_PERMISSION    // 필수
})

PDF 파일을 외부 앱으로 여는 함수 작성

  • openExternalAppToShowPDF()
    • 작성 위치: 뷰모델 클래스
    • 역할
      • 외부 앱으로 PDF 파일 열기 실행
      • 외부 앱 부재시 실패하여 false 리턴
    • 리턴 값
      • true: 파일 열기 성공
      • false: PDF 열 외부 앱 부재로 인해 파일 열기 실패 (ActivityNotFoundException)
fun openExternalAppToShowPDF(
    context: Context,
    pdfFileName: String
): Boolean {
    return try {
        if (!context.isFileCopiedToCacheDir(pdfFileName)) {
            context.copyFileToCacheDir(pdfFileName)
        }

        val fileUri: Uri = FileProvider.getUriForFile(
            context,
            "${context.packageName}.provider", // FileProvider authority
            File(context.cacheDir, pdfFileName)
        )
        context.startActivity(Intent(Intent.ACTION_VIEW).apply {
            data = fileUri
            flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
        })
        true
    }
    catch (e: ActivityNotFoundException) {
        e.printStackTrace()
        false
    }
}

액티비티 또는 컴포저블 함수에서 PDF 파일 열기

  • 위에서 작성한 openExternalAppToShowPDF 함수 호출
  • 이 함수가 false 리턴하면, 내부에서 PDF 실행 고려해볼 수 있음
val isPDFOpened = viewModel.openExternalAppToShowPDF(
    LocalContext.current,
    pdfFileName = pdfFileName
)

if (!isPDFOpened) {
    // 외부 앱 부재시 내부에서 PDF 파일 여는 코드 작성 (추후 포스팅 예정)
}

지난 안드로이드 개발 팁


Layout provided by Steemit Enhancer hommage by ayogom


Posted through the ECblog app (https://blog.etain.club)
Sort:  

안녕하세요.
SteemitKorea팀에서 제공하는 'steemit-enhancer'를 사용해 주셔서 감사합니다. 개선 사항이 있으면 언제나 저에게 연락을 주시면 되고, 관심이 있으신 분들은 https://cafe.naver.com/steemitkorea/425 에서 받아보실 수 있습니다. 사용시 @응원해 가 포함이 되며, 악용시에는 모든 서비스에서 제외될 수 있음을 알려드립니다.

[광고] STEEM 개발자 커뮤니티에 참여 하시면, 다양한 혜택을 받을 수 있습니다.


안녕하세요.
이 글은 SteemitKorea팀(@ayogom)님께서 저자이신 @dorian-mobileapp님을 응원하는 글입니다.
소정의 보팅을 해드렸습니다 ^^ 항상 좋은글 부탁드립니다
SteemitKorea팀에서는 보다 즐거운 steemit 생활을 위해 노력하고 있습니다.
이 글은 다음날 다시 한번 포스팅을 통해 소개 될 예정입니다. 감사합니다!

Upvoted! Thank you for supporting witness @jswit.

Coin Marketplace

STEEM 0.19
TRX 0.24
JST 0.037
BTC 100661.54
ETH 3118.61
SBD 4.05