diff options
author | mdankov <mdankov@ffa7fe5e-494d-0410-b361-a75ebd5db220> | 2013-08-11 16:00:27 +0000 |
---|---|---|
committer | mdankov <mdankov@ffa7fe5e-494d-0410-b361-a75ebd5db220> | 2013-08-11 16:00:27 +0000 |
commit | eebd0a7b5eba22666df57e914ccd0b799e3e4ef2 (patch) | |
tree | 54b4efe5457695e7e54f77138aec3ef0381bd3b8 /navit | |
parent | c35edb2152d6f41d61701c002aa7e1fb9b96eb48 (diff) | |
download | navit-eebd0a7b5eba22666df57e914ccd0b799e3e4ef2.tar.gz |
Add:port_android:Backup / Restore Function for Android Devices, see #1148|thank you, kamikaaze!
git-svn-id: http://svn.code.sf.net/p/navit/code/trunk/navit@5562 ffa7fe5e-494d-0410-b361-a75ebd5db220
Diffstat (limited to 'navit')
-rw-r--r-- | navit/android/res/values-de/strings.xml | 17 | ||||
-rw-r--r-- | navit/android/res/values/strings.xml | 27 | ||||
-rw-r--r-- | navit/android/src/org/navitproject/navit/Navit.java | 60 | ||||
-rw-r--r-- | navit/android/src/org/navitproject/navit/NavitBackupTask.java | 126 | ||||
-rw-r--r-- | navit/android/src/org/navitproject/navit/NavitDialogs.java | 71 | ||||
-rw-r--r-- | navit/android/src/org/navitproject/navit/NavitRestoreTask.java | 144 |
6 files changed, 440 insertions, 5 deletions
diff --git a/navit/android/res/values-de/strings.xml b/navit/android/res/values-de/strings.xml index de9bebb14..317b94fda 100644 --- a/navit/android/res/values-de/strings.xml +++ b/navit/android/res/values-de/strings.xml @@ -24,6 +24,7 @@ <string name="optionsmenu_toggle_poi">POI ein/aus</string> <string name="optionsmenu_address_search">@string/address_search_title</string> <string name="optionsmenu_exit_navit">Navit beenden</string> + <string name="optionsmenu_backup_restore">Sichern / Wiederherstellen</string> <!-- POSITION POP-UP --> <string name="position_popup_title">Position</string> @@ -55,5 +56,21 @@ <string name="address_search_set_destination">Neues Fahrziel:</string> <string name="address_search_towns">Städte</string> <string name="address_search_streets">Straßen</string> + + <!-- Backup Restore --> + <string name="choose_an_action">Bitte auswählen</string> + <string name="please_insert_an_sd_card">Bitte eine SD Karte einlegen</string> + <string name="backing_up">Sichern...</string> + <string name="failed_to_create_backup_directory">Sicherungsverzeichnis konnte nicht erstellt werden</string> + <string name="backup_failed">Sicherung Fehlgeschlagen</string> + <string name="no_backup_found">Keine Sicherung gefunden</string> + <string name="failed_to_restore">Fehler beim Wiederherstellen</string> + <string name="backup_successful">Sicherung erfolgreich</string> + <string name="restore_successful_please_restart_navit">Sicherung Erfolgreich\nNavit bitte neustarten</string> + <string name="backup_not_found">Backup nicht gefunden</string> + <string name="restore_failed">Wiederherstellen fehlgeschlagen</string> + <string name="select_backup">Backup auswählen</string> + <string name="backup">Sichern</string> + <string name="restore">Wiederherstellen</string> </resources> diff --git a/navit/android/res/values/strings.xml b/navit/android/res/values/strings.xml index 0d377a3e5..ce7d09f59 100644 --- a/navit/android/res/values/strings.xml +++ b/navit/android/res/values/strings.xml @@ -28,14 +28,15 @@ <string name="optionsmenu_toggle_poi">Toggle POIs</string> <string name="optionsmenu_address_search">@string/address_search_title</string> <string name="optionsmenu_exit_navit">Exit Navit</string> - + <string name="optionsmenu_backup_restore">Backup / Restore</string> + <!-- POSITION POP-UP --> <string name="position_popup_title">Position</string> <string name="position_popup_drive_here">Route to here</string> <!-- MAP DOWNLOAD --> <string name="map_delete">Delete this map?</string> - <string name="map_download_title">Map Download</string> + <string name="map_download_title">Map download</string> <string name="map_download_downloading">Downloading:</string> <string name="map_download_eta">ETA</string> <string name="map_download_ready">ready</string> @@ -59,6 +60,26 @@ <string name="address_search_set_destination">Setting destination to:</string> <string name="address_search_towns">Towns</string> <string name="address_search_streets">Streets</string> - + + <!-- Backup Restore --> + <string name="choose_an_action">Choose an action</string> + <string name="please_insert_an_sd_card">Please insert an SD Card</string> + <string name="backing_up">Backing up...</string> + <string name="restoring">Restoring...</string> + <string name="failed_to_create_backup_directory">Failed to create backup directory</string> + <string name="backup_failed">Backup failed</string> + <string name="no_backup_found">No backup found</string> + <string name="failed_to_restore">Failed to restore</string> + <string name="backup_successful">Backup successful</string> + <string name="restore_successful_please_restart_navit">Restore Successful\nPlease restart Navit</string> + <string name="backup_not_found">Backup not found</string> + <string name="restore_failed">Restore failed</string> + <string name="select_backup">Select backup</string> + <string name="backup">Backup</string> + <string name="restore">Restore</string> + <string-array name="dialog_backup_restore_items"> + <item >@string/backup</item> + <item >@string/restore</item> + </string-array> </resources> diff --git a/navit/android/src/org/navitproject/navit/Navit.java b/navit/android/src/org/navitproject/navit/Navit.java index 2b13930a4..97c36f710 100644 --- a/navit/android/src/org/navitproject/navit/Navit.java +++ b/navit/android/src/org/navitproject/navit/Navit.java @@ -22,6 +22,9 @@ package org.navitproject.navit; import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
@@ -92,6 +95,46 @@ public class Navit extends Activity static final String FIRST_STARTUP_FILE = NAVIT_DATA_SHARE_DIR + "/has_run_once.txt";
public static final String NAVIT_PREFS = "NavitPrefs";
+ public void removeFileIfExists(String source) {
+ File file = new File(source);
+
+ if (!file.exists())
+ return;
+
+ file.delete();
+ }
+
+ public void copyFileIfExists(String source, String destination) throws IOException {
+ File file = new File(source);
+
+ if (!file.exists())
+ return;
+
+ FileInputStream is = null;
+ FileOutputStream os = null;
+
+ try {
+ is = new FileInputStream(source);
+ os = new FileOutputStream(destination);
+
+ int len;
+ byte buffer[] = new byte[1024];
+
+ while ((len = is.read(buffer)) != -1) {
+ os.write(buffer, 0, len);
+ }
+ } finally {
+ /* Close the FileStreams to prevent Resource leaks */
+ if (is != null)
+ is.close();
+
+ if (os != null)
+ os.close();
+ }
+ return;
+ }
+
+
public static String get_text(String in)
{
return NavitTextTranslations.get_text(in);
@@ -418,6 +461,11 @@ public class Navit extends Activity menu.add(1, 6, 500, getString(R.string.optionsmenu_address_search)); //TRANS
menu.add(1, 99, 900, getString(R.string.optionsmenu_exit_navit)); //TRANS
+
+ /* Only show the Backup to SD-Card Option if we really have one */
+ if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
+ menu.add(1, 7, 700, getString(R.string.optionsmenu_backup_restore)); //TRANS
+
return true;
}
@@ -500,6 +548,10 @@ public class Navit extends Activity Intent search_intent = new Intent(this, NavitAddressSearchActivity.class);
this.startActivityForResult(search_intent, NavitAddressSearch_id);
break;
+ case 7 :
+ /* Backup / Restore */
+ showDialog(NavitDialogs.DIALOG_BACKUP_RESTORE);
+ break;
case 99 :
// exit
this.onStop();
@@ -550,7 +602,13 @@ public class Navit extends Activity }
}
- protected Dialog onCreateDialog(int id)
+ @Override
+ protected void onPrepareDialog(int id, Dialog dialog) {
+ dialogs.prepareDialog(id, dialog);
+ super.onPrepareDialog(id, dialog);
+ }
+
+ protected Dialog onCreateDialog(int id)
{
return dialogs.createDialog(id);
}
diff --git a/navit/android/src/org/navitproject/navit/NavitBackupTask.java b/navit/android/src/org/navitproject/navit/NavitBackupTask.java new file mode 100644 index 000000000..ca52ee46e --- /dev/null +++ b/navit/android/src/org/navitproject/navit/NavitBackupTask.java @@ -0,0 +1,126 @@ + +package org.navitproject.navit; + +import android.app.Activity; +import android.app.ProgressDialog; +import android.content.Context; +import android.os.AsyncTask; +import android.os.Environment; +import android.text.format.Time; +import android.widget.Toast; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectOutputStream; + +public class NavitBackupTask extends AsyncTask<Void, Void, String> { + + private Navit mActivity; + + private ProgressDialog mDialog; + + public NavitBackupTask(Navit context) { + mActivity = context; + } + + @Override + protected void onPreExecute() { + super.onPreExecute(); + + /* Create a Wait Progress Dialog to inform the User that we are working */ + mDialog = new ProgressDialog(mActivity); + mDialog.setIndeterminate(true); + mDialog.setMessage(mActivity.getString(R.string.backing_up)); + mDialog.show(); + } + + @Override + protected String doInBackground(Void... v) { + Time now = new Time(); + now.setToNow(); + + /* This is the Directory where all Subdirectories are stored by date */ + File mainBackupDir = new File(Environment.getExternalStorageDirectory().getPath() + "/navit/backup/"); + + /* Create the Main Backup Directory if it doesn't exist */ + if (!mainBackupDir.isDirectory()) { + if (!mainBackupDir.mkdirs()) + return mActivity.getString(R.string.failed_to_create_backup_directory); + } + + /* Create a Timestamp in the format YYYY-MM-DD-Index */ + String timestamp = now.year + "-" + String.format("%02d", now.month+1) + "-" + String.format("%02d", now.monthDay); + /* Get the next free index */ + int index = 1; + for (String s : mainBackupDir.list()) { + if (s.contains(timestamp)) { + int newIndex = Integer.parseInt(s.substring(11)); + if (newIndex >= index) + index = newIndex + 1; + } + } + timestamp += "-" + index; + + /* This is the Directory in which the Files are copied into */ + File backupDir = new File(Environment.getExternalStorageDirectory().getPath() + "/navit/backup/" + timestamp); + + /* Create the Backup Directory if it doesn't exist */ + if (!backupDir.isDirectory()) { + if (!backupDir.mkdirs()) + return mActivity.getString(R.string.failed_to_create_backup_directory); + } + + ObjectOutputStream preferencesOOs = null; + try { + /* Backup Files in home */ + mActivity.copyFileIfExists(Navit.NAVIT_DATA_DIR + "/home/bookmark.txt", backupDir.getPath() + "/bookmark.txt"); + mActivity.copyFileIfExists(Navit.NAVIT_DATA_DIR + "/home/destination.txt", backupDir.getPath() + "/destination.txt"); + mActivity.copyFileIfExists(Navit.NAVIT_DATA_DIR + "/home/gui_internal.txt", backupDir.getPath() + "/gui_internal.txt"); + + /* Backup Shared Preferences */ + preferencesOOs = new ObjectOutputStream(new FileOutputStream(backupDir.getPath() + "/preferences.bak")); + preferencesOOs.writeObject(mActivity.getSharedPreferences(Navit.NAVIT_PREFS, Context.MODE_PRIVATE).getAll()); + } + catch (IOException e) { + e.printStackTrace(); + return mActivity.getString(R.string.backup_failed); + } + finally { + /* Close Stream to prevent Resource Leaks */ + try { + if (preferencesOOs != null) + preferencesOOs.close(); + } + catch (IOException e) { + e.printStackTrace(); + return mActivity.getString(R.string.backup_failed); + } + } + + return null; + } + + @Override + protected void onPostExecute(String result) { + super.onPostExecute(result); + + /* Dismiss the Wait Progress Dialog */ + mDialog.dismiss(); + + /* If result is non null an Error occured */ + if (result != null) { + Toast.makeText(mActivity, result, Toast.LENGTH_LONG).show(); + return; + } + + Toast.makeText(mActivity, mActivity.getString(R.string.backup_successful), Toast.LENGTH_LONG).show(); + } + + @Override + protected void onCancelled() { + super.onCancelled(); + Toast.makeText(mActivity, mActivity.getString(R.string.backup_failed), Toast.LENGTH_LONG).show(); + mDialog.dismiss(); + } +} diff --git a/navit/android/src/org/navitproject/navit/NavitDialogs.java b/navit/android/src/org/navitproject/navit/NavitDialogs.java index 8cd4cf322..22bb8ca36 100644 --- a/navit/android/src/org/navitproject/navit/NavitDialogs.java +++ b/navit/android/src/org/navitproject/navit/NavitDialogs.java @@ -1,19 +1,26 @@ package org.navitproject.navit; +import java.io.File; +import android.app.AlertDialog; import android.app.Dialog; import android.app.ProgressDialog; import android.content.DialogInterface; +import android.content.DialogInterface.OnClickListener; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.Log; +import android.widget.ArrayAdapter; import android.widget.Toast; +import android.os.Environment; public class NavitDialogs extends Handler{ // Dialogs public static final int DIALOG_MAPDOWNLOAD = 1; - + public static final int DIALOG_BACKUP_RESTORE = 2; + public static final int DIALOG_SELECT_BACKUP = 3; + // dialog messages static final int MSG_MAP_DOWNLOAD_FINISHED = 0; static final int MSG_PROGRESS_BAR = 1; @@ -107,6 +114,8 @@ public class NavitDialogs extends Handler{ Dialog createDialog(int id) { + AlertDialog.Builder builder = new AlertDialog.Builder(mActivity); + switch (id) { case DIALOG_MAPDOWNLOAD : @@ -131,8 +140,68 @@ public class NavitDialogs extends Handler{ Navit.get_text("Map data (c) OpenStreetMap contributors, CC-BY-SA"), Toast.LENGTH_LONG).show(); //TRANS return mapdownloader_dialog; + + case DIALOG_BACKUP_RESTORE : + /* Create a Dialog that Displays Options wether to Backup or Restore */ + builder.setTitle(mActivity.getString(R.string.choose_an_action)). + setCancelable(true). + setItems(R.array.dialog_backup_restore_items, + new DialogInterface.OnClickListener() { + + @Override + public void onClick(DialogInterface dialog, int which) { + /* Notify User if no SD Card present */ + if(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) + Toast.makeText(mActivity,mActivity.getString(R.string.please_insert_an_sd_card), Toast.LENGTH_LONG).show(); + + switch (which) { + case 0: + /* Backup */ + new NavitBackupTask(mActivity).execute(); + break; + case 1: + /* Restore */ + mActivity.showDialog(DIALOG_SELECT_BACKUP); + break; + } + }}); + return builder.create(); + + case DIALOG_SELECT_BACKUP : + /* Create a Dialog with a list from which the user selects the Backup to be restored */ + File mainBackupDir = new File(Environment.getExternalStorageDirectory().getPath() + "/navit/backup/"); + + String[] backups = null; + if(mainBackupDir.isDirectory()) + backups = mainBackupDir.list(); + + if(backups == null || backups.length == 0) { + /* No Backups were found */ + builder.setTitle(mActivity.getText(R.string.no_backup_found)); + builder.setNegativeButton(mActivity.getText(android.R.string.cancel), null); + return builder.create(); + } + + builder.setTitle(mActivity.getString(R.string.select_backup)); + final ArrayAdapter<String> adapter = new ArrayAdapter<String>(mActivity, android.R.layout.simple_spinner_item, backups); + builder.setAdapter(adapter, new OnClickListener(){ + + @Override + public void onClick(DialogInterface dialog, int which) { + new NavitRestoreTask(mActivity, adapter.getItem(which)).execute(); + }}); + builder.setNegativeButton(mActivity.getString(android.R.string.cancel), null); + + return builder.create(); } // should never get here!! return null; } + + public void prepareDialog(int id, Dialog dialog) { + + /* Remove the Dialog to force Android to rerun onCreateDialog */ + if(id == DIALOG_SELECT_BACKUP) + mActivity.removeDialog(id); + } } diff --git a/navit/android/src/org/navitproject/navit/NavitRestoreTask.java b/navit/android/src/org/navitproject/navit/NavitRestoreTask.java new file mode 100644 index 000000000..aaffcb002 --- /dev/null +++ b/navit/android/src/org/navitproject/navit/NavitRestoreTask.java @@ -0,0 +1,144 @@ + +package org.navitproject.navit; + +import android.app.Activity; +import android.app.NotificationManager; +import android.app.ProgressDialog; +import android.content.Context; +import android.content.SharedPreferences.Editor; +import android.os.AsyncTask; +import android.os.Environment; +import android.widget.Toast; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.util.Map; +import java.util.Map.Entry; + +public class NavitRestoreTask extends AsyncTask<Void, Void, String> { + + private Navit mActivity; + + private ProgressDialog mDialog; + + private String mTimestamp; + + public NavitRestoreTask(Navit context, String timestamp) { + mActivity = context; + mTimestamp = timestamp; + } + + @Override + protected void onPreExecute() { + super.onPreExecute(); + + /* Create a Wait Progress Dialog to inform the User that we are working */ + mDialog = new ProgressDialog(mActivity); + mDialog.setIndeterminate(true); + mDialog.setMessage(mActivity.getString(R.string.restoring)); + mDialog.show(); + } + + @SuppressWarnings("unchecked") + @Override + protected String doInBackground(Void... v) { + + /* This is the Directory where all Subdirectories are stored by date */ + File backupDir = new File(Environment.getExternalStorageDirectory().getPath() + "/navit/backup/" + mTimestamp); + + /* Check if there is a Backup Directory */ + if (!backupDir.isDirectory()) + return mActivity.getString(R.string.backup_not_found); + + ObjectInputStream preferenceOIS = null; + try { + /* Delete all old Files in Home */ + mActivity.removeFileIfExists(Navit.NAVIT_DATA_DIR + "/home/bookmark.txt"); + mActivity.removeFileIfExists(Navit.NAVIT_DATA_DIR + "/home/destination.txt"); + mActivity.removeFileIfExists(Navit.NAVIT_DATA_DIR + "/home/gui_internal.txt"); + + + /* Restore Files in home */ + mActivity.copyFileIfExists(backupDir.getPath() + "/bookmark.txt", Navit.NAVIT_DATA_DIR + "/home/bookmark.txt"); + mActivity.copyFileIfExists(backupDir.getPath() + "/destination.txt", Navit.NAVIT_DATA_DIR + "/home/destination.txt"); + mActivity.copyFileIfExists(backupDir.getPath() + "/gui_internal.txt", Navit.NAVIT_DATA_DIR + "/home/gui_internal.txt"); + + /* Restore Shared Preferences */ + preferenceOIS = new ObjectInputStream(new FileInputStream(backupDir.getPath() + "/preferences.bak")); + Map<String, ?> entries = (Map<String, ?>) preferenceOIS.readObject(); + + Editor prefEditor = mActivity.getSharedPreferences(Navit.NAVIT_PREFS, Context.MODE_PRIVATE).edit(); + + /* Remove all old Preferences */ + prefEditor.clear(); + + /* Iterate through all Entries and add them to our Preferences */ + for (Entry<String, ?> entry : entries.entrySet()) { + Object value = entry.getValue(); + String key = entry.getKey(); + + if (value instanceof Boolean) + prefEditor.putBoolean(key, ((Boolean) value).booleanValue()); + else if (value instanceof Float) + prefEditor.putFloat(key, ((Float) value).floatValue()); + else if (value instanceof Integer) + prefEditor.putInt(key, ((Integer) value).intValue()); + else if (value instanceof Long) + prefEditor.putLong(key, ((Long) value).longValue()); + else if (value instanceof String) + prefEditor.putString(key, (String) value); + } + + if (!prefEditor.commit()) + return mActivity.getString(R.string.failed_to_restore); + + } + catch (Exception e) { + e.printStackTrace(); + return mActivity.getString(R.string.failed_to_restore); + } + finally { + try { + /* Close Stream to prevent Resource leak */ + if (preferenceOIS != null) + preferenceOIS.close(); + } + catch (IOException e) { + + } + } + + return null; + } + + @Override + protected void onPostExecute(String result) { + super.onPostExecute(result); + + /* Dismiss the Wait Progress Dialog */ + mDialog.dismiss(); + + /* If result is non null an Error occured */ + if (result != null) { + Toast.makeText(mActivity, result, Toast.LENGTH_LONG).show(); + return; + } + + /* Navit needs to be restarted. Currently the User has to restart it by himself */ + Toast.makeText(mActivity, mActivity.getString(R.string.restore_successful_please_restart_navit), Toast.LENGTH_LONG).show(); + NotificationManager nm = (NotificationManager) mActivity.getSystemService(Context.NOTIFICATION_SERVICE); + nm.cancel(R.string.app_name); + NavitVehicle.removeListener(); + mActivity.finish(); + } + + @Override + protected void onCancelled() { + super.onCancelled(); + Toast.makeText(mActivity, mActivity.getString(R.string.restore_failed), Toast.LENGTH_LONG).show(); + mDialog.dismiss(); + } +} |