parent
4a74e457d5
commit
9a2976827f
@ -1,32 +0,0 @@ |
||||
/* |
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria) |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0 |
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package com.arialyy.aria.core.task |
||||
|
||||
import com.arialyy.aria.orm.entity.BlockRecord |
||||
|
||||
class BlockState(val blockState: BlockRecord, val blockPath: String) { |
||||
|
||||
companion object { |
||||
/** |
||||
* dir/.fileName.blockId |
||||
*/ |
||||
const val BLOCK_PATH = "%s/.%s.%d" |
||||
|
||||
const val BLOCK_SIZE = 1024 * 1024 * 5L |
||||
} |
||||
|
||||
var curProgress: Long = 0 |
||||
} |
@ -1,83 +0,0 @@ |
||||
/* |
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria) |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0 |
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package com.arialyy.aria.util |
||||
|
||||
import android.database.Cursor |
||||
import android.net.Uri |
||||
import com.arialyy.aria.core.DuaContext |
||||
import timber.log.Timber |
||||
import java.io.InputStream |
||||
|
||||
object CheckUtil { |
||||
|
||||
val HTTP_REGEX = |
||||
Regex( |
||||
"(https?)://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]", |
||||
RegexOption.IGNORE_CASE |
||||
) |
||||
|
||||
/** |
||||
* check if url is correct |
||||
*/ |
||||
fun checkUrl(url: String) = HTTP_REGEX.matches(url) |
||||
|
||||
/** |
||||
* 1. Check if Uri is correct |
||||
* 2. Whether the file corresponding to Uri exists (may be deleted, or the system db has Uri related records, but the file is invalid or damaged) |
||||
* |
||||
* https://stackoverflow.com/questions/7645951/how-to-check-if-resource-pointed-by-uri-is-available |
||||
*/ |
||||
fun checkUri(uri: Uri?): Boolean { |
||||
if (uri == null) return false |
||||
val resolver = DuaContext.context.contentResolver |
||||
|
||||
//1. Check Uri |
||||
var cursor: Cursor? = null |
||||
val isUriExist: Boolean = try { |
||||
cursor = resolver.query(uri, null, null, null, null) |
||||
//cursor null: content Uri was invalid or some other error occurred |
||||
//cursor.moveToFirst() false: Uri was ok but no entry found. |
||||
(cursor != null && cursor.moveToFirst()) |
||||
} catch (t: Throwable) { |
||||
Timber.e("1.Check Uri Error: ${t.message}") |
||||
false |
||||
} finally { |
||||
try { |
||||
cursor?.close() |
||||
} catch (t: Throwable) { |
||||
} |
||||
} |
||||
|
||||
//2. Check File Exist |
||||
//如果系统 db 存有 Uri 相关记录, 但是文件失效或者损坏 (If the system db has Uri related records, but the file is invalid or damaged) |
||||
var ins: InputStream? = null |
||||
val isFileExist: Boolean = try { |
||||
ins = resolver.openInputStream(uri) |
||||
// file exists |
||||
true |
||||
} catch (t: Throwable) { |
||||
// File was not found eg: open failed: ENOENT (No such file or directory) |
||||
Timber.e("2. Check File Exist Error: ${t.message}") |
||||
false |
||||
} finally { |
||||
try { |
||||
ins?.close() |
||||
} catch (t: Throwable) { |
||||
} |
||||
} |
||||
return isUriExist && isFileExist |
||||
} |
||||
} |
@ -0,0 +1,70 @@ |
||||
/* |
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria) |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0 |
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package com.arialyy.aria.util |
||||
|
||||
import android.content.Intent |
||||
import android.content.pm.PackageManager |
||||
import android.net.Uri |
||||
import com.arialyy.aria.core.DuaContext |
||||
import timber.log.Timber |
||||
|
||||
internal const val AUTHORITY = ".andoFileProvider" |
||||
|
||||
/** |
||||
* @return 传入的Uri是否已具备访问权限 (Whether the incoming Uri has access permission) |
||||
*/ |
||||
fun giveUriPermission(uri: Uri?): Boolean { |
||||
return uri?.run { |
||||
when (DuaContext.context.checkUriPermission( |
||||
this, |
||||
android.os.Process.myPid(), |
||||
android.os.Process.myUid(), |
||||
Intent.FLAG_GRANT_READ_URI_PERMISSION |
||||
)) { |
||||
PackageManager.PERMISSION_GRANTED -> true |
||||
PackageManager.PERMISSION_DENIED -> { |
||||
DuaContext.context.grantUriPermission( |
||||
DuaContext.context.packageName, this, Intent.FLAG_GRANT_READ_URI_PERMISSION |
||||
) |
||||
false |
||||
} |
||||
else -> false |
||||
} |
||||
} ?: false |
||||
} |
||||
|
||||
fun revokeUriPermission(uri: Uri?) { |
||||
DuaContext.context.revokeUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION) |
||||
} |
||||
|
||||
inline fun <R> Uri.use(block: Uri.() -> R): R { |
||||
var isAlreadyHavePermission = false |
||||
try { |
||||
isAlreadyHavePermission = giveUriPermission(this) |
||||
return block() |
||||
} catch (t: Throwable) { |
||||
Timber.e("giveUriPermission Error ${t.message}") |
||||
} finally { |
||||
if (!isAlreadyHavePermission) { |
||||
try { |
||||
revokeUriPermission(this) |
||||
} catch (t: Throwable) { |
||||
Timber.e("revokeUriPermission Error ${t.message}") |
||||
} |
||||
} |
||||
} |
||||
return block() |
||||
} |
@ -0,0 +1,183 @@ |
||||
/* |
||||
* Copyright (C) 2016 AriaLyy(https://github.com/AriaLyy/Aria) |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0 |
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
package com.arialyy.aria.util |
||||
|
||||
import android.content.ContentResolver |
||||
import android.database.Cursor |
||||
import android.net.Uri |
||||
import android.provider.OpenableColumns |
||||
import com.arialyy.aria.core.DuaContext |
||||
import timber.log.Timber |
||||
import java.io.InputStream |
||||
import java.util.Locale |
||||
|
||||
object FileUtils { |
||||
|
||||
val HTTP_REGEX = |
||||
Regex( |
||||
"(https?)://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]", |
||||
RegexOption.IGNORE_CASE |
||||
) |
||||
|
||||
/** |
||||
* check if url is correct |
||||
*/ |
||||
fun checkUrl(url: String) = HTTP_REGEX.matches(url) |
||||
|
||||
/** |
||||
* https://github.com/javakam/FileOperator/blob/master/library_core/src/main/java/ando/file/core/FileUtils.kt |
||||
* |
||||
* 1. Check if Uri is correct |
||||
* 2. Whether the file corresponding to Uri exists (may be deleted, or the system db has Uri related records, but the file is invalid or damaged) |
||||
* |
||||
* https://stackoverflow.com/questions/7645951/how-to-check-if-resource-pointed-by-uri-is-available |
||||
*/ |
||||
fun uriEffective(uri: Uri?): Boolean { |
||||
if (uri == null) return false |
||||
val resolver = DuaContext.context.contentResolver |
||||
|
||||
//1. Check Uri |
||||
var cursor: Cursor? = null |
||||
val isUriExist: Boolean = try { |
||||
cursor = resolver.query(uri, null, null, null, null) |
||||
//cursor null: content Uri was invalid or some other error occurred |
||||
//cursor.moveToFirst() false: Uri was ok but no entry found. |
||||
(cursor != null && cursor.moveToFirst()) |
||||
} catch (t: Throwable) { |
||||
Timber.e("1.Check Uri Error: ${t.message}") |
||||
false |
||||
} finally { |
||||
try { |
||||
cursor?.close() |
||||
} catch (t: Throwable) { |
||||
} |
||||
} |
||||
|
||||
//2. Check File Exist |
||||
//如果系统 db 存有 Uri 相关记录, 但是文件失效或者损坏 (If the system db has Uri related records, but the file is invalid or damaged) |
||||
|
||||
return isUriExist && checkFileExistByUri(uri, resolver) |
||||
} |
||||
|
||||
/** |
||||
* check file exist |
||||
* @return true exist |
||||
*/ |
||||
fun checkFileExistByUri(uri: Uri, resolver: ContentResolver): Boolean { |
||||
var ins: InputStream? = null |
||||
val isFileExist: Boolean = try { |
||||
ins = resolver.openInputStream(uri) |
||||
// file exists |
||||
true |
||||
} catch (t: Throwable) { |
||||
// File was not found eg: open failed: ENOENT (No such file or directory) |
||||
Timber.e("2. Check File Exist Error: ${t.message}") |
||||
false |
||||
} finally { |
||||
try { |
||||
ins?.close() |
||||
} catch (t: Throwable) { |
||||
} |
||||
} |
||||
return isFileExist |
||||
} |
||||
|
||||
/** |
||||
* ### 路径分割 |
||||
* |
||||
* ``` |
||||
* eg: |
||||
* srcPath=/storage/emulated/0/Movies/myVideo.mp4 path=/storage/emulated/0/Movies name=myVideo suffix=mp4 nameSuffix=myVideo.mp4 |
||||
* |
||||
* /xxx/xxx/note.txt -> path: /xxx/xxx name: note suffix: txt |
||||
* ///note.txt -> path: /// name: note suffix: txt |
||||
* /note.txt -> path: "" name: note suffix: txt |
||||
* note.txt -> path: "" name: note suffix: txt |
||||
* ``` |
||||
*/ |
||||
fun splitFilePath( |
||||
srcPath: String?, |
||||
nameSplit: Char = '/', |
||||
suffixSplit: Char = '.', |
||||
block: ((path: String, name: String, suffix: String, nameSuffix: String) -> Unit)? = null, |
||||
) { |
||||
if (srcPath.isNullOrBlank()) return |
||||
val cut = srcPath.lastIndexOf(nameSplit) |
||||
// /xxx/xxx/note.txt +0: /xxx/xxx +1: /xxx/xxx/ |
||||
val path = if (cut == -1) "" else srcPath.substring(0, cut) |
||||
val nameSuffix = if (cut == -1) srcPath else srcPath.substring(cut + 1) |
||||
|
||||
val dot = nameSuffix.lastIndexOf(suffixSplit) |
||||
if (dot != -1) { |
||||
val suffix = nameSuffix.substring((dot + 1)).lowercase(Locale.getDefault()) |
||||
val name = nameSuffix.substring(0, dot) |
||||
Timber.d("splitFilePath srcPath=$srcPath path=$path name=$name suffix=$suffix nameSuffix=$nameSuffix") |
||||
block?.invoke(path, name, suffix, nameSuffix) |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* abc.jpg -> jpg |
||||
*/ |
||||
fun getFileNameSuffix(path: String): String { |
||||
var nameSuffix = path |
||||
splitFilePath(srcPath = path) { _: String, _: String, suffix: String, _: String -> |
||||
nameSuffix = suffix |
||||
} |
||||
return nameSuffix |
||||
} |
||||
|
||||
/** |
||||
* /storage/emulated/0/Movies/myVideo.mp4 -> /storage/emulated/0/Movies |
||||
*/ |
||||
fun getFilePathFromFullPath(path: String?, split: Char = '/'): String? { |
||||
if (path.isNullOrBlank()) return null |
||||
val cut = path.lastIndexOf(split) |
||||
// (cut+1): /storage/emulated/0/Movies/ |
||||
if (cut != -1) return path.substring(0, cut) |
||||
return path |
||||
} |
||||
|
||||
/** |
||||
* /storage/emulated/0/Movies/myVideo.mp4 -> myVideo.mp4 |
||||
*/ |
||||
fun getFileNameFromPath(path: String?, split: Char = '/'): String? { |
||||
if (path.isNullOrBlank()) return null |
||||
val cut = path.lastIndexOf(split) |
||||
if (cut != -1) return path.substring(cut + 1) |
||||
return path |
||||
} |
||||
|
||||
/** |
||||
* /storage/emulated/0/Movies/myVideo.mp4 -> myVideo.mp4 |
||||
*/ |
||||
fun getFileNameFromUri(uri: Uri?): String? = |
||||
uri?.use { |
||||
var filename: String? = null |
||||
val resolver = DuaContext.context.contentResolver |
||||
val mimeType = resolver.getType(uri) |
||||
|
||||
if (mimeType == null) { |
||||
filename = getFileNameFromPath(FileUri.getPathByUri(uri)) |
||||
} else { |
||||
resolver.query(uri, null, null, null, null)?.use { c: Cursor -> |
||||
val nameIndex = c.getColumnIndex(OpenableColumns.DISPLAY_NAME) |
||||
if (c.moveToFirst()) filename = c.getString(nameIndex) |
||||
} |
||||
} |
||||
filename |
||||
} |
||||
} |
Loading…
Reference in new issue