rewrite how preference screens are invokved

Daniel Gultsch created

Change summary

src/main/AndroidManifest.xml                                  |   4 
src/main/java/eu/siacs/conversations/ui/SettingsActivity.java | 125 ++--
src/main/java/eu/siacs/conversations/ui/SettingsFragment.java |  77 +-
src/main/res/xml/preferences.xml                              |  12 
4 files changed, 100 insertions(+), 118 deletions(-)

Detailed changes

src/main/AndroidManifest.xml 🔗

@@ -186,6 +186,10 @@
             <meta-data
                 android:name="android.support.PARENT_ACTIVITY"
                 android:value="eu.siacs.conversations.ui.SettingsActivity" />
+            <intent-filter>
+                <action android:name="android.intent.action.VIEW" />
+                <category android:name="android.intent.category.PREFERENCE" />
+            </intent-filter>
         </activity>
         <activity android:name="com.soundcloud.android.crop.CropImageActivity" />
         <activity android:name=".ui.MemorizingActivity"/>

src/main/java/eu/siacs/conversations/ui/SettingsActivity.java 🔗

@@ -7,7 +7,7 @@ import android.content.Intent;
 import android.content.SharedPreferences;
 import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
 import android.content.pm.PackageManager;
-import android.content.pm.ResolveInfo;
+
 import android.net.Uri;
 import android.os.Build;
 import android.os.Bundle;
@@ -63,6 +63,7 @@ public class SettingsActivity extends XmppActivity implements
 			mSettingsFragment = new SettingsFragment();
 			fm.beginTransaction().replace(android.R.id.content, mSettingsFragment).commit();
 		}
+		mSettingsFragment.setActivityIntent(getIntent());
 
 		this.mTheme = findTheme();
 		setTheme(this.mTheme);
@@ -132,9 +133,8 @@ public class SettingsActivity extends XmppActivity implements
 		}
 
 		final Preference removeCertsPreference = mSettingsFragment.findPreference("remove_trusted_certificates");
-		removeCertsPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
-			@Override
-			public boolean onPreferenceClick(Preference preference) {
+		if (removeCertsPreference != null) {
+			removeCertsPreference.setOnPreferenceClickListener(preference -> {
 				final MemorizingTrustManager mtm = xmppConnectionService.getMemorizingTrustManager();
 				final ArrayList<String> aliases = Collections.list(mtm.getCertificates());
 				if (aliases.size() == 0) {
@@ -145,44 +145,37 @@ public class SettingsActivity extends XmppActivity implements
 				final AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(SettingsActivity.this);
 				dialogBuilder.setTitle(getResources().getString(R.string.dialog_manage_certs_title));
 				dialogBuilder.setMultiChoiceItems(aliases.toArray(new CharSequence[aliases.size()]), null,
-						new DialogInterface.OnMultiChoiceClickListener() {
-							@Override
-							public void onClick(DialogInterface dialog, int indexSelected,
-												boolean isChecked) {
-								if (isChecked) {
-									selectedItems.add(indexSelected);
-								} else if (selectedItems.contains(indexSelected)) {
-									selectedItems.remove(Integer.valueOf(indexSelected));
-								}
-								if (selectedItems.size() > 0)
-									((AlertDialog) dialog).getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(true);
-								else {
-									((AlertDialog) dialog).getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(false);
-								}
+						(dialog, indexSelected, isChecked) -> {
+							if (isChecked) {
+								selectedItems.add(indexSelected);
+							} else if (selectedItems.contains(indexSelected)) {
+								selectedItems.remove(Integer.valueOf(indexSelected));
+							}
+							if (selectedItems.size() > 0)
+								((AlertDialog) dialog).getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(true);
+							else {
+								((AlertDialog) dialog).getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(false);
 							}
 						});
 
 				dialogBuilder.setPositiveButton(
-						getResources().getString(R.string.dialog_manage_certs_positivebutton), new DialogInterface.OnClickListener() {
-							@Override
-							public void onClick(DialogInterface dialog, int which) {
-								int count = selectedItems.size();
-								if (count > 0) {
-									for (int i = 0; i < count; i++) {
-										try {
-											Integer item = Integer.valueOf(selectedItems.get(i).toString());
-											String alias = aliases.get(item);
-											mtm.deleteCertificate(alias);
-										} catch (KeyStoreException e) {
-											e.printStackTrace();
-											displayToast("Error: " + e.getLocalizedMessage());
-										}
-									}
-									if (xmppConnectionServiceBound) {
-										reconnectAccounts();
+						getResources().getString(R.string.dialog_manage_certs_positivebutton), (dialog, which) -> {
+							int count = selectedItems.size();
+							if (count > 0) {
+								for (int i = 0; i < count; i++) {
+									try {
+										Integer item = Integer.valueOf(selectedItems.get(i).toString());
+										String alias = aliases.get(item);
+										mtm.deleteCertificate(alias);
+									} catch (KeyStoreException e) {
+										e.printStackTrace();
+										displayToast("Error: " + e.getLocalizedMessage());
 									}
-									displayToast(getResources().getQuantityString(R.plurals.toast_delete_certificates, count, count));
 								}
+								if (xmppConnectionServiceBound) {
+									reconnectAccounts();
+								}
+								displayToast(getResources().getQuantityString(R.plurals.toast_delete_certificates, count, count));
 							}
 						});
 				dialogBuilder.setNegativeButton(getResources().getString(R.string.dialog_manage_certs_negativebutton), null);
@@ -190,48 +183,35 @@ public class SettingsActivity extends XmppActivity implements
 				removeCertsDialog.show();
 				removeCertsDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
 				return true;
-			}
-		});
+			});
+		}
 
 		final Preference exportLogsPreference = mSettingsFragment.findPreference("export_logs");
-		exportLogsPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
-			@Override
-			public boolean onPreferenceClick(Preference preference) {
+		if (exportLogsPreference != null) {
+			exportLogsPreference.setOnPreferenceClickListener(preference -> {
 				if (hasStoragePermission(REQUEST_WRITE_LOGS)) {
 					startExport();
 				}
 				return true;
-			}
-		});
+			});
+		}
 
 		if (Config.ONLY_INTERNAL_STORAGE) {
 			final Preference cleanCachePreference = mSettingsFragment.findPreference("clean_cache");
-			cleanCachePreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
-				@Override
-				public boolean onPreferenceClick(Preference preference) {
-					cleanCache();
-					return true;
-				}
-			});
+			if (cleanCachePreference != null) {
+				cleanCachePreference.setOnPreferenceClickListener(preference -> cleanCache());
+			}
 
 			final Preference cleanPrivateStoragePreference = mSettingsFragment.findPreference("clean_private_storage");
-			cleanPrivateStoragePreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
-				@Override
-				public boolean onPreferenceClick(Preference preference) {
-					cleanPrivateStorage();
-					return true;
-				}
-			});
+			if (cleanPrivateStoragePreference != null) {
+				cleanPrivateStoragePreference.setOnPreferenceClickListener(preference -> cleanPrivateStorage());
+			}
 		}
 
 		final Preference deleteOmemoPreference = mSettingsFragment.findPreference("delete_omemo_identities");
