はじめに
URLからpdfなどのファイルをダウンロードして、ダウンロード完了後に表示する方法について記載。
以下の2つの方法を紹介。
- コルーチンを使用した方法
- DownloadManagerを使用した方法
コルーチンを使用した方法
事前にFileProviderを使うように設定する必要あり。
まず、コルーチンを使用するための設定。
build.gradle
dependencies {
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.1'
}
そして、ダウンロード用のメソッドを作成。
fun download() {
try {
// linkにファイルが置かれたURLを指定
val link = "https://example.com/example.pdf"
//getExternalStoragePublicDirectoryはAndroid Qで非推奨になっているため、適宜変更。
val dir = Environment.getExternalStoragePublicDirectory(DIRECTORY_DOWNLOADS).absolutePath
val path = dir + link.substring(link.lastIndexOf("/"))
//ここでファイルをサーバからダウンロード
URL(link).openStream().copyTo(FileOutputStream(File(path)))
//intentによりファイルを開く
val intent = Intent(Intent.ACTION_VIEW)
val uri = FileProvider.getUriForFile(this@MainActivity, BuildConfig.APPLICATION_ID + ".provider", File(path))
intent.setDataAndType(uri, contentResolver.getType(uri))
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
startActivity(intent)
} catch (e: Exception) {
Log.e(localClassName, "Cancel", e)
}
}
次に、ダウンロードしたいタイミングで以下を記述。
CoroutineScope(Dispatchers.Default).launch {
download()
}
DownloadManagerを使用した方法
先ほどと同様、まずはダウンロード用のメソッドを作成。
fun download() {
try {
// linkにファイルが置かれたURLを指定
val link = "https://example.com/example.pdf"
val fileName = link.substring(link.lastIndexOf("/") + 1)
//DownloadManagerを使用してファイルをダウンロード
val manager = getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
val request = DownloadManager.Request(Uri.parse(link))
request.setTitle(fileName)
request.setDescription("Downloading")
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
request.setDestinationInExternalPublicDir(DIRECTORY_DOWNLOADS, fileName)
val downloadId = manager.enqueue(request)
val receiver = object : BroadcastReceiver() {
//ダウンロード完了後の処理
override fun onReceive(context: Context, intent: Intent) {
val id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1)
if (id == downloadId) {
//intentによりファイルを開く
val openFileIntent = Intent(Intent.ACTION_VIEW)
val uri = manager.getUriForDownloadedFile(id)
openFileIntent.setDataAndType(uri, contentResolver.getType(uri))
openFileIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
startActivity(openFileIntent)
}
}
}
registerReceiver(receiver, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE))
} catch (e: Exception) {
Log.e(localClassName, "Cancel", e)
}
}
次に、ダウンロードしたいタイミングで以下を記述。こちらはコルーチンで囲わない。
download()