Jelajahi Sumber

Merge branch 'gif'

cooperku_kdanmobile 6 tahun lalu
induk
melakukan
f3fc25c8fa

+ 1 - 0
build.gradle

@@ -63,6 +63,7 @@ dependencies {
 
     implementation 'com.squareup.picasso:picasso:2.71828'
     implementation 'com.github.naman14:TAndroidLame:1.1'
+    implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.16'
 }
 repositories {
     mavenCentral()

+ 5 - 1
src/main/java/com/bomostory/sceneeditmodule/SceneEditActivity.kt

@@ -1228,7 +1228,11 @@ class SceneEditActivity : AppCompatActivity(), ActorAdapter.OnActorDragListener,
             PHOTO_FROM_GALLERY ->
                 when (resultCode) {
                     Activity.RESULT_OK -> if (data != null) {
-                        FileUtils.saveImageForActor(this, data.data, System.currentTimeMillis().toString())
+                        var uri = data.data
+                        if (uri.path.endsWith(".gif"))
+                            FileUtils.saveGifForActor(this, data.data, System.currentTimeMillis().toString())
+                        else
+                            FileUtils.saveImageForActor(this, data.data, System.currentTimeMillis().toString())
                     }
                     Activity.RESULT_CANCELED -> {
                     }

+ 10 - 1
src/main/java/com/bomostory/sceneeditmodule/screen/view/ActorView.kt

@@ -7,6 +7,7 @@ import android.util.AttributeSet
 import android.widget.ImageView
 import com.bomostory.sceneeditmodule.DialogueDrawer
 import com.bomostory.sceneeditmodule.basicdata.Actor
+import pl.droidsonroids.gif.GifDrawable
 
 class ActorView : ImageView {
 
@@ -14,7 +15,15 @@ class ActorView : ImageView {
         set(value) {
             field = value
             value?.let {
-                if(!it.isDialogue) setImageDrawable(Drawable.createFromPath(it.resourcePath))
+                if(!it.isDialogue) {
+                    if (it.resourcePath.toLowerCase().endsWith(".gif")) {
+                        val gifDrawable = GifDrawable(it.resourcePath)
+                        setImageDrawable(gifDrawable)
+                        gifDrawable.start()
+                    } else {
+                        setImageDrawable(Drawable.createFromPath(it.resourcePath))
+                    }
+                }
                 if (it.isMirror && !it.isDialogue) {
                     this.scaleX = -1f
                     this.scaleY = 1f

+ 159 - 4
src/main/java/com/bomostory/sceneeditmodule/utils/FileUtils.kt

@@ -1,18 +1,21 @@
 package com.bomostory.sceneeditmodule.utils
 
+import android.content.ContentUris
 import android.content.Context
+import android.database.Cursor
 import android.graphics.Bitmap
 import android.net.Uri
+import android.os.Build
+import android.os.Environment
+import android.provider.DocumentsContract
 import android.provider.MediaStore
 import com.bomostory.sceneeditmodule.Config
 import com.bomostory.sceneeditmodule.SceneDrawer
 import com.bomostory.sceneeditmodule.basicdata.Project
 import com.google.gson.Gson
 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 {
 
@@ -21,6 +24,158 @@ object FileUtils {
         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){
         val dir = File(Config.IMAGE_FOLDER,"")
         dir.mkdir()