|
@@ -1,18 +1,21 @@
|
|
package com.bomostory.sceneeditmodule.utils
|
|
package com.bomostory.sceneeditmodule.utils
|
|
|
|
|
|
|
|
+import android.content.ContentUris
|
|
import android.content.Context
|
|
import android.content.Context
|
|
|
|
+import android.database.Cursor
|
|
import android.graphics.Bitmap
|
|
import android.graphics.Bitmap
|
|
import android.net.Uri
|
|
import android.net.Uri
|
|
|
|
+import android.os.Build
|
|
|
|
+import android.os.Environment
|
|
|
|
+import android.provider.DocumentsContract
|
|
import android.provider.MediaStore
|
|
import android.provider.MediaStore
|
|
import com.bomostory.sceneeditmodule.Config
|
|
import com.bomostory.sceneeditmodule.Config
|
|
import com.bomostory.sceneeditmodule.SceneDrawer
|
|
import com.bomostory.sceneeditmodule.SceneDrawer
|
|
import com.bomostory.sceneeditmodule.basicdata.Project
|
|
import com.bomostory.sceneeditmodule.basicdata.Project
|
|
import com.google.gson.Gson
|
|
import com.google.gson.Gson
|
|
import io.reactivex.Completable
|
|
import io.reactivex.Completable
|
|
-import java.io.BufferedOutputStream
|
|
|
|
-import java.io.File
|
|
|
|
-import java.io.FileOutputStream
|
|
|
|
-import java.io.FileWriter
|
|
|
|
|
|
+import java.io.*
|
|
|
|
+
|
|
|
|
|
|
object FileUtils {
|
|
object FileUtils {
|
|
|
|
|
|
@@ -21,6 +24,158 @@ object FileUtils {
|
|
return File(projectFolder, Config.VIDEO_FILE_NAME)
|
|
return File(projectFolder, Config.VIDEO_FILE_NAME)
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ fun getRealPathFromURI(context: Context, uri: Uri): String? {
|
|
|
|
+ val isKitKat = Build.VERSION.SDK_INT >= 19
|
|
|
|
+
|
|
|
|
+ if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
|
|
|
|
+ // DocumentProvider
|
|
|
|
+ if (isExternalStorageDocument(uri)) {
|
|
|
|
+ // ExternalStorageProvider
|
|
|
|
+ val docId = DocumentsContract.getDocumentId(uri)
|
|
|
|
+ val split = docId.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
|
|
|
|
+ val type = split[0]
|
|
|
|
+
|
|
|
|
+ return if ("primary".equals(type, ignoreCase = true)) {
|
|
|
|
+ Environment.getExternalStorageDirectory().toString() + "/" + split[1]
|
|
|
|
+ } else {
|
|
|
|
+ File(uri.toString()).absolutePath
|
|
|
|
+ }
|
|
|
|
+ } else if (isDownloadsDocument(uri)) {
|
|
|
|
+ // DownloadsProvider
|
|
|
|
+ val id = DocumentsContract.getDocumentId(uri)
|
|
|
|
+ if (id.startsWith("raw:")) {
|
|
|
|
+ return id.replaceFirst("raw:", "");
|
|
|
|
+ }
|
|
|
|
+ try {
|
|
|
|
+ val contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), id.toLong())
|
|
|
|
+ return getDataColumn(context, contentUri, null, null)
|
|
|
|
+ } catch (e: NumberFormatException) {
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ } else if (isMediaDocument(uri)) {
|
|
|
|
+ // MediaProvider
|
|
|
|
+ val docId = DocumentsContract.getDocumentId(uri)
|
|
|
|
+ val split = docId.split(":".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
|
|
|
|
+ val type = split[0]
|
|
|
|
+
|
|
|
|
+ var contentUri: Uri? = null
|
|
|
|
+ if ("image" == type) {
|
|
|
|
+ contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
|
|
|
|
+ } else if ("video" == type) {
|
|
|
|
+ contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI
|
|
|
|
+ } else if ("audio" == type) {
|
|
|
|
+ contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ val selection = "_id=?"
|
|
|
|
+ val selectionArgs = arrayOf(split[1])
|
|
|
|
+
|
|
|
|
+ return getDataColumn(context, contentUri, selection, selectionArgs)
|
|
|
|
+ }
|
|
|
|
+ } else if ("content".equals(uri.scheme!!, ignoreCase = true)) {
|
|
|
|
+ // Return the remote address
|
|
|
|
+ if (isGooglePhotosUri(uri))
|
|
|
|
+ return uri.lastPathSegment
|
|
|
|
+ return getDataColumn(context, uri, null, null)
|
|
|
|
+ } else if ("file".equals(uri.scheme!!, ignoreCase = true)) {
|
|
|
|
+ // File
|
|
|
|
+ return uri.path
|
|
|
|
+ }
|
|
|
|
+ return null
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Get the value of the data column for this Uri. This is useful for MediaStore Uris, and other file-based ContentProviders.
|
|
|
|
+ *
|
|
|
|
+ * @param context
|
|
|
|
+ * The context.
|
|
|
|
+ * @param uri
|
|
|
|
+ * The Uri to query.
|
|
|
|
+ * @param selection
|
|
|
|
+ * (Optional) Filter used in the query.
|
|
|
|
+ * @param selectionArgs
|
|
|
|
+ * (Optional) Selection arguments used in the query.
|
|
|
|
+ * @return The value of the _data column, which is typically a file path.
|
|
|
|
+ */
|
|
|
|
+ private fun getDataColumn(context: Context, uri: Uri?, selection: String?, selectionArgs: Array<String>?): String? {
|
|
|
|
+ var cursor: Cursor? = null
|
|
|
|
+ val column = "_data"
|
|
|
|
+ val projection = arrayOf(column)
|
|
|
|
+
|
|
|
|
+ try {
|
|
|
|
+ cursor = context.contentResolver.query(uri!!, projection, selection, selectionArgs, null)
|
|
|
|
+ if (cursor != null && cursor.moveToFirst()) {
|
|
|
|
+ val index = cursor.getColumnIndexOrThrow(column)
|
|
|
|
+ return cursor.getString(index)
|
|
|
|
+ }
|
|
|
|
+ } finally {
|
|
|
|
+ cursor?.close()
|
|
|
|
+ }
|
|
|
|
+ return null
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * @param uri
|
|
|
|
+ * The Uri to check.
|
|
|
|
+ * @return Whether the Uri authority is ExternalStorageProvider.
|
|
|
|
+ */
|
|
|
|
+ private fun isExternalStorageDocument(uri: Uri): Boolean {
|
|
|
|
+ return "com.android.externalstorage.documents" == uri.authority
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * @param uri
|
|
|
|
+ * The Uri to check.
|
|
|
|
+ * @return Whether the Uri authority is DownloadsProvider.
|
|
|
|
+ */
|
|
|
|
+ private fun isDownloadsDocument(uri: Uri): Boolean {
|
|
|
|
+ return "com.android.providers.downloads.documents" == uri.authority
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * @param uri
|
|
|
|
+ * The Uri to check.
|
|
|
|
+ * @return Whether the Uri authority is MediaProvider.
|
|
|
|
+ */
|
|
|
|
+ private fun isMediaDocument(uri: Uri): Boolean {
|
|
|
|
+ return "com.android.providers.media.documents" == uri.authority
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * @param uri
|
|
|
|
+ * The Uri to check.
|
|
|
|
+ * @return Whether the Uri authority is Google Photos.
|
|
|
|
+ */
|
|
|
|
+ private fun isGooglePhotosUri(uri: Uri): Boolean {
|
|
|
|
+ return "com.google.android.apps.photos.content" == uri.authority
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ fun saveGifForActor(context: Context, uri: Uri, fileName: String) {
|
|
|
|
+ val dir = File(Config.IMAGE_FOLDER,"")
|
|
|
|
+ dir.mkdir()
|
|
|
|
+ val file = File(Config.IMAGE_FOLDER, fileName.plus(".gif"))
|
|
|
|
+ try {
|
|
|
|
+ var sourceFile = File(getRealPathFromURI(context, uri))
|
|
|
|
+ val bis = BufferedInputStream(FileInputStream(sourceFile))
|
|
|
|
+ val bos = BufferedOutputStream(FileOutputStream(file))
|
|
|
|
+ val buf = ByteArray(1024)
|
|
|
|
+ bis.read(buf)
|
|
|
|
+ do {
|
|
|
|
+ bos.write(buf)
|
|
|
|
+ } while (bis.read(buf) !== -1)
|
|
|
|
+ bos.flush()
|
|
|
|
+ bos.close()
|
|
|
|
+ bis.close()
|
|
|
|
+ if (context is OnSaveActorImage) {
|
|
|
|
+ context.onSaveActorImage(file.path)
|
|
|
|
+ } else {
|
|
|
|
+ throw RuntimeException(context.toString() + " must implement OnFragmentInteractionListener")
|
|
|
|
+ }
|
|
|
|
+ } catch (e: Exception) {
|
|
|
|
+ e.printStackTrace()
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
fun saveImageForActor(context: Context, uri: Uri, fileName: String){
|
|
fun saveImageForActor(context: Context, uri: Uri, fileName: String){
|
|
val dir = File(Config.IMAGE_FOLDER,"")
|
|
val dir = File(Config.IMAGE_FOLDER,"")
|
|
dir.mkdir()
|
|
dir.mkdir()
|