Closed5
Android標準のビューアでPDFを開きたい
まずAndroid標準のビューアでPDFを開く記事(どのアプリで開くか選択させる)
後でやってみる
val target = Intent(Intent.ACTION_VIEW)
target.apply {
setDataAndType(Uri.fromFile(pdfFile),"application/pdf")
setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)
}
val intent = Intent.createChooser(target, "Open File")
try {
startActivity(intent);
} catch (e) {
// Instruct the user to install a PDF reader here, or something
}
なんか上手くいかないので、画像として表示してみる。
val parcelFileDescriptor = ParcelFileDescriptor.open(pdfFile, ParcelFileDescriptor.MODE_READ_ONLY)
val pdfRenderer = PdfRenderer(parcelFileDescriptor)
// とりあえず1ページ目だけ
val page = pdfRenderer.openPage(0)
val bitmap = Bitmap.createBitmap(page.width, page.height, Bitmap.Config.ARGB_8888)
page.render(bitmap, Rect(0, 0, page.width, page.height), null, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY)
val imageFos = FileOutputStream(imagePath)
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, imageFos)
imageFos.flush()
imageFos.close()
page.close()
pdfRenderer.close()
val imageFile = File(imagePath)
val target = Intent(Intent.ACTION_VIEW)
target.apply {
setDataAndType(Uri.fromFile(imageFile),"image/jpg")
setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)
}
val intent = Intent.createChooser(target, "Open File")
try {
startActivity(intent);
} catch (e) {
}
これをすると、トーストで「ファイル形式は現在サポートされていません」と表示される。普通に撮影した画像は表示されるのでサポートされてないはずはない。
Device File Explorerで確認すると画像自体は書き出せている。
Uri.fromFile
でうまくファイルが読めていないのでは?と思い調べてみると、FileProviderを利用したFile Uriの取得方法があった。(今更)
今回はcacheDirに画像を保存していたので、cache-path
要素を持ったpaths.xml
を追加
app/res/xml/paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<cache-path
name="files"
path="." />
</paths>
AndroidManifest.xmlにもproviderの記載を追加
app/src/main/AndroidManifest.xml
<application
...
<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/paths" />
</provider>
</application>
FileProviderクラスを使った実装に修正
val uri =
FileProvider.getUriForFile(requireContext(), "${BuildConfig.APPLICATION_ID}.fileprovider", imageFile)
これをすると、一瞬何か別アプリが立ち上がるがすぐに閉じる、みたいな挙動になった
下記の記事を参考に、元のコードから
- Intent.flagsを
Intent.FLAG_GRANT_READ_URI_PERMISSION
に変更 - createChooserをやめる
とPDFファイルのままで標準のビューアが立ち上がった。
最終的なコード
val target = Intent(Intent.ACTION_VIEW)
val uri =
FileProvider.getUriForFile(requireContext(), "${BuildConfig.APPLICATION_ID}.fileprovider", pdfFile)
val mime = requireContext().contentResolver.getType(uri)
target.setDataAndType(uri, mime)
target.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
startActivity(target)
このスクラップは2022/02/20にクローズされました