第一步,需要添加授权
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="32"
tools:ignore="ScopedStorage" />
第二步:网络请求网络图片地址
val imageUrl = "https://static.jikecrm.com/2018-06-10/152862233429525.jpg"
val client = OkHttpClient()
val request = Request.Builder()
.url(imageUrl)
.build()
val call = client.newCall(request)
call.enqueue(object: Callback {
override fun onFailure(call: Call, e: IOException) {
Log.e("TAG", "onFailure: 下载失败:${e.message}", )
}
override fun onResponse(call: Call, response: Response) {
if(response.isSuccessful){
val inputStream = response.body?.byteStream() ?: return
DownLoadImage().saveImage(inputStream,context)
}else{
Log.e("TAG", "onResponse: 下载失败~~~~~~~", )
}
}
})
在协程中去请求,不要在UI主线程请求。
第三步保存图片到本地
fun saveImage(inputStream: InputStream, context: Context) {
val values = ContentValues().apply {
put(MediaStore.Images.Media.DISPLAY_NAME, "tj_${System.currentTimeMillis()}.jpg") // 图片文件名
put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg") // 图片MIME类型
put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES) // 存储目录,此处为Pictures
}
val uri = context.contentResolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values)
if (uri == null) {
// 创建文件失败,处理错误
Log.e("DownLoad", "saveImage: 创建文件失败")
return
}
try {
val fos = context.contentResolver.openOutputStream(uri, "w") ?: return
val buffer = ByteArray(4 * 1024)
var read: Int
while (inputStream.read(buffer).also { read = it } != -1) {
fos.write(buffer, 0, read)
}
fos.close()
inputStream.close()
// 更新媒体数据库,使图片在系统相册中可见
MediaScannerConnection.scanFile(
context,
arrayOf(Environment.DIRECTORY_PICTURES),
null,
null
)
Log.i("DownLoad", "saveImage: 保存成功~~~")
} catch (e: Exception) {
context.contentResolver.delete(uri, null, null)
Log.e("DownLoad", "saveImage: 保存失败:${e.message}")
}
}
如果是同一张网络图片,系统默认是覆盖的。