diff --git a/app/src/main/java/com/fieldbook/tracker/activities/FieldEditorActivity.java b/app/src/main/java/com/fieldbook/tracker/activities/FieldEditorActivity.java index 845b7fee3..e5ede39a2 100644 --- a/app/src/main/java/com/fieldbook/tracker/activities/FieldEditorActivity.java +++ b/app/src/main/java/com/fieldbook/tracker/activities/FieldEditorActivity.java @@ -295,7 +295,11 @@ public void onDestroyActionMode(ActionMode mode) { }; public void setActiveField(int studyId) { - FieldObject field = database.getFieldObject(studyId); + + //get current field id and compare the input, only switch if they are different + int currentFieldId = preferences.getInt(GeneralKeys.SELECTED_FIELD_ID, -1); + if (currentFieldId == studyId) return; + fieldSwitcher.switchField(studyId); CollectActivity.reloadData = true; if (mAdapter != null) { diff --git a/app/src/main/java/com/fieldbook/tracker/activities/FileExploreActivity.kt b/app/src/main/java/com/fieldbook/tracker/activities/FileExploreActivity.kt index f885a3a37..7a9329957 100644 --- a/app/src/main/java/com/fieldbook/tracker/activities/FileExploreActivity.kt +++ b/app/src/main/java/com/fieldbook/tracker/activities/FileExploreActivity.kt @@ -117,48 +117,56 @@ class FileExploreActivity : ActivityDialog(), CoroutineScope by MainScope() { mainListView?.onItemClickListener = AdapterView.OnItemClickListener { _: AdapterView<*>?, _: View?, which: Int, _: Long -> - chosenFile = fileList[which].file - //File sel = new File(path + "/" + chosenFile); - val file = path?.findFile(chosenFile!!) - if (file != null && file.exists() && file.isDirectory) { - firstLvl = false - - // Adds chosen directory to list - str.add(chosenFile) - fileList.clear() - path = file - - loadFilesProgress(file, exclude, include) - - } else if (chosenFile.equals(getString(R.string.activity_file_explorer_up_directory_name)) - && (file == null || !file.exists()) - ) { - // present directory removed from list - str.removeAt(str.size - 1) - - // path modified to exclude present directory - path = path?.parentFile - - fileList.clear() - - // if there are no more directories in the list, then - // its the first level - if (str.isEmpty()) { - firstLvl = true - } - loadFilesProgress(path, exclude, include) + launch(Dispatchers.IO) { + + chosenFile = fileList[which].file + //File sel = new File(path + "/" + chosenFile); + val file = path?.findFile(chosenFile!!) + if (file != null && file.exists() && file.isDirectory) { + firstLvl = false + + // Adds chosen directory to list + str.add(chosenFile) + fileList.clear() + path = file + + withContext(Dispatchers.Main) { + loadFilesProgress(file, exclude, include) + } + + } else if (chosenFile.equals(getString(R.string.activity_file_explorer_up_directory_name)) + && (file == null || !file.exists()) + ) { + // present directory removed from list + str.removeAt(str.size - 1) + + // path modified to exclude present directory + path = path?.parentFile + + fileList.clear() + + // if there are no more directories in the list, then + // its the first level + if (str.isEmpty()) { + firstLvl = true + } + + withContext(Dispatchers.Main) { + loadFilesProgress(path, exclude, include) + } - } else { - try { - if (file != null && file.exists()) { - val returnIntent = Intent() - returnIntent.putExtra(EXTRA_RESULT_KEY, file.uri.toString()) - setResult(RESULT_OK, returnIntent) - finish() + } else { + try { + if (file != null && file.exists()) { + val returnIntent = Intent() + returnIntent.putExtra(EXTRA_RESULT_KEY, file.uri.toString()) + setResult(RESULT_OK, returnIntent) + finish() + } + } catch (e: Exception) { + e.printStackTrace() } - } catch (e: Exception) { - e.printStackTrace() } } } diff --git a/app/src/main/java/com/fieldbook/tracker/activities/brapi/BrapiExportActivity.java b/app/src/main/java/com/fieldbook/tracker/activities/brapi/BrapiExportActivity.java index 046ce5d7b..9b15a0db0 100644 --- a/app/src/main/java/com/fieldbook/tracker/activities/brapi/BrapiExportActivity.java +++ b/app/src/main/java/com/fieldbook/tracker/activities/brapi/BrapiExportActivity.java @@ -831,33 +831,42 @@ private void moveToNextField() { } private void showExportButton() { - Button exportButton = findViewById(R.id.brapi_export_btn); - Button nextFieldButton = findViewById(R.id.next_field_btn); - Button closeButton = findViewById(R.id.close_btn); - exportButton.setVisibility(View.VISIBLE); - nextFieldButton.setVisibility(View.GONE); - closeButton.setVisibility(View.GONE); + runOnUiThread(() -> { + Button exportButton = findViewById(R.id.brapi_export_btn); + Button nextFieldButton = findViewById(R.id.next_field_btn); + Button closeButton = findViewById(R.id.close_btn); + + exportButton.setVisibility(View.VISIBLE); + nextFieldButton.setVisibility(View.GONE); + closeButton.setVisibility(View.GONE); + }); } private void showNextFieldButton() { - Button exportButton = findViewById(R.id.brapi_export_btn); - Button nextFieldButton = findViewById(R.id.next_field_btn); - Button closeButton = findViewById(R.id.close_btn); - exportButton.setVisibility(View.GONE); - nextFieldButton.setVisibility(View.VISIBLE); - closeButton.setVisibility(View.GONE); + runOnUiThread(() -> { + Button exportButton = findViewById(R.id.brapi_export_btn); + Button nextFieldButton = findViewById(R.id.next_field_btn); + Button closeButton = findViewById(R.id.close_btn); + + exportButton.setVisibility(View.GONE); + nextFieldButton.setVisibility(View.VISIBLE); + closeButton.setVisibility(View.GONE); + }); } private void showCloseButton() { - Button exportButton = findViewById(R.id.brapi_export_btn); - Button nextFieldButton = findViewById(R.id.next_field_btn); - Button closeButton = findViewById(R.id.close_btn); - exportButton.setVisibility(View.GONE); - nextFieldButton.setVisibility(View.GONE); - closeButton.setVisibility(View.VISIBLE); + runOnUiThread(() -> { + Button exportButton = findViewById(R.id.brapi_export_btn); + Button nextFieldButton = findViewById(R.id.next_field_btn); + Button closeButton = findViewById(R.id.close_btn); + + exportButton.setVisibility(View.GONE); + nextFieldButton.setVisibility(View.GONE); + closeButton.setVisibility(View.VISIBLE); + }); } public enum UploadError { diff --git a/app/src/main/java/com/fieldbook/tracker/activities/brapi/io/BrapiStudyImportActivity.kt b/app/src/main/java/com/fieldbook/tracker/activities/brapi/io/BrapiStudyImportActivity.kt index c9762c780..53f27199e 100644 --- a/app/src/main/java/com/fieldbook/tracker/activities/brapi/io/BrapiStudyImportActivity.kt +++ b/app/src/main/java/com/fieldbook/tracker/activities/brapi/io/BrapiStudyImportActivity.kt @@ -653,7 +653,7 @@ class BrapiStudyImportActivity : ThemedActivity(), CoroutineScope by MainScope() attributesTable?.get(study.studyDbId)?.let { studyAttributes -> observationUnits[study.studyDbId]?.filter { - if (it.observationUnitPosition.entryType.name == "TEST") true + if (it.observationUnitPosition?.entryType?.name == "TEST") true else it.observationUnitPosition.observationLevel.levelName == level.observationLevelName } ?.let { units -> diff --git a/app/src/main/java/com/fieldbook/tracker/brapi/BrapiLoadDialog.java b/app/src/main/java/com/fieldbook/tracker/brapi/BrapiLoadDialog.java index 34d80c242..5b13198cb 100644 --- a/app/src/main/java/com/fieldbook/tracker/brapi/BrapiLoadDialog.java +++ b/app/src/main/java/com/fieldbook/tracker/brapi/BrapiLoadDialog.java @@ -327,7 +327,10 @@ private void loadStudy() { primary.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView adapterView, View view, int index, long id) { - selectedPrimary = studyDetails.getAttributes().get(index); + List attrs = studyDetails.getAttributes(); + if (attrs != null && !attrs.isEmpty() && index < attrs.size()) { + selectedPrimary = attrs.get(index); + } } @Override @@ -341,7 +344,10 @@ public void onNothingSelected(AdapterView adapterView) { secondary.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView adapterView, View view, int index, long id) { - selectedSecondary = studyDetails.getAttributes().get(index); + List attrs = studyDetails.getAttributes(); + if (attrs != null && !attrs.isEmpty() && index < attrs.size()) { + selectedSecondary = attrs.get(index); + } } @Override @@ -355,7 +361,10 @@ public void onNothingSelected(AdapterView adapterView) { sort.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override public void onItemSelected(AdapterView adapterView, View view, int index, long id) { - selectedSort = studyDetails.getAttributes().get(index); + List attrs = studyDetails.getAttributes(); + if (attrs != null && !attrs.isEmpty() && index < attrs.size()) { + selectedSort = attrs.get(index); + } } @Override diff --git a/app/src/main/java/com/fieldbook/tracker/database/dao/ObservationUnitPropertyDao.kt b/app/src/main/java/com/fieldbook/tracker/database/dao/ObservationUnitPropertyDao.kt index dfdafbbf9..68b7da0b6 100644 --- a/app/src/main/java/com/fieldbook/tracker/database/dao/ObservationUnitPropertyDao.kt +++ b/app/src/main/java/com/fieldbook/tracker/database/dao/ObservationUnitPropertyDao.kt @@ -318,19 +318,25 @@ class ObservationUnitPropertyDao { getExportTableData(context, expId, traits)?.use { cursor -> - val requiredColumns = arrayOf(uniqueName) + traits.map { it.name }.toTypedArray() + val requiredTraits = traits.map { it.name }.toTypedArray() + val requiredColumns = arrayOf(uniqueName) + requiredTraits val matrixCursor = MatrixCursor(requiredColumns) + val traitStartIndex = cursor.columnCount - requiredTraits.size while (cursor.moveToNext()) { val rowData = mutableListOf() - requiredColumns.forEachIndexed { index, s -> + //add the unique id + rowData.add(cursor.getStringOrNull(0)) + + //skip ahead to the traits and add all trait values + requiredTraits.forEachIndexed { index, s -> try { rowData.add( - cursor.getStringOrNull(index) + cursor.getStringOrNull(index + traitStartIndex) ) } catch (e: Exception) { diff --git a/app/src/main/java/com/fieldbook/tracker/utilities/ExportUtil.kt b/app/src/main/java/com/fieldbook/tracker/utilities/ExportUtil.kt index cb45c4b91..7e85c93ff 100644 --- a/app/src/main/java/com/fieldbook/tracker/utilities/ExportUtil.kt +++ b/app/src/main/java/com/fieldbook/tracker/utilities/ExportUtil.kt @@ -114,10 +114,14 @@ class ExportUtil @Inject constructor(@ActivityContext private val context: Conte val perms = arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE) if (EasyPermissions.hasPermissions(context, *perms) || Build.VERSION.SDK_INT > Build.VERSION_CODES.P) { - if (fieldIds.isNotEmpty()) { - exportLocal(fieldIds.mapNotNull { database.getFieldObject(it) }) + val fieldsToExport = fieldIds.mapNotNull { database.getFieldObject(it) } + + if (fieldsToExport.isNotEmpty()) { + + exportLocal(fieldsToExport) } + } else { EasyPermissions.requestPermissions( context as Activity, diff --git a/app/src/main/java/com/fieldbook/tracker/views/RangeBoxView.kt b/app/src/main/java/com/fieldbook/tracker/views/RangeBoxView.kt index da2a5d33a..f134c38e2 100644 --- a/app/src/main/java/com/fieldbook/tracker/views/RangeBoxView.kt +++ b/app/src/main/java/com/fieldbook/tracker/views/RangeBoxView.kt @@ -3,7 +3,7 @@ package com.fieldbook.tracker.views import android.app.Service import android.content.Context import android.content.SharedPreferences -import android.database.sqlite.SQLiteException +import android.database.Cursor import android.os.Handler import android.text.Editable import android.text.TextWatcher @@ -22,14 +22,11 @@ import android.widget.TextView import android.widget.Toast import androidx.constraintlayout.widget.ConstraintLayout import com.fieldbook.tracker.R -import com.fieldbook.tracker.activities.CollectActivity import com.fieldbook.tracker.interfaces.CollectRangeController import com.fieldbook.tracker.objects.RangeObject import com.fieldbook.tracker.objects.TraitObject import com.fieldbook.tracker.preferences.GeneralKeys import com.fieldbook.tracker.utilities.Utils -import com.google.firebase.crashlytics.CustomKeysAndValues -import com.google.firebase.crashlytics.FirebaseCrashlytics import java.util.* class RangeBoxView : ConstraintLayout { @@ -80,6 +77,8 @@ class RangeBoxView : ConstraintLayout { private var delay = 100 private var count = 1 + private var exportDataCursor: Cursor? = null + init { val v = inflate(context, R.layout.view_range_box, this) @@ -105,6 +104,9 @@ class RangeBoxView : ConstraintLayout { firstName = controller.getPreferences().getString(GeneralKeys.PRIMARY_NAME, "") ?: "" secondName = controller.getPreferences().getString(GeneralKeys.SECONDARY_NAME, "") ?: "" uniqueName = controller.getPreferences().getString(GeneralKeys.UNIQUE_NAME, "") ?: "" + + refreshCursor() + } constructor(ctx: Context) : super(ctx) @@ -631,13 +633,10 @@ class RangeBoxView : ConstraintLayout { } private fun moveToNextUncollectedObs(currentPos: Int, direction: Int, traits: ArrayList): Int { - val studyId = controller.getPreferences().getInt(GeneralKeys.SELECTED_FIELD_ID, 0) - val study = controller.getDatabase().getFieldObject(studyId) - val cursor = controller.getDatabase().getExportTableDataShort(studyId, study.unique_id, traits) val traitNames = traits.map { it.name } - cursor?.use { + exportDataCursor?.use { cursor -> // Convert one-based range position to zero-based cursor position val zeroBasedPos = currentPos - 1 cursor.moveToPosition(zeroBasedPos) @@ -675,7 +674,6 @@ class RangeBoxView : ConstraintLayout { return pos } } - } } } @@ -716,4 +714,12 @@ class RangeBoxView : ConstraintLayout { fun clickRight() { rangeRight.performClick() } + + fun refreshCursor() { + exportDataCursor?.close() + val studyId = controller.getPreferences().getInt(GeneralKeys.SELECTED_FIELD_ID, 0) + val uniqueName = controller.getPreferences().getString(GeneralKeys.UNIQUE_NAME, "") ?: "" + val traits = controller.getDatabase().visibleTraitObjects + exportDataCursor = controller.getDatabase().getExportTableDataShort(studyId, uniqueName, traits) + } } \ No newline at end of file