Merge pull request #1036 from esensar/move-migrations-settings

Move migrations into app settings
This commit is contained in:
Tibor Kaputa 2023-09-27 09:26:31 +02:00 committed by GitHub
commit 6472e3e14c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 203 additions and 159 deletions

View File

@ -1,22 +1,18 @@
package com.simplemobiletools.contacts.pro.activities package com.simplemobiletools.contacts.pro.activities
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.app.Activity
import android.content.ActivityNotFoundException import android.content.ActivityNotFoundException
import android.content.Intent import android.content.Intent
import android.content.pm.ShortcutInfo import android.content.pm.ShortcutInfo
import android.graphics.drawable.ColorDrawable import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Icon import android.graphics.drawable.Icon
import android.graphics.drawable.LayerDrawable import android.graphics.drawable.LayerDrawable
import android.net.Uri
import android.os.Bundle import android.os.Bundle
import android.widget.Toast
import androidx.viewpager.widget.ViewPager import androidx.viewpager.widget.ViewPager
import com.simplemobiletools.commons.databases.ContactsDatabase import com.simplemobiletools.commons.databases.ContactsDatabase
import com.simplemobiletools.commons.databinding.BottomTablayoutItemBinding import com.simplemobiletools.commons.databinding.BottomTablayoutItemBinding
import com.simplemobiletools.commons.dialogs.ChangeViewTypeDialog import com.simplemobiletools.commons.dialogs.ChangeViewTypeDialog
import com.simplemobiletools.commons.dialogs.ConfirmationDialog import com.simplemobiletools.commons.dialogs.ConfirmationDialog
import com.simplemobiletools.commons.dialogs.FilePickerDialog
import com.simplemobiletools.commons.dialogs.RadioGroupDialog import com.simplemobiletools.commons.dialogs.RadioGroupDialog
import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.* import com.simplemobiletools.commons.helpers.*
@ -29,32 +25,22 @@ import com.simplemobiletools.contacts.pro.R
import com.simplemobiletools.contacts.pro.adapters.ViewPagerAdapter import com.simplemobiletools.contacts.pro.adapters.ViewPagerAdapter
import com.simplemobiletools.contacts.pro.databinding.ActivityMainBinding import com.simplemobiletools.contacts.pro.databinding.ActivityMainBinding
import com.simplemobiletools.contacts.pro.dialogs.ChangeSortingDialog import com.simplemobiletools.contacts.pro.dialogs.ChangeSortingDialog
import com.simplemobiletools.contacts.pro.dialogs.ExportContactsDialog
import com.simplemobiletools.contacts.pro.dialogs.FilterContactSourcesDialog import com.simplemobiletools.contacts.pro.dialogs.FilterContactSourcesDialog
import com.simplemobiletools.contacts.pro.dialogs.ImportContactsDialog
import com.simplemobiletools.contacts.pro.extensions.config import com.simplemobiletools.contacts.pro.extensions.config
import com.simplemobiletools.contacts.pro.extensions.handleGenericContactClick import com.simplemobiletools.contacts.pro.extensions.handleGenericContactClick
import com.simplemobiletools.contacts.pro.extensions.tryImportContactsFromFile
import com.simplemobiletools.contacts.pro.fragments.FavoritesFragment import com.simplemobiletools.contacts.pro.fragments.FavoritesFragment
import com.simplemobiletools.contacts.pro.fragments.MyViewPagerFragment import com.simplemobiletools.contacts.pro.fragments.MyViewPagerFragment
import com.simplemobiletools.contacts.pro.helpers.ALL_TABS_MASK import com.simplemobiletools.contacts.pro.helpers.ALL_TABS_MASK
import com.simplemobiletools.contacts.pro.helpers.VcfExporter
import com.simplemobiletools.contacts.pro.helpers.tabsList import com.simplemobiletools.contacts.pro.helpers.tabsList
import com.simplemobiletools.contacts.pro.interfaces.RefreshContactsListener import com.simplemobiletools.contacts.pro.interfaces.RefreshContactsListener
import me.grantland.widget.AutofitHelper import me.grantland.widget.AutofitHelper
import java.io.FileOutputStream
import java.io.OutputStream
import java.util.* import java.util.*
class MainActivity : SimpleActivity(), RefreshContactsListener { class MainActivity : SimpleActivity(), RefreshContactsListener {
companion object {
private const val PICK_IMPORT_SOURCE_INTENT = 1
private const val PICK_EXPORT_FILE_INTENT = 2
}
private var werePermissionsHandled = false private var werePermissionsHandled = false
private var isFirstResume = true private var isFirstResume = true
private var isGettingContacts = false private var isGettingContacts = false
private var ignoredExportContactSources = HashSet<String>()
private var storedShowContactThumbnails = false private var storedShowContactThumbnails = false
private var storedShowPhoneNumbers = false private var storedShowPhoneNumbers = false
@ -173,20 +159,6 @@ class MainActivity : SimpleActivity(), RefreshContactsListener {
} }
} }
override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) {
super.onActivityResult(requestCode, resultCode, resultData)
if (requestCode == PICK_IMPORT_SOURCE_INTENT && resultCode == Activity.RESULT_OK && resultData?.data != null) {
tryImportContactsFromFile(resultData.data!!)
} else if (requestCode == PICK_EXPORT_FILE_INTENT && resultCode == Activity.RESULT_OK && resultData?.data != null) {
try {
val outputStream = contentResolver.openOutputStream(resultData.data!!)
exportContactsTo(ignoredExportContactSources, outputStream)
} catch (e: Exception) {
showErrorToast(e)
}
}
}
override fun onBackPressed() { override fun onBackPressed() {
if (binding.mainMenu.isSearchOpen) { if (binding.mainMenu.isSearchOpen) {
binding.mainMenu.closeSearch() binding.mainMenu.closeSearch()
@ -227,8 +199,6 @@ class MainActivity : SimpleActivity(), RefreshContactsListener {
R.id.sort -> showSortingDialog(showCustomSorting = getCurrentFragment() is FavoritesFragment) R.id.sort -> showSortingDialog(showCustomSorting = getCurrentFragment() is FavoritesFragment)
R.id.filter -> showFilterDialog() R.id.filter -> showFilterDialog()
R.id.dialpad -> launchDialpad() R.id.dialpad -> launchDialpad()
R.id.import_contacts -> tryImportContacts()
R.id.export_contacts -> tryExportContacts()
R.id.more_apps_from_us -> launchMoreAppsFromUsIntent() R.id.more_apps_from_us -> launchMoreAppsFromUsIntent()
R.id.change_view_type -> changeViewType() R.id.change_view_type -> changeViewType()
R.id.column_count -> changeColumnCount() R.id.column_count -> changeColumnCount()
@ -403,7 +373,13 @@ class MainActivity : SimpleActivity(), RefreshContactsListener {
} }
if (intent?.action == Intent.ACTION_VIEW && intent.data != null) { if (intent?.action == Intent.ACTION_VIEW && intent.data != null) {
tryImportContactsFromFile(intent.data!!) tryImportContactsFromFile(intent.data!!) {
if (it) {
runOnUiThread {
refreshContacts(ALL_TABS_MASK)
}
}
}
intent.data = null intent.data = null
} }
@ -469,119 +445,6 @@ class MainActivity : SimpleActivity(), RefreshContactsListener {
} }
} }
private fun tryImportContacts() {
if (isQPlus()) {
Intent(Intent.ACTION_GET_CONTENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = "text/x-vcard"
try {
startActivityForResult(this, PICK_IMPORT_SOURCE_INTENT)
} catch (e: ActivityNotFoundException) {
toast(com.simplemobiletools.commons.R.string.system_service_disabled, Toast.LENGTH_LONG)
} catch (e: Exception) {
showErrorToast(e)
}
}
} else {
handlePermission(PERMISSION_READ_STORAGE) {
if (it) {
importContacts()
}
}
}
}
private fun importContacts() {
FilePickerDialog(this) {
showImportContactsDialog(it)
}
}
private fun showImportContactsDialog(path: String) {
ImportContactsDialog(this, path) {
if (it) {
runOnUiThread {
refreshContacts(ALL_TABS_MASK)
}
}
}
}
private fun tryImportContactsFromFile(uri: Uri) {
when {
uri.scheme == "file" -> showImportContactsDialog(uri.path!!)
uri.scheme == "content" -> {
val tempFile = getTempFile()
if (tempFile == null) {
toast(com.simplemobiletools.commons.R.string.unknown_error_occurred)
return
}
try {
val inputStream = contentResolver.openInputStream(uri)
val out = FileOutputStream(tempFile)
inputStream!!.copyTo(out)
showImportContactsDialog(tempFile.absolutePath)
} catch (e: Exception) {
showErrorToast(e)
}
}
else -> toast(com.simplemobiletools.commons.R.string.invalid_file_format)
}
}
private fun tryExportContacts() {
if (isQPlus()) {
ExportContactsDialog(this, config.lastExportPath, true) { file, ignoredContactSources ->
ignoredExportContactSources = ignoredContactSources
Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
type = "text/x-vcard"
putExtra(Intent.EXTRA_TITLE, file.name)
addCategory(Intent.CATEGORY_OPENABLE)
try {
startActivityForResult(this, PICK_EXPORT_FILE_INTENT)
} catch (e: ActivityNotFoundException) {
toast(com.simplemobiletools.commons.R.string.no_app_found, Toast.LENGTH_LONG)
} catch (e: Exception) {
showErrorToast(e)
}
}
}
} else {
handlePermission(PERMISSION_WRITE_STORAGE) {
if (it) {
ExportContactsDialog(this, config.lastExportPath, false) { file, ignoredContactSources ->
getFileOutputStream(file.toFileDirItem(this), true) {
exportContactsTo(ignoredContactSources, it)
}
}
}
}
}
}
private fun exportContactsTo(ignoredContactSources: HashSet<String>, outputStream: OutputStream?) {
ContactsHelper(this).getContacts(true, false, ignoredContactSources) { contacts ->
if (contacts.isEmpty()) {
toast(com.simplemobiletools.commons.R.string.no_entries_for_exporting)
} else {
VcfExporter().exportContacts(this, outputStream, contacts, true) { result ->
toast(
when (result) {
VcfExporter.ExportResult.EXPORT_OK -> com.simplemobiletools.commons.R.string.exporting_successful
VcfExporter.ExportResult.EXPORT_PARTIAL -> com.simplemobiletools.commons.R.string.exporting_some_entries_failed
else -> com.simplemobiletools.commons.R.string.exporting_failed
}
)
}
}
}
}
private fun launchSettings() { private fun launchSettings() {
hideKeyboard() hideKeyboard()
startActivity(Intent(applicationContext, SettingsActivity::class.java)) startActivity(Intent(applicationContext, SettingsActivity::class.java))

View File

@ -1,25 +1,37 @@
package com.simplemobiletools.contacts.pro.activities package com.simplemobiletools.contacts.pro.activities
import android.app.Activity
import android.content.ActivityNotFoundException
import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.widget.Toast
import com.simplemobiletools.commons.dialogs.FilePickerDialog
import com.simplemobiletools.commons.dialogs.RadioGroupDialog import com.simplemobiletools.commons.dialogs.RadioGroupDialog
import com.simplemobiletools.commons.extensions.* import com.simplemobiletools.commons.extensions.*
import com.simplemobiletools.commons.helpers.* import com.simplemobiletools.commons.helpers.*
import com.simplemobiletools.commons.models.RadioItem import com.simplemobiletools.commons.models.RadioItem
import com.simplemobiletools.contacts.pro.R import com.simplemobiletools.contacts.pro.R
import com.simplemobiletools.contacts.pro.databinding.ActivitySettingsBinding import com.simplemobiletools.contacts.pro.databinding.ActivitySettingsBinding
import com.simplemobiletools.contacts.pro.dialogs.ExportContactsDialog
import com.simplemobiletools.contacts.pro.dialogs.ManageAutoBackupsDialog import com.simplemobiletools.contacts.pro.dialogs.ManageAutoBackupsDialog
import com.simplemobiletools.contacts.pro.dialogs.ManageVisibleFieldsDialog import com.simplemobiletools.contacts.pro.dialogs.ManageVisibleFieldsDialog
import com.simplemobiletools.contacts.pro.dialogs.ManageVisibleTabsDialog import com.simplemobiletools.contacts.pro.dialogs.ManageVisibleTabsDialog
import com.simplemobiletools.contacts.pro.extensions.cancelScheduledAutomaticBackup import com.simplemobiletools.contacts.pro.extensions.*
import com.simplemobiletools.contacts.pro.extensions.config import com.simplemobiletools.contacts.pro.helpers.VcfExporter
import com.simplemobiletools.contacts.pro.extensions.scheduleNextAutomaticBackup import java.io.OutputStream
import java.util.Locale import java.util.Locale
import kotlin.system.exitProcess import kotlin.system.exitProcess
class SettingsActivity : SimpleActivity() { class SettingsActivity : SimpleActivity() {
companion object {
private const val PICK_IMPORT_SOURCE_INTENT = 1
private const val PICK_EXPORT_FILE_INTENT = 2
}
private val binding by viewBinding(ActivitySettingsBinding::inflate) private val binding by viewBinding(ActivitySettingsBinding::inflate)
private var ignoredExportContactSources = HashSet<String>()
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
isMaterialActivity = true isMaterialActivity = true
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@ -50,6 +62,8 @@ class SettingsActivity : SimpleActivity() {
setupDefaultTab() setupDefaultTab()
setupEnableAutomaticBackups() setupEnableAutomaticBackups()
setupManageAutomaticBackups() setupManageAutomaticBackups()
setupExportContacts()
setupImportContacts()
updateTextColors(binding.settingsHolder) updateTextColors(binding.settingsHolder)
arrayOf( arrayOf(
@ -57,7 +71,8 @@ class SettingsActivity : SimpleActivity() {
binding.settingsGeneralSettingsLabel, binding.settingsGeneralSettingsLabel,
binding.settingsMainScreenLabel, binding.settingsMainScreenLabel,
binding.settingsListViewLabel, binding.settingsListViewLabel,
binding.settingsBackupsLabel binding.settingsBackupsLabel,
binding.settingsMigratingLabel
).forEach { ).forEach {
it.setTextColor(getProperPrimaryColor()) it.setTextColor(getProperPrimaryColor())
} }
@ -268,4 +283,109 @@ class SettingsActivity : SimpleActivity() {
binding.settingsEnableAutomaticBackups.isChecked = enable binding.settingsEnableAutomaticBackups.isChecked = enable
binding.settingsManageAutomaticBackupsHolder.beVisibleIf(enable) binding.settingsManageAutomaticBackupsHolder.beVisibleIf(enable)
} }
private fun setupExportContacts() {
binding.contactsExportHolder.setOnClickListener {
tryExportContacts()
}
}
private fun setupImportContacts() {
binding.contactsImportHolder.setOnClickListener {
tryImportContacts()
}
}
private fun tryImportContacts() {
if (isQPlus()) {
Intent(Intent.ACTION_GET_CONTENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = "text/x-vcard"
try {
startActivityForResult(this, PICK_IMPORT_SOURCE_INTENT)
} catch (e: ActivityNotFoundException) {
toast(com.simplemobiletools.commons.R.string.system_service_disabled, Toast.LENGTH_LONG)
} catch (e: Exception) {
showErrorToast(e)
}
}
} else {
handlePermission(PERMISSION_READ_STORAGE) {
if (it) {
importContacts()
}
}
}
}
private fun importContacts() {
FilePickerDialog(this) {
showImportContactsDialog(it) {}
}
}
private fun tryExportContacts() {
if (isQPlus()) {
ExportContactsDialog(this, config.lastExportPath, true) { file, ignoredContactSources ->
ignoredExportContactSources = ignoredContactSources
Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
type = "text/x-vcard"
putExtra(Intent.EXTRA_TITLE, file.name)
addCategory(Intent.CATEGORY_OPENABLE)
try {
startActivityForResult(this, PICK_EXPORT_FILE_INTENT)
} catch (e: ActivityNotFoundException) {
toast(com.simplemobiletools.commons.R.string.no_app_found, Toast.LENGTH_LONG)
} catch (e: Exception) {
showErrorToast(e)
}
}
}
} else {
handlePermission(PERMISSION_WRITE_STORAGE) {
if (it) {
ExportContactsDialog(this, config.lastExportPath, false) { file, ignoredContactSources ->
getFileOutputStream(file.toFileDirItem(this), true) {
exportContactsTo(ignoredContactSources, it)
}
}
}
}
}
}
private fun exportContactsTo(ignoredContactSources: HashSet<String>, outputStream: OutputStream?) {
ContactsHelper(this).getContacts(true, false, ignoredContactSources) { contacts ->
if (contacts.isEmpty()) {
toast(com.simplemobiletools.commons.R.string.no_entries_for_exporting)
} else {
VcfExporter().exportContacts(this, outputStream, contacts, true) { result ->
toast(
when (result) {
VcfExporter.ExportResult.EXPORT_OK -> com.simplemobiletools.commons.R.string.exporting_successful
VcfExporter.ExportResult.EXPORT_PARTIAL -> com.simplemobiletools.commons.R.string.exporting_some_entries_failed
else -> com.simplemobiletools.commons.R.string.exporting_failed
}
)
}
}
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) {
super.onActivityResult(requestCode, resultCode, resultData)
if (requestCode == PICK_IMPORT_SOURCE_INTENT && resultCode == Activity.RESULT_OK && resultData?.data != null) {
tryImportContactsFromFile(resultData.data!!) {}
} else if (requestCode == PICK_EXPORT_FILE_INTENT && resultCode == Activity.RESULT_OK && resultData?.data != null) {
try {
val outputStream = contentResolver.openOutputStream(resultData.data!!)
exportContactsTo(ignoredExportContactSources, outputStream)
} catch (e: Exception) {
showErrorToast(e)
}
}
}
} }

View File

@ -14,9 +14,11 @@ import com.simplemobiletools.contacts.pro.R
import com.simplemobiletools.contacts.pro.activities.EditContactActivity import com.simplemobiletools.contacts.pro.activities.EditContactActivity
import com.simplemobiletools.contacts.pro.activities.SimpleActivity import com.simplemobiletools.contacts.pro.activities.SimpleActivity
import com.simplemobiletools.contacts.pro.activities.ViewContactActivity import com.simplemobiletools.contacts.pro.activities.ViewContactActivity
import com.simplemobiletools.contacts.pro.dialogs.ImportContactsDialog
import com.simplemobiletools.contacts.pro.helpers.DEFAULT_FILE_NAME import com.simplemobiletools.contacts.pro.helpers.DEFAULT_FILE_NAME
import com.simplemobiletools.contacts.pro.helpers.VcfExporter import com.simplemobiletools.contacts.pro.helpers.VcfExporter
import ezvcard.VCardVersion import ezvcard.VCardVersion
import java.io.FileOutputStream
fun SimpleActivity.startCallIntent(recipient: String) { fun SimpleActivity.startCallIntent(recipient: String) {
handlePermission(PERMISSION_CALL_PHONE) { handlePermission(PERMISSION_CALL_PHONE) {
@ -110,3 +112,32 @@ fun Activity.editContact(contact: Contact) {
startActivity(this) startActivity(this)
} }
} }
fun SimpleActivity.tryImportContactsFromFile(uri: Uri, callback: (Boolean) -> Unit) {
when (uri.scheme) {
"file" -> showImportContactsDialog(uri.path!!, callback)
"content" -> {
val tempFile = getTempFile()
if (tempFile == null) {
toast(com.simplemobiletools.commons.R.string.unknown_error_occurred)
return
}
try {
val inputStream = contentResolver.openInputStream(uri)
val out = FileOutputStream(tempFile)
inputStream!!.copyTo(out)
showImportContactsDialog(tempFile.absolutePath, callback)
} catch (e: Exception) {
showErrorToast(e)
}
}
else -> toast(com.simplemobiletools.commons.R.string.invalid_file_format)
}
}
fun SimpleActivity.showImportContactsDialog(path: String, callback: (Boolean) -> Unit) {
ImportContactsDialog(this, path, callback)
}

View File

@ -383,6 +383,46 @@
</RelativeLayout> </RelativeLayout>
<include
android:id="@+id/settings_backups_divider"
layout="@layout/divider" />
<TextView
android:id="@+id/settings_migrating_label"
style="@style/SettingsSectionLabelStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/migrating" />
<RelativeLayout
android:id="@+id/contacts_export_holder"
style="@style/SettingsHolderTextViewOneLinerStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/contacts_export"
style="@style/SettingsTextLabelStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/export_contacts_to_vcf" />
</RelativeLayout>
<RelativeLayout
android:id="@+id/contacts_import_holder"
style="@style/SettingsHolderTextViewOneLinerStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.simplemobiletools.commons.views.MyTextView
android:id="@+id/contacts_import"
style="@style/SettingsTextLabelStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/import_contacts_from_vcf" />
</RelativeLayout>
</LinearLayout> </LinearLayout>
</androidx.core.widget.NestedScrollView> </androidx.core.widget.NestedScrollView>
</androidx.coordinatorlayout.widget.CoordinatorLayout> </androidx.coordinatorlayout.widget.CoordinatorLayout>

View File

@ -28,16 +28,6 @@
android:icon="@drawable/ic_column_count_vector" android:icon="@drawable/ic_column_count_vector"
android:title="@string/column_count" android:title="@string/column_count"
app:showAsAction="ifRoom" /> app:showAsAction="ifRoom" />
<item
android:id="@+id/import_contacts"
android:showAsAction="never"
android:title="@string/import_contacts_from_vcf"
app:showAsAction="never" />
<item
android:id="@+id/export_contacts"
android:showAsAction="never"
android:title="@string/export_contacts_to_vcf"
app:showAsAction="never" />
<item <item
android:id="@+id/settings" android:id="@+id/settings"
android:icon="@drawable/ic_settings_cog_vector" android:icon="@drawable/ic_settings_cog_vector"