-		deleteOmemoPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
-			@Override
-			public boolean onPreferenceClick(Preference preference) {
-				deleteOmemoIdentities();
-				return true;
-			}
-		});
+		if (deleteOmemoPreference != null) {
+			deleteOmemoPreference.setOnPreferenceClickListener(preference -> deleteOmemoIdentities());
+		}
 	}
 
 	private boolean isCallable(final Intent i) {
@@ -239,15 +219,17 @@ public class SettingsActivity extends XmppActivity implements
 	}
 
 
-	private void cleanCache() {
+	private boolean cleanCache() {
 		Intent intent = new Intent(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
 		intent.setData(Uri.parse("package:" + getPackageName()));
 		startActivity(intent);
+		return true;
 	}
 
-	private void cleanPrivateStorage() {
+	private boolean cleanPrivateStorage() {
 		cleanPrivatePictures();
 		cleanPrivateFiles();
+		return true;
 	}
 
 	private void cleanPrivatePictures() {
@@ -290,11 +272,11 @@ public class SettingsActivity extends XmppActivity implements
 		}
 	}
 
-	private void deleteOmemoIdentities() {
+	private boolean deleteOmemoIdentities() {
 		AlertDialog.Builder builder = new AlertDialog.Builder(this);
 		builder.setTitle(R.string.pref_delete_omemo_identities);
 		final List<CharSequence> accounts = new ArrayList<>();
-		for(Account account : xmppConnectionService.getAccounts()) {
+		for (Account account : xmppConnectionService.getAccounts()) {
 			if (account.isEnabled()) {
 				accounts.add(account.getJid().toBareJid().toString());
 			}
@@ -305,7 +287,7 @@ public class SettingsActivity extends XmppActivity implements
 			public void onClick(DialogInterface dialog, int which, boolean isChecked) {
 				checkedItems[which] = isChecked;
 				final AlertDialog alertDialog = (AlertDialog) dialog;
-				for(boolean item : checkedItems) {
+				for (boolean item : checkedItems) {
 					if (item) {
 						alertDialog.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(true);
 						return;
@@ -314,11 +296,11 @@ public class SettingsActivity extends XmppActivity implements
 				alertDialog.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(false);
 			}
 		});
-		builder.setNegativeButton(R.string.cancel,null);
+		builder.setNegativeButton(R.string.cancel, null);
 		builder.setPositiveButton(R.string.delete_selected_keys, new DialogInterface.OnClickListener() {
 			@Override
 			public void onClick(DialogInterface dialog, int which) {
-				for(int i = 0; i < checkedItems.length; ++i) {
+				for (int i = 0; i < checkedItems.length; ++i) {
 					if (checkedItems[i]) {
 						try {
 							Jid jid = Jid.fromString(accounts.get(i).toString());
@@ -337,6 +319,7 @@ public class SettingsActivity extends XmppActivity implements
 		AlertDialog dialog = builder.create();
 		dialog.show();
 		dialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
+		return true;
 	}
 
 	@Override

src/main/java/eu/siacs/conversations/ui/SettingsFragment.java 🔗

@@ -1,77 +1,60 @@
 package eu.siacs.conversations.ui;
 
-import android.app.Dialog;
+import android.content.Intent;
 import android.os.Bundle;
 import android.preference.Preference;
 import android.preference.PreferenceCategory;
 import android.preference.PreferenceFragment;
 import android.preference.PreferenceScreen;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.ViewParent;
-import android.widget.FrameLayout;
-import android.widget.LinearLayout;
+import android.text.TextUtils;
 
 import eu.siacs.conversations.Config;
 import eu.siacs.conversations.R;
 
 public class SettingsFragment extends PreferenceFragment {
 
-	//http://stackoverflow.com/questions/16374820/action-bar-home-button-not-functional-with-nested-preferencescreen/16800527#16800527
-	private void initializeActionBar(PreferenceScreen preferenceScreen) {
-		final Dialog dialog = preferenceScreen.getDialog();
-
-		if (dialog != null) {
-			View homeBtn = dialog.findViewById(android.R.id.home);
-
-			if (homeBtn != null) {
-				View.OnClickListener dismissDialogClickListener = new View.OnClickListener() {
-					@Override
-					public void onClick(View v) {
-						dialog.dismiss();
-					}
-				};
-
-				ViewParent homeBtnContainer = homeBtn.getParent();
-
-				if (homeBtnContainer instanceof FrameLayout) {
-					ViewGroup containerParent = (ViewGroup) homeBtnContainer.getParent();
-					if (containerParent instanceof LinearLayout) {
-						((LinearLayout) containerParent).setOnClickListener(dismissDialogClickListener);
-					} else {
-						((FrameLayout) homeBtnContainer).setOnClickListener(dismissDialogClickListener);
-					}
-				} else {
-					homeBtn.setOnClickListener(dismissDialogClickListener);
-				}
-			}
-		}
-	}
+	private String page = null;
 
 	@Override
 	public void onCreate(Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
 
-		// Load the preferences from an XML resource
 		addPreferencesFromResource(R.xml.preferences);
 
 		// Remove from standard preferences if the flag ONLY_INTERNAL_STORAGE is not true
 		if (!Config.ONLY_INTERNAL_STORAGE) {
 			PreferenceCategory mCategory = (PreferenceCategory) findPreference("security_options");
-			Preference mPref1 = findPreference("clean_cache");
-			Preference mPref2 = findPreference("clean_private_storage");
-			mCategory.removePreference(mPref1);
-			mCategory.removePreference(mPref2);
+			if (mCategory != null) {
+				Preference cleanCache = findPreference("clean_cache");
+				Preference cleanPrivateStorage = findPreference("clean_private_storage");
+				mCategory.removePreference(cleanCache);
+				mCategory.removePreference(cleanPrivateStorage);
+			}
+		}
+
+		if (!TextUtils.isEmpty(page)) {
+			openPreferenceScreen(page);
 		}
 
 	}
 
-	@Override
-	public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) {
-		super.onPreferenceTreeClick(preferenceScreen, preference);
-		if (preference instanceof PreferenceScreen) {
-			initializeActionBar((PreferenceScreen) preference);
+	public void setActivityIntent(final Intent intent) {
+		if (intent != null) {
+			if (Intent.ACTION_VIEW.equals(intent.getAction())) {
+				if (intent.getExtras() != null) {
+					this.page = intent.getExtras().getString("page");
+				}
+			}
+		}
+	}
+
+	private void openPreferenceScreen(final String screenName) {
+		final Preference pref = findPreference(screenName);
+		if (pref instanceof PreferenceScreen) {
+			final PreferenceScreen preferenceScreen = (PreferenceScreen) pref;
+			getActivity().setTitle(preferenceScreen.getTitle());
+			preferenceScreen.setDependency("");
+			setPreferenceScreen((PreferenceScreen) pref);
 		}
-		return false;
 	}
 }

src/main/res/xml/preferences.xml 🔗

@@ -87,6 +87,12 @@
             android:key="quiet_hours"
             android:summary="@string/pref_quiet_hours_summary"
             android:title="@string/title_pref_quiet_hours">
+            <intent
+                android:action="android.intent.action.VIEW"
+                android:targetPackage="eu.siacs.conversations"
+                android:targetClass="eu.siacs.conversations.ui.SettingsActivity" >
+                <extra android:name="page" android:value="quiet_hours" />
+            </intent>
             <CheckBoxPreference
                 android:defaultValue="@bool/enable_quiet_hours"
                 android:key="enable_quiet_hours"
@@ -185,6 +191,12 @@
             android:key="expert"
             android:summary="@string/pref_expert_options_summary"
             android:title="@string/pref_expert_options">
+            <intent
+                android:action="android.intent.action.VIEW"
+                android:targetPackage="eu.siacs.conversations"
+                android:targetClass="eu.siacs.conversations.ui.SettingsActivity" >
+                <extra android:name="page" android:value="expert" />
+            </intent>
             <PreferenceCategory android:title="@string/pref_security_settings"
                 android:key="security_options">
                 <CheckBoxPreference