Author: kmorin Date: 2014-01-24 11:26:23 +0100 (Fri, 24 Jan 2014) New Revision: 22 Url: http://forge.codelutin.com/projects/wlo/repository/revisions/22 Log: fixes #4191 ?\195?\137cran Configuration refs #4166 Import des r?\195?\169f?\195?\169rentiels Added: trunk/src/fr/ifremer/wlo/storage/StorageUtils.java Modified: trunk/AndroidManifest.xml trunk/res/values-fr/strings.xml trunk/res/values/strings.xml trunk/res/xml/preferences.xml trunk/src/fr/ifremer/wlo/LocationFormActivity.java trunk/src/fr/ifremer/wlo/ScientificSpeciesActivity.java trunk/src/fr/ifremer/wlo/models/referentials/imports/ImportUtil.java trunk/src/fr/ifremer/wlo/preferences/SettingsActivity.java Modified: trunk/AndroidManifest.xml =================================================================== --- trunk/AndroidManifest.xml 2014-01-23 11:29:55 UTC (rev 21) +++ trunk/AndroidManifest.xml 2014-01-24 10:26:23 UTC (rev 22) @@ -20,6 +20,7 @@ <uses-sdk minSdkVersion="7" android:targetSdkVersion="15"/> + <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" android:maxSdkVersion="18"/> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.BLUETOOTH" /> Modified: trunk/res/values/strings.xml =================================================================== --- trunk/res/values/strings.xml 2014-01-23 11:29:55 UTC (rev 21) +++ trunk/res/values/strings.xml 2014-01-24 10:26:23 UTC (rev 22) @@ -77,6 +77,7 @@ <string name="preferences_date_format">Date format</string> <string name="preferences_use_place">Use place</string> <string name="preferences_ichtyometer">Ichtyometer</string> + <string name="preferences_referentials">Referentials</string> <string name="preferences_imports">Imports</string> <string name="preferences_import_summary">%s items currently</string> @@ -91,6 +92,9 @@ <string name="preferences_import_scientific_species">Import scientific species</string> <string name="preferences_import_states">Import states</string> <string name="preferences_import_vessels">Import vessels</string> + <string name="preferences_import_no_external_storage_title">External storage unavailable</string> + <string name="preferences_import_no_external_storage_message">No externat storage is available.\nWould you like to import the data without saving the source file?</string> + <string name="preferences_importing_referential">Importing referential data</string> <!-- Contexts --> <string name="add_context">Create a new context</string> Modified: trunk/res/values-fr/strings.xml =================================================================== --- trunk/res/values-fr/strings.xml 2014-01-23 11:29:55 UTC (rev 21) +++ trunk/res/values-fr/strings.xml 2014-01-24 10:26:23 UTC (rev 22) @@ -72,6 +72,7 @@ <string name="preferences_weight_unit">Unité de poids</string> <string name="preferences_date_format">Format de la date</string> <string name="preferences_use_place">Lieu d\'utilisation</string> + <string name="preferences_referentials">Référentiels</string> <string name="preferences_imports">Imports</string> <string name="preferences_import_summary">%s éléments actuellement</string> @@ -86,6 +87,9 @@ <string name="preferences_import_scientific_species">Importer des espèces scientifiques</string> <string name="preferences_import_states">Importer des états</string> <string name="preferences_import_vessels">Importer des navires</string> + <string name="preferences_import_no_external_storage_title">Stockage externe non trouvé</string> + <string name="preferences_import_no_external_storage_message">Aucun stockage externe n\'est disponible.\nVoulez vous continuer sans sauvegarder le fichier d\'origine ?</string> + <string name="preferences_importing_referential">Import des données du référentiel en cours</string> <!-- Contexts --> <string name="add_context">Créer un nouveau contexte</string> Modified: trunk/res/xml/preferences.xml =================================================================== --- trunk/res/xml/preferences.xml 2014-01-23 11:29:55 UTC (rev 21) +++ trunk/res/xml/preferences.xml 2014-01-24 10:26:23 UTC (rev 22) @@ -33,32 +33,39 @@ </PreferenceCategory> <PreferenceCategory - android:title="@string/preferences_imports" - android:key="preferences_imports"> + android:title="@string/preferences_referentials" + android:key="preferences_referentials"> - <Preference android:title="@string/preferences_import_commercial_species" - android:key="import_commercial_species"/> - <Preference android:title="@string/preferences_import_scientific_species" - android:key="import_scientific_species"/> - <Preference android:title="@string/preferences_import_locations" - android:key="import_locations"/> - <Preference android:title="@string/preferences_import_vessels" - android:key="import_vessels"/> - <Preference android:title="@string/preferences_import_metiers" - android:key="import_metiers"/> - <Preference android:title="@string/preferences_import_presentations" - android:key="import_presentations"/> - <Preference android:title="@string/preferences_import_states" - android:key="import_states"/> - <Preference android:title="@string/preferences_import_mensurations" - android:key="import_mensurations"/> - <Preference android:title="@string/preferences_import_ages" - android:key="import_ages"/> - <Preference android:title="@string/preferences_import_maturities" - android:key="import_maturities"/> - <Preference android:title="@string/preferences_import_genders" - android:key="import_genders"/> + <PreferenceScreen + android:key="preferences_imports" + android:title="@string/preferences_imports" + android:persistent="false"> + <Preference android:title="@string/preferences_import_commercial_species" + android:key="import_commercial_species"/> + <Preference android:title="@string/preferences_import_scientific_species" + android:key="import_scientific_species"/> + <Preference android:title="@string/preferences_import_locations" + android:key="import_locations"/> + <Preference android:title="@string/preferences_import_vessels" + android:key="import_vessels"/> + <Preference android:title="@string/preferences_import_metiers" + android:key="import_metiers"/> + <Preference android:title="@string/preferences_import_presentations" + android:key="import_presentations"/> + <Preference android:title="@string/preferences_import_states" + android:key="import_states"/> + <Preference android:title="@string/preferences_import_mensurations" + android:key="import_mensurations"/> + <Preference android:title="@string/preferences_import_ages" + android:key="import_ages"/> + <Preference android:title="@string/preferences_import_maturities" + android:key="import_maturities"/> + <Preference android:title="@string/preferences_import_genders" + android:key="import_genders"/> + + </PreferenceScreen> + </PreferenceCategory> </PreferenceScreen> \ No newline at end of file Modified: trunk/src/fr/ifremer/wlo/LocationFormActivity.java =================================================================== --- trunk/src/fr/ifremer/wlo/LocationFormActivity.java 2014-01-23 11:29:55 UTC (rev 21) +++ trunk/src/fr/ifremer/wlo/LocationFormActivity.java 2014-01-24 10:26:23 UTC (rev 22) @@ -1,31 +1,22 @@ package fr.ifremer.wlo; import android.content.SharedPreferences; -import android.database.Cursor; import android.os.Bundle; import android.preference.PreferenceManager; import android.support.v4.app.DialogFragment; import android.util.Log; import android.view.View; -import android.widget.AdapterView; -import android.widget.ArrayAdapter; -import android.widget.AutoCompleteTextView; -import android.widget.ListView; -import android.widget.SimpleCursorAdapter; -import android.widget.Spinner; import android.widget.TextView; import com.google.common.collect.Lists; import fr.ifremer.wlo.models.LocationModel; import fr.ifremer.wlo.models.referentials.Location; import fr.ifremer.wlo.preferences.StringPreference; import fr.ifremer.wlo.storage.DataCache; -import fr.ifremer.wlo.storage.WloSqlOpenHelper; import fr.ifremer.wlo.utils.DatePickerFragment; import fr.ifremer.wlo.utils.TimePickerFragment; import fr.ifremer.wlo.utils.UIUtils; import java.util.Calendar; -import java.util.Collection; import java.util.List; /** Modified: trunk/src/fr/ifremer/wlo/ScientificSpeciesActivity.java =================================================================== --- trunk/src/fr/ifremer/wlo/ScientificSpeciesActivity.java 2014-01-23 11:29:55 UTC (rev 21) +++ trunk/src/fr/ifremer/wlo/ScientificSpeciesActivity.java 2014-01-24 10:26:23 UTC (rev 22) @@ -34,7 +34,8 @@ @Override public boolean onCreateOptionsMenu(Menu menu) { CommercialSpeciesModel parent = (CommercialSpeciesModel) parentModel; - if (parent.isSpeciesMix() || adapter.getCount() == 0) { + //TODO handle npe + if (parent == null || parent.isSpeciesMix() || adapter.getCount() == 0) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.model_list_menu, menu); } Modified: trunk/src/fr/ifremer/wlo/models/referentials/imports/ImportUtil.java =================================================================== --- trunk/src/fr/ifremer/wlo/models/referentials/imports/ImportUtil.java 2014-01-23 11:29:55 UTC (rev 21) +++ trunk/src/fr/ifremer/wlo/models/referentials/imports/ImportUtil.java 2014-01-24 10:26:23 UTC (rev 22) @@ -54,7 +54,7 @@ public static void importGenders(Context context, String path) { try { - importAges(context, new FileInputStream(path)); + importGenders(context, new FileInputStream(path)); } catch (FileNotFoundException e) { Log.e(TAG, "File " + path + " not found", e); } @@ -68,7 +68,7 @@ public static void importLocations(Context context, String path) { try { - importAges(context, new FileInputStream(path)); + importLocations(context, new FileInputStream(path)); } catch (FileNotFoundException e) { Log.e(TAG, "File " + path + " not found", e); } @@ -82,7 +82,7 @@ public static void importMaturities(Context context, String path) { try { - importAges(context, new FileInputStream(path)); + importMaturities(context, new FileInputStream(path)); } catch (FileNotFoundException e) { Log.e(TAG, "File " + path + " not found", e); } @@ -96,7 +96,7 @@ public static void importMensurations(Context context, String path) { try { - importAges(context, new FileInputStream(path)); + importMensurations(context, new FileInputStream(path)); } catch (FileNotFoundException e) { Log.e(TAG, "File " + path + " not found", e); } @@ -110,7 +110,7 @@ public static void importMetiers(Context context, String path) { try { - importAges(context, new FileInputStream(path)); + importMetiers(context, new FileInputStream(path)); } catch (FileNotFoundException e) { Log.e(TAG, "File " + path + " not found", e); } @@ -124,7 +124,7 @@ public static void importPresentations(Context context, String path) { try { - importAges(context, new FileInputStream(path)); + importPresentations(context, new FileInputStream(path)); } catch (FileNotFoundException e) { Log.e(TAG, "File " + path + " not found", e); } @@ -138,7 +138,7 @@ public static void importScientificSpecies(Context context, String path) { try { - importAges(context, new FileInputStream(path)); + importScientificSpecies(context, new FileInputStream(path)); } catch (FileNotFoundException e) { Log.e(TAG, "File " + path + " not found", e); } @@ -150,9 +150,9 @@ DataCache.invalidateScientificSpecies(); } - public static void importSates(Context context, String path) { + public static void importStates(Context context, String path) { try { - importAges(context, new FileInputStream(path)); + importStates(context, new FileInputStream(path)); } catch (FileNotFoundException e) { Log.e(TAG, "File " + path + " not found", e); } @@ -166,7 +166,7 @@ public static void importVessels(Context context, String path) { try { - importAges(context, new FileInputStream(path)); + importVessels(context, new FileInputStream(path)); } catch (FileNotFoundException e) { Log.e(TAG, "File " + path + " not found", e); } Modified: trunk/src/fr/ifremer/wlo/preferences/SettingsActivity.java =================================================================== --- trunk/src/fr/ifremer/wlo/preferences/SettingsActivity.java 2014-01-23 11:29:55 UTC (rev 21) +++ trunk/src/fr/ifremer/wlo/preferences/SettingsActivity.java 2014-01-24 10:26:23 UTC (rev 22) @@ -1,21 +1,36 @@ package fr.ifremer.wlo.preferences; +import android.app.AlertDialog; +import android.app.ProgressDialog; import android.content.Context; +import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.os.Bundle; +import android.os.Environment; import android.preference.Preference; import android.preference.PreferenceFragment; +import android.text.format.DateFormat; +import android.util.Log; +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; import com.google.common.collect.Maps; import fr.ifremer.wlo.MainActivity; import fr.ifremer.wlo.R; import fr.ifremer.wlo.WloBaseActivity; import fr.ifremer.wlo.storage.DataCache; +import fr.ifremer.wlo.storage.StorageUtils; import fr.ifremer.wlo.storage.WloSqlOpenHelper; import fr.ifremer.wlo.models.referentials.imports.ImportUtil; +import fr.ifremer.wlo.utils.UIUtils; import fr.ifremer.wlo.utils.filechooser.FileDialog; import fr.ifremer.wlo.utils.filechooser.SelectionMode; +import org.apache.commons.io.FileUtils; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.Date; import java.util.Map; /** @@ -60,6 +75,9 @@ public static class SettingsFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener { + // map pref_key / request code + protected BiMap<String, Integer> requestCodeByPrefKey = HashBiMap.create(); + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -68,14 +86,13 @@ addPreferencesFromResource(R.xml.preferences); // create map pref_key / request code - Map<String, Integer> requestCodeByPrefKey = Maps.newHashMap(); requestCodeByPrefKey.put("import_ages", REQUEST_IMPORT_AGES); requestCodeByPrefKey.put("import_commercial_species", REQUEST_IMPORT_COMMERCIAL_SPECIES); requestCodeByPrefKey.put("import_genders", REQUEST_IMPORT_GENDERS); requestCodeByPrefKey.put("import_locations", REQUEST_IMPORT_LOCATIONS); requestCodeByPrefKey.put("import_maturities", REQUEST_IMPORT_MATURITIES); requestCodeByPrefKey.put("import_mensurations", REQUEST_IMPORT_MENSURATIONS); - requestCodeByPrefKey.put("import_metiers", REQUEST_IMPORT_MENSURATIONS); + requestCodeByPrefKey.put("import_metiers", REQUEST_IMPORT_METIERS); requestCodeByPrefKey.put("import_presentations", REQUEST_IMPORT_PRESENTATIONS); requestCodeByPrefKey.put("import_scientific_species", REQUEST_IMPORT_SCIENTIFIC_SPECIES); requestCodeByPrefKey.put("import_states", REQUEST_IMPORT_STATES); @@ -165,52 +182,122 @@ } @Override - public void onActivityResult(int requestCode, int resultCode, Intent data) { - if (resultCode == RESULT_OK) { - String path = data.getStringExtra(FileDialog.RESULT_PATH); + public void onActivityResult(final int requestCode, final int resultCode, final Intent data) { + if (resultCode == RESULT_OK + && requestCode >= REQUEST_IMPORT_AGES && requestCode <= REQUEST_IMPORT_VESSELS) { + Context context = getActivity(); - switch (requestCode) { - case REQUEST_IMPORT_AGES: - ImportUtil.importAges(context, path); - break; - case REQUEST_IMPORT_COMMERCIAL_SPECIES: - ImportUtil.importCommercialSpecies(context, path); - break; - case REQUEST_IMPORT_GENDERS: - ImportUtil.importGenders(context, path); - break; - case REQUEST_IMPORT_LOCATIONS: - ImportUtil.importLocations(context, path); - break; - case REQUEST_IMPORT_MATURITIES: - ImportUtil.importMaturities(context, path); - break; - case REQUEST_IMPORT_MENSURATIONS: - ImportUtil.importMensurations(context, path); - break; - case REQUEST_IMPORT_METIERS: - ImportUtil.importMetiers(context, path); - break; - case REQUEST_IMPORT_PRESENTATIONS: - ImportUtil.importPresentations(context, path); - break; - case REQUEST_IMPORT_SCIENTIFIC_SPECIES: - ImportUtil.importScientificSpecies(context, path); - break; - case REQUEST_IMPORT_STATES: - ImportUtil.importSates(context, path); - break; - case REQUEST_IMPORT_VESSELS: - ImportUtil.importVessels(context, path); - break; - default: - super.onActivityResult(requestCode, resultCode, data); + if (!StorageUtils.isExternalStorageWritable()) { + AlertDialog dialog = new AlertDialog.Builder(context) + .setTitle(R.string.preferences_import_no_external_storage_title) + .setMessage(R.string.preferences_import_no_external_storage_message) + .setCancelable(false) + .setNegativeButton(R.string.no, UIUtils.getCancelClickListener()) + .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + importData(requestCode, data, false); + } + }).create(); + dialog.show(); + + } else { + importData(requestCode, data, true); } } else { super.onActivityResult(requestCode, resultCode, data); } } + + protected void importData(final int requestCode, final Intent data, final boolean backupFile) { + final Context context = getActivity(); + + final ProgressDialog dialog = new ProgressDialog(context); + dialog.setCancelable(false); + dialog.setMessage(getString(R.string.preferences_importing_referential)); + dialog.show(); + + new Thread(new Runnable() { + @Override + public void run() { + String path = data.getStringExtra(FileDialog.RESULT_PATH); + Log.d(TAG, path); + final int updatedNb; + switch (requestCode) { + case REQUEST_IMPORT_AGES: + ImportUtil.importAges(context, path); + updatedNb = DataCache.getAllAges(context).size(); + break; + case REQUEST_IMPORT_COMMERCIAL_SPECIES: + ImportUtil.importCommercialSpecies(context, path); + updatedNb = DataCache.getAllCommercialSpecies(context).size(); + break; + case REQUEST_IMPORT_GENDERS: + ImportUtil.importGenders(context, path); + updatedNb = DataCache.getAllGenders(context).size(); + break; + case REQUEST_IMPORT_LOCATIONS: + ImportUtil.importLocations(context, path); + updatedNb = DataCache.getAllLocations(context).size(); + break; + case REQUEST_IMPORT_MATURITIES: + ImportUtil.importMaturities(context, path); + updatedNb = DataCache.getAllMaturities(context).size(); + break; + case REQUEST_IMPORT_MENSURATIONS: + ImportUtil.importMensurations(context, path); + updatedNb = DataCache.getAllMensurations(context).size(); + break; + case REQUEST_IMPORT_METIERS: + ImportUtil.importMetiers(context, path); + updatedNb = DataCache.getAllMetiers(context).size(); + break; + case REQUEST_IMPORT_PRESENTATIONS: + ImportUtil.importPresentations(context, path); + updatedNb = DataCache.getAllPresentations(context).size(); + break; + case REQUEST_IMPORT_SCIENTIFIC_SPECIES: + ImportUtil.importScientificSpecies(context, path); + updatedNb = DataCache.getAllScientificSpecies(context).size(); + break; + case REQUEST_IMPORT_STATES: + ImportUtil.importStates(context, path); + updatedNb = DataCache.getAllStates(context).size(); + break; + case REQUEST_IMPORT_VESSELS: + ImportUtil.importVessels(context, path); + updatedNb = DataCache.getAllVessels(context).size(); + break; + default: + updatedNb = 0; + } + + dialog.setOnDismissListener(new DialogInterface.OnDismissListener() { + @Override + public void onDismiss(DialogInterface dialog) { + String key = requestCodeByPrefKey.inverse().get(requestCode); + Preference filePicker = findPreference(key); + filePicker.setSummary(getString(R.string.preferences_import_summary, updatedNb)); + } + }); + + if (backupFile) { + File importedFile = new File(path); + String copyFileName = String.format("%1$tY%1$tm%1$td-%1$tH%1$tM%1$tS-", new Date()) + importedFile.getName(); + File dir = Environment.getExternalStoragePublicDirectory(".wlo"); + File file = new File(dir, copyFileName); + try { + FileUtils.copyInputStreamToFile(new FileInputStream(path), file); + } catch (IOException e) { + Log.e(TAG, "Error while copying the file", e); + } + } + + dialog.dismiss(); + } + }).start(); + } } } \ No newline at end of file Added: trunk/src/fr/ifremer/wlo/storage/StorageUtils.java =================================================================== --- trunk/src/fr/ifremer/wlo/storage/StorageUtils.java (rev 0) +++ trunk/src/fr/ifremer/wlo/storage/StorageUtils.java 2014-01-24 10:26:23 UTC (rev 22) @@ -0,0 +1,18 @@ +package fr.ifremer.wlo.storage; + +import android.os.Environment; + +/** + * @author kmorin <kmorin@codelutin.com> + * @since 0.1 + */ +public class StorageUtils { + + public static boolean isExternalStorageWritable() { + String state = Environment.getExternalStorageState(); + if (Environment.MEDIA_MOUNTED.equals(state)) { + return true; + } + return false; + } +}