やりたいこと
Android用の画像読み込みライブラリ Coil を使うと、下記の1行だけで任意のURLの画像をダウンロードして ImageView
に表示することができます。
imageView.load(imageUrl)
Twitterクライアントのようなアプリでツイートの添付画像を表示する場合は上記のコードで十分ですが、DM(メッセージ)の添付画像の場合は認証が必要となるので 401 が返ってきてしまいます。
coil.network.HttpException: HTTP 401:
at coil.fetch.HttpUrlFetcher.fetch(HttpUrlFetcher.kt:57)
at coil.fetch.HttpUrlFetcher$fetch$1.invokeSuspend(Unknown Source:16)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:56)
at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:561)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:727)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:667)
at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:655)
ちなみに上記のエラーは listener
の onError
で取れます。
imageView.load(imageUrl) {
listener(onError = { _, throwable ->
Log.e(TAG, throwable.message, throwable)
})
)
これまで Twitter4J
で DM の添付画像を取得したい場合は下記のように専用のメソッドを利用していました。
// DM添付画像対応のため認証付きで取得する
twitter.getDMImageAsStream(imageUrl)
この InputStream
を Coil
に渡せればいいのですがあいにくそんなI/Fはないので、別の方法が必要です。
Coil に認証ヘッダーを設定する
前置きが長くなりましたが、Coil
でTwitterの DM 添付画像をロードするには下記のように認証ヘッダーを設定するだけです。
imageView.load(imageUrl) {
val twitter = ... // 何らかの方法で Twitter4J の Twitter インスタンスを取得する
val req = HttpRequest(RequestMethod.GET, imageUrl, null, twitter.authorization, emptyMap())
val authorizationHeader = req.authorization?.getAuthorizationHeader(req)
addHeader("Authorization", authorizationHeader)
}
おお、Coil経由でDMの画像取れた! pic.twitter.com/F83xafcX8I
— 竹内裕昭 (@takke) January 8, 2020
Coil
便利だなー。