🖼️
【Android】URL から画像をダウンロードする
URL から画像をダウンロードする機能を実装する機会があったので、試した方法について書いてみたいと思います。
Picasso
build.gradle
implementation 'com.squareup.picasso:picasso:2.71828'
実装
fun downloadImage(url: URL): Bitmap {
return Picasso.get()
.load(url.toString())
.get()
}
Glide
build.gradle
def glideVersion = '4.15.0'
implementation "com.github.bumptech.glide:glide:$glideVersion"
annotationProcessor "com.github.bumptech.glide:compiler:$glideVersion"
実装
fun downloadImage(url: URL): Bitmap {
return Glide.with(context)
.asBitmap()
.load(url.toString())
.submit()
.get()
}
openConnection
実装
fun downloadImage(url: URL): Bitmap {
return url.openConnection().getInputStream().use { stream ->
BitmapFactory.decodeStream(stream)
}
}
実装例 : 画像をダウンロードして Picutures フォルダに保存する
ImageDownload.kt
class ImageDownload {
fun download(
resolver: ContentResolver,
url: URL,
directory: String
): Boolean {
// 画像を保存するURIを取得
val values = ContentValues().apply {
put(MediaStore.Images.Media.DISPLAY_NAME, getFileName(url))
put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg")
put(
MediaStore.Images.Media.DATE_MODIFIED,
Instant.ofEpochMilli(Date().time).epochSecond
)
}
val contentUri = getContentUri(resolver, values, url, directory) ?: return false
// 画像をダウンロード
val bitmap = url.openConnection().getInputStream().use { stream ->
BitmapFactory.decodeStream(stream)
}
// 画像を書き込む
val isSuccess = resolver.openOutputStream(contentUri, "w").use { stream ->
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream)
}
// Android10 以上の場合は、排他制御を解除する
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
values.put(MediaStore.Images.Media.IS_PENDING, Pending.DISABLED.value)
resolver.update(contentUri, values, null, null)
}
return isSuccess
}
private fun getContentUri(
resolver: ContentResolver,
values: ContentValues,
url: URL,
directory: String
) = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
getUriApiVersionQ(resolver, values, directory)
} else {
getUri(resolver, url, values, directory)
}
private fun getUri(
resolver: ContentResolver,
url: URL,
values: ContentValues,
directory: String
): Uri? {
val file = File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
directory
)
if (!file.exists()) {
file.mkdir()
}
values.put(
MediaStore.Images.Media.DATA,
File(file, getFileName(url)).absolutePath
)
return resolver.insert(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
values
)
}
@RequiresApi(Build.VERSION_CODES.Q)
private fun getUriApiVersionQ(
resolver: ContentResolver,
values: ContentValues,
directory: String
): Uri? {
values.apply {
put(
MediaStore.Images.Media.RELATIVE_PATH,
File(Environment.DIRECTORY_PICTURES, directory).path
)
put(MediaStore.Images.Media.IS_PENDING, Pending.ENABLED.value)
}
return resolver.insert(
MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY),
values
)
}
private fun getFileName(url: URL): String {
val index = url.file.lastIndexOf("/")
return url.file.substring(index + 1)
}
private enum class Pending(val value: Int) {
ENABLED(1),
DISABLED(0)
}
}
Discussion