Android 圖片讀取&影片讀取&音檔讀取&其他檔案讀取SAF
- 讀取前要先取得權限
- 圖片讀取(Images)
- 影片讀取(Video)
- 音檔讀取(Video)
- 其他檔案讀取(利用SAF)
- 檔案儲存到機身外部儲存
1.讀取前要先取得權限
Manifest
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
Activity
const val REQUEST_READ_EXTERNAL_STORAGE = 3
requestPermissions(arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE), REQUEST_READ_EXTERNAL_STORAGE)
2.圖片讀取(Images)
Uri(MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
val cursor = contentResolver.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, null, null, null, null)
cursor?.apply {
while (moveToNext()) {
val id = getLong(getColumnIndexOrThrow(MediaStore.MediaColumns._ID))
val uri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id)
uriToFileApiQ(uri, false)
}
cursor.close()
}
3.影片讀取(Video)
Uri(MediaStore.Video.Media.EXTERNAL_CONTENT_URI)
val cursor = contentResolver.query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, null, null, null, null)
cursor?.apply {
while (moveToNext()) {
val id = getLong(getColumnIndexOrThrow(MediaStore.MediaColumns._ID))
val uri = ContentUris.withAppendedId(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, id)
uriToFileApiQ(uri, false)
}
cursor.close()
}
4.音檔讀取(Video)
Uri(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI)
val cursor = contentResolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, null)
cursor?.apply {
while (moveToNext()) {
val id = getLong(getColumnIndexOrThrow(MediaStore.MediaColumns._ID))
val uri = ContentUris.withAppendedId(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, id)
uriToFileApiQ(uri, false)
}
cursor.close()
}
5.其他檔案讀取(利用SAF)
const val SAF_REQUEST = 0
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT)
intent.type = "application/pdf"
//開啟多選
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
startActivityForResult(intent, SAF_REQUEST)
回傳單筆與多筆
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == SAF_REQUEST && resultCode == Activity.RESULT_OK) {
//單筆
data?.data?.let {
val uri = Uri.parse(it.toString())
uriToFileApiQ(uri, true)
}
//多筆
data?.clipData?.let {
for (i in 0 until it.itemCount) {
val uri = Uri.parse(it.getItemAt(i).uri.toString())
uriToFileApiQ(uri, true)
}
}
}
}
6.檔案儲存到機身外部儲存
@SuppressLint("SimpleDateFormat")
private fun uriToFileApiQ(uri: Uri, pdf: Boolean): File? {
var file: File? = null
if (uri.scheme == ContentResolver.SCHEME_FILE) {
file = File(uri.toString())
} else if (uri.scheme == ContentResolver.SCHEME_CONTENT) {
var date: String
val info = contentResolver.query(uri, null, null, null, null)
info?.run {
moveToFirst()
//檔案大小
val size = getString(getColumnIndexOrThrow(MediaStore.Images.Media.SIZE))
date = if (!pdf) {
//檔案建立日期(時間戳轉換)
val dateAdded =
getString(getColumnIndexOrThrow(MediaStore.Images.Media.DATE_ADDED))
val sdf = SimpleDateFormat("yyyy年MM月dd日 HH點mm分ss秒")
sdf.format(Date(dateAdded.toLong() * 1000))
} else {
""
}
//檔案名稱
val fileName =
getString(getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME))
if (size.isNullOrEmpty()) return@run
//輸入流
val inputStream = contentResolver.openInputStream(uri)
//輸出流
val filePath = File(getExternalFilesDir("myPhoto")?.absolutePath, "datefileName")
val fos = FileOutputStream(filePath)
FileUtils.copy(inputStream!!, fos)
file = filePath
fos.close()
inputStream.close()
info.close()
}
}
return file
}
MediaStore.Images.Media.RELATIVE_PATH //取得圖片上層路徑
MediaStore.Images.Media.DISPLAY_NAME //圖片名稱