diff --git a/app/src/main/java/com/kunzisoft/keepass/activities/EntryActivity.kt b/app/src/main/java/com/kunzisoft/keepass/activities/EntryActivity.kt index 87b9de595..a6090f132 100644 --- a/app/src/main/java/com/kunzisoft/keepass/activities/EntryActivity.kt +++ b/app/src/main/java/com/kunzisoft/keepass/activities/EntryActivity.kt @@ -39,6 +39,7 @@ import androidx.coordinatorlayout.widget.CoordinatorLayout import com.google.android.material.appbar.CollapsingToolbarLayout import com.kunzisoft.keepass.R import com.kunzisoft.keepass.activities.helpers.ReadOnlyHelper +import com.kunzisoft.keepass.activities.helpers.ExternalFileHelper import com.kunzisoft.keepass.activities.helpers.SpecialMode import com.kunzisoft.keepass.activities.lock.LockingActivity import com.kunzisoft.keepass.activities.lock.resetAppTimeoutWhenViewFocusedOrChanged @@ -93,6 +94,8 @@ class EntryActivity : LockingActivity() { private var clipboardHelper: ClipboardHelper? = null private var mFirstLaunchOfActivity: Boolean = false + private var mExternalFileHelper: ExternalFileHelper? = null + private var iconColor: Int = 0 override fun onCreate(savedInstanceState: Bundle?) { @@ -140,6 +143,9 @@ class EntryActivity : LockingActivity() { clipboardHelper = ClipboardHelper(this) mFirstLaunchOfActivity = savedInstanceState?.getBoolean(KEY_FIRST_LAUNCH_ACTIVITY) ?: true + // Init SAF manager + mExternalFileHelper = ExternalFileHelper(this) + // Init attachment service binder manager mAttachmentFileBinderManager = AttachmentFileBinderManager(this) @@ -344,7 +350,7 @@ class EntryActivity : LockingActivity() { // Manage attachments entryContentsView?.assignAttachments(entryInfo.attachments.toSet(), StreamDirection.DOWNLOAD) { attachmentItem -> - createDocument(this, attachmentItem.name)?.let { requestCode -> + mExternalFileHelper?.createDocument(attachmentItem.name)?.let { requestCode -> mAttachmentsToDownload[requestCode] = attachmentItem } } @@ -380,7 +386,7 @@ class EntryActivity : LockingActivity() { } } - onCreateDocumentResult(requestCode, resultCode, data) { createdFileUri -> + mExternalFileHelper?.onCreateDocumentResult(requestCode, resultCode, data) { createdFileUri -> if (createdFileUri != null) { mAttachmentsToDownload[requestCode]?.let { attachmentToDownload -> mAttachmentFileBinderManager diff --git a/app/src/main/java/com/kunzisoft/keepass/activities/EntryEditActivity.kt b/app/src/main/java/com/kunzisoft/keepass/activities/EntryEditActivity.kt index d5d2dd9f8..3661cf08a 100644 --- a/app/src/main/java/com/kunzisoft/keepass/activities/EntryEditActivity.kt +++ b/app/src/main/java/com/kunzisoft/keepass/activities/EntryEditActivity.kt @@ -45,7 +45,7 @@ import com.kunzisoft.keepass.activities.dialogs.* import com.kunzisoft.keepass.activities.dialogs.FileTooBigDialogFragment.Companion.MAX_WARNING_BINARY_FILE import com.kunzisoft.keepass.activities.fragments.EntryEditFragment import com.kunzisoft.keepass.activities.helpers.EntrySelectionHelper -import com.kunzisoft.keepass.activities.helpers.SelectFileHelper +import com.kunzisoft.keepass.activities.helpers.ExternalFileHelper import com.kunzisoft.keepass.activities.lock.LockingActivity import com.kunzisoft.keepass.activities.lock.resetAppTimeoutWhenViewFocusedOrChanged import com.kunzisoft.keepass.autofill.AutofillComponent @@ -103,7 +103,7 @@ class EntryEditActivity : LockingActivity(), private var lockView: View? = null // To manage attachments - private var mSelectFileHelper: SelectFileHelper? = null + private var mExternalFileHelper: ExternalFileHelper? = null private var mAttachmentFileBinderManager: AttachmentFileBinderManager? = null private var mAllowMultipleAttachments: Boolean = false private var mTempAttachments = ArrayList() @@ -241,7 +241,7 @@ class EntryEditActivity : LockingActivity(), } // To retrieve attachment - mSelectFileHelper = SelectFileHelper(this) + mExternalFileHelper = ExternalFileHelper(this) mAttachmentFileBinderManager = AttachmentFileBinderManager(this) // Save button @@ -459,7 +459,7 @@ class EntryEditActivity : LockingActivity(), * Add a new attachment */ private fun addNewAttachment(item: MenuItem) { - mSelectFileHelper?.selectFileOnClickViewListener?.onMenuItemClick(item) + mExternalFileHelper?.selectFileOnClickViewListener?.onMenuItemClick(item) } override fun onValidateUploadFileTooBig(attachmentToUploadUri: Uri?, fileName: String?) { @@ -505,7 +505,7 @@ class EntryEditActivity : LockingActivity(), entryEditFragment?.icon = icon } - mSelectFileHelper?.onActivityResultCallback(requestCode, resultCode, data) { uri -> + mExternalFileHelper?.onActivityResultCallback(requestCode, resultCode, data) { uri -> uri?.let { attachmentToUploadUri -> UriUtil.getFileData(this, attachmentToUploadUri)?.also { documentFile -> documentFile.name?.let { fileName -> @@ -655,7 +655,7 @@ class EntryEditActivity : LockingActivity(), && entryEditActivityEducation.checkAndPerformedAttachmentEducation( attachmentView, { - mSelectFileHelper?.selectFileOnClickViewListener?.onClick(attachmentView) + mExternalFileHelper?.selectFileOnClickViewListener?.onClick(attachmentView) }, { performedNextEducation(entryEditActivityEducation) diff --git a/app/src/main/java/com/kunzisoft/keepass/activities/FileDatabaseSelectActivity.kt b/app/src/main/java/com/kunzisoft/keepass/activities/FileDatabaseSelectActivity.kt index 83dd275b1..56a31d432 100644 --- a/app/src/main/java/com/kunzisoft/keepass/activities/FileDatabaseSelectActivity.kt +++ b/app/src/main/java/com/kunzisoft/keepass/activities/FileDatabaseSelectActivity.kt @@ -42,7 +42,7 @@ import com.google.android.material.snackbar.Snackbar import com.kunzisoft.keepass.R import com.kunzisoft.keepass.activities.dialogs.AssignMasterKeyDialogFragment import com.kunzisoft.keepass.activities.helpers.EntrySelectionHelper -import com.kunzisoft.keepass.activities.helpers.SelectFileHelper +import com.kunzisoft.keepass.activities.helpers.ExternalFileHelper import com.kunzisoft.keepass.activities.helpers.SpecialMode import com.kunzisoft.keepass.activities.selection.SpecialModeActivity import com.kunzisoft.keepass.adapters.FileDatabaseHistoryAdapter @@ -82,7 +82,7 @@ class FileDatabaseSelectActivity : SpecialModeActivity(), private var mDatabaseFileUri: Uri? = null - private var mSelectFileHelper: SelectFileHelper? = null + private var mExternalFileHelper: ExternalFileHelper? = null private var mProgressDatabaseTaskProvider: ProgressDatabaseTaskProvider? = null @@ -103,10 +103,10 @@ class FileDatabaseSelectActivity : SpecialModeActivity(), createDatabaseButtonView?.setOnClickListener { createNewFile() } // Open database button - mSelectFileHelper = SelectFileHelper(this) + mExternalFileHelper = ExternalFileHelper(this) openDatabaseButtonView = findViewById(R.id.open_keyfile_button) openDatabaseButtonView?.apply { - mSelectFileHelper?.selectFileOnClickViewListener?.let { + mExternalFileHelper?.selectFileOnClickViewListener?.let { setOnClickListener(it) setOnLongClickListener(it) } @@ -234,7 +234,7 @@ class FileDatabaseSelectActivity : SpecialModeActivity(), * Create a new file by calling the content provider */ private fun createNewFile() { - createDocument(this, getString(R.string.database_file_name_default) + + mExternalFileHelper?.createDocument( getString(R.string.database_file_name_default) + getString(R.string.database_file_extension_default), "application/x-keepass") } @@ -286,7 +286,7 @@ class FileDatabaseSelectActivity : SpecialModeActivity(), // Show open and create button or special mode when (mSpecialMode) { SpecialMode.DEFAULT -> { - if (allowCreateDocumentByStorageAccessFramework(packageManager)) { + if (ExternalFileHelper.allowCreateDocumentByStorageAccessFramework(packageManager)) { // There is an activity which can handle this intent. createDatabaseButtonView?.visibility = View.VISIBLE } else{ @@ -359,14 +359,14 @@ class FileDatabaseSelectActivity : SpecialModeActivity(), AutofillHelper.onActivityResultSetResultAndFinish(this, requestCode, resultCode, data) } - mSelectFileHelper?.onActivityResultCallback(requestCode, resultCode, data) { uri -> + mExternalFileHelper?.onActivityResultCallback(requestCode, resultCode, data) { uri -> if (uri != null) { launchPasswordActivityWithPath(uri) } } // Retrieve the created URI from the file manager - onCreateDocumentResult(requestCode, resultCode, data) { databaseFileCreatedUri -> + mExternalFileHelper?.onCreateDocumentResult(requestCode, resultCode, data) { databaseFileCreatedUri -> mDatabaseFileUri = databaseFileCreatedUri if (mDatabaseFileUri != null) { AssignMasterKeyDialogFragment.getInstance(true) @@ -414,7 +414,7 @@ class FileDatabaseSelectActivity : SpecialModeActivity(), openDatabaseButtonView!!, {tapTargetView -> tapTargetView?.let { - mSelectFileHelper?.selectFileOnClickViewListener?.onClick(it) + mExternalFileHelper?.selectFileOnClickViewListener?.onClick(it) } }, {} diff --git a/app/src/main/java/com/kunzisoft/keepass/activities/IconPickerActivity.kt b/app/src/main/java/com/kunzisoft/keepass/activities/IconPickerActivity.kt index 1cd3e76ea..939bc5b75 100644 --- a/app/src/main/java/com/kunzisoft/keepass/activities/IconPickerActivity.kt +++ b/app/src/main/java/com/kunzisoft/keepass/activities/IconPickerActivity.kt @@ -34,7 +34,7 @@ import androidx.fragment.app.commit import com.google.android.material.snackbar.Snackbar import com.kunzisoft.keepass.R import com.kunzisoft.keepass.activities.fragments.IconPickerFragment -import com.kunzisoft.keepass.activities.helpers.SelectFileHelper +import com.kunzisoft.keepass.activities.helpers.ExternalFileHelper import com.kunzisoft.keepass.activities.lock.LockingActivity import com.kunzisoft.keepass.activities.lock.resetAppTimeoutWhenViewFocusedOrChanged import com.kunzisoft.keepass.database.element.Database @@ -66,7 +66,7 @@ class IconPickerActivity : LockingActivity() { private var mDatabase: Database? = null - private var mSelectFileHelper: SelectFileHelper? = null + private var mExternalFileHelper: ExternalFileHelper? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -87,10 +87,10 @@ class IconPickerActivity : LockingActivity() { uploadButton = findViewById(R.id.icon_picker_upload) if (mDatabase?.allowCustomIcons == true) { uploadButton.setOnClickListener { - mSelectFileHelper?.selectFileOnClickViewListener?.onClick(it) + mExternalFileHelper?.selectFileOnClickViewListener?.onClick(it) } uploadButton.setOnLongClickListener { - mSelectFileHelper?.selectFileOnClickViewListener?.onLongClick(it) + mExternalFileHelper?.selectFileOnClickViewListener?.onLongClick(it) true } } else { @@ -124,7 +124,7 @@ class IconPickerActivity : LockingActivity() { // Focus view to reinitialize timeout findViewById(R.id.icon_picker_container)?.resetAppTimeoutWhenViewFocusedOrChanged(this) - mSelectFileHelper = SelectFileHelper(this) + mExternalFileHelper = ExternalFileHelper(this) iconPickerViewModel.standardIconPicked.observe(this) { iconStandard -> mIconImage.standard = iconStandard @@ -281,7 +281,7 @@ class IconPickerActivity : LockingActivity() { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) - mSelectFileHelper?.onActivityResultCallback(requestCode, resultCode, data) { uri -> + mExternalFileHelper?.onActivityResultCallback(requestCode, resultCode, data) { uri -> addCustomIcon(uri) } } diff --git a/app/src/main/java/com/kunzisoft/keepass/activities/PasswordActivity.kt b/app/src/main/java/com/kunzisoft/keepass/activities/PasswordActivity.kt index df62f36b5..7b497854e 100644 --- a/app/src/main/java/com/kunzisoft/keepass/activities/PasswordActivity.kt +++ b/app/src/main/java/com/kunzisoft/keepass/activities/PasswordActivity.kt @@ -44,7 +44,7 @@ import com.kunzisoft.keepass.R import com.kunzisoft.keepass.activities.dialogs.DuplicateUuidDialog import com.kunzisoft.keepass.activities.helpers.EntrySelectionHelper import com.kunzisoft.keepass.activities.helpers.ReadOnlyHelper -import com.kunzisoft.keepass.activities.helpers.SelectFileHelper +import com.kunzisoft.keepass.activities.helpers.ExternalFileHelper import com.kunzisoft.keepass.activities.helpers.SpecialMode import com.kunzisoft.keepass.activities.lock.LockingActivity import com.kunzisoft.keepass.activities.selection.SpecialModeActivity @@ -95,7 +95,7 @@ open class PasswordActivity : SpecialModeActivity(), AdvancedUnlockFragment.Buil private var mDatabaseKeyFileUri: Uri? = null private var mRememberKeyFile: Boolean = false - private var mSelectFileHelper: SelectFileHelper? = null + private var mExternalFileHelper: ExternalFileHelper? = null private var mPermissionAsked = false private var readOnly: Boolean = false @@ -138,9 +138,9 @@ open class PasswordActivity : SpecialModeActivity(), AdvancedUnlockFragment.Buil readOnly = ReadOnlyHelper.retrieveReadOnlyFromInstanceStateOrPreference(this, savedInstanceState) mRememberKeyFile = PreferencesUtil.rememberKeyFileLocations(this) - mSelectFileHelper = SelectFileHelper(this@PasswordActivity) + mExternalFileHelper = ExternalFileHelper(this@PasswordActivity) keyFileSelectionView?.apply { - mSelectFileHelper?.selectFileOnClickViewListener?.let { + mExternalFileHelper?.selectFileOnClickViewListener?.let { setOnClickListener(it) setOnLongClickListener(it) } @@ -702,7 +702,7 @@ open class PasswordActivity : SpecialModeActivity(), AdvancedUnlockFragment.Buil } var keyFileResult = false - mSelectFileHelper?.let { + mExternalFileHelper?.let { keyFileResult = it.onActivityResultCallback(requestCode, resultCode, data ) { uri -> if (uri != null) { diff --git a/app/src/main/java/com/kunzisoft/keepass/activities/dialogs/AssignMasterKeyDialogFragment.kt b/app/src/main/java/com/kunzisoft/keepass/activities/dialogs/AssignMasterKeyDialogFragment.kt index b9a857688..cba487782 100644 --- a/app/src/main/java/com/kunzisoft/keepass/activities/dialogs/AssignMasterKeyDialogFragment.kt +++ b/app/src/main/java/com/kunzisoft/keepass/activities/dialogs/AssignMasterKeyDialogFragment.kt @@ -30,13 +30,12 @@ import android.text.SpannableStringBuilder import android.text.TextWatcher import android.view.View import android.widget.CompoundButton -import android.widget.ImageView import android.widget.TextView import androidx.appcompat.app.AlertDialog import androidx.fragment.app.DialogFragment import com.google.android.material.textfield.TextInputLayout import com.kunzisoft.keepass.R -import com.kunzisoft.keepass.activities.helpers.SelectFileHelper +import com.kunzisoft.keepass.activities.helpers.ExternalFileHelper import com.kunzisoft.keepass.model.MainCredential import com.kunzisoft.keepass.utils.UriUtil import com.kunzisoft.keepass.view.KeyFileSelectionView @@ -60,7 +59,7 @@ class AssignMasterKeyDialogFragment : DialogFragment() { private var mListener: AssignPasswordDialogListener? = null - private var mSelectFileHelper: SelectFileHelper? = null + private var mExternalFileHelper: ExternalFileHelper? = null private var mEmptyPasswordConfirmationDialog: AlertDialog? = null private var mNoKeyConfirmationDialog: AlertDialog? = null @@ -133,10 +132,10 @@ class AssignMasterKeyDialogFragment : DialogFragment() { keyFileCheckBox = rootView?.findViewById(R.id.keyfile_checkox) keyFileSelectionView = rootView?.findViewById(R.id.keyfile_selection) - mSelectFileHelper = SelectFileHelper(this) + mExternalFileHelper = ExternalFileHelper(this) keyFileSelectionView?.apply { - setOnClickListener(mSelectFileHelper?.selectFileOnClickViewListener) - setOnLongClickListener(mSelectFileHelper?.selectFileOnClickViewListener) + setOnClickListener(mExternalFileHelper?.selectFileOnClickViewListener) + setOnLongClickListener(mExternalFileHelper?.selectFileOnClickViewListener) } val dialog = builder.create() @@ -289,7 +288,7 @@ class AssignMasterKeyDialogFragment : DialogFragment() { override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) - mSelectFileHelper?.onActivityResultCallback(requestCode, resultCode, data) { uri -> + mExternalFileHelper?.onActivityResultCallback(requestCode, resultCode, data) { uri -> uri?.let { pathUri -> UriUtil.getFileData(requireContext(), uri)?.length()?.let { lengthFile -> keyFileSelectionView?.error = null diff --git a/app/src/main/java/com/kunzisoft/keepass/activities/helpers/SelectFileHelper.kt b/app/src/main/java/com/kunzisoft/keepass/activities/helpers/ExternalFileHelper.kt similarity index 71% rename from app/src/main/java/com/kunzisoft/keepass/activities/helpers/SelectFileHelper.kt rename to app/src/main/java/com/kunzisoft/keepass/activities/helpers/ExternalFileHelper.kt index eca32bd60..0fcbc5a65 100644 --- a/app/src/main/java/com/kunzisoft/keepass/activities/helpers/SelectFileHelper.kt +++ b/app/src/main/java/com/kunzisoft/keepass/activities/helpers/ExternalFileHelper.kt @@ -20,7 +20,6 @@ package com.kunzisoft.keepass.activities.helpers import android.annotation.SuppressLint -import android.app.Activity import android.app.Activity.RESULT_OK import android.content.Context import android.content.Intent @@ -35,15 +34,15 @@ import androidx.fragment.app.FragmentActivity import com.kunzisoft.keepass.activities.dialogs.FileManagerDialogFragment import com.kunzisoft.keepass.utils.UriUtil -class SelectFileHelper { +class ExternalFileHelper { - private var activity: Activity? = null + private var activity: FragmentActivity? = null private var fragment: Fragment? = null val selectFileOnClickViewListener: SelectFileOnClickViewListener get() = SelectFileOnClickViewListener() - constructor(context: Activity) { + constructor(context: FragmentActivity) { this.activity = context this.fragment = null } @@ -60,18 +59,10 @@ class SelectFileHelper { private fun onAbstractClick(longClick: Boolean = false) { try { - if (longClick) { - try { - openActivityWithActionGetContent() - } catch (e: Exception) { - openActivityWithActionOpenDocument() - } - } else { - try { - openActivityWithActionOpenDocument() - } catch (e: Exception) { - openActivityWithActionGetContent() - } + try { + openDocument(longClick) + } catch (e: Exception) { + openDocument(!longClick) } } catch (e: Exception) { Log.e(TAG, "Enable to start the file picker activity", e) @@ -96,6 +87,14 @@ class SelectFileHelper { } } + fun openDocument(getContent: Boolean) { + if (getContent) { + openActivityWithActionGetContent() + } else { + openActivityWithActionOpenDocument() + } + } + @SuppressLint("InlinedApi") private fun openActivityWithActionOpenDocument() { val intentOpenDocument = Intent(Intent.ACTION_OPEN_DOCUMENT).apply { @@ -187,10 +186,7 @@ class SelectFileHelper { * @param keyFileCallback Callback retrieve from data * @return true if requestCode was captured, false elsechere */ - fun onActivityResultCallback( - requestCode: Int, - resultCode: Int, - data: Intent?, + fun onActivityResultCallback(requestCode: Int, resultCode: Int, data: Intent?, keyFileCallback: ((uri: Uri?) -> Unit)?): Boolean { when (requestCode) { @@ -231,6 +227,50 @@ class SelectFileHelper { return false } + private fun showFileManagerDialogFragment() { + if (fragment != null) { + fragment?.parentFragmentManager + } else { + activity?.supportFragmentManager + }?.let { fragmentManager -> + FileManagerDialogFragment().show(fragmentManager, "browserDialog") + } + } + + fun createDocument(titleString: String, + typeString: String = "application/octet-stream"): Int? { + + val idCode = getUnusedCreateFileRequestCode() + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + try { + val intent = Intent(Intent.ACTION_CREATE_DOCUMENT).apply { + addCategory(Intent.CATEGORY_OPENABLE) + type = typeString + putExtra(Intent.EXTRA_TITLE, titleString) + } + if (fragment != null) + fragment?.startActivityForResult(intent, idCode) + else + activity?.startActivityForResult(intent, idCode) + return idCode + } catch (e: Exception) { + showFileManagerDialogFragment() + } + } else { + showFileManagerDialogFragment() + } + return null + } + + fun onCreateDocumentResult(requestCode: Int, resultCode: Int, data: Intent?, + action: (fileCreated: Uri?)->Unit) { + // Retrieve the created URI from the file manager + if (fileRequestCodes.contains(requestCode) && resultCode == RESULT_OK) { + action.invoke(data?.data) + fileRequestCodes.remove(requestCode) + } + } + companion object { private const val TAG = "OpenFileHelper" @@ -240,5 +280,28 @@ class SelectFileHelper { private const val GET_CONTENT = 25745 private const val OPEN_DOC = 25845 private const val FILE_BROWSE = 25645 + + private var CREATE_FILE_REQUEST_CODE_DEFAULT = 3853 + private var fileRequestCodes = ArrayList() + + private fun getUnusedCreateFileRequestCode(): Int { + val newCreateFileRequestCode = CREATE_FILE_REQUEST_CODE_DEFAULT++ + fileRequestCodes.add(newCreateFileRequestCode) + return newCreateFileRequestCode + } + + @SuppressLint("InlinedApi") + fun allowCreateDocumentByStorageAccessFramework(packageManager: PackageManager): Boolean { + return when { + // To check if a custom file manager can manage the ACTION_CREATE_DOCUMENT + Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT -> { + packageManager.queryIntentActivities(Intent(Intent.ACTION_CREATE_DOCUMENT).apply { + addCategory(Intent.CATEGORY_OPENABLE) + type = "application/x-keepass" + }, PackageManager.MATCH_DEFAULT_ONLY).isNotEmpty() + } + else -> true + } + } } } diff --git a/app/src/main/java/com/kunzisoft/keepass/utils/ExternalFileManager.kt b/app/src/main/java/com/kunzisoft/keepass/utils/ExternalFileManager.kt deleted file mode 100644 index c42d25127..000000000 --- a/app/src/main/java/com/kunzisoft/keepass/utils/ExternalFileManager.kt +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2019 Jeremy Jamet / Kunzisoft. - * - * This file is part of KeePassDX. - * - * KeePassDX is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * KeePassDX is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with KeePassDX. If not, see . - * - */ -package com.kunzisoft.keepass.utils - -import android.annotation.SuppressLint -import android.app.Activity -import android.content.Intent -import android.content.pm.PackageManager -import android.net.Uri -import android.os.Build -import androidx.fragment.app.FragmentActivity -import com.kunzisoft.keepass.activities.dialogs.FileManagerDialogFragment - - -private var CREATE_FILE_REQUEST_CODE_DEFAULT = 3853 -private var fileRequestCodes = ArrayList() - -fun getUnusedCreateFileRequestCode(): Int { - val newCreateFileRequestCode = CREATE_FILE_REQUEST_CODE_DEFAULT++ - fileRequestCodes.add(newCreateFileRequestCode) - return newCreateFileRequestCode -} - -@SuppressLint("InlinedApi") -fun allowCreateDocumentByStorageAccessFramework(packageManager: PackageManager): Boolean { - return when { - // To check if a custom file manager can manage the ACTION_CREATE_DOCUMENT - Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT -> { - packageManager.queryIntentActivities(Intent(Intent.ACTION_CREATE_DOCUMENT).apply { - addCategory(Intent.CATEGORY_OPENABLE) - type = "application/x-keepass" - }, PackageManager.MATCH_DEFAULT_ONLY).isNotEmpty() - } - else -> true - } -} - -fun createDocument(activity: FragmentActivity, - titleString: String, - typeString: String = "application/octet-stream"): Int? { - - val idCode = getUnusedCreateFileRequestCode() - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { - try { - activity.startActivityForResult(Intent(Intent.ACTION_CREATE_DOCUMENT).apply { - addCategory(Intent.CATEGORY_OPENABLE) - type = typeString - putExtra(Intent.EXTRA_TITLE, titleString) - }, idCode) - return idCode - } catch (e: Exception) { - FileManagerDialogFragment().show(activity.supportFragmentManager, "browserDialog") - } - } else { - FileManagerDialogFragment().show(activity.supportFragmentManager, "browserDialog") - } - - return null -} - -fun onCreateDocumentResult(requestCode: Int, resultCode: Int, data: Intent?, - action: (fileCreated: Uri?)->Unit) { - // Retrieve the created URI from the file manager - if (fileRequestCodes.contains(requestCode) && resultCode == Activity.RESULT_OK) { - action.invoke(data?.data) - fileRequestCodes.remove(requestCode) - } -} \ No newline at end of file