mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-01-03 15:47:40 +00:00
Simplify MediaStoreUtils
This commit is contained in:
parent
e32cd03d0b
commit
300b233a27
@ -8,8 +8,6 @@ import android.net.Uri
|
|||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
import com.topjohnwu.magisk.core.Info
|
import com.topjohnwu.magisk.core.Info
|
||||||
import com.topjohnwu.magisk.core.di.AppContext
|
|
||||||
import com.topjohnwu.magisk.core.ktx.cachedFile
|
|
||||||
import com.topjohnwu.magisk.core.model.MagiskJson
|
import com.topjohnwu.magisk.core.model.MagiskJson
|
||||||
import com.topjohnwu.magisk.core.model.module.OnlineModule
|
import com.topjohnwu.magisk.core.model.module.OnlineModule
|
||||||
import com.topjohnwu.magisk.core.utils.MediaStoreUtils
|
import com.topjohnwu.magisk.core.utils.MediaStoreUtils
|
||||||
|
@ -21,10 +21,6 @@ object MediaStoreUtils {
|
|||||||
|
|
||||||
private val cr get() = AppContext.contentResolver
|
private val cr get() = AppContext.contentResolver
|
||||||
|
|
||||||
@get:RequiresApi(api = 29)
|
|
||||||
private val tableUri
|
|
||||||
get() = MediaStore.Downloads.EXTERNAL_CONTENT_URI
|
|
||||||
|
|
||||||
private fun relativePath(name: String) =
|
private fun relativePath(name: String) =
|
||||||
if (name.isEmpty()) Environment.DIRECTORY_DOWNLOADS
|
if (name.isEmpty()) Environment.DIRECTORY_DOWNLOADS
|
||||||
else Environment.DIRECTORY_DOWNLOADS + File.separator + name
|
else Environment.DIRECTORY_DOWNLOADS + File.separator + name
|
||||||
@ -32,20 +28,21 @@ object MediaStoreUtils {
|
|||||||
fun fullPath(name: String): String =
|
fun fullPath(name: String): String =
|
||||||
File(Environment.getExternalStorageDirectory(), relativePath(name)).canonicalPath
|
File(Environment.getExternalStorageDirectory(), relativePath(name)).canonicalPath
|
||||||
|
|
||||||
private val relativePath get() = relativePath(Config.downloadDir)
|
private val downloadPath get() = relativePath(Config.downloadDir)
|
||||||
|
|
||||||
@RequiresApi(api = 30)
|
@RequiresApi(api = 30)
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
private fun insertFile(displayName: String): MediaStoreFile {
|
private fun insertFile(displayName: String): MediaStoreFile {
|
||||||
val values = ContentValues()
|
val values = ContentValues()
|
||||||
values.put(MediaStore.MediaColumns.RELATIVE_PATH, relativePath)
|
values.put(MediaStore.MediaColumns.RELATIVE_PATH, downloadPath)
|
||||||
values.put(MediaStore.MediaColumns.DISPLAY_NAME, displayName)
|
values.put(MediaStore.MediaColumns.DISPLAY_NAME, displayName)
|
||||||
|
|
||||||
// When a file with the same name exists and was not created by us:
|
// When a file with the same name exists and was not created by us:
|
||||||
// - Before Android 11, insert will return null
|
// - Before Android 11, insert will return null
|
||||||
// - On Android 11+, the system will automatically create a new name
|
// - On Android 11+, the system will automatically create a new name
|
||||||
// Thus the reason to restrict this method call to API 30+
|
// Thus the reason to restrict this method call to API 30+
|
||||||
val fileUri = cr.insert(tableUri, values) ?: throw IOException("Can't insert $displayName.")
|
val fileUri = cr.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, values)
|
||||||
|
?: throw IOException("Can't insert $displayName.")
|
||||||
|
|
||||||
val projection = arrayOf(MediaStore.MediaColumns._ID, MediaStore.MediaColumns.DATA)
|
val projection = arrayOf(MediaStore.MediaColumns._ID, MediaStore.MediaColumns.DATA)
|
||||||
cr.query(fileUri, projection, null, null, null)?.use { cursor ->
|
cr.query(fileUri, projection, null, null, null)?.use { cursor ->
|
||||||
@ -68,13 +65,16 @@ object MediaStoreUtils {
|
|||||||
val selection = "${MediaStore.MediaColumns.DISPLAY_NAME} == ?"
|
val selection = "${MediaStore.MediaColumns.DISPLAY_NAME} == ?"
|
||||||
val selectionArgs = arrayOf(displayName)
|
val selectionArgs = arrayOf(displayName)
|
||||||
val sortOrder = "${MediaStore.MediaColumns.DATE_ADDED} DESC"
|
val sortOrder = "${MediaStore.MediaColumns.DATE_ADDED} DESC"
|
||||||
cr.query(tableUri, projection, selection, selectionArgs, sortOrder)?.use { cursor ->
|
val query = cr.query(
|
||||||
|
MediaStore.Downloads.EXTERNAL_CONTENT_URI,
|
||||||
|
projection, selection, selectionArgs, sortOrder)
|
||||||
|
query?.use { cursor ->
|
||||||
val idColumn = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns._ID)
|
val idColumn = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns._ID)
|
||||||
val dataColumn = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA)
|
val dataColumn = cursor.getColumnIndexOrThrow(MediaStore.MediaColumns.DATA)
|
||||||
while (cursor.moveToNext()) {
|
while (cursor.moveToNext()) {
|
||||||
val id = cursor.getLong(idColumn)
|
val id = cursor.getLong(idColumn)
|
||||||
val data = cursor.getString(dataColumn)
|
val data = cursor.getString(dataColumn)
|
||||||
if (data.endsWith(relativePath + File.separator + displayName)) {
|
if (data.endsWith(downloadPath + File.separator + displayName)) {
|
||||||
return MediaStoreFile(id, data)
|
return MediaStoreFile(id, data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -83,24 +83,21 @@ object MediaStoreUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
fun getFile(displayName: String, skipQuery: Boolean = false): UriFile {
|
fun getFile(displayName: String): UriFile {
|
||||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
|
return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
|
||||||
// Fallback to file based I/O pre Android 11
|
// Fallback to file based I/O pre Android 11
|
||||||
val parent = File(Environment.getExternalStorageDirectory(), relativePath)
|
val parent = File(Environment.getExternalStorageDirectory(), downloadPath)
|
||||||
parent.mkdirs()
|
parent.mkdirs()
|
||||||
return LegacyUriFile(File(parent, displayName))
|
LegacyUriFile(File(parent, displayName))
|
||||||
|
} else {
|
||||||
|
queryFile(displayName) ?: insertFile(displayName)
|
||||||
}
|
}
|
||||||
|
|
||||||
return if (skipQuery) insertFile(displayName)
|
|
||||||
else queryFile(displayName) ?: insertFile(displayName)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Uri.inputStream() = cr.openInputStream(this) ?: throw FileNotFoundException()
|
fun Uri.inputStream() = cr.openInputStream(this) ?: throw FileNotFoundException()
|
||||||
|
|
||||||
fun Uri.outputStream() = cr.openOutputStream(this, "rwt") ?: throw FileNotFoundException()
|
fun Uri.outputStream() = cr.openOutputStream(this, "rwt") ?: throw FileNotFoundException()
|
||||||
|
|
||||||
fun Uri.fileDescriptor(mode: String) = cr.openFileDescriptor(this, mode) ?: throw FileNotFoundException()
|
|
||||||
|
|
||||||
val Uri.displayName: String get() {
|
val Uri.displayName: String get() {
|
||||||
if (scheme == "file") {
|
if (scheme == "file") {
|
||||||
// Simple uri wrapper over file, directly get file name
|
// Simple uri wrapper over file, directly get file name
|
||||||
@ -130,7 +127,7 @@ object MediaStoreUtils {
|
|||||||
|
|
||||||
@RequiresApi(api = 29)
|
@RequiresApi(api = 29)
|
||||||
private class MediaStoreFile(private val id: Long, private val data: String) : UriFile {
|
private class MediaStoreFile(private val id: Long, private val data: String) : UriFile {
|
||||||
override val uri = ContentUris.withAppendedId(tableUri, id)
|
override val uri = ContentUris.withAppendedId(MediaStore.Downloads.EXTERNAL_CONTENT_URI, id)
|
||||||
override fun toString() = data
|
override fun toString() = data
|
||||||
override fun delete(): Boolean {
|
override fun delete(): Boolean {
|
||||||
val selection = "${MediaStore.MediaColumns._ID} == ?"
|
val selection = "${MediaStore.MediaColumns._ID} == ?"
|
||||||
|
@ -105,7 +105,7 @@ class FlashViewModel : BaseViewModel() {
|
|||||||
val name = "magisk_install_log_%s.log".format(
|
val name = "magisk_install_log_%s.log".format(
|
||||||
System.currentTimeMillis().toTime(timeFormatStandard)
|
System.currentTimeMillis().toTime(timeFormatStandard)
|
||||||
)
|
)
|
||||||
val file = MediaStoreUtils.getFile(name, true)
|
val file = MediaStoreUtils.getFile(name)
|
||||||
file.uri.outputStream().bufferedWriter().use { writer ->
|
file.uri.outputStream().bufferedWriter().use { writer ->
|
||||||
synchronized(logItems) {
|
synchronized(logItems) {
|
||||||
logItems.forEach {
|
logItems.forEach {
|
||||||
|
@ -69,7 +69,7 @@ class LogViewModel(
|
|||||||
viewModelScope.launch(Dispatchers.IO) {
|
viewModelScope.launch(Dispatchers.IO) {
|
||||||
val filename = "magisk_log_%s.log".format(
|
val filename = "magisk_log_%s.log".format(
|
||||||
System.currentTimeMillis().toTime(timeFormatStandard))
|
System.currentTimeMillis().toTime(timeFormatStandard))
|
||||||
val logFile = MediaStoreUtils.getFile(filename, true)
|
val logFile = MediaStoreUtils.getFile(filename)
|
||||||
logFile.uri.outputStream().bufferedWriter().use { file ->
|
logFile.uri.outputStream().bufferedWriter().use { file ->
|
||||||
file.write("---Detected Device Info---\n\n")
|
file.write("---Detected Device Info---\n\n")
|
||||||
file.write("isAB=${Info.isAB}\n")
|
file.write("isAB=${Info.isAB}\n")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user