diff --git a/app/build.gradle b/app/build.gradle index 51a873232..dc52337a2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -33,7 +33,8 @@ android { buildTypes { debug { - applicationIdSuffix ".debug" + // we cannot change the original package name, else PhotoEditorSDK won't work + //applicationIdSuffix ".debug" } release { minifyEnabled true @@ -84,3 +85,27 @@ dependencies { implementation 'androidx.room:room-runtime:2.2.2' annotationProcessor 'androidx.room:room-compiler:2.2.2' } + +// Apply the PESDKPlugin +apply plugin: 'ly.img.android.pesdk' + +pesdkConfig { + licencePath 'pesdk_license' + + supportLibVersion "28.0.0" + + modules { + include 'ly.img.android.pesdk.ui.mobile_ui:core' + include 'ly.img.android.pesdk.ui.mobile_ui:text' + include 'ly.img.android.pesdk.ui.mobile_ui:focus' + include 'ly.img.android.pesdk.ui.mobile_ui:brush' + include 'ly.img.android.pesdk.ui.mobile_ui:filter' + include 'ly.img.android.pesdk.ui.mobile_ui:transform' + include 'ly.img.android.pesdk.ui.mobile_ui:adjustment' + include 'ly.img.android.pesdk.ui.mobile_ui:text-design' + + // Add asset packs if you need + include 'ly.img.android.pesdk.assets:font-basic' + include 'ly.img.android.pesdk.assets:filter-basic' + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a95a3ba3b..11b2f5c91 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -10,6 +10,9 @@ + @@ -198,7 +201,7 @@ @@ -207,6 +210,11 @@ + + + diff --git a/app/src/main/assets/pesdk_license b/app/src/main/assets/pesdk_license new file mode 100644 index 000000000..764680c1d --- /dev/null +++ b/app/src/main/assets/pesdk_license @@ -0,0 +1 @@ +{"api_token":"aulo3T5M9uyXgeJauoiJjw","app_identifiers":["com.simplemobiletools.gallery.pro"],"available_actions":[],"domains":["https://api.photoeditorsdk.com"],"enterprise_license":false,"expires_at":null,"features":["camera","library","export","customassets","whitelabel","adjustment","brush","filter","focus","text","textdesign","transform"],"issued_at":1576163964,"minimum_sdk_version":"1.0","owner":"Tikap s.r.o.","platform":"Android","products":["pesdk"],"version":"2.4","signature":"JvD7pjiy3iomgGW7XgEaHCs7aWxTIRl/PN7dp1muFSpE6S+IVmKDfSR5+enE2Tdh2EFC/3lyVuG7S5FcyOyxeXtyfKW/+H2y8Oem6VQzgTlYus8Eacz3/mk+GShUq+C+xQvbp5cWB/prScOZHPOaiZCu531rFYOGfwgaThtpawtG4B6wxvRWfjJor8fbsIHzEQnUnsEKsQR4UhwAUQvpDnCE0JtuP0CAxFyP03XfLlwIGhbUiCbaHh/kcG3IVzeQxSjjjsefu3rCtjYbm0eZKLbgsCvbNoVv2p011P2XN1pAu1uTMFscD74FbAFAgO12vYHfJ4iQE6cmZBiVSIJftJw3Gawj91NsiJbnLmPSqwSuUApatE5pMAff443s7ML32rHj+gD2IQ3oAHowGtbyofC0LrLPxaIMZEcd9Ttfk3ujn001rvekVXk6Uj/l3P3RpyLs6FHpMMSHo5nAk7ab7MYeR6PZfWDE+ggM1sqWV5fd4rh9qd36ioJgGaL6OnYCh/2t1xeMrFG2aw55hhjZPjxw3yfTvbJrOs1p0G503nkPCzRn4TCvPefkFDquAFCQaVmIJuFi51j4HA34o2E4Twru2SkI0od5ewHE5+hAR+9JalOaZWN/kLi59B9VrAEfskYmfVszqIpekpAyloMPYrpBseUDlWVCqbJIlyQt564="} \ No newline at end of file diff --git a/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/NewEditActivity.kt b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/NewEditActivity.kt new file mode 100644 index 000000000..23dccbee2 --- /dev/null +++ b/app/src/main/kotlin/com/simplemobiletools/gallery/pro/activities/NewEditActivity.kt @@ -0,0 +1,187 @@ +package com.simplemobiletools.gallery.pro.activities + +import android.app.Activity +import android.content.Intent +import android.net.Uri +import android.os.Bundle +import android.provider.MediaStore +import androidx.core.util.Pair +import com.simplemobiletools.commons.asynctasks.CopyMoveTask +import com.simplemobiletools.commons.extensions.* +import com.simplemobiletools.commons.helpers.CONFLICT_OVERWRITE +import com.simplemobiletools.commons.helpers.PERMISSION_WRITE_STORAGE +import com.simplemobiletools.commons.helpers.REAL_FILE_PATH +import com.simplemobiletools.commons.interfaces.CopyMoveListener +import com.simplemobiletools.commons.models.FileDirItem +import com.simplemobiletools.gallery.pro.R +import com.simplemobiletools.gallery.pro.dialogs.SaveAsDialog +import com.simplemobiletools.gallery.pro.extensions.config +import com.simplemobiletools.gallery.pro.extensions.fixDateTaken +import ly.img.android.pesdk.assets.filter.basic.FilterPackBasic +import ly.img.android.pesdk.assets.font.basic.FontPackBasic +import ly.img.android.pesdk.backend.model.state.EditorLoadSettings +import ly.img.android.pesdk.backend.model.state.EditorSaveSettings +import ly.img.android.pesdk.backend.model.state.manager.SettingsList +import ly.img.android.pesdk.ui.activity.PhotoEditorBuilder +import ly.img.android.pesdk.ui.model.state.UiConfigFilter +import ly.img.android.pesdk.ui.model.state.UiConfigText +import ly.img.android.pesdk.ui.model.state.UiConfigTheme +import java.io.File + +class NewEditActivity : SimpleActivity() { + private val PESDK_EDIT_IMAGE = 1 + private val SOURCE_IMAGE_PATH = "SOURCE_IMAGE_PATH" + private val RESULT_IMAGE_PATH = "RESULT_IMAGE_PATH" + private var sourceFileLastModified = 0L + private var destinationFilePath = "" + private var imagePathFromEditor = "" // delete the file stored at the internal app storage (the editor saves it there) in case moving to the selected location fails + + private lateinit var uri: Uri + private lateinit var saveUri: Uri + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_new_edit) + + if (checkAppSideloading()) { + return + } + + handlePermission(PERMISSION_WRITE_STORAGE) { + if (it) { + initEditActivity() + } else { + toast(R.string.no_storage_permissions) + finish() + } + } + } + + private fun initEditActivity() { + if (intent.data == null) { + toast(R.string.invalid_image_path) + finish() + return + } + + uri = intent.data!! + if (uri.scheme != "file" && uri.scheme != "content") { + toast(R.string.unknown_file_location) + finish() + return + } + + if (intent.extras?.containsKey(REAL_FILE_PATH) == true) { + val realPath = intent.extras!!.getString(REAL_FILE_PATH) + uri = when { + isPathOnOTG(realPath!!) -> uri + realPath.startsWith("file:/") -> Uri.parse(realPath) + else -> Uri.fromFile(File(realPath)) + } + } else { + (getRealPathFromURI(uri))?.apply { + uri = Uri.fromFile(File(this)) + } + } + + saveUri = when { + intent.extras?.containsKey(MediaStore.EXTRA_OUTPUT) == true -> intent.extras!!.get(MediaStore.EXTRA_OUTPUT) as Uri + else -> uri + } + + openEditor(uri) + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) { + if (requestCode == PESDK_EDIT_IMAGE) { + val extras = resultData?.extras + val source = extras?.getString(SOURCE_IMAGE_PATH, "") ?: "" + imagePathFromEditor = extras?.getString(RESULT_IMAGE_PATH, "") ?: "" + + if (resultCode != Activity.RESULT_OK || source.isEmpty() || imagePathFromEditor.isEmpty() || source == imagePathFromEditor) { + finish() + } else { + // the image is stored at the internal app storage first, for example /data/user/0/com.simplemobiletools.gallery.pro/files/editor/IMG_20191207_183023.jpg + // first we rename it to the desired name, then move + SaveAsDialog(this, source, true, cancelCallback = { + toast(R.string.image_editing_failed) + finish() + }, callback = { + destinationFilePath = it + handleSAFDialog(destinationFilePath) { + if (it) { + sourceFileLastModified = File(source).lastModified() + val newFile = File("${imagePathFromEditor.getParentPath()}/${destinationFilePath.getFilenameFromPath()}") + File(imagePathFromEditor).renameTo(newFile) + val sourceFile = FileDirItem(newFile.absolutePath, newFile.name) + + val conflictResolutions = LinkedHashMap() + conflictResolutions[destinationFilePath] = CONFLICT_OVERWRITE + + val pair = Pair(arrayListOf(sourceFile), destinationFilePath.getParentPath()) + CopyMoveTask(this, false, true, conflictResolutions, editCopyMoveListener, true).execute(pair) + } else { + toast(R.string.image_editing_failed) + File(imagePathFromEditor).delete() + finish() + } + } + }) + } + } + super.onActivityResult(requestCode, resultCode, resultData) + } + + private val editCopyMoveListener = object : CopyMoveListener { + override fun copySucceeded(copyOnly: Boolean, copiedAll: Boolean, destinationPath: String) { + if (config.keepLastModified) { + updateLastModified(destinationFilePath, sourceFileLastModified) + } + + val paths = arrayListOf(destinationFilePath) + rescanPaths(paths) { + fixDateTaken(paths, false) + } + + setResult(Activity.RESULT_OK, intent) + toast(R.string.file_edited_successfully) + finish() + } + + override fun copyFailed() { + toast(R.string.unknown_error_occurred) + File(imagePathFromEditor).delete() + finish() + } + } + + private fun openEditor(inputImage: Uri) { + val filename = inputImage.toString().getFilenameFromPath() + val settingsList = createPesdkSettingsList(filename) + + settingsList.getSettingsModel(EditorLoadSettings::class.java).imageSource = inputImage + + PhotoEditorBuilder(this) + .setSettingsList(settingsList) + .startActivityForResult(this, PESDK_EDIT_IMAGE) + } + + private fun createPesdkSettingsList(filename: String): SettingsList { + val settingsList = SettingsList() + settingsList.getSettingsModel(UiConfigFilter::class.java).setFilterList( + FilterPackBasic.getFilterPack() + ) + + settingsList.getSettingsModel(UiConfigText::class.java).setFontList( + FontPackBasic.getFontPack() + ) + + settingsList.getSettingsModel(UiConfigTheme::class.java).theme = R.style.Imgly_Theme_NoFullscreen + + settingsList.getSettingsModel(EditorSaveSettings::class.java) + .setOutputFilePath("$filesDir/editor/$filename") + .savePolicy = EditorSaveSettings.SavePolicy.RETURN_SOURCE_OR_CREATE_OUTPUT_IF_NECESSARY + + return settingsList + } +} diff --git a/app/src/main/res/layout/activity_new_edit.xml b/app/src/main/res/layout/activity_new_edit.xml new file mode 100644 index 000000000..1200b5a4a --- /dev/null +++ b/app/src/main/res/layout/activity_new_edit.xml @@ -0,0 +1,8 @@ + + + + diff --git a/build.gradle b/build.gradle index 969a40070..f16279588 100644 --- a/build.gradle +++ b/build.gradle @@ -6,11 +6,13 @@ buildscript { repositories { google() jcenter() + maven { url 'https://artifactory.img.ly/artifactory/imgly' } } dependencies { classpath 'com.android.tools.build:gradle:3.5.3' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + classpath 'ly.img.android.pesdk:plugin:6.6.4' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files