diff --git a/app/build.gradle b/app/build.gradle --- a/app/build.gradle +++ b/app/build.gradle @@ -123,7 +123,7 @@ //multidex - we need this to build the app implementation "androidx.multidex:multidex:$multidex_version" - implementation 'de.siegmar:fastcsv:2.0.0' + implementation 'de.siegmar:fastcsv:2.2.2' testImplementation 'junit:junit:4.12' implementation 'junit:junit:4.12' diff --git a/app/src/main/java/it/reyboz/bustorino/ActivityExperiments.java b/app/src/main/java/it/reyboz/bustorino/ActivityExperiments.java --- a/app/src/main/java/it/reyboz/bustorino/ActivityExperiments.java +++ b/app/src/main/java/it/reyboz/bustorino/ActivityExperiments.java @@ -27,7 +27,7 @@ public class ActivityExperiments extends GeneralActivity implements CommonFragmentListener { - final static String DEBUG_TAG = "ExperimentsGTFS"; + final static String DEBUG_TAG = "ExperimentsActivity"; @Override protected void onCreate(Bundle savedInstanceState) { @@ -54,7 +54,7 @@ //.add(R.id.fragment_container_view, LinesDetailFragment.class, // LinesDetailFragment.Companion.makeArgs("gtt:4U")) - .add(R.id.fragment_container_view, TestRealtimeGtfsFragment.class, null) + .add(R.id.fragment_container_view, TestSavingFragment.class, null) .commit(); } } diff --git a/app/src/main/java/it/reyboz/bustorino/data/DBUpdateWorker.java b/app/src/main/java/it/reyboz/bustorino/data/DBUpdateWorker.java --- a/app/src/main/java/it/reyboz/bustorino/data/DBUpdateWorker.java +++ b/app/src/main/java/it/reyboz/bustorino/data/DBUpdateWorker.java @@ -76,13 +76,13 @@ final NotificationManagerCompat notificationManager = NotificationManagerCompat.from(getApplicationContext()); final int notification_ID = 32198; final SharedPreferences shPr = con.getSharedPreferences(con.getString(R.string.mainSharedPreferences),MODE_PRIVATE); - final int current_DB_version = shPr.getInt(DatabaseUpdate.DB_VERSION_KEY,-10); + final int current_DB_version = shPr.getInt(PreferencesHolder.DB_GTT_VERSION_KEY,-10); final int new_DB_version = DatabaseUpdate.getNewVersion(); final boolean isUpdateCompulsory = getInputData().getBoolean(FORCED_UPDATE,false); - final long lastDBUpdateTime = shPr.getLong(DatabaseUpdate.DB_LAST_UPDATE_KEY, 0); + final long lastDBUpdateTime = shPr.getLong(PreferencesHolder.DB_LAST_UPDATE_KEY, 0); long currentTime = System.currentTimeMillis()/1000; //showNotification(notificationManager, notification_ID); @@ -143,9 +143,9 @@ Log.d(DEBUG_TAG, "Update finished successfully!"); //update the version in the shared preference final SharedPreferences.Editor editor = shPr.edit(); - editor.putInt(DatabaseUpdate.DB_VERSION_KEY, new_DB_version); + editor.putInt(PreferencesHolder.DB_GTT_VERSION_KEY, new_DB_version); currentTime = System.currentTimeMillis()/1000; - editor.putLong(DatabaseUpdate.DB_LAST_UPDATE_KEY, currentTime); + editor.putLong(PreferencesHolder.DB_LAST_UPDATE_KEY, currentTime); editor.apply(); cancelNotification(notification_ID); diff --git a/app/src/main/java/it/reyboz/bustorino/data/DatabaseUpdate.java b/app/src/main/java/it/reyboz/bustorino/data/DatabaseUpdate.java --- a/app/src/main/java/it/reyboz/bustorino/data/DatabaseUpdate.java +++ b/app/src/main/java/it/reyboz/bustorino/data/DatabaseUpdate.java @@ -57,8 +57,7 @@ public static final int VERSION_UNAVAILABLE = -2; public static final int JSON_PARSING_ERROR = -4; - public static final String DB_VERSION_KEY = "NextGenDB.GTTVersion"; - public static final String DB_LAST_UPDATE_KEY = "NextGenDB.LastDBUpdate"; + enum Result { @@ -305,8 +304,8 @@ .build()) .setInputData(reqData) .build(); - final int version = theShPr.getInt(DatabaseUpdate.DB_VERSION_KEY, -10); - final long lastDBUpdateTime = theShPr.getLong(DatabaseUpdate.DB_LAST_UPDATE_KEY, -10); + final int version = theShPr.getInt(PreferencesHolder.DB_GTT_VERSION_KEY, -10); + final long lastDBUpdateTime = theShPr.getLong(PreferencesHolder.DB_LAST_UPDATE_KEY, -10); if ((version >= 0 || lastDBUpdateTime >=0) && !restart) workManager.enqueueUniquePeriodicWork(DBUpdateWorker.DEBUG_TAG, ExistingPeriodicWorkPolicy.KEEP, wr); diff --git a/app/src/main/java/it/reyboz/bustorino/data/PreferencesHolder.java b/app/src/main/java/it/reyboz/bustorino/data/PreferencesHolder.java --- a/app/src/main/java/it/reyboz/bustorino/data/PreferencesHolder.java +++ b/app/src/main/java/it/reyboz/bustorino/data/PreferencesHolder.java @@ -19,7 +19,6 @@ import android.content.Context; import android.content.SharedPreferences; -import android.util.Log; import it.reyboz.bustorino.R; import static android.content.Context.MODE_PRIVATE; @@ -36,9 +35,12 @@ public static final String PREF_GTFS_DB_VERSION = "gtfs_db_version"; public static final String PREF_INTRO_ACTIVITY_RUN ="pref_intro_activity_run"; - + public static final String DB_GTT_VERSION_KEY = "NextGenDB.GTTVersion"; + public static final String DB_LAST_UPDATE_KEY = "NextGenDB.LastDBUpdate"; public static final String PREF_FAVORITE_LINES = "pref_favorite_lines"; + public static final Set IGNORE_KEYS_LOAD_MAIN = Set.of(PREF_GTFS_DB_VERSION, PREF_INTRO_ACTIVITY_RUN, DB_GTT_VERSION_KEY, DB_LAST_UPDATE_KEY); + public static SharedPreferences getMainSharedPreferences(Context context){ return context.getSharedPreferences(context.getString(R.string.mainSharedPreferences), MODE_PRIVATE); } diff --git a/app/src/main/java/it/reyboz/bustorino/data/UserDB.java b/app/src/main/java/it/reyboz/bustorino/data/UserDB.java --- a/app/src/main/java/it/reyboz/bustorino/data/UserDB.java +++ b/app/src/main/java/it/reyboz/bustorino/data/UserDB.java @@ -27,11 +27,13 @@ import android.net.Uri; import android.util.Log; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; +import java.io.IOException; +import java.util.*; +import de.siegmar.fastcsv.reader.CloseableIterator; +import de.siegmar.fastcsv.reader.CsvReader; +import de.siegmar.fastcsv.reader.CsvRow; +import de.siegmar.fastcsv.writer.CsvWriter; import it.reyboz.bustorino.backend.Stop; import it.reyboz.bustorino.backend.StopsDBInterface; @@ -40,8 +42,12 @@ private static final String DATABASE_NAME = "user.db"; static final String TABLE_NAME = "favorites"; private final Context c; // needed during upgrade + public final static String COL_ID = "ID"; + public final static String COL_USERNAME="username"; + + public static final int FILE_INVALID=-10; private final static String[] usernameColumnNameAsArray = {"username"}; - public final static String[] getFavoritesColumnNamesAsArray = {"ID", "username"}; + public final static String[] getFavoritesColumnNamesAsArray = {COL_ID, COL_USERNAME}; private static final Uri FAVORITES_URI = AppDataProvider.getUriBuilderToComplete().appendPath( AppDataProvider.FAVORITES).build(); @@ -323,4 +329,66 @@ return found; } + + //extract rows into CSV + public boolean writeFavoritesToCsv(CsvWriter writer){ + SQLiteDatabase db = this.getReadableDatabase(); + + String sortOrder = + COL_ID + " DESC"; + Cursor cursor = db.query(TABLE_NAME, getFavoritesColumnNamesAsArray,null,null,null,null, sortOrder); + + final int nCols = 2;//cursor.getColumnCount(); + writer.writeRow(cursor.getColumnNames()); + while (cursor.moveToNext()){ + String[] arr = {cursor.getString(0), cursor.getString(1)}; + writer.writeRow(arr); + } + cursor.close(); + return true; + } + + public int insertRowsFromCSV(CsvReader reader){ + SQLiteDatabase db = this.getWritableDatabase(); + + boolean firstrow = true; + final HashMap colIndexByRows = new HashMap<>(); + + final CloseableIterator rowsIter = reader.iterator(); + if (!rowsIter.hasNext()){ + //nothing to do, it's an empty file + return -1; + } + final CsvRow firstRow = rowsIter.next(); + // close if there isn't another rows + if(!rowsIter.hasNext()) return -2; + for (int i =0; i= 0) + updated +=1; + } + db.setTransactionSuccessful(); + db.endTransaction(); + + db.close(); + + return updated; + } } diff --git a/app/src/main/java/it/reyboz/bustorino/fragments/TestSavingFragment.kt b/app/src/main/java/it/reyboz/bustorino/fragments/TestSavingFragment.kt new file mode 100644 --- /dev/null +++ b/app/src/main/java/it/reyboz/bustorino/fragments/TestSavingFragment.kt @@ -0,0 +1,297 @@ +package it.reyboz.bustorino.fragments + +import android.app.Activity +import android.content.Intent +import android.net.Uri +import android.os.Bundle +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.Button +import android.widget.CheckBox +import android.widget.Toast +import androidx.activity.result.contract.ActivityResultContracts +import androidx.fragment.app.Fragment +import de.siegmar.fastcsv.reader.CsvReader +import de.siegmar.fastcsv.writer.CsvWriter +import it.reyboz.bustorino.R +import it.reyboz.bustorino.data.PreferencesHolder +import it.reyboz.bustorino.data.UserDB +import it.reyboz.bustorino.util.Saving +import java.io.* +import java.text.DateFormat +import java.text.SimpleDateFormat +import java.util.* +import java.util.zip.ZipEntry +import java.util.zip.ZipInputStream +import java.util.zip.ZipOutputStream + + +/** + * A simple [Fragment] subclass. + * Use the [TestSavingFragment.newInstance] factory method to + * create an instance of this fragment. + */ +class TestSavingFragment : Fragment() { + + private val saveFileLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> + if (result.resultCode == Activity.RESULT_OK) { + result.data?.data?.also { uri -> + writeDataZip(uri) + } + } + } + + private val openFileLauncher = + registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> + if (!(loadFavorites|| loadPreferences)){ + Toast.makeText(context, R.string.message_check_at_least_one, Toast.LENGTH_SHORT).show() + } + else if (result.resultCode == Activity.RESULT_OK) { + + result.data?.data?.also { uri -> + + loadZipData(uri,loadFavorites, loadPreferences) + } + } + } + + + private lateinit var saveButton: Button + private var loadFavorites = true + private var loadPreferences = true + private lateinit var checkFavorites: CheckBox + private lateinit var checkPreferences: CheckBox + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + /*arguments?.let { + param1 = it.getString(ARG_PARAM1) + param2 = it.getString(ARG_PARAM2) + }*/ + } + + + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + // Inflate the layout for this fragment + val rootview= inflater.inflate(R.layout.fragment_test_saving, container, false) + + saveButton = rootview.findViewById(R.id.saveButton) + saveButton.setOnClickListener { + startFileSaveIntent() + } + checkFavorites = rootview.findViewById(R.id.favoritesCheckBox) + checkFavorites.setOnCheckedChangeListener { _, isChecked -> + loadFavorites = isChecked + + } + checkPreferences = rootview.findViewById(R.id.preferencesCheckBox) + checkPreferences.setOnCheckedChangeListener { _, isChecked -> + loadPreferences = isChecked + + } + val readFavoritesButton = rootview.findViewById