반응형

PDF Viewer 예제

  • assets/ 내에 파일을 넣어두고 오픈
    • file provider를 이용해 assets내의 파일을 앱 내로 가져온 뒤에 오픈
    • 앱 내의 위치는 files-path를 이용(Context.getFilesDir())
  • 웹에 있는 pdf 오픈

 

res/values/strings.xml

<string name="file_provider_authority" translatable="false">myfileprovider</string>

res/xml/file_provider_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <!-- Context.getFilesDir() -->
    <files-path name="internal_files" path="."/>
</paths>

AndroidManifest.xml

<application
    ...>

    <provider
        android:name="androidx.core.content.FileProvider"
        android:authorities="@string/file_provider_authority"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_provider_paths" />
    </provider>
    
</application>

src/main/assets/ 내에 pdf파일 복사

pdf_sample1.pdf
pdf_sample2.pdf
pdf_sample3.pdf

openPdf() 메서드

void openPdf(String fileName) {
    copyFileFromAssets(fileName);

    /** PDF reader code */
    File file = new File(getFilesDir() + "/" + fileName);

    Uri uri = null;
    if(!fileName.startsWith("http")) {
        uri = FileProvider.getUriForFile(this, getString(R.string.file_provider_authority), file);
    } else {
        uri = Uri.parse(fileName);
    }
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setDataAndType(uri, "application/pdf");
    intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    try {
        startActivity(intent);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

private void copyFileFromAssets(String fileName) {
    AssetManager assetManager = this.getAssets();

    //앱 내의 파일폴더에 저장
    File cacheFile = new File( getFilesDir() + "/" + fileName );
    InputStream in = null;
    OutputStream out = null;
    try {
        if ( cacheFile.exists() ) {
            return;
        } else {
            in = assetManager.open(fileName);
            out = new FileOutputStream(cacheFile);
            copyFile(in, out);

            in.close();
            in = null;
            out.flush();
            out.close();
            out = null;
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

private void copyFile(InputStream in, OutputStream out) throws IOException {
    byte[] buffer = new byte[1024];
    int read;
    while ((read = in.read(buffer)) != -1) {
        out.write(buffer, 0, read);
    }
}

사용1) assets pdf 열기

openPdf("pdf_sample1.pdf");
openPdf("pdf_sample2.pdf");
openPdf("pdf_sample3.pdf");

사용2) 웹 pdf 열기

openPdf("https://www.abc.co.kr/pdf_sample4.pdf");
openPdf("https://www.abc.co.kr/pdf_sample5.pdf");

앱 내의 저장공간이 아닌 외부 영역에 저장하기

app build.gradle 권한 추가, 속성 변경

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

<!-- SDK29부터 외부영역은 사용불가능 : 아래 추가해줘야 가능해짐 -->
<application
  //...
  android:requestLegacyExternalStorage="true">

file_provider_path.xml 외부 영역 추가

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <files-path name="internal_files" path="."/>
    <external-path name="external_files" path="." /><!--추가-->
</paths>

 

(참고) file provider path

<files-path/> –> Context.getFilesDir()
<cache-path/> –> Context.getCacheDir()
<external-path/> –> Environment.getExternalStorageDirectory()
<external-files-path/> –> Context.getExternalFilesDir(String)
<external-cache-path/> –> Context.getExternalCacheDir()
<external-media-path/> –> Context.getExternalMediaDirs()

 

프로젝트 소스 다운↓

PdfViewer.zip
2.34MB

반응형
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기