summaryrefslogtreecommitdiff
path: root/navit/android
diff options
context:
space:
mode:
authormdankov <mdankov@ffa7fe5e-494d-0410-b361-a75ebd5db220>2013-08-11 16:00:27 +0000
committermdankov <mdankov@ffa7fe5e-494d-0410-b361-a75ebd5db220>2013-08-11 16:00:27 +0000
commite67d74dd65ed2ab802661474dc6a5902a99e1692 (patch)
tree54b4efe5457695e7e54f77138aec3ef0381bd3b8 /navit/android
parentc4b059ebbdb780ea583788dc62538dcb6ca37d47 (diff)
downloadnavit-svn-e67d74dd65ed2ab802661474dc6a5902a99e1692.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/android')
-rw-r--r--navit/android/res/values-de/strings.xml17
-rw-r--r--navit/android/res/values/strings.xml27
-rw-r--r--navit/android/src/org/navitproject/navit/Navit.java60
-rw-r--r--navit/android/src/org/navitproject/navit/NavitBackupTask.java126
-rw-r--r--navit/android/src/org/navitproject/navit/NavitDialogs.java71
-rw-r--r--navit/android/src/org/navitproject/navit/NavitRestoreTask.java144
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 de9bebb1..317b94fd 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 0d377a3e..ce7d09f5 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 2b13930a..97c36f71 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 00000000..ca52ee46
--- /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 8cd4cf32..22bb8ca3 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 00000000..aaffcb00
--- /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();
+ }
+}