From b54092cd9ba5db759010bd020bbb1723929b470b Mon Sep 17 00:00:00 2001 From: Patrick Schneider Date: Mon, 20 May 2024 21:13:32 +0200 Subject: [PATCH 01/15] Changes backupapp to targetSDK 34. --- BackupApp/src/main/AndroidManifest.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/BackupApp/src/main/AndroidManifest.xml b/BackupApp/src/main/AndroidManifest.xml index 3b89191..61c453b 100644 --- a/BackupApp/src/main/AndroidManifest.xml +++ b/BackupApp/src/main/AndroidManifest.xml @@ -12,6 +12,7 @@ + From 6858e3f1c94a4e43d8ddaada627eb513f70492e8 Mon Sep 17 00:00:00 2001 From: Patrick Schneider Date: Fri, 7 Jun 2024 13:43:35 +0200 Subject: [PATCH 02/15] [migration] updates to targetSDK 34 --- BackupAPI | 2 +- BackupApp/build.gradle | 27 +++++---- BackupApp/src/main/AndroidManifest.xml | 3 +- .../BackupApplication.kt | 2 +- .../data/room/model/BackupJob.kt | 1 - .../ApplicationOverviewFragment.kt | 14 +++-- .../ui/backup/BackupOverviewFragment.kt | 19 ++++--- .../ui/common/DisplayMenuItemActivity.kt | 9 ++- .../encryption/EncryptionSettingsActivity.kt | 8 ++- .../ui/help/HelpFragment.kt | 9 +-- .../ui/inspection/DataInspectionFragment.kt | 57 ++++++++++--------- .../ui/main/AboutFragment.kt | 13 +++-- BackupApp/src/main/res/layout/item_list.xml | 19 ++++--- build.gradle | 9 ++- gradle/wrapper/gradle-wrapper.properties | 2 +- 15 files changed, 110 insertions(+), 84 deletions(-) diff --git a/BackupAPI b/BackupAPI index de5ed1f..ac8e3a0 160000 --- a/BackupAPI +++ b/BackupAPI @@ -1 +1 @@ -Subproject commit de5ed1fadd0b5320dab3f6f0ecfc569cfcde87c5 +Subproject commit ac8e3a0ca2df3b212815585bf55be0b187b21e71 diff --git a/BackupApp/build.gradle b/BackupApp/build.gradle index de50e41..419d6f4 100644 --- a/BackupApp/build.gradle +++ b/BackupApp/build.gradle @@ -1,8 +1,7 @@ apply plugin: 'com.android.application' apply plugin: 'kotlin-android' -apply plugin: 'kotlin-android-extensions' +apply plugin: 'kotlin-parcelize' apply plugin: 'kotlin-kapt' - def pfaFile = rootProject.file('pfa.properties') android { @@ -19,14 +18,15 @@ android { } } } - compileSdkVersion 32 + compileSdk 34 defaultConfig { + namespace "org.secuso.privacyfriendlybackup" applicationId "org.secuso.privacyfriendlybackup" minSdkVersion 21 - targetSdkVersion 32 - versionCode 4 - versionName "1.3" + targetSdkVersion 34 + versionCode 5 + versionName "1.3.1" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" @@ -47,6 +47,10 @@ android { } } + buildFeatures { + viewBinding true + } + buildTypes { release { minifyEnabled false @@ -61,13 +65,13 @@ android { } compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = JavaVersion.VERSION_1_8.toString() + jvmTarget = JavaVersion.VERSION_17.toString() } sourceSets { @@ -76,6 +80,7 @@ android { lint { abortOnError false } + namespace 'org.secuso.privacyfriendlybackup' } dependencies { @@ -101,14 +106,14 @@ dependencies { implementation 'org.sufficientlysecure:openpgp-api:12.0' // WorkManager - def work_version = "2.7.1" + def work_version = "2.8.1" implementation "androidx.work:work-runtime:$work_version" implementation "androidx.work:work-runtime-ktx:$work_version" androidTestImplementation "androidx.work:work-testing:$work_version" testImplementation "androidx.work:work-testing:$work_version" // Room Database - def roomVersion = "2.4.2" + def roomVersion = "2.5.1" implementation "androidx.room:room-runtime:$roomVersion" annotationProcessor "androidx.room:room-compiler:$roomVersion" kapt "androidx.room:room-compiler:$roomVersion" diff --git a/BackupApp/src/main/AndroidManifest.xml b/BackupApp/src/main/AndroidManifest.xml index 61c453b..8c5a175 100644 --- a/BackupApp/src/main/AndroidManifest.xml +++ b/BackupApp/src/main/AndroidManifest.xml @@ -1,7 +1,6 @@ + xmlns:tools="http://schemas.android.com/tools"> diff --git a/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/BackupApplication.kt b/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/BackupApplication.kt index 606c463..902a4a3 100644 --- a/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/BackupApplication.kt +++ b/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/BackupApplication.kt @@ -29,7 +29,7 @@ class BackupApplication : Application(), Configuration.Provider { Log.d(TAG, "schedulePeriodicWork()") val periodicJobManagerWork = PeriodicWorkRequestBuilder(15, TimeUnit.MINUTES) - .setBackoffCriteria(BackoffPolicy.LINEAR, PeriodicWorkRequest.MIN_BACKOFF_MILLIS, TimeUnit.MILLISECONDS) + .setBackoffCriteria(BackoffPolicy.LINEAR, WorkRequest.MIN_BACKOFF_MILLIS, TimeUnit.MILLISECONDS) .build() WorkManager.getInstance(this).enqueueUniquePeriodicWork( diff --git a/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/data/room/model/BackupJob.kt b/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/data/room/model/BackupJob.kt index 4db60ef..dcde86d 100644 --- a/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/data/room/model/BackupJob.kt +++ b/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/data/room/model/BackupJob.kt @@ -3,7 +3,6 @@ package org.secuso.privacyfriendlybackup.data.room.model import android.os.Parcelable import androidx.recyclerview.widget.DiffUtil import androidx.room.* -import androidx.room.ForeignKey.CASCADE import kotlinx.android.parcel.Parcelize import org.secuso.privacyfriendlybackup.data.BackupJobManager import org.secuso.privacyfriendlybackup.data.room.model.enums.BackupJobAction diff --git a/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/application/ApplicationOverviewFragment.kt b/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/application/ApplicationOverviewFragment.kt index e6fd89b..01297da 100644 --- a/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/application/ApplicationOverviewFragment.kt +++ b/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/application/ApplicationOverviewFragment.kt @@ -8,10 +8,10 @@ import android.view.* import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.observe import androidx.recyclerview.widget.LinearLayoutManager -import kotlinx.android.synthetic.main.fragment_backup_overview.* import org.secuso.privacyfriendlybackup.BackupApplication import org.secuso.privacyfriendlybackup.R import org.secuso.privacyfriendlybackup.data.room.model.BackupJob +import org.secuso.privacyfriendlybackup.databinding.FragmentBackupOverviewBinding import org.secuso.privacyfriendlybackup.ui.common.BaseFragment import org.secuso.privacyfriendlybackup.ui.common.DisplayMenuItemActivity import org.secuso.privacyfriendlybackup.ui.main.MainActivity @@ -27,6 +27,7 @@ class ApplicationOverviewFragment : BaseFragment(), ApplicationAdapter.ManageLis private lateinit var adapter : ApplicationAdapter private var oldMode : Mode = Mode.NORMAL + lateinit var binding: FragmentBackupOverviewBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -42,7 +43,8 @@ class ApplicationOverviewFragment : BaseFragment(), ApplicationAdapter.ManageLis } override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { - return inflater.inflate(R.layout.fragment_backup_overview, container, false) + binding = FragmentBackupOverviewBinding.inflate(layoutInflater) + return binding.root } override fun onActivityCreated(savedInstanceState: Bundle?) { @@ -53,11 +55,11 @@ class ApplicationOverviewFragment : BaseFragment(), ApplicationAdapter.ManageLis viewModel = ViewModelProvider(this)[ApplicationOverviewViewModel::class.java] adapter = ApplicationAdapter(requireContext(), this, viewLifecycleOwner) - fragment_backup_overview_list.adapter = adapter - fragment_backup_overview_list.layoutManager = + binding.fragmentBackupOverviewList.adapter = adapter + binding.fragmentBackupOverviewList.layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false) - backup_overview_no_entries_name.setText(R.string.application_overview_no_entries_text) + binding.backupOverviewNoEntriesName.setText(R.string.application_overview_no_entries_text) viewModel.appLiveData.observe(viewLifecycleOwner) { data -> adapter.setData(data) @@ -119,6 +121,6 @@ class ApplicationOverviewFragment : BaseFragment(), ApplicationAdapter.ManageLis } private fun displayNoElementsImage(show: Boolean) { - backup_overview_no_entries.visibility = if(show) View.VISIBLE else View.GONE + binding.backupOverviewNoEntries.visibility = if(show) View.VISIBLE else View.GONE } } \ No newline at end of file diff --git a/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/backup/BackupOverviewFragment.kt b/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/backup/BackupOverviewFragment.kt index c8f5ea2..a9e65fe 100644 --- a/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/backup/BackupOverviewFragment.kt +++ b/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/backup/BackupOverviewFragment.kt @@ -19,13 +19,13 @@ import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearSmoothScroller import androidx.recyclerview.widget.RecyclerView.SmoothScroller -import kotlinx.android.synthetic.main.fragment_backup_overview.* import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.delay import kotlinx.coroutines.launch import org.secuso.privacyfriendlybackup.R import org.secuso.privacyfriendlybackup.data.BackupDataStorageRepository +import org.secuso.privacyfriendlybackup.databinding.FragmentBackupOverviewBinding import org.secuso.privacyfriendlybackup.preference.PreferenceKeys.DIALOG_SKIP_IMPORT_START import org.secuso.privacyfriendlybackup.ui.common.BaseFragment import org.secuso.privacyfriendlybackup.ui.common.DisplayMenuItemActivity @@ -51,6 +51,7 @@ class BackupOverviewFragment : BaseFragment(), private lateinit var viewModel: BackupOverviewViewModel private lateinit var adapter : FilterableBackupAdapter + private lateinit var binding: FragmentBackupOverviewBinding private var toolbarDeleteIcon: MenuItem? = null private var searchIcon: MenuItem? = null @@ -98,8 +99,8 @@ class BackupOverviewFragment : BaseFragment(), this ) - fragment_backup_overview_list.adapter = adapter - fragment_backup_overview_list.layoutManager = when { + binding.fragmentBackupOverviewList.adapter = adapter + binding.fragmentBackupOverviewList.layoutManager = when { isXLargeTablet() -> { GridLayoutManager( context, @@ -121,7 +122,7 @@ class BackupOverviewFragment : BaseFragment(), } } - fab.setOnClickListener { + binding.fab.setOnClickListener { if(Mode.DELETE.isActiveIn(viewModel.getCurrentMode())) { val builder = AlertDialog.Builder(requireContext()).apply { @@ -204,7 +205,7 @@ class BackupOverviewFragment : BaseFragment(), } private fun displayNoElementsImage(show: Boolean) { - backup_overview_no_entries.visibility = if(show) View.VISIBLE else View.GONE + binding.backupOverviewNoEntries.visibility = if(show) View.VISIBLE else View.GONE } private fun playAnimationIfApplicable(data: List) { @@ -222,7 +223,7 @@ class BackupOverviewFragment : BaseFragment(), delay(250L) Log.d(TAG, "## finding viewholder for item id $highlight") - val vh = fragment_backup_overview_list.findViewHolderForItemId(highlight) + val vh = binding.fragmentBackupOverviewList.findViewHolderForItemId(highlight) if(vh != null) { (vh as FilterableBackupAdapter.ViewHolder).apply { ObjectAnimator.ofObject( @@ -254,7 +255,7 @@ class BackupOverviewFragment : BaseFragment(), } } smoothScroller.targetPosition = position - fragment_backup_overview_list.layoutManager?.startSmoothScroll(smoothScroller) + binding.fragmentBackupOverviewList.layoutManager?.startSmoothScroll(smoothScroller) } override fun onBackPressed() { @@ -425,7 +426,7 @@ class BackupOverviewFragment : BaseFragment(), toolbarDeleteIcon?.isVisible = false selectAllIcon?.isVisible = true - fab.show() + binding.fab.show() } override fun onItemClick( @@ -486,7 +487,7 @@ class BackupOverviewFragment : BaseFragment(), toolbarDeleteIcon?.isVisible = true selectAllIcon?.isVisible = false - fab?.hide() + binding.fab.hide() adapter.disableDeleteMode() } diff --git a/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/common/DisplayMenuItemActivity.kt b/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/common/DisplayMenuItemActivity.kt index c035fc8..5f609a4 100644 --- a/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/common/DisplayMenuItemActivity.kt +++ b/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/common/DisplayMenuItemActivity.kt @@ -6,8 +6,8 @@ import android.util.Log import android.view.MenuItem import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.Fragment -import kotlinx.android.synthetic.main.activity_display_menu_item.* import org.secuso.privacyfriendlybackup.R +import org.secuso.privacyfriendlybackup.databinding.ActivityDisplayMenuItemBinding import org.secuso.privacyfriendlybackup.ui.main.MainActivity /** @@ -18,10 +18,13 @@ import org.secuso.privacyfriendlybackup.ui.main.MainActivity */ class DisplayMenuItemActivity : AppCompatActivity() { + lateinit var binding: ActivityDisplayMenuItemBinding + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_display_menu_item) - setSupportActionBar(toolbar) + binding = ActivityDisplayMenuItemBinding.inflate(layoutInflater) + setContentView(binding.root) + setSupportActionBar(binding.toolbar) supportActionBar?.setDisplayHomeAsUpEnabled(true) diff --git a/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/encryption/EncryptionSettingsActivity.kt b/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/encryption/EncryptionSettingsActivity.kt index 3946f12..00377d2 100644 --- a/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/encryption/EncryptionSettingsActivity.kt +++ b/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/encryption/EncryptionSettingsActivity.kt @@ -2,14 +2,16 @@ package org.secuso.privacyfriendlybackup.ui.encryption import android.os.Bundle import androidx.appcompat.app.AppCompatActivity -import kotlinx.android.synthetic.main.activity_display_menu_item.* import org.secuso.privacyfriendlybackup.R +import org.secuso.privacyfriendlybackup.databinding.ActivityDisplayMenuItemBinding import org.secuso.privacyfriendlybackup.ui.backup.BackupOverviewFragment class EncryptionSettingsActivity : AppCompatActivity(){ + lateinit var binding: ActivityDisplayMenuItemBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) - setContentView(R.layout.activity_display_menu_item) + binding = ActivityDisplayMenuItemBinding.inflate(layoutInflater) + setContentView(binding.root) initResources() @@ -24,7 +26,7 @@ class EncryptionSettingsActivity : AppCompatActivity(){ } private fun initResources() { - setSupportActionBar(toolbar) + setSupportActionBar(binding.toolbar) supportActionBar?.setDisplayHomeAsUpEnabled(true) supportActionBar?.setTitle(R.string.app_name) } diff --git a/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/help/HelpFragment.kt b/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/help/HelpFragment.kt index 4a71244..e1ddde5 100644 --- a/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/help/HelpFragment.kt +++ b/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/help/HelpFragment.kt @@ -4,18 +4,19 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import kotlinx.android.synthetic.main.fragment_help.* -import org.secuso.privacyfriendlybackup.R +import org.secuso.privacyfriendlybackup.databinding.FragmentHelpBinding import org.secuso.privacyfriendlybackup.ui.common.BaseFragment class HelpFragment : BaseFragment() { + lateinit var binding: FragmentHelpBinding override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - return inflater.inflate(R.layout.fragment_help, container, false) + binding = FragmentHelpBinding.inflate(layoutInflater) + return binding.root } override fun onActivityCreated(savedInstanceState: Bundle?) { @@ -27,7 +28,7 @@ class HelpFragment : BaseFragment() { val expandableListDetail = helpDataDump.dataGeneral val expandableListTitleGeneral: List = ArrayList(expandableListDetail.keys) expandableListAdapter = ExpandableListAdapter(requireActivity(), expandableListTitleGeneral, expandableListDetail) - generalExpandableListView.setAdapter(expandableListAdapter) + binding.generalExpandableListView.setAdapter(expandableListAdapter) } override fun onBackPressed() { diff --git a/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/inspection/DataInspectionFragment.kt b/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/inspection/DataInspectionFragment.kt index 500c34a..ad1323f 100644 --- a/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/inspection/DataInspectionFragment.kt +++ b/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/inspection/DataInspectionFragment.kt @@ -23,10 +23,10 @@ import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.ViewModelProvider import androidx.preference.PreferenceManager import com.bumptech.glide.Glide -import kotlinx.android.synthetic.main.data_inspection_fragment.* -import kotlinx.android.synthetic.main.item_application_job.* import org.openintents.openpgp.OpenPgpSignatureResult import org.secuso.privacyfriendlybackup.R +import org.secuso.privacyfriendlybackup.databinding.DataInspectionFragmentBinding +import org.secuso.privacyfriendlybackup.databinding.ItemApplicationJobBinding import org.secuso.privacyfriendlybackup.preference.PreferenceKeys import org.secuso.privacyfriendlybackup.ui.backup.BackupOverviewFragment import java.io.FileNotFoundException @@ -41,6 +41,8 @@ class DataInspectionFragment : Fragment() { private var encryptionEnabled : Boolean = false private var showSigInfo: Boolean = false + lateinit var dataBinding: DataInspectionFragmentBinding + companion object { fun newInstance() = DataInspectionFragment() @@ -58,7 +60,8 @@ class DataInspectionFragment : Fragment() { } override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View { - return inflater.inflate(R.layout.data_inspection_fragment, container, false) + dataBinding = DataInspectionFragmentBinding.inflate(layoutInflater) + return dataBinding.root } override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { @@ -105,9 +108,9 @@ class DataInspectionFragment : Fragment() { showSigInfo = !showSigInfo val set = ConstraintSet() - set.clone(data_inspection) + set.clone(dataBinding.dataInspection) set.setVisibility(R.id.data_inspection_encryption_details, if(showSigInfo) View.VISIBLE else View.GONE) - set.applyTo(data_inspection) + set.applyTo(dataBinding.dataInspection) } private fun handleExportClicked() { @@ -224,27 +227,27 @@ class DataInspectionFragment : Fragment() { viewModel.getLoadStatus().observe(viewLifecycleOwner) { Log.d("TEST", "## Load Status Updated To ${it.name}") - Glide.with(requireActivity()).load(it.imageRes).into(data_inspection_load_status_image) - data_inspection_load_status_name.setText(it.descriptionRes) - data_inspection_load_status_image.setColorFilter(ContextCompat.getColor(requireActivity(), it.colorRes)) + Glide.with(requireActivity()).load(it.imageRes).into(dataBinding.dataInspectionSignatureStatus) + dataBinding.dataInspectionLoadStatusName.setText(it.descriptionRes) + dataBinding.dataInspectionLoadStatusImage.setColorFilter(ContextCompat.getColor(requireActivity(), it.colorRes)) when(it) { LoadStatus.UNKNOWN, null -> { - data_inspection_load_status.visibility = View.GONE + dataBinding.dataInspectionLoadStatusName.visibility = View.GONE } LoadStatus.ERROR_INVALID_JSON, LoadStatus.ERROR -> { - data_inspection_load_status.visibility = View.VISIBLE + dataBinding.dataInspectionLoadStatusName.visibility = View.VISIBLE } LoadStatus.LOADING -> { - data_inspection_load_status.visibility = View.VISIBLE + dataBinding.dataInspectionLoadStatusName.visibility = View.VISIBLE } LoadStatus.DECRYPTING -> { - data_inspection_load_status.visibility = View.VISIBLE + dataBinding.dataInspectionLoadStatusName.visibility = View.VISIBLE } LoadStatus.DECRYPTION_ERROR -> { - data_inspection_load_status.visibility = View.VISIBLE + dataBinding.dataInspectionLoadStatusName.visibility = View.VISIBLE } LoadStatus.DONE -> { - data_inspection_load_status.visibility = View.GONE + dataBinding.dataInspectionLoadStatusName.visibility = View.GONE encryptionEnabled = encryptionEnabled and viewModel.isEncrypted @@ -259,31 +262,31 @@ class DataInspectionFragment : Fragment() { } viewModel.getData().observe(viewLifecycleOwner) { - data_inspection_json_list.bindJson(it) + dataBinding.dataInspectionJsonList.bindJson(it) } // Color - data_inspection_json_list.setKeyColor( + dataBinding.dataInspectionJsonList.setKeyColor( ContextCompat.getColor( activity, R.color.colorPrimary ) ) - data_inspection_json_list.setValueTextColor(ContextCompat.getColor(activity, R.color.green)) - data_inspection_json_list.setValueNumberColor( + dataBinding.dataInspectionJsonList.setValueTextColor(ContextCompat.getColor(activity, R.color.green)) + dataBinding.dataInspectionJsonList.setValueNumberColor( ContextCompat.getColor( activity, R.color.colorAccent ) ) - data_inspection_json_list.setValueUrlColor(ContextCompat.getColor(activity, R.color.red)) - data_inspection_json_list.setValueNullColor( + dataBinding.dataInspectionJsonList.setValueUrlColor(ContextCompat.getColor(activity, R.color.red)) + dataBinding.dataInspectionJsonList.setValueNullColor( ContextCompat.getColor( activity, R.color.orange ) ) - data_inspection_json_list.setBracesColor(ContextCompat.getColor(activity, R.color.black)) + dataBinding.dataInspectionJsonList.setBracesColor(ContextCompat.getColor(activity, R.color.black)) //data_inspection_json_list.setTextSize() viewModel.getDecryptionMetaData().observe(requireActivity()) { @@ -297,8 +300,8 @@ class DataInspectionFragment : Fragment() { OpenPgpSignatureResult.RESULT_NO_SIGNATURE -> { // not signed statusText = requireActivity().getString(R.string.signature_result_no_signature) - data_inspection_signature_user_id.visibility = View.GONE - data_inspection_signature_key_id.visibility = View.GONE + dataBinding.dataInspectionSignatureUserId.visibility = View.GONE + dataBinding.dataInspectionSignatureKeyId.visibility = View.GONE } OpenPgpSignatureResult.RESULT_INVALID_SIGNATURE -> { // invalid signature @@ -337,10 +340,10 @@ class DataInspectionFragment : Fragment() { mutate() setTint(color) } - data_inspection_signature_status.setImageDrawable(statusIcon) - data_inspection_signature_status_text.text = statusText - data_inspection_signature_user_id.text = requireActivity().getString(R.string.data_inspection_signature_user_id, it.signature?.primaryUserId) - data_inspection_signature_key_id.text = requireActivity().getString(R.string.data_inspection_signature_key_id, it.signature?.keyId.toString()) + dataBinding.dataInspectionSignatureStatus.setImageDrawable(statusIcon) + dataBinding.dataInspectionSignatureStatusText.text = statusText + dataBinding.dataInspectionSignatureUserId.text = requireActivity().getString(R.string.data_inspection_signature_user_id, it.signature?.primaryUserId) + dataBinding.dataInspectionSignatureKeyId.text = requireActivity().getString(R.string.data_inspection_signature_key_id, it.signature?.keyId.toString()) } } diff --git a/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/main/AboutFragment.kt b/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/main/AboutFragment.kt index bd3da4d..edce153 100644 --- a/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/main/AboutFragment.kt +++ b/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/main/AboutFragment.kt @@ -5,27 +5,28 @@ import android.text.method.LinkMovementMethod import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import kotlinx.android.synthetic.main.fragment_about.* import org.secuso.privacyfriendlybackup.BuildConfig import org.secuso.privacyfriendlybackup.R +import org.secuso.privacyfriendlybackup.databinding.FragmentAboutBinding import org.secuso.privacyfriendlybackup.ui.common.BaseFragment class AboutFragment : BaseFragment() { - + lateinit var binding: FragmentAboutBinding override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { - return inflater.inflate(R.layout.fragment_about, container, false) + binding = FragmentAboutBinding.inflate(layoutInflater) + return binding.root } override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) - githubURL.movementMethod = LinkMovementMethod.getInstance() - secusoWebsite.movementMethod = LinkMovementMethod.getInstance() - textFieldVersion.text = requireActivity().getString(R.string.version_number, BuildConfig.VERSION_NAME) + binding.githubURL.movementMethod = LinkMovementMethod.getInstance() + binding.secusoWebsite.movementMethod = LinkMovementMethod.getInstance() + binding.textFieldVersion.text = requireActivity().getString(R.string.version_number, BuildConfig.VERSION_NAME) } diff --git a/BackupApp/src/main/res/layout/item_list.xml b/BackupApp/src/main/res/layout/item_list.xml index ced6d38..6258c15 100644 --- a/BackupApp/src/main/res/layout/item_list.xml +++ b/BackupApp/src/main/res/layout/item_list.xml @@ -1,11 +1,16 @@ - \ No newline at end of file + android:layout_height="match_parent"> + + \ No newline at end of file diff --git a/build.gradle b/build.gradle index ba2839c..109722e 100644 --- a/build.gradle +++ b/build.gradle @@ -1,12 +1,12 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = "1.6.10" + ext.kotlin_version = "1.8.10" repositories { google() jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:7.2.1' + classpath 'com.android.tools.build:gradle:7.4.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong @@ -14,6 +14,11 @@ buildscript { } } +plugins { + id 'com.google.devtools.ksp' version '1.8.10-1.0.9' apply false +} + + allprojects { repositories { google() diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 204fb37..510e968 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-all.zip From 9afa6534a0215726a60a94f070c6c34a2a82f7a3 Mon Sep 17 00:00:00 2001 From: Patrick Schneider Date: Wed, 12 Jun 2024 20:35:28 +0200 Subject: [PATCH 03/15] [fix] Fixes missing view binding. --- .idea/compiler.xml | 2 +- .idea/gradle.xml | 5 ++--- .idea/misc.xml | 10 +++++++--- .../ui/backup/BackupOverviewFragment.kt | 3 ++- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/.idea/compiler.xml b/.idea/compiler.xml index fb7f4a8..b589d56 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml index c81a0e2..594e36a 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -4,10 +4,8 @@ diff --git a/.idea/misc.xml b/.idea/misc.xml index 9815e2a..c7ab052 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -5,7 +5,7 @@ - + diff --git a/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/backup/BackupOverviewFragment.kt b/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/backup/BackupOverviewFragment.kt index a9e65fe..107fc63 100644 --- a/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/backup/BackupOverviewFragment.kt +++ b/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/backup/BackupOverviewFragment.kt @@ -84,7 +84,8 @@ class BackupOverviewFragment : BaseFragment(), container: ViewGroup?, savedInstanceState: Bundle? ): View? { - return inflater.inflate(R.layout.fragment_backup_overview, container, false) + binding = FragmentBackupOverviewBinding.inflate(inflater, container, false) + return binding.root } override fun onActivityCreated(savedInstanceState: Bundle?) { From 32dd5c253a534438b713398963253ab8c5ff725d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20L=C3=A4nge?= Date: Fri, 14 Jun 2024 15:15:42 +0200 Subject: [PATCH 04/15] Add workflows: `ci.yml` and `android-test.yml` --- .github/workflows/android-test.yml | 98 ++++++++++++++++++++++++++++++ .github/workflows/ci.yml | 49 +++++++++++++++ 2 files changed, 147 insertions(+) create mode 100644 .github/workflows/android-test.yml create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/android-test.yml b/.github/workflows/android-test.yml new file mode 100644 index 0000000..efd1db7 --- /dev/null +++ b/.github/workflows/android-test.yml @@ -0,0 +1,98 @@ +name: Android Emulator Tests +on: [ push, pull_request ] + +jobs: + check-if-tests-exist: + runs-on: ubuntu-latest + outputs: + status: ${{ steps.check-androidTest.outputs.NOT_EMPTY }} + min-sdk-version: ${{ steps.get-sdk-version.outputs.MIN_SDK_VERSION }} + target-sdk-version: ${{ steps.get-sdk-version.outputs.TARGET_SDK_VERSION }} + app-id: ${{ steps.get-app-id.outputs.APP_ID }} + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + submodules: "recursive" + - name: Check if androidTest folder is not empty + run: | + echo "NOT_EMPTY=$([ "$(ls -A BackupApp/src/androidTest)" ] && echo 'true' || echo 'false')" + echo "NOT_EMPTY=$([ "$(ls -A BackupApp/src/androidTest)" ] && echo 'true' || echo 'false')" >> $GITHUB_OUTPUT + id: check-androidTest + - name: Get min and target sdk + if: steps.check-androidTest.outputs.NOT_EMPTY == 'true' + id: get-sdk-version + run: | + echo "MIN_SDK_VERSION=$(cat BackupApp/build.gradle | grep minSdkVersion | rev | cut -d' ' -f 1 | rev)" >> $GITHUB_OUTPUT + echo "TARGET_SDK_VERSION=$(cat BackupApp/build.gradle | grep targetSdkVersion | rev | cut -d' ' -f 1 | rev)" >> $GITHUB_OUTPUT + - name: Get app ID + id: get-app-id + run: | + echo "APP_ID=$(cat BackupApp/build.gradle | grep applicationId | rev | cut -d' ' -f 1 | rev | tr -d '"')" >> $GITHUB_OUTPUT + + test: + needs: check-if-tests-exist + if: needs.check-if-tests-exist.outputs.status == 'true' + runs-on: ubuntu-latest + strategy: + matrix: + api-level: [34, "${{ needs.check-if-tests-exist.outputs.min-sdk-version }}", "${{ needs.check-if-tests-exist.outputs.target-sdk-version }}"] + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + submodules: 'recursive' + + - name: Enable KVM group perms + run: | + echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules + sudo udevadm control --reload-rules + sudo udevadm trigger --name-match=kvm + + - name: Gradle cache + uses: gradle/gradle-build-action@v3 + + - name: AVD cache + uses: actions/cache@v4 + id: avd-cache + with: + path: | + ~/.android/avd/* + ~/.android/adb* + key: avd-${{ matrix.api-level }} + + - name: Set up JDK environment + uses: actions/setup-java@v3 + with: + distribution: 'zulu' + java-version: 17 + + - name: create AVD and generate snapshot for caching + if: steps.avd-cache.outputs.cache-hit != 'true' + uses: reactivecircus/android-emulator-runner@v2 + with: + api-level: ${{ matrix.api-level }} + target: ${{ matrix.api-level >= 30 && 'google_apis' || 'default' }} + arch: ${{ matrix.api-level < 21 && 'x86' || 'x86_64' }} + force-avd-creation: false + emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none + disable-animations: false + script: echo "Generated AVD snapshot for caching." + + - name: Run connected tests + uses: ReactiveCircus/android-emulator-runner@v2 + with: + api-level: ${{ matrix.api-level }} + target: ${{ matrix.api-level >= 30 && 'google_apis' || 'default' }} + arch: ${{ matrix.api-level < 21 && 'x86' || 'x86_64' }} + force-avd-creation: false + emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none + disable-animations: true + script: | + adb uninstall ${{needs.check-if-tests-exist.outputs.app-id}} || true + adb uninstall ${{needs.check-if-tests-exist.outputs.app-id}}.test || true + adb uninstall ${{needs.check-if-tests-exist.outputs.app-id}}.androidTest || true + ./gradlew :BackupApp:connectedCheck --stacktrace + adb uninstall ${{needs.check-if-tests-exist.outputs.app-id}} || true + adb uninstall ${{needs.check-if-tests-exist.outputs.app-id}}.test || true + adb uninstall ${{needs.check-if-tests-exist.outputs.app-id}}.androidTest || true diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..9e60fe6 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,49 @@ +name: Continuous Integration +on: [push, pull_request] + +jobs: + test: + runs-on: ubuntu-20.04 + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + submodules: "recursive" + + - name: Set up JDK environment + uses: actions/setup-java@v3 + with: + distribution: "zulu" + java-version: 17 + + - name: Make gradlew executable + run: chmod +x ./gradlew + + - name: Setup Gradle + uses: gradle/gradle-build-action@v2 + + - name: Run local unit tests + run: bash ./gradlew test --stacktrace + + build: + runs-on: ubuntu-20.04 + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + submodules: "recursive" + + - name: Set up JDK environment + uses: actions/setup-java@v3 + with: + distribution: "zulu" + java-version: 17 + + - name: Make gradlew executable + run: chmod +x ./gradlew + + - name: Setup Gradle + uses: gradle/gradle-build-action@v2 + + - name: Build the app + run: bash ./gradlew build --stacktrace From 4119bdbfaca8843eb4b3e4371fc1c1b31bafbf79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20L=C3=A4nge?= Date: Fri, 14 Jun 2024 15:38:40 +0200 Subject: [PATCH 05/15] Change BackupAPI version to v1.3.0 --- BackupAPI | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BackupAPI b/BackupAPI index ac8e3a0..8687a8d 160000 --- a/BackupAPI +++ b/BackupAPI @@ -1 +1 @@ -Subproject commit ac8e3a0ca2df3b212815585bf55be0b187b21e71 +Subproject commit 8687a8dbd170866707dc41bcb879375400ef697a From 1977f842d47cba63905d7cb864cdf328b8ae92ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20L=C3=A4nge?= Date: Fri, 14 Jun 2024 15:50:25 +0200 Subject: [PATCH 06/15] Update gradle --- BackupApp/build.gradle | 5 ++++- build.gradle | 6 +++--- gradle.properties | 5 ++++- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/BackupApp/build.gradle b/BackupApp/build.gradle index 419d6f4..af930c1 100644 --- a/BackupApp/build.gradle +++ b/BackupApp/build.gradle @@ -21,7 +21,6 @@ android { compileSdk 34 defaultConfig { - namespace "org.secuso.privacyfriendlybackup" applicationId "org.secuso.privacyfriendlybackup" minSdkVersion 21 targetSdkVersion 34 @@ -74,6 +73,10 @@ android { jvmTarget = JavaVersion.VERSION_17.toString() } + kotlin { + jvmToolchain(17) + } + sourceSets { androidTest.assets.srcDirs += files("$projectDir/schemas".toString()) } diff --git a/build.gradle b/build.gradle index 109722e..7e98f85 100644 --- a/build.gradle +++ b/build.gradle @@ -1,12 +1,12 @@ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { - ext.kotlin_version = "1.8.10" + ext.kotlin_version = "1.9.10" repositories { google() jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:7.4.2' + classpath 'com.android.tools.build:gradle:8.1.4' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong @@ -15,7 +15,7 @@ buildscript { } plugins { - id 'com.google.devtools.ksp' version '1.8.10-1.0.9' apply false + id 'com.google.devtools.ksp' version "$kotlin_version-1.0.13" apply false } diff --git a/gradle.properties b/gradle.properties index 4d15d01..fde9fa4 100644 --- a/gradle.properties +++ b/gradle.properties @@ -18,4 +18,7 @@ android.useAndroidX=true # Automatically convert third-party libraries to use AndroidX android.enableJetifier=true # Kotlin code style for this project: "official" or "obsolete": -kotlin.code.style=official \ No newline at end of file +kotlin.code.style=official +android.defaults.buildfeatures.buildconfig=true +android.nonTransitiveRClass=false +android.nonFinalResIds=false \ No newline at end of file From 75fb93cb9f5cae8aa7fbef334a77c744af15a054 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20L=C3=A4nge?= Date: Fri, 14 Jun 2024 15:54:43 +0200 Subject: [PATCH 07/15] Update `.gitignore` - Remove `.idea` folder --- .gitignore | 8 +- .idea/codeStyles/Project.xml | 122 --------------------------- .idea/codeStyles/codeStyleConfig.xml | 5 -- .idea/compiler.xml | 6 -- .idea/gradle.xml | 21 ----- .idea/jarRepositories.xml | 25 ------ .idea/misc.xml | 56 ------------ .idea/vcs.xml | 7 -- 8 files changed, 2 insertions(+), 248 deletions(-) delete mode 100644 .idea/codeStyles/Project.xml delete mode 100644 .idea/codeStyles/codeStyleConfig.xml delete mode 100644 .idea/compiler.xml delete mode 100644 .idea/gradle.xml delete mode 100644 .idea/jarRepositories.xml delete mode 100644 .idea/misc.xml delete mode 100644 .idea/vcs.xml diff --git a/.gitignore b/.gitignore index 1f4cbd7..aa9c63f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,8 @@ *.iml .gradle /local.properties -/.idea/caches -/.idea/libraries -/.idea/modules.xml -/.idea/workspace.xml -/.idea/navEditor.xml -/.idea/assetWizardSettings.xml +.idea/ +misc.xml .DS_Store /build /captures diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml deleted file mode 100644 index 88ea3aa..0000000 --- a/.idea/codeStyles/Project.xml +++ /dev/null @@ -1,122 +0,0 @@ - - - - - - - - - -
- - - - xmlns:android - - ^$ - - - -
-
- - - - xmlns:.* - - ^$ - - - BY_NAME - -
-
- - - - .*:id - - http://schemas.android.com/apk/res/android - - - -
-
- - - - .*:name - - http://schemas.android.com/apk/res/android - - - -
-
- - - - name - - ^$ - - - -
-
- - - - style - - ^$ - - - -
-
- - - - .* - - ^$ - - - BY_NAME - -
-
- - - - .* - - http://schemas.android.com/apk/res/android - - - ANDROID_ATTRIBUTE_ORDER - -
-
- - - - .* - - .* - - - BY_NAME - -
-
-
-
- - -
-
\ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml deleted file mode 100644 index 79ee123..0000000 --- a/.idea/codeStyles/codeStyleConfig.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml deleted file mode 100644 index b589d56..0000000 --- a/.idea/compiler.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml deleted file mode 100644 index 594e36a..0000000 --- a/.idea/gradle.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml deleted file mode 100644 index a5f05cd..0000000 --- a/.idea/jarRepositories.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index c7ab052..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,56 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml deleted file mode 100644 index 407beea..0000000 --- a/.idea/vcs.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file From dc2418617dd7f68911996486da27872bc9636850 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20L=C3=A4nge?= Date: Fri, 14 Jun 2024 16:05:38 +0200 Subject: [PATCH 08/15] Replace `libs/jsonviewer` with maven dependency --- BackupApp/build.gradle | 4 +- libs/jsonviewer/.gitignore | 1 - libs/jsonviewer/build.gradle | 33 -- libs/jsonviewer/proguard-rules.pro | 21 -- libs/jsonviewer/src/main/AndroidManifest.xml | 1 - .../jsonviewer/library/JsonRecyclerView.java | 194 ------------ .../adapter/BaseJsonViewerAdapter.java | 20 -- .../library/adapter/JsonViewerAdapter.java | 287 ------------------ .../yuyh/jsonviewer/library/utils/Utils.java | 85 ------ .../jsonviewer/library/view/JsonItemView.java | 133 -------- .../main/res/drawable/jsonviewer_minus.xml | 10 - .../src/main/res/drawable/jsonviewer_plus.xml | 24 -- .../layout/jsonviewer_layout_item_view.xml | 44 --- .../src/main/res/values/strings.xml | 4 - settings.gradle | 5 +- 15 files changed, 4 insertions(+), 862 deletions(-) delete mode 100644 libs/jsonviewer/.gitignore delete mode 100644 libs/jsonviewer/build.gradle delete mode 100644 libs/jsonviewer/proguard-rules.pro delete mode 100644 libs/jsonviewer/src/main/AndroidManifest.xml delete mode 100644 libs/jsonviewer/src/main/java/com/yuyh/jsonviewer/library/JsonRecyclerView.java delete mode 100644 libs/jsonviewer/src/main/java/com/yuyh/jsonviewer/library/adapter/BaseJsonViewerAdapter.java delete mode 100644 libs/jsonviewer/src/main/java/com/yuyh/jsonviewer/library/adapter/JsonViewerAdapter.java delete mode 100644 libs/jsonviewer/src/main/java/com/yuyh/jsonviewer/library/utils/Utils.java delete mode 100644 libs/jsonviewer/src/main/java/com/yuyh/jsonviewer/library/view/JsonItemView.java delete mode 100644 libs/jsonviewer/src/main/res/drawable/jsonviewer_minus.xml delete mode 100644 libs/jsonviewer/src/main/res/drawable/jsonviewer_plus.xml delete mode 100644 libs/jsonviewer/src/main/res/layout/jsonviewer_layout_item_view.xml delete mode 100644 libs/jsonviewer/src/main/res/values/strings.xml diff --git a/BackupApp/build.gradle b/BackupApp/build.gradle index af930c1..a2f4b1c 100644 --- a/BackupApp/build.gradle +++ b/BackupApp/build.gradle @@ -88,7 +88,6 @@ android { dependencies { implementation project(path: ':BackupAPI') - implementation project(path: ':jsonviewer') implementation fileTree(dir: "libs", include: ["*.jar"]) implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" @@ -135,6 +134,9 @@ dependencies { // Glide implementation 'com.github.bumptech.glide:glide:4.11.0' + // JSON Viewer + implementation 'com.yuyh.json:jsonviewer:1.0.6' + // Retrofit for Google Drive Test implementation 'com.squareup.retrofit2:retrofit:2.9.0' implementation 'com.squareup.retrofit2:converter-gson:2.9.0' diff --git a/libs/jsonviewer/.gitignore b/libs/jsonviewer/.gitignore deleted file mode 100644 index 796b96d..0000000 --- a/libs/jsonviewer/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/build diff --git a/libs/jsonviewer/build.gradle b/libs/jsonviewer/build.gradle deleted file mode 100644 index e8a321d..0000000 --- a/libs/jsonviewer/build.gradle +++ /dev/null @@ -1,33 +0,0 @@ -apply plugin: 'com.android.library' - -android { - compileSdkVersion 30 - resourcePrefix "jsonviewer" - - defaultConfig { - minSdkVersion 14 - targetSdkVersion 30 - versionCode 6 - versionName "1.0.6" - } - - buildTypes { - release { - postprocessing { - removeUnusedCode false - removeUnusedResources false - obfuscate false - optimizeCode false - proguardFile 'proguard-rules.pro' - } - } - } - -} - -dependencies { - implementation fileTree(dir: 'libs', include: ['*.jar']) - - implementation 'androidx.appcompat:appcompat:1.2.0' - implementation 'androidx.recyclerview:recyclerview:1.1.0' -} diff --git a/libs/jsonviewer/proguard-rules.pro b/libs/jsonviewer/proguard-rules.pro deleted file mode 100644 index f1b4245..0000000 --- a/libs/jsonviewer/proguard-rules.pro +++ /dev/null @@ -1,21 +0,0 @@ -# Add project specific ProGuard rules here. -# You can control the set of applied configuration files using the -# proguardFiles setting in build.gradle. -# -# For more details, see -# http://developer.android.com/guide/developing/tools/proguard.html - -# If your project uses WebView with JS, uncomment the following -# and specify the fully qualified class name to the JavaScript interface -# class: -#-keepclassmembers class fqcn.of.javascript.interface.for.webview { -# public *; -#} - -# Uncomment this to preserve the line number information for -# debugging stack traces. -#-keepattributes SourceFile,LineNumberTable - -# If you keep the line number information, uncomment this to -# hide the original source file name. -#-renamesourcefileattribute SourceFile diff --git a/libs/jsonviewer/src/main/AndroidManifest.xml b/libs/jsonviewer/src/main/AndroidManifest.xml deleted file mode 100644 index 7e0335f..0000000 --- a/libs/jsonviewer/src/main/AndroidManifest.xml +++ /dev/null @@ -1 +0,0 @@ - diff --git a/libs/jsonviewer/src/main/java/com/yuyh/jsonviewer/library/JsonRecyclerView.java b/libs/jsonviewer/src/main/java/com/yuyh/jsonviewer/library/JsonRecyclerView.java deleted file mode 100644 index 99515d8..0000000 --- a/libs/jsonviewer/src/main/java/com/yuyh/jsonviewer/library/JsonRecyclerView.java +++ /dev/null @@ -1,194 +0,0 @@ -package com.yuyh.jsonviewer.library; - -import android.content.Context; -import android.text.style.ForegroundColorSpan; -import android.util.AttributeSet; -import android.view.MotionEvent; -import android.view.View; - -import androidx.annotation.Nullable; -import androidx.recyclerview.widget.LinearLayoutManager; -import androidx.recyclerview.widget.RecyclerView; - -import com.yuyh.jsonviewer.library.adapter.BaseJsonViewerAdapter; -import com.yuyh.jsonviewer.library.adapter.JsonViewerAdapter; -import com.yuyh.jsonviewer.library.view.JsonItemView; - -import org.json.JSONArray; -import org.json.JSONObject; - -/** - * Created by yuyuhang on 2017/11/30. - */ -public class JsonRecyclerView extends RecyclerView { - - private BaseJsonViewerAdapter mAdapter; - - public JsonRecyclerView(Context context) { - this(context, null); - } - - public JsonRecyclerView(Context context, @Nullable AttributeSet attrs) { - this(context, attrs, 0); - } - - public JsonRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - - initView(); - } - - private void initView() { - setLayoutManager(new LinearLayoutManager(getContext())); - } - - public void bindJson(String jsonStr) { - mAdapter = null; - mAdapter = new JsonViewerAdapter(jsonStr); - setAdapter(mAdapter); - } - - public void bindJson(JSONArray array) { - mAdapter = null; - mAdapter = new JsonViewerAdapter(array); - setAdapter(mAdapter); - } - - public void bindJson(JSONObject object) { - mAdapter = null; - mAdapter = new JsonViewerAdapter(object); - setAdapter(mAdapter); - } - - public void setKeyColor(int color) { - BaseJsonViewerAdapter.KEY_COLOR = color; - } - - public void setValueTextColor(int color) { - BaseJsonViewerAdapter.TEXT_COLOR = color; - } - - public void setValueNumberColor(int color) { - BaseJsonViewerAdapter.NUMBER_COLOR = color; - } - - public void setValueBooleanColor(int color) { - BaseJsonViewerAdapter.BOOLEAN_COLOR = color; - } - - public void setValueUrlColor(int color) { - BaseJsonViewerAdapter.URL_COLOR = color; - } - - public void setValueNullColor(int color) { - BaseJsonViewerAdapter.NUMBER_COLOR = color; - } - - public void setBracesColor(int color) { - BaseJsonViewerAdapter.BRACES_COLOR = color; - } - - public void setTextSize(float sizeDP) { - if (sizeDP < 10) { - sizeDP = 10; - } else if (sizeDP > 30) { - sizeDP = 30; - } - - if (BaseJsonViewerAdapter.TEXT_SIZE_DP != sizeDP) { - BaseJsonViewerAdapter.TEXT_SIZE_DP = sizeDP; - if (mAdapter != null) { - updateAll(sizeDP); - } - } - } - - public void setScaleEnable(boolean enable) { - if (enable) { - addOnItemTouchListener(touchListener); - } else { - removeOnItemTouchListener(touchListener); - } - } - - public void updateAll(float textSize) { - LayoutManager manager = getLayoutManager(); - - int count = manager.getChildCount(); - - for (int i = 0; i < count; i++) { - View view = manager.getChildAt(i); - loop(view, textSize); - } - } - - private void loop(View view, float textSize) { - if (view instanceof JsonItemView) { - JsonItemView group = (JsonItemView) view; - - group.setTextSize(textSize); - - int childCount = group.getChildCount(); - - for (int i = 0; i < childCount; i++) { - View view1 = group.getChildAt(i); - loop(view1, textSize); - } - } - } - - int mode; - float oldDist; - - private void zoom(float f) { - setTextSize(BaseJsonViewerAdapter.TEXT_SIZE_DP * f); - } - - private float spacing(MotionEvent event) { - float x = event.getX(0) - event.getX(1); - float y = event.getY(0) - event.getY(1); - return (float) Math.sqrt(x * x + y * y); - } - - private OnItemTouchListener touchListener = new OnItemTouchListener() { - @Override - public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent event) { - switch (event.getAction() & event.getActionMasked()) { - case MotionEvent.ACTION_DOWN: - mode = 1; - break; - case MotionEvent.ACTION_UP: - mode = 0; - break; - case MotionEvent.ACTION_POINTER_UP: - mode -= 1; - break; - case MotionEvent.ACTION_POINTER_DOWN: - oldDist = spacing(event); - mode += 1; - break; - - case MotionEvent.ACTION_MOVE: - if (mode >= 2) { - float newDist = spacing(event); - if (Math.abs(newDist - oldDist) > 0.5f) { - zoom(newDist / oldDist); - oldDist = newDist; - } - } - break; - } - return false; - } - - @Override - public void onTouchEvent(RecyclerView rv, MotionEvent event) { - - } - - @Override - public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { - - } - }; -} diff --git a/libs/jsonviewer/src/main/java/com/yuyh/jsonviewer/library/adapter/BaseJsonViewerAdapter.java b/libs/jsonviewer/src/main/java/com/yuyh/jsonviewer/library/adapter/BaseJsonViewerAdapter.java deleted file mode 100644 index 3554528..0000000 --- a/libs/jsonviewer/src/main/java/com/yuyh/jsonviewer/library/adapter/BaseJsonViewerAdapter.java +++ /dev/null @@ -1,20 +0,0 @@ -package com.yuyh.jsonviewer.library.adapter; - -import android.text.style.ForegroundColorSpan; -import androidx.recyclerview.widget.RecyclerView; - -/** - * Created by yuyuhang on 2017/11/30. - */ -public abstract class BaseJsonViewerAdapter extends RecyclerView.Adapter { - - public static int KEY_COLOR = 0xFF922799; - public static int TEXT_COLOR = 0xFF3AB54A; - public static int NUMBER_COLOR = 0xFF25AAE2; - public static int BOOLEAN_COLOR = 0xFFF98280; - public static int URL_COLOR = 0xFF66D2D5; - public static int NULL_COLOR = 0xFFEF5935; - public static int BRACES_COLOR = 0xFF4A555F; - - public static float TEXT_SIZE_DP = 12; -} diff --git a/libs/jsonviewer/src/main/java/com/yuyh/jsonviewer/library/adapter/JsonViewerAdapter.java b/libs/jsonviewer/src/main/java/com/yuyh/jsonviewer/library/adapter/JsonViewerAdapter.java deleted file mode 100644 index 520268a..0000000 --- a/libs/jsonviewer/src/main/java/com/yuyh/jsonviewer/library/adapter/JsonViewerAdapter.java +++ /dev/null @@ -1,287 +0,0 @@ -package com.yuyh.jsonviewer.library.adapter; - -import android.text.SpannableStringBuilder; -import android.text.Spanned; -import android.text.style.ForegroundColorSpan; -import android.view.View; -import android.view.ViewGroup; - -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.RecyclerView; - -import com.yuyh.jsonviewer.library.utils.Utils; -import com.yuyh.jsonviewer.library.view.JsonItemView; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.json.JSONTokener; - -/** - * Created by yuyuhang on 2017/11/29. - */ -public class JsonViewerAdapter extends BaseJsonViewerAdapter { - - private String jsonStr; - - private JSONObject mJSONObject; - private JSONArray mJSONArray; - - public JsonViewerAdapter(String jsonStr) { - this.jsonStr = jsonStr; - - Object object = null; - try { - object = new JSONTokener(jsonStr).nextValue(); - } catch (JSONException e) { - e.printStackTrace(); - } - if (object instanceof JSONObject) { - mJSONObject = (JSONObject) object; - } else if (object instanceof JSONArray) { - mJSONArray = (JSONArray) object; - } else { - throw new IllegalArgumentException("jsonStr is illegal."); - } - } - - public JsonViewerAdapter(JSONObject jsonObject) { - this.mJSONObject = jsonObject; - if (mJSONObject == null) { - throw new IllegalArgumentException("jsonObject can not be null."); - } - } - - public JsonViewerAdapter(JSONArray jsonArray) { - this.mJSONArray = jsonArray; - if (mJSONArray == null) { - throw new IllegalArgumentException("jsonArray can not be null."); - } - } - - @Override - public JsonItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - return new JsonItemViewHolder(new JsonItemView(parent.getContext())); - } - - @Override - public void onBindViewHolder(JsonItemViewHolder holder, int position) { - JsonItemView itemView = holder.itemView; - itemView.setTextSize(TEXT_SIZE_DP); - itemView.setRightColor(BRACES_COLOR); - if (mJSONObject != null) { - if (position == 0) { - itemView.hideLeft(); - itemView.hideIcon(); - itemView.showRight("{"); - return; - } else if (position == getItemCount() - 1) { - itemView.hideLeft(); - itemView.hideIcon(); - itemView.showRight("}"); - return; - } else if (mJSONObject.names() == null) { - return; - } - - String key = mJSONObject.names().optString(position - 1); // 遍历key - Object value = mJSONObject.opt(key); - if (position < getItemCount() - 2) { - handleJsonObject(key, value, itemView, true, 1); - } else { - handleJsonObject(key, value, itemView, false, 1); // 最后一组,结尾不需要逗号 - } - } - - if (mJSONArray != null) { - if (position == 0) { - itemView.hideLeft(); - itemView.hideIcon(); - itemView.showRight("["); - return; - } else if (position == getItemCount() - 1) { - itemView.hideLeft(); - itemView.hideIcon(); - itemView.showRight("]"); - return; - } - - Object value = mJSONArray.opt(position - 1); // 遍历array - if (position < getItemCount() - 2) { - handleJsonArray(value, itemView, true, 1); - } else { - handleJsonArray(value, itemView, false, 1); // 最后一组,结尾不需要逗号 - } - } - } - - @Override - public int getItemCount() { - if (mJSONObject != null) { - if (mJSONObject.names() != null) { - return mJSONObject.names().length() + 2; - } else { - return 2; - } - } - if (mJSONArray != null) { - return mJSONArray.length() + 2; - } - return 0; - } - - /** - * 处理 value 上级为 JsonObject 的情况,value有key - * - * @param value - * @param key - * @param itemView - * @param appendComma - * @param hierarchy - */ - private void handleJsonObject(String key, Object value, JsonItemView itemView, boolean appendComma, int hierarchy) { - SpannableStringBuilder keyBuilder = new SpannableStringBuilder(Utils.getHierarchyStr(hierarchy)); - keyBuilder.append("\"").append(key).append("\"").append(":"); - keyBuilder.setSpan(new ForegroundColorSpan(KEY_COLOR), 0, keyBuilder.length() - 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - keyBuilder.setSpan(new ForegroundColorSpan(BRACES_COLOR), keyBuilder.length() - 1, keyBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - - itemView.showLeft(keyBuilder); - - handleValue(value, itemView, appendComma, hierarchy); - } - - /** - * 处理 value 上级为 JsonArray 的情况,value无key - * - * @param value - * @param itemView - * @param appendComma 结尾是否需要逗号(最后一组 value 不需要逗号) - * @param hierarchy 缩进层级 - */ - private void handleJsonArray(Object value, JsonItemView itemView, boolean appendComma, int hierarchy) { - itemView.showLeft(new SpannableStringBuilder(Utils.getHierarchyStr(hierarchy))); - - handleValue(value, itemView, appendComma, hierarchy); - } - - /** - * @param value - * @param itemView - * @param appendComma 结尾是否需要逗号(最后一组 key:value 不需要逗号) - * @param hierarchy 缩进层级 - */ - private void handleValue(Object value, JsonItemView itemView, boolean appendComma, int hierarchy) { - SpannableStringBuilder valueBuilder = new SpannableStringBuilder(); - if (value instanceof Number) { - valueBuilder.append(value.toString()); - valueBuilder.setSpan(new ForegroundColorSpan(NUMBER_COLOR), 0, valueBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - } else if (value instanceof Boolean) { - valueBuilder.append(value.toString()); - valueBuilder.setSpan(new ForegroundColorSpan(BOOLEAN_COLOR), 0, valueBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - } else if (value instanceof JSONObject) { - itemView.showIcon(true); - valueBuilder.append("Object{...}"); - valueBuilder.setSpan(new ForegroundColorSpan(BRACES_COLOR), 0, valueBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - itemView.setIconClickListener(new JsonItemClickListener(value, itemView, appendComma, hierarchy + 1)); - } else if (value instanceof JSONArray) { - itemView.showIcon(true); - valueBuilder.append("Array[").append(String.valueOf(((JSONArray) value).length())).append("]"); - int len = valueBuilder.length(); - valueBuilder.setSpan(new ForegroundColorSpan(BRACES_COLOR), 0, 6, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - valueBuilder.setSpan(new ForegroundColorSpan(NUMBER_COLOR), 6, len - 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - valueBuilder.setSpan(new ForegroundColorSpan(BRACES_COLOR), len - 1, len, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - itemView.setIconClickListener(new JsonItemClickListener(value, itemView, appendComma, hierarchy + 1)); - } else if (value instanceof String) { - itemView.hideIcon(); - valueBuilder.append("\"").append(value.toString()).append("\""); - if (Utils.isUrl(value.toString())) { - valueBuilder.setSpan(new ForegroundColorSpan(TEXT_COLOR), 0, 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - valueBuilder.setSpan(new ForegroundColorSpan(URL_COLOR), 1, valueBuilder.length() - 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - valueBuilder.setSpan(new ForegroundColorSpan(TEXT_COLOR), valueBuilder.length() - 1, valueBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - } else { - valueBuilder.setSpan(new ForegroundColorSpan(TEXT_COLOR), 0, valueBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - } - } else if (valueBuilder.length() == 0 || value == null) { - itemView.hideIcon(); - valueBuilder.append("null"); - valueBuilder.setSpan(new ForegroundColorSpan(NULL_COLOR), 0, valueBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); - } - if (appendComma) { - valueBuilder.append(","); - } - - itemView.showRight(valueBuilder); - } - - class JsonItemClickListener implements View.OnClickListener { - - private Object value; - private JsonItemView itemView; - private boolean appendComma; - private int hierarchy; - - private boolean isCollapsed = true; - private boolean isJsonArray; - - JsonItemClickListener(Object value, JsonItemView itemView, boolean appendComma, int hierarchy) { - this.value = value; - this.itemView = itemView; - this.appendComma = appendComma; - this.hierarchy = hierarchy; - this.isJsonArray = value != null && value instanceof JSONArray; - } - - @Override - public void onClick(View view) { - if (itemView.getChildCount() == 1) { // 初始(折叠) --> 展开"" - isCollapsed = false; - itemView.showIcon(false); - itemView.setTag(itemView.getRightText()); - itemView.showRight(isJsonArray ? "[" : "{"); - JSONArray array = isJsonArray ? (JSONArray) value : ((JSONObject) value).names(); - for (int i = 0; array != null && i < array.length(); i++) { - JsonItemView childItemView = new JsonItemView(itemView.getContext()); - childItemView.setTextSize(TEXT_SIZE_DP); - childItemView.setRightColor(BRACES_COLOR); - Object childValue = array.opt(i); - if (isJsonArray) { - handleJsonArray(childValue, childItemView, i < array.length() - 1, hierarchy); - } else { - handleJsonObject((String) childValue, ((JSONObject) value).opt((String) childValue), childItemView, i < array.length() - 1, hierarchy); - } - itemView.addViewNoInvalidate(childItemView); - } - - JsonItemView childItemView = new JsonItemView(itemView.getContext()); - childItemView.setTextSize(TEXT_SIZE_DP); - childItemView.setRightColor(BRACES_COLOR); - StringBuilder builder = new StringBuilder(Utils.getHierarchyStr(hierarchy - 1)); - builder.append(isJsonArray ? "]" : "}").append(appendComma ? "," : ""); - childItemView.showRight(builder); - itemView.addViewNoInvalidate(childItemView); - itemView.requestLayout(); - itemView.invalidate(); - } else { // 折叠 <--> 展开 - CharSequence temp = itemView.getRightText(); - itemView.showRight((CharSequence) itemView.getTag()); - itemView.setTag(temp); - itemView.showIcon(!isCollapsed); - for (int i = 1; i < itemView.getChildCount(); i++) { - itemView.getChildAt(i).setVisibility(isCollapsed ? View.VISIBLE : View.GONE); - } - isCollapsed = !isCollapsed; - } - } - } - - class JsonItemViewHolder extends RecyclerView.ViewHolder { - - JsonItemView itemView; - - JsonItemViewHolder(JsonItemView itemView) { - super(itemView); - setIsRecyclable(false); - this.itemView = itemView; - } - } -} diff --git a/libs/jsonviewer/src/main/java/com/yuyh/jsonviewer/library/utils/Utils.java b/libs/jsonviewer/src/main/java/com/yuyh/jsonviewer/library/utils/Utils.java deleted file mode 100644 index 1cc59bd..0000000 --- a/libs/jsonviewer/src/main/java/com/yuyh/jsonviewer/library/utils/Utils.java +++ /dev/null @@ -1,85 +0,0 @@ -package com.yuyh.jsonviewer.library.utils; - -import java.util.regex.Pattern; - -/** - * Created by yuyuhang on 2017/11/30. - */ -public class Utils { - - private static Pattern urlPattern = Pattern.compile("^((https|http|ftp|rtsp|mms)?://)" - + "?(([0-9a-z_!~*'().&=+$%-]+: )?[0-9a-z_!~*'().&=+$%-]+@)?" //ftp的user@ - + "(([0-9]{1,3}\\.){3}[0-9]{1,3}" // IP形式的URL- 199.194.52.184 - + "|" // 允许IP和DOMAIN(域名) - + "([0-9a-z_!~*'()-]+\\.)*" // 域名- www. - + "([0-9a-z][0-9a-z-]{0,61})?[0-9a-z]\\." // 二级域名 - + "[a-z]{2,6})" // first level domain- .com or .museum - + "(:[0-9]{1,4})?" // 端口- :80 - + "((/?)|" // a slash isn't required if there is no file name - + "(/[0-9a-z_!~*'().;?:@&=+$,%#-]+)+/?)$"); - - /** - * 判断字符串是否是url - * - * @param str - * @return - */ - public static boolean isUrl(String str) { - return urlPattern.matcher(str).matches(); - } - - /** - * json 格式化缩进(格式化前不能有缩进,最好是格式化从服务端下发的) - * - * @param jsonStr - * @return - */ - public static String jsonFormat(String jsonStr) { - if (jsonStr == null) return ""; - int level = 0; - StringBuilder builder = new StringBuilder(); - for (int i = 0; i < jsonStr.length(); i++) { - char c = jsonStr.charAt(i); - if (level > 0 && '\n' == builder.charAt(builder.length() - 1)) { - builder.append(getHierarchyStr(level)); - } - switch (c) { - case '{': - case '[': - builder.append(c).append("\n"); - level++; - break; - case ',': - builder.append(c).append("\n"); - break; - case '}': - case ']': - builder.append("\n"); - level--; - builder.append(getHierarchyStr(level)); - builder.append(c); - break; - default: - builder.append(c); - break; - } - } - - return builder.toString(); - } - - /** - * 对应层级前面所需的空格数 - * - * @param hierarchy 缩进层级 - * @return - */ - public static String getHierarchyStr(int hierarchy) { - StringBuilder levelStr = new StringBuilder(); - for (int levelI = 0; levelI < hierarchy; levelI++) { - levelStr.append(" "); - } - return levelStr.toString(); - } - -} diff --git a/libs/jsonviewer/src/main/java/com/yuyh/jsonviewer/library/view/JsonItemView.java b/libs/jsonviewer/src/main/java/com/yuyh/jsonviewer/library/view/JsonItemView.java deleted file mode 100644 index 05e6f26..0000000 --- a/libs/jsonviewer/src/main/java/com/yuyh/jsonviewer/library/view/JsonItemView.java +++ /dev/null @@ -1,133 +0,0 @@ -package com.yuyh.jsonviewer.library.view; - -import android.content.Context; -import android.util.AttributeSet; -import android.util.TypedValue; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.TextView; - -import androidx.annotation.Nullable; - -import com.yuyh.jsonviewer.library.R; -import com.yuyh.jsonviewer.library.adapter.BaseJsonViewerAdapter; - -/** - * Created by yuyuhang on 2017/11/29. - */ -public class JsonItemView extends LinearLayout { - - public static int TEXT_SIZE_DP = 12; - - private Context mContext; - - private TextView mTvLeft, mTvRight; - private ImageView mIvIcon; - - public JsonItemView(Context context) { - this(context, null); - } - - public JsonItemView(Context context, @Nullable AttributeSet attrs) { - this(context, attrs, 0); - } - - public JsonItemView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - - mContext = context; - - initView(); - } - - private void initView() { - setOrientation(VERTICAL); - LayoutInflater.from(mContext).inflate(R.layout.jsonviewer_layout_item_view, this, true); - - mTvLeft = findViewById(R.id.tv_left); - mTvRight = findViewById(R.id.tv_right); - mIvIcon = findViewById(R.id.iv_icon); - } - - public void setTextSize(float textSizeDp) { - if (textSizeDp < 12) { - textSizeDp = 12; - } else if (textSizeDp > 30) { - textSizeDp = 30; - } - - TEXT_SIZE_DP = (int) textSizeDp; - - mTvLeft.setTextSize(TEXT_SIZE_DP); - mTvRight.setTextSize(TEXT_SIZE_DP); - mTvRight.setTextColor(BaseJsonViewerAdapter.BRACES_COLOR); - - // align the vertically expand/collapse icon to the text - int textSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, TEXT_SIZE_DP, getResources().getDisplayMetrics()); - - LinearLayout.LayoutParams layoutParams = (LinearLayout.LayoutParams) mIvIcon.getLayoutParams(); - layoutParams.height = textSize; - layoutParams.width = textSize; - layoutParams.topMargin = textSize / 5; - - mIvIcon.setLayoutParams(layoutParams); - } - - public void setRightColor(int color) { - mTvRight.setTextColor(color); - } - - public void hideLeft() { - mTvLeft.setVisibility(GONE); - } - - public void showLeft(CharSequence text) { - mTvLeft.setVisibility(VISIBLE); - if (text != null) { - mTvLeft.setText(text); - } - } - - public void hideRight() { - mTvRight.setVisibility(GONE); - } - - public void showRight(CharSequence text) { - mTvRight.setVisibility(VISIBLE); - if (text != null) { - mTvRight.setText(text); - } - } - - public CharSequence getRightText() { - return mTvRight.getText(); - } - - public void hideIcon() { - mIvIcon.setVisibility(GONE); - } - - public void showIcon(boolean isPlus) { - mIvIcon.setVisibility(VISIBLE); - mIvIcon.setImageResource(isPlus ? R.drawable.jsonviewer_plus : R.drawable.jsonviewer_minus); - mIvIcon.setContentDescription(getResources().getString(isPlus ? R.string.jsonViewer_icon_plus : R.string.jsonViewer_icon_minus)); - } - - public void setIconClickListener(OnClickListener listener) { - mIvIcon.setOnClickListener(listener); - } - - public void addViewNoInvalidate(View child) { - ViewGroup.LayoutParams params = child.getLayoutParams(); - if (params == null) { - params = generateDefaultLayoutParams(); - if (params == null) { - throw new IllegalArgumentException("generateDefaultLayoutParams() cannot return null"); - } - } - addViewInLayout(child, -1, params); - } -} diff --git a/libs/jsonviewer/src/main/res/drawable/jsonviewer_minus.xml b/libs/jsonviewer/src/main/res/drawable/jsonviewer_minus.xml deleted file mode 100644 index d7ec09a..0000000 --- a/libs/jsonviewer/src/main/res/drawable/jsonviewer_minus.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/libs/jsonviewer/src/main/res/drawable/jsonviewer_plus.xml b/libs/jsonviewer/src/main/res/drawable/jsonviewer_plus.xml deleted file mode 100644 index b41fc31..0000000 --- a/libs/jsonviewer/src/main/res/drawable/jsonviewer_plus.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/libs/jsonviewer/src/main/res/layout/jsonviewer_layout_item_view.xml b/libs/jsonviewer/src/main/res/layout/jsonviewer_layout_item_view.xml deleted file mode 100644 index 4887a0e..0000000 --- a/libs/jsonviewer/src/main/res/layout/jsonviewer_layout_item_view.xml +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/libs/jsonviewer/src/main/res/values/strings.xml b/libs/jsonviewer/src/main/res/values/strings.xml deleted file mode 100644 index c2e6692..0000000 --- a/libs/jsonviewer/src/main/res/values/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ - - expand - collapse - diff --git a/settings.gradle b/settings.gradle index 92b831f..13d6585 100644 --- a/settings.gradle +++ b/settings.gradle @@ -2,7 +2,4 @@ include ':BackupApp' rootProject.name = "Backup" include ':BackupAPI' -project(':BackupAPI').projectDir = new File('BackupAPI/BackupAPI') - -include ':jsonviewer' -project(':jsonviewer').projectDir = new File('libs/jsonviewer') \ No newline at end of file +project(':BackupAPI').projectDir = new File('BackupAPI/BackupAPI') \ No newline at end of file From 57e743c5c9f5fb8013df4e387830a6be798732c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20L=C3=A4nge?= Date: Fri, 14 Jun 2024 16:40:14 +0200 Subject: [PATCH 09/15] Update dependencies --- BackupApp/build.gradle | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/BackupApp/build.gradle b/BackupApp/build.gradle index a2f4b1c..a787475 100644 --- a/BackupApp/build.gradle +++ b/BackupApp/build.gradle @@ -91,18 +91,18 @@ dependencies { implementation fileTree(dir: "libs", include: ["*.jar"]) implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.1' + implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4' - implementation 'androidx.core:core-ktx:1.8.0' - implementation 'androidx.appcompat:appcompat:1.4.2' + implementation 'androidx.core:core-ktx:1.13.1' + implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'androidx.legacy:legacy-support-v4:1.0.0' - implementation 'androidx.recyclerview:recyclerview:1.2.1' - implementation 'com.google.android.material:material:1.6.1' + implementation 'androidx.recyclerview:recyclerview:1.3.2' + implementation 'com.google.android.material:material:1.11.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' - testImplementation 'junit:junit:4.13.1' - androidTestImplementation 'androidx.test.ext:junit:1.1.3' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' + testImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.5' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' // OpenPGP API implementation 'org.sufficientlysecure:openpgp-api:12.0' @@ -115,20 +115,20 @@ dependencies { testImplementation "androidx.work:work-testing:$work_version" // Room Database - def roomVersion = "2.5.1" + def roomVersion = "2.6.1" implementation "androidx.room:room-runtime:$roomVersion" annotationProcessor "androidx.room:room-compiler:$roomVersion" kapt "androidx.room:room-compiler:$roomVersion" implementation "androidx.room:room-ktx:$roomVersion" // Lifecycle - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0" - implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.5.0' + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.2" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.8.2' implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' - implementation 'androidx.lifecycle:lifecycle-common-java8:2.5.0' + implementation 'androidx.lifecycle:lifecycle-common-java8:2.8.2' // Preferences - def preference_version = "1.2.0" + def preference_version = "1.2.1" implementation "androidx.preference:preference-ktx:$preference_version" // Glide From 341419966498c7c2ddc33d1fac6c954375987f40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20L=C3=A4nge?= Date: Fri, 14 Jun 2024 16:49:56 +0200 Subject: [PATCH 10/15] Make gradlew executable --- gradlew | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 gradlew diff --git a/gradlew b/gradlew old mode 100644 new mode 100755 From 687e8cf78f1ecbe3aca7109c5b4f11b72a36c7eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20L=C3=A4nge?= Date: Fri, 14 Jun 2024 16:57:03 +0200 Subject: [PATCH 11/15] Remove old workflow --- .github/workflows/main.yml | 53 -------------------------------------- 1 file changed, 53 deletions(-) delete mode 100644 .github/workflows/main.yml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index b85bc32..0000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,53 +0,0 @@ -name: Continuous integration - -on: [push, pull_request] - -jobs: - test: - name: Unit Tests - runs-on: ubuntu-20.04 - steps: - - uses: actions/checkout@v2 - with: - submodules: 'recursive' - - name: Make gradlew executable - run: chmod +x ./gradlew - - name: Run unit tests - run: ./gradlew test - - name: Android Test Report - uses: asadmansr/android-test-report-action@v1.2.0 - -#### These tests can not run because the api and another app needs to be installed -# androidTest: -# name: Instrumented Tests -# runs-on: macOS-latest -# steps: -# - uses: actions/checkout@v2 -# with: -# submodules: 'recursive' -# - name: Set up JDK 1.8 -# uses: actions/setup-java@v1 -# with: -# java-version: 1.8 -# - name: Make gradlew executable -# run: chmod +x ./gradlew -# - name: Run Instrumented Tests -# uses: reactivecircus/android-emulator-runner@v1 -# with: -# api-level: 29 -# arch: x86 -# disable-animations: true -# script: ./gradlew connectedAndroidTest --stacktrace - - apk: - name: Build APK - runs-on: ubuntu-20.04 - - steps: - - uses: actions/checkout@v2 - with: - submodules: 'recursive' - - name: Make gradlew executable - run: chmod +x ./gradlew - - name: Build debug APK - run: ./gradlew assembleDebug From 387277af49a9c7d48719ea6cf4655645abcc5d2d Mon Sep 17 00:00:00 2001 From: Patrick Schneider Date: Fri, 28 Jun 2024 10:19:06 +0200 Subject: [PATCH 12/15] [fix] makes loading icon invisible as expected. --- .../ui/inspection/DataInspectionFragment.kt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/inspection/DataInspectionFragment.kt b/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/inspection/DataInspectionFragment.kt index ad1323f..24e5192 100644 --- a/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/inspection/DataInspectionFragment.kt +++ b/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/ui/inspection/DataInspectionFragment.kt @@ -232,22 +232,22 @@ class DataInspectionFragment : Fragment() { dataBinding.dataInspectionLoadStatusImage.setColorFilter(ContextCompat.getColor(requireActivity(), it.colorRes)) when(it) { LoadStatus.UNKNOWN, null -> { - dataBinding.dataInspectionLoadStatusName.visibility = View.GONE + dataBinding.dataInspectionLoadStatus.visibility = View.GONE } LoadStatus.ERROR_INVALID_JSON, LoadStatus.ERROR -> { - dataBinding.dataInspectionLoadStatusName.visibility = View.VISIBLE + dataBinding.dataInspectionLoadStatus.visibility = View.VISIBLE } LoadStatus.LOADING -> { - dataBinding.dataInspectionLoadStatusName.visibility = View.VISIBLE + dataBinding.dataInspectionLoadStatus.visibility = View.VISIBLE } LoadStatus.DECRYPTING -> { - dataBinding.dataInspectionLoadStatusName.visibility = View.VISIBLE + dataBinding.dataInspectionLoadStatus.visibility = View.VISIBLE } LoadStatus.DECRYPTION_ERROR -> { - dataBinding.dataInspectionLoadStatusName.visibility = View.VISIBLE + dataBinding.dataInspectionLoadStatus.visibility = View.VISIBLE } LoadStatus.DONE -> { - dataBinding.dataInspectionLoadStatusName.visibility = View.GONE + dataBinding.dataInspectionLoadStatus.visibility = View.GONE encryptionEnabled = encryptionEnabled and viewModel.isEncrypted From 3cb7359a7a98cacf7005a4e68a39b25181433694 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20L=C3=A4nge?= Date: Wed, 3 Jul 2024 10:22:46 +0200 Subject: [PATCH 13/15] fix: Replace deprecated android.parcel with parcelize --- .../secuso/privacyfriendlybackup/data/room/model/BackupJob.kt | 2 +- .../privacyfriendlybackup/data/room/model/InternalBackupData.kt | 2 +- .../org/secuso/privacyfriendlybackup/data/room/model/PFAJob.kt | 2 +- .../data/room/model/StoredBackupMetaData.kt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/data/room/model/BackupJob.kt b/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/data/room/model/BackupJob.kt index dcde86d..a7d6d0d 100644 --- a/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/data/room/model/BackupJob.kt +++ b/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/data/room/model/BackupJob.kt @@ -3,7 +3,7 @@ package org.secuso.privacyfriendlybackup.data.room.model import android.os.Parcelable import androidx.recyclerview.widget.DiffUtil import androidx.room.* -import kotlinx.android.parcel.Parcelize +import kotlinx.parcelize.Parcelize import org.secuso.privacyfriendlybackup.data.BackupJobManager import org.secuso.privacyfriendlybackup.data.room.model.enums.BackupJobAction import java.util.* diff --git a/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/data/room/model/InternalBackupData.kt b/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/data/room/model/InternalBackupData.kt index 068daa9..6f86048 100644 --- a/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/data/room/model/InternalBackupData.kt +++ b/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/data/room/model/InternalBackupData.kt @@ -4,7 +4,7 @@ import android.os.Parcelable import androidx.room.Entity import androidx.room.Index import androidx.room.PrimaryKey -import kotlinx.android.parcel.Parcelize +import kotlinx.parcelize.Parcelize import java.util.* @Parcelize diff --git a/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/data/room/model/PFAJob.kt b/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/data/room/model/PFAJob.kt index 7a5a52b..9ad24c3 100644 --- a/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/data/room/model/PFAJob.kt +++ b/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/data/room/model/PFAJob.kt @@ -2,7 +2,7 @@ package org.secuso.privacyfriendlybackup.data.room.model import android.os.Parcelable import androidx.room.* -import kotlinx.android.parcel.Parcelize +import kotlinx.parcelize.Parcelize import org.secuso.privacyfriendlybackup.data.room.model.enums.PFAJobAction import java.util.* diff --git a/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/data/room/model/StoredBackupMetaData.kt b/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/data/room/model/StoredBackupMetaData.kt index a3a99df..35b2e6f 100644 --- a/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/data/room/model/StoredBackupMetaData.kt +++ b/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/data/room/model/StoredBackupMetaData.kt @@ -4,7 +4,7 @@ import android.os.Parcelable import androidx.room.Entity import androidx.room.Index import androidx.room.PrimaryKey -import kotlinx.android.parcel.Parcelize +import kotlinx.parcelize.Parcelize import org.secuso.privacyfriendlybackup.data.room.model.enums.StorageType import java.util.* From bed95487c197292697c652fd60d786c5955a3c90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20L=C3=A4nge?= Date: Wed, 3 Jul 2024 10:51:40 +0200 Subject: [PATCH 14/15] chore: update dependencies Fix workManagerConfiguration in `BackupApplication.kt` to work with the new version --- BackupApp/build.gradle | 23 ++++++++++--------- .../BackupApplication.kt | 12 ++++++---- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/BackupApp/build.gradle b/BackupApp/build.gradle index a787475..e10153a 100644 --- a/BackupApp/build.gradle +++ b/BackupApp/build.gradle @@ -40,9 +40,10 @@ android { } } - applicationVariants.all { variant -> + android.applicationVariants.configureEach { variant -> variant.outputs.all { - outputFileName = "pfa-backup-${variant.name}-v${variant.versionName}.apk" + def appName = "pfa-backup" + outputFileName = appName + "-${variant.name}-v${variant.versionName}.apk" } } @@ -91,24 +92,24 @@ dependencies { implementation fileTree(dir: "libs", include: ["*.jar"]) implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" - implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4' + implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3' implementation 'androidx.core:core-ktx:1.13.1' - implementation 'androidx.appcompat:appcompat:1.6.1' + implementation 'androidx.appcompat:appcompat:1.7.0' implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation 'androidx.recyclerview:recyclerview:1.3.2' - implementation 'com.google.android.material:material:1.11.0' + implementation 'com.google.android.material:material:1.12.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' testImplementation 'junit:junit:4.13.2' - androidTestImplementation 'androidx.test.ext:junit:1.1.5' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' + androidTestImplementation 'androidx.test.ext:junit:1.2.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.6.1' // OpenPGP API implementation 'org.sufficientlysecure:openpgp-api:12.0' // WorkManager - def work_version = "2.8.1" + def work_version = "2.9.0" implementation "androidx.work:work-runtime:$work_version" implementation "androidx.work:work-runtime-ktx:$work_version" androidTestImplementation "androidx.work:work-testing:$work_version" @@ -122,10 +123,10 @@ dependencies { implementation "androidx.room:room-ktx:$roomVersion" // Lifecycle - implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.2" - implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.8.2' + implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.3" + implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.8.3' implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0' - implementation 'androidx.lifecycle:lifecycle-common-java8:2.8.2' + implementation 'androidx.lifecycle:lifecycle-common-java8:2.8.3' // Preferences def preference_version = "1.2.1" diff --git a/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/BackupApplication.kt b/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/BackupApplication.kt index 902a4a3..b86df29 100644 --- a/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/BackupApplication.kt +++ b/BackupApp/src/main/java/org/secuso/privacyfriendlybackup/BackupApplication.kt @@ -5,8 +5,12 @@ import android.app.NotificationChannel import android.app.NotificationManager import android.os.Build import android.util.Log -import androidx.work.* -import org.secuso.privacyfriendlybackup.data.room.BackupDatabase +import androidx.work.BackoffPolicy +import androidx.work.Configuration +import androidx.work.ExistingPeriodicWorkPolicy +import androidx.work.PeriodicWorkRequestBuilder +import androidx.work.WorkManager +import androidx.work.WorkRequest import org.secuso.privacyfriendlybackup.worker.BackupJobManagerWorker import java.util.concurrent.TimeUnit @@ -54,8 +58,8 @@ class BackupApplication : Application(), Configuration.Provider { } } - override fun getWorkManagerConfiguration(): Configuration = - Configuration.Builder() + override val workManagerConfiguration: Configuration + get() = Configuration.Builder() .setMinimumLoggingLevel(Log.ERROR) .build() } \ No newline at end of file From 1db21dfc0917250af7beaf6796c6da49012bbe90 Mon Sep 17 00:00:00 2001 From: Patrick Schneider Date: Thu, 4 Jul 2024 10:54:33 +0200 Subject: [PATCH 15/15] [fix] adds required post_notifications permission. --- BackupApp/src/main/AndroidManifest.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/BackupApp/src/main/AndroidManifest.xml b/BackupApp/src/main/AndroidManifest.xml index 8c5a175..9900b86 100644 --- a/BackupApp/src/main/AndroidManifest.xml +++ b/BackupApp/src/main/AndroidManifest.xml @@ -12,6 +12,7 @@
+