Browse Source

Added support for importing/exporting settings via QR code. Fixes #178.

pull/187/head
Eric Kok 10 years ago
parent
commit
219b2b71bc
  1. 30
      app/src/main/java/org/transdroid/core/app/settings/ApplicationSettings.java
  2. 95
      app/src/main/java/org/transdroid/core/app/settings/SettingsPersistence.java
  3. 4
      app/src/main/java/org/transdroid/core/gui/TorrentsActivity.java
  4. 66
      app/src/main/java/org/transdroid/core/gui/search/BarcodeHelper.java
  5. 236
      app/src/main/java/org/transdroid/core/gui/settings/SystemSettingsActivity.java
  6. 4
      app/src/main/res/values/changelog.xml
  7. 4
      app/src/main/res/values/strings.xml

30
app/src/main/java/org/transdroid/core/app/settings/ApplicationSettings.java

@ -258,7 +258,7 @@ public class ApplicationSettings { @@ -258,7 +258,7 @@ public class ApplicationSettings {
edit.putInt("header_defaultserver", --order);
}
edit.commit();
edit.apply();
}
@ -352,7 +352,7 @@ public class ApplicationSettings { @@ -352,7 +352,7 @@ public class ApplicationSettings {
* @param order The key identifying the specific server
*/
public void setLastUsedServerKey(int order) {
prefs.edit().putInt("system_lastusedserver", order).commit();
prefs.edit().putInt("system_lastusedserver", order).apply();
}
/**
@ -367,10 +367,10 @@ public class ApplicationSettings { @@ -367,10 +367,10 @@ public class ApplicationSettings {
/**
* Registers some navigation filter as being the last used by the user
* @param server The navigation filter that the user last used in the interface
* @param filter The navigation filter that the user last used in the interface
*/
public void setLastUsedNavigationFilter(NavigationFilter filter) {
prefs.edit().putString("system_lastusedfilter", filter.getCode()).commit();
prefs.edit().putString("system_lastusedfilter", filter.getCode()).apply();
}
/**
@ -432,7 +432,7 @@ public class ApplicationSettings { @@ -432,7 +432,7 @@ public class ApplicationSettings {
edit.remove("websearch_name_" + max);
edit.remove("websearch_baseurl_" + max);
edit.remove("websearch_cookies_" + max);
edit.commit();
edit.apply();
}
@ -503,7 +503,7 @@ public class ApplicationSettings { @@ -503,7 +503,7 @@ public class ApplicationSettings {
edit.remove("rssfeed_reqauth_" + max);
edit.remove("rssfeed_alarmnew_" + max);
edit.remove("rssfeed_lastviewed_" + max);
edit.commit();
edit.apply();
}
@ -522,7 +522,7 @@ public class ApplicationSettings { @@ -522,7 +522,7 @@ public class ApplicationSettings {
Editor edit = prefs.edit();
edit.putLong("rssfeed_lastviewed_" + order, lastViewed.getTime());
edit.putString("rssfeed_lastvieweditemurl_" + order, lastViewedItemUrl);
edit.commit();
edit.apply();
}
/**
@ -531,8 +531,10 @@ public class ApplicationSettings { @@ -531,8 +531,10 @@ public class ApplicationSettings {
* @param currentSortAscending The sort order direction that was last used
*/
public void setLastUsedSortOrder(TorrentsSortBy currentSortOrder, boolean currentSortAscending) {
prefs.edit().putInt("system_lastusedsortorder", currentSortOrder.getCode()).commit();
prefs.edit().putBoolean("system_lastusedsortdirection", currentSortAscending).commit();
Editor edit = prefs.edit();
edit.putInt("system_lastusedsortorder", currentSortOrder.getCode());
edit.putBoolean("system_lastusedsortdirection", currentSortAscending);
edit.apply();
}
/**
@ -631,10 +633,10 @@ public class ApplicationSettings { @@ -631,10 +633,10 @@ public class ApplicationSettings {
/**
* Registers the unique key of some web search or in-app search site as being last used by the user
* @param order The key identifying the specific server
* @param site The site settings to register as being last used
*/
public void setLastUsedSearchSite(SearchSetting site) {
prefs.edit().putString("header_setsearchsite", site.getKey()).commit();
prefs.edit().putString("header_setsearchsite", site.getKey()).apply();
}
/**
@ -660,7 +662,7 @@ public class ApplicationSettings { @@ -660,7 +662,7 @@ public class ApplicationSettings {
* @param lastStats A JSON array of JSON objects that each represent a single seen torrent
*/
public void setServerLastStats(ServerSetting server, JSONArray lastStats) {
prefs.edit().putString(server.getUniqueIdentifier(), lastStats.toString()).commit();
prefs.edit().putString(server.getUniqueIdentifier(), lastStats.toString()).apply();
}
/**
@ -699,7 +701,7 @@ public class ApplicationSettings { @@ -699,7 +701,7 @@ public class ApplicationSettings {
edit.putBoolean("widget_reverse_" + appWidgetId, settings.shouldReserveSort());
edit.putBoolean("widget_showstatus_" + appWidgetId, settings.shouldShowStatusView());
edit.putBoolean("widget_darktheme_" + appWidgetId, settings.shouldUseDarkTheme());
edit.commit();
edit.apply();
}
/**
@ -714,7 +716,7 @@ public class ApplicationSettings { @@ -714,7 +716,7 @@ public class ApplicationSettings {
edit.remove("widget_reverse_" + appWidgetId);
edit.remove("widget_showstatus_" + appWidgetId);
edit.remove("widget_darktheme_" + appWidgetId);
edit.commit();
edit.apply();
}
}

95
app/src/main/java/org/transdroid/core/app/settings/SettingsPersistence.java

@ -52,21 +52,37 @@ public class SettingsPersistence { @@ -52,21 +52,37 @@ public class SettingsPersistence {
public static final String DEFAULT_SETTINGS_FILENAME = "/settings.json";
public static final File DEFAULT_SETTINGS_FILE = new File(DEFAULT_SETTINGS_DIR + DEFAULT_SETTINGS_FILENAME);
/**
* Reads the server, web searches, RSS feed, background service and system settings from a JSON-encoded String, such as when read via a QR code.
* @param prefs The application-global preferences object to write settings to
* @param contents The JSON-encoded settings as raw String
* @throws JSONException Thrown when the file did not contain valid JSON content
*/
public void importSettingsAsString(SharedPreferences prefs, String contents) throws JSONException {
importSettings(prefs, new JSONObject(contents));
}
/**
* Synchronously reads the server, web searches, RSS feed, background service and system settings from a file in
* JSON format.
* @param settingsFile The local file to write the settings to
* @throws FileNotFoundException Thrown when the settings file doesn't exist or couln't be read
* @param prefs The application-global preferences object to write settings to
* @param settingsFile The local file to read the settings from
* @throws FileNotFoundException Thrown when the settings file doesn't exist or couldn't be read
* @throws JSONException Thrown when the file did not contain valid JSON content
*/
public void importSettings(SharedPreferences prefs, File settingsFile) throws FileNotFoundException,
public void importSettingsFromFile(SharedPreferences prefs, File settingsFile) throws FileNotFoundException,
JSONException {
Editor editor = prefs.edit();
// Read the settings file
String raw = HttpHelper.convertStreamToString(new FileInputStream(settingsFile));
JSONObject json = new JSONObject(raw);
importSettings(prefs, new JSONObject(raw));
}
public void importSettings(SharedPreferences prefs, JSONObject json) throws JSONException {
Editor editor = prefs.edit();
// Import servers
if (json.has("servers")) {
@ -96,7 +112,7 @@ public class SettingsPersistence { @@ -96,7 +112,7 @@ public class SettingsPersistence {
if (server.has("folder"))
editor.putString("server_folder_" + postfix, server.getString("folder"));
if (server.has("use_auth"))
editor.putBoolean("server_useauth_" + postfix, server.getBoolean("use_auth"));
editor.putBoolean("server_disableauth_" + postfix, !server.getBoolean("use_auth"));
if (server.has("username"))
editor.putString("server_user_" + postfix, server.getString("username"));
if (server.has("password"))
@ -132,6 +148,8 @@ public class SettingsPersistence { @@ -132,6 +148,8 @@ public class SettingsPersistence {
editor.putString("websearch_name_" + postfix, site.getString("name"));
if (site.has("url"))
editor.putString("websearch_baseurl_" + postfix, site.getString("url"));
if (site.has("cookies"))
editor.putString("websearch_cookies_" + postfix, site.getString("cookies"));
}
}
@ -149,6 +167,8 @@ public class SettingsPersistence { @@ -149,6 +167,8 @@ public class SettingsPersistence {
editor.putString("rssfeed_url_" + postfix, feed.getString("url"));
if (feed.has("needs_auth"))
editor.putBoolean("rssfeed_reqauth_" + postfix, feed.getBoolean("needs_auth"));
if (feed.has("new_item_alarm"))
editor.putBoolean("rssfeed_alarmnew_" + postfix, feed.getBoolean("new_item_alarm"));
if (feed.has("last_seen"))
editor.putString("rssfeed_lastnew_" + postfix, feed.getString("last_seen"));
@ -168,24 +188,54 @@ public class SettingsPersistence { @@ -168,24 +188,54 @@ public class SettingsPersistence {
editor.putInt("notifications_ledcolour", json.getInt("alarm_ledcolour"));
if (json.has("alarm_adwnotifications"))
editor.putBoolean("notifications_adwnotify", json.getBoolean("alarm_adwnotifications"));
if (json.has("system_dormantasinactive"))
editor.putBoolean("system_dormantasinactive", json.getBoolean("system_dormantasinactive"));
if (json.has("system_autorefresh"))
editor.putString("system_autorefresh", json.getString("system_autorefresh"));
if (json.has("system_checkupdates"))
editor.putBoolean("system_checkupdates", json.getBoolean("system_checkupdates"));
if (json.has("system_usedarktheme"))
editor.putBoolean("system_usedarktheme", json.getBoolean("system_usedarktheme"));
editor.commit();
editor.apply();
}
/**
* Returns encoded server, web searches, RSS feed, background service and system settings as a JSON data object structure, serialized to a String.
* @param prefs The application-global preferences object to read settings from
* @throws JSONException Thrown when the JSON content could not be constructed properly
*/
public String exportSettingsAsString(SharedPreferences prefs) throws JSONException {
return exportSettings(prefs).toString();
}
/**
* Synchronously writes the server, web searches, RSS feed, background service and system settings to a file in JSON
* format.
* @param prefs The application-global preferences object to write settings to
* @param prefs The application-global preferences object to read settings from
* @param settingsFile The local file to read the settings from
* @throws JSONException Thrown when the JSON content could not be constructed properly
* @throws IOException Thrown when the settings file could not be created or written to
*/
public void exportSettings(SharedPreferences prefs, File settingsFile) throws JSONException, IOException {
public void exportSettingsToFile(SharedPreferences prefs, File settingsFile) throws JSONException, IOException {
JSONObject json = exportSettings(prefs);
// Serialise the JSON object to a file
if (settingsFile.exists()) {
settingsFile.delete();
}
settingsFile.getParentFile().mkdirs();
settingsFile.createNewFile();
FileWriter writer = new FileWriter(settingsFile);
writer.write(json.toString(2));
writer.flush();
writer.close();
}
private JSONObject exportSettings(SharedPreferences prefs) throws JSONException {
// Create a single JSON object that will contain all settings
JSONObject json = new JSONObject();
@ -207,7 +257,7 @@ public class SettingsPersistence { @@ -207,7 +257,7 @@ public class SettingsPersistence {
server.put("ssl_accept_all", prefs.getBoolean("server_ssltrustall_" + postfixi, false));
server.put("ssl_trust_key", prefs.getString("server_ssltrustkey_" + postfixi, null));
server.put("folder", prefs.getString("server_folder_" + postfixi, null));
server.put("use_auth", prefs.getBoolean("server_useauth_" + postfixi, true));
server.put("use_auth", !prefs.getBoolean("server_disableauth_" + postfixi, false));
server.put("username", prefs.getString("server_user_" + postfixi, null));
server.put("password", prefs.getString("server_pass_" + postfixi, null));
server.put("extra_password", prefs.getString("server_extrapass_" + postfixi, null));
@ -234,6 +284,7 @@ public class SettingsPersistence { @@ -234,6 +284,7 @@ public class SettingsPersistence {
JSONObject site = new JSONObject();
site.put("name", prefs.getString("websearch_name_" + postfixj, null));
site.put("url", prefs.getString("websearch_baseurl_" + postfixj, null));
site.put("cookies", prefs.getString("websearch_cookies_" + postfixj, null));
sites.put(site);
j++;
@ -251,6 +302,7 @@ public class SettingsPersistence { @@ -251,6 +302,7 @@ public class SettingsPersistence {
feed.put("name", prefs.getString("rssfeed_name_" + postfixk, null));
feed.put("url", prefs.getString("rssfeed_url_" + postfixk, null));
feed.put("needs_auth", prefs.getBoolean("rssfeed_reqauth_" + postfixk, false));
feed.put("new_item_alarm", prefs.getBoolean("rssfeed_alarmnew_" + postfixk, false));
feed.put("last_seen", prefs.getString("rssfeed_lastnew_" + postfixk, null));
feeds.put(feed);
@ -266,20 +318,13 @@ public class SettingsPersistence { @@ -266,20 +318,13 @@ public class SettingsPersistence {
json.put("alarm_vibrate", prefs.getBoolean("notifications_vibrate", false));
json.put("alarm_ledcolour", prefs.getInt("notifications_ledcolour", -1));
json.put("alarm_adwnotifications", prefs.getBoolean("notifications_adwnotify", false));
json.put("system_checkupdates", prefs.getBoolean("system_checkupdates", true));
json.put("system_dormantasinactive", prefs.getBoolean("system_dormantasinactive", false));
json.put("system_autorefresh", prefs.getString("system_autorefresh", "0"));
json.put("system_usedarktheme", prefs.getBoolean("system_usedarktheme", false));
json.put("system_checkupdates", prefs.getBoolean("system_checkupdates", true));
// Serialise the JSON object to a file
if (settingsFile.exists()) {
settingsFile.delete();
}
settingsFile.getParentFile().mkdirs();
settingsFile.createNewFile();
FileWriter writer = new FileWriter(settingsFile);
writer.write(json.toString(2));
writer.flush();
writer.close();
return json;
}
}

4
app/src/main/java/org/transdroid/core/gui/TorrentsActivity.java

@ -712,11 +712,11 @@ public class TorrentsActivity extends Activity implements OnNavigationListener, @@ -712,11 +712,11 @@ public class TorrentsActivity extends Activity implements OnNavigationListener,
@OptionsItem(resName = "action_add_frombarcode")
protected void startBarcodeScanner() {
BarcodeHelper.startBarcodeScanner(this);
BarcodeHelper.startBarcodeScanner(this, BarcodeHelper.ACTIVITY_BARCODE_ADDTORRENT);
}
@Background
@OnActivityResult(BarcodeHelper.ACTIVITY_BARCODE)
@OnActivityResult(BarcodeHelper.ACTIVITY_BARCODE_ADDTORRENT)
public void onBarcodeScanned(int resultCode, Intent data) {
// We receive from the helper either a URL (as string) or a query we can start a search for
String query = BarcodeHelper.handleScanResult(resultCode, data);

66
app/src/main/java/org/transdroid/core/gui/search/BarcodeHelper.java

@ -16,9 +16,6 @@ @@ -16,9 +16,6 @@
*/
package org.transdroid.core.gui.search;
import org.transdroid.R;
import org.transdroid.core.app.search.GoogleWebSearchBarcodeResolver;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
@ -29,23 +26,53 @@ import android.content.Intent; @@ -29,23 +26,53 @@ import android.content.Intent;
import android.net.Uri;
import android.text.TextUtils;
import org.transdroid.R;
import org.transdroid.core.app.search.GoogleWebSearchBarcodeResolver;
public class BarcodeHelper {
public static final int ACTIVITY_BARCODE = 0x0000c0de; // A 'random' ID to identify scan intents
public static final int ACTIVITY_BARCODE_ADDTORRENT = 0x0000c0de;
// A 'random' ID to identify torrent adding scan intents
public static final int ACTIVITY_BARCODE_QRSETTINGS = 0x0000c0df;
// A 'random' ID to identify QR-encoded settings scan intents
public static final Uri SCANNER_MARKET_URI = Uri.parse("market://search?q=pname:com.google.zxing.client.android");
/**
* Call this to start a bar code scanner intent. The calling activity will receive an Intent result with ID
* {@link #ACTIVITY_BARCODE}. From there {@link #handleScanResult(int, Intent)} should be called to parse the result
* into a search query.
* Call this to start a bar code scanner intent. The calling activity will receive an Intent result with ID {@link
* #ACTIVITY_BARCODE_ADDTORRENT} or {@link #ACTIVITY_BARCODE_QRSETTINGS}. From there {@link #handleScanResult(int,
* Intent)} can be called to parse the result into a search query, in case of {@link #ACTIVITY_BARCODE_ADDTORRENT}
* scans.
* @param activity The calling activity, to which the result is returned or a dialog is bound that asks to install
* the bar code scanner
* @param requestCode {@link #ACTIVITY_BARCODE_ADDTORRENT} or {@link #ACTIVITY_BARCODE_QRSETTINGS
*/
public static void startBarcodeScanner(final Activity activity, int requestCode) {
// Start a bar code scanner that can handle the SCAN intent (specifically ZXing)
startBarcodeIntent(activity, new Intent("com.google.zxing.client.android.SCAN"), requestCode);
}
/**
* Call this to share content encoded in a QR code, specially used to share settings. The calling activity will
* receive an Intent result with ID {@link #ACTIVITY_BARCODE_QRSETTINGS}. From there the returned intent will
* contain the data as SCAN_RESULT String extra.
* @param activity The calling activity, to which the result is returned or a dialog is bound that asks to install
* the bar code scanner
* the bar code scanner
* @param content The content to share, that is, the raw data (Transdroid settings encoded as JSON data structure)
* to share as QR code
*/
public static void shareContentBarcode(final Activity activity, final String content) {
// Start a bar code encoded that can handle the ENCODE intent (specifically ZXing)
Intent encodeIntent = new Intent("com.google.zxing.client.android.ENCODE");
encodeIntent.putExtra("ENCODE_TYPE", "TEXT_TYPE");
encodeIntent.putExtra("ENCODE_DATA", content);
encodeIntent.putExtra("ENCODE_SHOW_CONTENTS", false);
startBarcodeIntent(activity, encodeIntent, -1);
}
@SuppressLint("ValidFragment")
public static void startBarcodeScanner(final Activity activity) {
private static void startBarcodeIntent(final Activity activity, final Intent intent, int requestCode) {
try {
// Start a bar code scanner that can handle the SCAN intent (specifically ZXing)
activity.startActivityForResult(new Intent("com.google.zxing.client.android.SCAN"), ACTIVITY_BARCODE);
activity.startActivityForResult(intent, requestCode);
} catch (Exception e) {
// Can't start the bar code scanner, for example with a SecurityException or when ZXing is not present
new DialogFragment() {
@ -55,22 +82,26 @@ public class BarcodeHelper { @@ -55,22 +82,26 @@ public class BarcodeHelper {
.setPositiveButton(android.R.string.yes, new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (activity != null)
if (activity != null) {
activity.startActivity(new Intent(Intent.ACTION_VIEW, SCANNER_MARKET_URI));
}
}
}).setNegativeButton(android.R.string.no, null).create();
};
}
;
}.show(activity.getFragmentManager(), "installscanner");
}
}
/**
* The activity that called {@link #startBarcodeScanner(Activity)} should call this after the scan
* result was returned. This will parse the scan data and return a query search query appropriate to the bar code.
* The activity that called {@link #startBarcodeScanner(android.app.Activity, int)} with {@link
* #ACTIVITY_BARCODE_ADDTORRENT} should call this after the scan result was returned. This will parse the scan data
* and return a query search query appropriate to the bar code.
* @param resultCode The raw result code as returned by the bar code scanner
* @param data The raw data as returned from the bar code scanner
* @return A String that can be used as new search query, or null if the bar code could not be scanned or no query
* can be constructed for it
* can be constructed for it
*/
public static String handleScanResult(int resultCode, Intent data) {
String contents = data.getStringExtra("SCAN_RESULT");
@ -79,8 +110,9 @@ public class BarcodeHelper { @@ -79,8 +110,9 @@ public class BarcodeHelper {
// Scanned barcode was a QR code: return the contents directly
return contents;
} else {
if (TextUtils.isEmpty(contents))
if (TextUtils.isEmpty(contents)) {
return null;
}
// Get a meaningful search query based on a Google Search product lookup
return GoogleWebSearchBarcodeResolver.resolveBarcode(contents);
}

236
app/src/main/java/org/transdroid/core/gui/settings/SystemSettingsActivity.java

@ -16,21 +16,6 @@ @@ -16,21 +16,6 @@
*/
package org.transdroid.core.gui.settings;
import java.io.FileNotFoundException;
import java.io.IOException;
import org.androidannotations.annotations.Bean;
import org.androidannotations.annotations.EActivity;
import org.androidannotations.annotations.OptionsItem;
import org.json.JSONException;
import org.transdroid.R;
import org.transdroid.core.app.settings.ApplicationSettings;
import org.transdroid.core.app.settings.SettingsPersistence;
import org.transdroid.core.gui.log.ErrorLogSender;
import org.transdroid.core.gui.navigation.NavigationHelper;
import org.transdroid.core.gui.search.SearchHistoryProvider;
import org.transdroid.core.service.BootReceiver;
import android.annotation.TargetApi;
import android.app.AlertDialog;
import android.app.Dialog;
@ -45,14 +30,48 @@ import android.preference.Preference; @@ -45,14 +30,48 @@ import android.preference.Preference;
import android.preference.Preference.OnPreferenceClickListener;
import android.preference.PreferenceActivity;
import android.preference.PreferenceManager;
import android.text.TextUtils;
import org.androidannotations.annotations.Bean;
import org.androidannotations.annotations.EActivity;
import org.androidannotations.annotations.OnActivityResult;
import org.androidannotations.annotations.OptionsItem;
import org.json.JSONException;
import org.transdroid.R;
import org.transdroid.core.app.settings.ApplicationSettings;
import org.transdroid.core.app.settings.SettingsPersistence;
import org.transdroid.core.gui.log.ErrorLogSender;
import org.transdroid.core.gui.navigation.NavigationHelper;
import org.transdroid.core.gui.search.BarcodeHelper;
import org.transdroid.core.gui.search.SearchHistoryProvider;
import org.transdroid.core.service.BootReceiver;
import java.io.FileNotFoundException;
import java.io.IOException;
import de.keyboardsurfer.android.widget.crouton.Crouton;
@EActivity
public class SystemSettingsActivity extends PreferenceActivity {
protected static final int DIALOG_IMPORTSETTINGS = 0;
private OnPreferenceClickListener onImportSettingsClick = new OnPreferenceClickListener() {
@SuppressWarnings("deprecation")
@Override
public boolean onPreferenceClick(Preference preference) {
showDialog(DIALOG_IMPORTSETTINGS);
return true;
}
};
protected static final int DIALOG_EXPORTSETTINGS = 1;
private OnPreferenceClickListener onExportSettingsClick = new OnPreferenceClickListener() {
@SuppressWarnings("deprecation")
@Override
public boolean onPreferenceClick(Preference preference) {
showDialog(DIALOG_EXPORTSETTINGS);
return true;
}
};
@Bean
protected NavigationHelper navigationHelper;
@Bean
@ -61,63 +80,17 @@ public class SystemSettingsActivity extends PreferenceActivity { @@ -61,63 +80,17 @@ public class SystemSettingsActivity extends PreferenceActivity {
protected ErrorLogSender errorLogSender;
@Bean
protected SettingsPersistence settingsPersistence;
@SuppressWarnings("deprecation")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getActionBar().setDisplayHomeAsUpEnabled(true);
// Just load the system-related preferences from XML
addPreferencesFromResource(R.xml.pref_system);
// Handle outgoing links and preference changes
if (navigationHelper.enableUpdateChecker()) {
findPreference("system_checkupdates").setOnPreferenceClickListener(onCheckUpdatesClick);
} else {
getPreferenceScreen().removePreference(findPreference("system_checkupdates"));
}
findPreference("system_clearsearch").setOnPreferenceClickListener(onClearSearchClick);
findPreference("system_importsettings").setOnPreferenceClickListener(onImportSettingsClick);
findPreference("system_exportsettings").setOnPreferenceClickListener(onExportSettingsClick);
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@OptionsItem(android.R.id.home)
protected void navigateUp() {
MainSettingsActivity_.intent(this).flags(Intent.FLAG_ACTIVITY_CLEAR_TOP).start();
}
private OnPreferenceClickListener onCheckUpdatesClick = new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
if (((CheckBoxPreference) preference).isChecked())
if (((CheckBoxPreference) preference).isChecked()) {
BootReceiver.startAppUpdatesService(getApplicationContext());
else
} else {
BootReceiver.cancelAppUpdates(getApplicationContext());
}
return true;
}
};
private OnPreferenceClickListener onImportSettingsClick = new OnPreferenceClickListener() {
@SuppressWarnings("deprecation")
@Override
public boolean onPreferenceClick(Preference preference) {
showDialog(DIALOG_IMPORTSETTINGS);
return true;
}
};
private OnPreferenceClickListener onExportSettingsClick = new OnPreferenceClickListener() {
@SuppressWarnings("deprecation")
@Override
public boolean onPreferenceClick(Preference preference) {
showDialog(DIALOG_EXPORTSETTINGS);
return true;
}
};
private OnPreferenceClickListener onClearSearchClick = new OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
@ -127,41 +100,12 @@ public class SystemSettingsActivity extends PreferenceActivity { @@ -127,41 +100,12 @@ public class SystemSettingsActivity extends PreferenceActivity {
return true;
}
};
protected Dialog onCreateDialog(int id) {
switch (id) {
case DIALOG_IMPORTSETTINGS:
// @formatter:off
return new AlertDialog.Builder(this)
.setMessage(
getString(
R.string.pref_import_dialog,
getString(R.string.app_name),
SettingsPersistence.DEFAULT_SETTINGS_FILE.toString()))
.setPositiveButton(android.R.string.ok, importSettings)
.setNegativeButton(android.R.string.cancel, null).create();
// @formatter:on
case DIALOG_EXPORTSETTINGS:
// @formatter:off
return new AlertDialog.Builder(this)
.setMessage(
getString(
R.string.pref_export_dialog,
getString(R.string.app_name),
SettingsPersistence.DEFAULT_SETTINGS_FILE.toString()))
.setPositiveButton(android.R.string.ok, exportSettings)
.setNegativeButton(android.R.string.cancel, null).create();
// @formatter:on
}
return null;
}
private OnClickListener importSettings = new OnClickListener() {
private OnClickListener importSettingsFromFile = new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(SystemSettingsActivity.this);
try {
settingsPersistence.importSettings(prefs, SettingsPersistence.DEFAULT_SETTINGS_FILE);
settingsPersistence.importSettingsFromFile(prefs, SettingsPersistence.DEFAULT_SETTINGS_FILE);
Crouton.showText(SystemSettingsActivity.this, R.string.pref_import_success,
NavigationHelper.CROUTON_INFO_STYLE);
} catch (FileNotFoundException e) {
@ -174,13 +118,18 @@ public class SystemSettingsActivity extends PreferenceActivity { @@ -174,13 +118,18 @@ public class SystemSettingsActivity extends PreferenceActivity {
}
}
};
private OnClickListener exportSettings = new OnClickListener() {
private OnClickListener importSettingsFromQr = new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
BarcodeHelper.startBarcodeScanner(SystemSettingsActivity.this, BarcodeHelper.ACTIVITY_BARCODE_QRSETTINGS);
}
};
private OnClickListener exportSettingsToFile = new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(SystemSettingsActivity.this);
try {
settingsPersistence.exportSettings(prefs, SettingsPersistence.DEFAULT_SETTINGS_FILE);
settingsPersistence.exportSettingsToFile(prefs, SettingsPersistence.DEFAULT_SETTINGS_FILE);
Crouton.showText(SystemSettingsActivity.this, R.string.pref_export_success,
NavigationHelper.CROUTON_INFO_STYLE);
} catch (JSONException e) {
@ -192,5 +141,94 @@ public class SystemSettingsActivity extends PreferenceActivity { @@ -192,5 +141,94 @@ public class SystemSettingsActivity extends PreferenceActivity {
}
}
};
private OnClickListener exportSettingsToQr = new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(SystemSettingsActivity.this);
try {
String settings = settingsPersistence.exportSettingsAsString(prefs);
BarcodeHelper.shareContentBarcode(SystemSettingsActivity.this, settings);
} catch (JSONException e) {
Crouton.showText(SystemSettingsActivity.this, R.string.error_cant_write_settings_file,
NavigationHelper.CROUTON_ERROR_STYLE);
}
}
};
@SuppressWarnings("deprecation")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getActionBar().setDisplayHomeAsUpEnabled(true);
// Just load the system-related preferences from XML
addPreferencesFromResource(R.xml.pref_system);
// Handle outgoing links and preference changes
if (navigationHelper.enableUpdateChecker()) {
findPreference("system_checkupdates").setOnPreferenceClickListener(onCheckUpdatesClick);
} else {
getPreferenceScreen().removePreference(findPreference("system_checkupdates"));
}
findPreference("system_clearsearch").setOnPreferenceClickListener(onClearSearchClick);
findPreference("system_importsettings").setOnPreferenceClickListener(onImportSettingsClick);
findPreference("system_exportsettings").setOnPreferenceClickListener(onExportSettingsClick);
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@OptionsItem(android.R.id.home)
protected void navigateUp() {
MainSettingsActivity_.intent(this).flags(Intent.FLAG_ACTIVITY_CLEAR_TOP).start();
}
@OnActivityResult(BarcodeHelper.ACTIVITY_BARCODE_QRSETTINGS)
public void onQrCodeScanned(int resultCode, Intent data) {
// We should have received Intent extras with the QR-decoded data representing Transdroid settings
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(SystemSettingsActivity.this);
String contents = data.getStringExtra("SCAN_RESULT");
String formatName = data.getStringExtra("SCAN_RESULT_FORMAT");
if (formatName != null && formatName.equals("QR_CODE") && !TextUtils.isEmpty(contents)) {
try {
settingsPersistence.importSettingsAsString(prefs, contents);
Crouton.showText(SystemSettingsActivity.this, R.string.pref_import_success,
NavigationHelper.CROUTON_INFO_STYLE);
} catch (JSONException e) {
Crouton.showText(SystemSettingsActivity.this, R.string.error_file_not_found,
NavigationHelper.CROUTON_ERROR_STYLE);
}
}
}
@SuppressWarnings("deprecation")
protected Dialog onCreateDialog(int id) {
switch (id) {
case DIALOG_IMPORTSETTINGS:
// @formatter:off
return new AlertDialog.Builder(this)
.setMessage(
getString(
R.string.pref_import_dialog,
getString(R.string.app_name),
SettingsPersistence.DEFAULT_SETTINGS_FILE.toString()))
.setPositiveButton(R.string.pref_import_fromfile, importSettingsFromFile)
.setNeutralButton(R.string.pref_import_fromqr, importSettingsFromQr)
.setNegativeButton(android.R.string.cancel, null).create();
// @formatter:on
case DIALOG_EXPORTSETTINGS:
// @formatter:off
return new AlertDialog.Builder(this)
.setMessage(
getString(
R.string.pref_export_dialog,
getString(R.string.app_name),
SettingsPersistence.DEFAULT_SETTINGS_FILE.toString()))
.setPositiveButton(R.string.pref_export_tofile, exportSettingsToFile)
.setNeutralButton(R.string.pref_export_toqr, exportSettingsToQr)
.setNegativeButton(android.R.string.cancel, null).create();
// @formatter:on
}
return null;
}
}

4
app/src/main/res/values/changelog.xml

@ -21,8 +21,10 @@ Transdroid 2.3.0\n @@ -21,8 +21,10 @@ Transdroid 2.3.0\n
- Aria2 support\n
- Improved SSL support with TLS 1.1/1.2 and SNI hostname verification\n
- Fixed server checker when one is unavailable\n
- Fixed Deluge magnet links from Chrome\n
- Fixed magnet links from Chrome\n
- Enable RSS notifications per feed\n
- Improved bug logging\n
- Import/export settings using QR code\n
\n
Transdroid 2.2.0\n
- Dropped legacy Android support; Android 4.0.3 is the new minimum\n

4
app/src/main/res/values/strings.xml

@ -321,9 +321,13 @@ @@ -321,9 +321,13 @@
<string name="pref_clearsearch_success">Search history is cleared</string>
<string name="pref_import">Import settings</string>
<string name="pref_import_dialog">%1$s will try to import server, web search, RSS and system settings from: %2$s</string>
<string name="pref_import_fromfile">Use file</string>
<string name="pref_import_fromqr">Use QR code</string>
<string name="pref_import_success">Settings successfully imported</string>
<string name="pref_export">Export settings</string>
<string name="pref_export_dialog">%1$s will export server (including passwords), web search, RSS and system settings to the following plain text JSON file: %2$s</string>
<string name="pref_export_tofile">To file</string>
<string name="pref_export_toqr">To QR code</string>
<string name="pref_export_success">Settings successfully exported</string>
<string name="pref_help">Transdroid help</string>

Loading…
Cancel
Save