Commit e5d70381 authored by akwizgran's avatar akwizgran
Browse files

Merge branch '206-settings-prefs-alt' into 'master'

Material design settings - alternative

Closes #206.

Alternative to !77 that does not rely on an additional external library. The two alternatives should be compared for backwards-compatibility specifically regarding the ringtone selector.

Includes code from https://github.com/consp1racy/android-support-preference
License: Apache License v2.0

See merge request !78
parents e8ad1121 770d9ddc
......@@ -168,6 +168,19 @@
android:name=".android.StartupFailureActivity"
android:label="@string/startup_failed_activity_title">
</activity>
<activity
android:name=".android.SettingsActivity"
android:label="@string/settings_title"
android:parentActivityName=".android.NavDrawerActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".android.NavDrawerActivity"
/>
<intent-filter>
<action android:name="android.intent.action.MANAGE_NETWORK_USAGE"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<activity
android:name=".android.panic.PanicPreferencesActivity"
android:label="@string/panic_setting">
......
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="org.briarproject.android.fragment.SettingsFragment"/>
</FrameLayout>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="boolean_array">
<item>true</item>
<item>false</item>
</string-array>
<string-array name="bt_setting_names">
<item>@string/bluetooth_setting_enabled</item>
<item>@string/bluetooth_setting_disabled</item>
</string-array>
<string-array name="tor_mobile_setting_names">
<item>@string/tor_mobile_setting_enabled</item>
<item>@string/tor_mobile_setting_disabled</item>
</string-array>
</resources>
\ No newline at end of file
......@@ -17,11 +17,12 @@
<color name="briar_primary">#2D3E50</color>
<color name="briar_primary_dark">#0f1720</color>
<color name="briar_accent">#2D3E50</color>
<color name="briar_accent_dark">#0f1720</color>
<color name="briar_text_link">#75ab0d</color>
<color name="briar_green_light">#95d220</color>
<color name="briar_green_dark">#75ab0d</color>
<color name="briar_text_primary">#333333</color>
<color name="briar_text_primary">#808080</color>
<color name="briar_text_primary_inverse">#ffffff</color>
<!-- this is needed as preference_category_material layout uses this color as the text color -->
......
......@@ -96,18 +96,17 @@
<item quantity="other">%d new forum posts.</item>
</plurals>
<string name="settings_title">Settings</string>
<string name="bluetooth_setting_title">BLUETOOTH</string>
<string name="network_settings_title">Networks</string>
<string name="bluetooth_setting">Connect via Bluetooth</string>
<string name="bluetooth_setting_enabled">Whenever contacts are nearby</string>
<string name="bluetooth_setting_disabled">Only when adding contacts</string>
<string name="tor_wifi_setting_title">TOR</string>
<string name="tor_wifi_setting">Connect via Tor</string>
<string name="tor_wifi_setting_enabled">Only when using Wi-Fi</string>
<string name="tor_wifi_setting_disabled">When using Wi-Fi or mobile data</string>
<string name="panic_setting">Panic Button Setup</string>
<string name="panic_setting_title">PANIC BUTTON</string>
<string name="tor_mobile_setting">Connect via Tor</string>
<string name="tor_mobile_setting_enabled">When using Wi-Fi or mobile data</string>
<string name="tor_mobile_setting_disabled">Only when using Wi-Fi</string>
<string name="panic_setting">Panic button setup</string>
<string name="panic_setting_title">Panic button</string>
<string name="panic_setting_hint">Configure how Briar will react when you use a panic button app</string>
<string name="notification_settings_title">NOTIFICATIONS</string>
<string name="notification_settings_title">Notifications</string>
<string name="notify_private_messages_setting">Show alerts for private messages</string>
<string name="notify_forum_posts_setting">Show alerts for forum posts</string>
<string name="notify_vibration_setting">Vibrate</string>
......
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:title="@string/network_settings_title">
<ListPreference
android:defaultValue="false"
android:entries="@array/bt_setting_names"
android:entryValues="@array/boolean_array"
android:key="pref_key_bluetooth"
android:persistent="false"
android:summary="%s"
android:title="@string/bluetooth_setting"/>
<ListPreference
android:defaultValue="true"
android:entries="@array/tor_mobile_setting_names"
android:entryValues="@array/boolean_array"
android:key="pref_key_tor_mobile"
android:persistent="false"
android:summary="%s"
android:title="@string/tor_mobile_setting"/>
</PreferenceCategory>
<PreferenceCategory
android:title="@string/panic_setting_title">
<Preference
android:summary="@string/panic_setting_hint"
android:title="@string/panic_setting">
<intent
android:targetClass="org.briarproject.android.panic.PanicPreferencesActivity"
android:targetPackage="org.briarproject"/>
</Preference>
</PreferenceCategory>
<PreferenceCategory
android:title="@string/notification_settings_title">
<CheckBoxPreference
android:defaultValue="true"
android:key="pref_key_notify_private_messages"
android:persistent="false"
android:title="@string/notify_private_messages_setting"/>
<CheckBoxPreference
android:defaultValue="true"
android:key="pref_key_notify_forum_posts"
android:persistent="false"
android:title="@string/notify_forum_posts_setting"/>
<CheckBoxPreference
android:defaultValue="true"
android:key="pref_key_notify_vibration"
android:persistent="false"
android:title="@string/notify_vibration_setting"/>
<Preference
android:key="pref_key_notify_sound"
android:title="@string/notify_sound_setting"/>
</PreferenceCategory>
</PreferenceScreen>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:title="Debug">
<Preference
android:title="Debug information">
<intent
android:targetClass="org.briarproject.android.TestingActivity"
android:targetPackage="org.briarproject"/>
</Preference>
</PreferenceCategory>
</PreferenceScreen>
\ No newline at end of file
......@@ -7,11 +7,10 @@ import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.ActionBar;
import org.briarproject.R;
import org.briarproject.android.fragment.BaseFragment;
import org.briarproject.android.contact.ContactListFragment;
import org.briarproject.android.fragment.DashboardFragment;
import org.briarproject.android.forum.ForumListFragment;
import org.briarproject.android.fragment.SettingsFragment;
import org.briarproject.android.fragment.BaseFragment;
import org.briarproject.android.fragment.DashboardFragment;
/**
* This class should be extended by classes that wish to utilise fragments in
......@@ -26,8 +25,6 @@ public abstract class BriarFragmentActivity extends BriarActivity {
if (fragmentTag.equals(DashboardFragment.TAG)) {
actionBar.setTitle(R.string.dashboard_toolbar_header);
} else if (fragmentTag.equals(SettingsFragment.TAG)) {
actionBar.setTitle(R.string.settings_toolbar_header);
} else if (fragmentTag.equals(ContactListFragment.TAG)) {
actionBar.setTitle(R.string.contacts_toolbar_header);
} else if (fragmentTag.equals(ForumListFragment.TAG)) {
......
......@@ -22,7 +22,6 @@ import org.briarproject.R;
import org.briarproject.android.contact.ContactListFragment;
import org.briarproject.android.forum.ForumListFragment;
import org.briarproject.android.fragment.BaseFragment;
import org.briarproject.android.fragment.SettingsFragment;
import org.briarproject.android.util.CustomAnimations;
import org.briarproject.api.TransportId;
import org.briarproject.api.android.ReferenceManager;
......@@ -225,7 +224,7 @@ public class NavDrawerActivity extends BriarFragmentActivity implements
startFragment(ForumListFragment.newInstance());
break;
case R.id.nav_btn_settings:
startFragment(SettingsFragment.newInstance());
startActivity(new Intent(this, SettingsActivity.class));
break;
case R.id.nav_btn_signout:
signOut();
......
package org.briarproject.android;
import android.os.Bundle;
import android.support.v7.app.ActionBar;
import android.view.MenuItem;
import org.briarproject.R;
import org.briarproject.api.event.EventBus;
import org.briarproject.api.settings.SettingsManager;
import javax.inject.Inject;
public class SettingsActivity extends BriarActivity {
@Inject private SettingsManager settingsManager;
@Inject private EventBus eventBus;
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setHomeButtonEnabled(true);
actionBar.setDisplayHomeAsUpEnabled(true);
}
setContentView(R.layout.activity_settings);
}
public SettingsManager getSettingsManager() {
return settingsManager;
}
public EventBus getEventBus() {
return eventBus;
}
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == android.R.id.home) {
onBackPressed();
return true;
}
return false;
}
}
package org.briarproject.android.fragment;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.preference.CheckBoxPreference;
import android.support.v7.preference.ListPreference;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceFragmentCompat;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.TextView;
import org.briarproject.R;
import org.briarproject.android.TestingActivity;
import org.briarproject.android.panic.PanicPreferencesActivity;
import org.briarproject.android.SettingsActivity;
import org.briarproject.android.util.AndroidUtils;
import org.briarproject.android.util.FixedVerticalSpace;
import org.briarproject.android.util.HorizontalBorder;
import org.briarproject.android.util.LayoutUtils;
import org.briarproject.android.util.ListLoadingProgressBar;
import org.briarproject.android.widget.PreferenceDividerDecoration;
import org.briarproject.api.db.DbException;
import org.briarproject.api.event.Event;
import org.briarproject.api.event.EventBus;
import org.briarproject.api.event.EventListener;
import org.briarproject.api.event.SettingsUpdatedEvent;
import org.briarproject.api.settings.Settings;
import org.briarproject.api.settings.SettingsManager;
......@@ -34,10 +30,7 @@ import org.briarproject.util.StringUtils;
import java.util.logging.Logger;
import javax.inject.Inject;
import static android.app.Activity.RESULT_OK;
import static android.graphics.Typeface.DEFAULT_BOLD;
import static android.media.RingtoneManager.ACTION_RINGTONE_PICKER;
import static android.media.RingtoneManager.EXTRA_RINGTONE_DEFAULT_URI;
import static android.media.RingtoneManager.EXTRA_RINGTONE_EXISTING_URI;
......@@ -47,230 +40,122 @@ import static android.media.RingtoneManager.EXTRA_RINGTONE_TITLE;
import static android.media.RingtoneManager.EXTRA_RINGTONE_TYPE;
import static android.media.RingtoneManager.TYPE_NOTIFICATION;
import static android.provider.Settings.System.DEFAULT_NOTIFICATION_URI;
import static android.view.Gravity.CENTER;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
import static android.widget.LinearLayout.VERTICAL;
import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING;
import static org.briarproject.android.TestingConstants.SHOW_TESTING_ACTIVITY;
import static org.briarproject.android.util.CommonLayoutParams.MATCH_WRAP;
import static org.briarproject.android.util.CommonLayoutParams.MATCH_WRAP_1;
public class SettingsFragment extends BaseEventFragment implements
View.OnClickListener {
public class SettingsFragment extends PreferenceFragmentCompat
implements EventListener, Preference.OnPreferenceChangeListener {
public static final String TAG = "SettingsFragment";
public static final int REQUEST_RINGTONE = 2;
public static final String SETTINGS_NAMESPACE = "android-ui";
private static final Logger LOG =
Logger.getLogger(SettingsFragment.class.getName());
private ScrollView scroll = null;
private TextView enableBluetooth = null, enableBluetoothHint = null;
private CheckBox notifyPrivateMessages = null, notifyForumPosts = null;
private CheckBox notifyVibration = null;
private TextView torOverWifi = null, torOverWifiHint = null;
private TextView panicSettings = null, panicSettingsHint = null;
private TextView notifySound = null, notifySoundHint = null;
private ListLoadingProgressBar progress = null;
private ImageButton testingButton = null;
private SettingsActivity listener;
private ListPreference enableBluetooth;
private ListPreference torOverMobile;
private CheckBoxPreference notifyPrivateMessages;
private CheckBoxPreference notifyForumPosts;
private CheckBoxPreference notifyVibration;
private Preference notifySound;
// Fields that are accessed from background threads must be volatile
@Inject private volatile SettingsManager settingsManager;
private volatile SettingsManager settingsManager;
private volatile EventBus eventBus;
private volatile Settings settings;
private volatile boolean bluetoothSetting = false, torSetting = false;
public static SettingsFragment newInstance() {
Bundle args = new Bundle();
SettingsFragment fragment = new SettingsFragment();
fragment.setArguments(args);
return fragment;
}
@Override
public String getUniqueTag() {
return TAG;
public void onAttach(Context context) {
super.onAttach(context);
try {
listener = (SettingsActivity) context;
settingsManager = listener.getSettingsManager();
eventBus = listener.getEventBus();
} catch (ClassCastException e) {
throw new ClassCastException(context.toString()
+ " is not a SettingsActivity");
}
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
LinearLayout layout = new LinearLayout(getContext());
layout.setOrientation(VERTICAL);
scroll = new ScrollView(getContext());
LinearLayout settings = new LinearLayout(getContext());
settings.setOrientation(VERTICAL);
int pad = LayoutUtils.getPadding(getContext());
settings.setPadding(pad, pad, pad, pad);
TextView bluetoothTitle = new TextView(getContext());
bluetoothTitle.setPadding(pad, 0, pad, 0);
bluetoothTitle.setTypeface(DEFAULT_BOLD);
Resources res = getResources();
int titleText = res.getColor(R.color.settings_title_text);
bluetoothTitle.setTextColor(titleText);
bluetoothTitle.setText(R.string.bluetooth_setting_title);
settings.addView(bluetoothTitle);
HorizontalBorder underline = new HorizontalBorder(getContext());
int titleUnderline = res.getColor(R.color.settings_title_underline);
underline.setBackgroundColor(titleUnderline);
settings.addView(underline);
enableBluetooth = new TextView(getContext());
enableBluetooth.setPadding(pad, pad, pad, 0);
enableBluetooth.setTextSize(18);
enableBluetooth.setText(R.string.bluetooth_setting);
enableBluetooth.setOnClickListener(this);
settings.addView(enableBluetooth);
enableBluetoothHint = new TextView(getContext());
enableBluetoothHint.setPadding(pad, 0, pad, pad);
enableBluetoothHint.setOnClickListener(this);
settings.addView(enableBluetoothHint);
TextView torTitle = new TextView(getContext());
torTitle.setPadding(pad, 0, pad, 0);
torTitle.setTypeface(DEFAULT_BOLD);
torTitle.setTextColor(titleText);
torTitle.setText(R.string.tor_wifi_setting_title);
settings.addView(torTitle);
underline = new HorizontalBorder(getContext());
underline.setBackgroundColor(titleUnderline);
settings.addView(underline);
torOverWifi = new TextView(getContext());
torOverWifi.setPadding(pad, pad, pad, 0);
torOverWifi.setTextSize(18);
torOverWifi.setText(R.string.tor_wifi_setting);
torOverWifi.setOnClickListener(this);
settings.addView(torOverWifi);
torOverWifiHint = new TextView(getContext());
torOverWifiHint.setPadding(pad, 0, pad, pad);
torOverWifiHint.setOnClickListener(this);
settings.addView(torOverWifiHint);
TextView panicTitle = new TextView(getContext());
panicTitle.setPadding(pad, 0, pad, 0);
panicTitle.setTypeface(DEFAULT_BOLD);
panicTitle.setTextColor(titleText);
panicTitle.setText(R.string.panic_setting_title);
settings.addView(panicTitle);
underline = new HorizontalBorder(getContext());
underline.setBackgroundColor(titleUnderline);
settings.addView(underline);
panicSettings = new TextView(getContext());
panicSettings.setPadding(pad, pad, pad, 0);
panicSettings.setTextSize(18);
panicSettings.setText(R.string.panic_setting);
panicSettings.setOnClickListener(this);
settings.addView(panicSettings);
panicSettingsHint = new TextView(getContext());
panicSettingsHint.setText(R.string.panic_setting_hint);
panicSettingsHint.setPadding(pad, 0, pad, pad);
panicSettingsHint.setOnClickListener(this);
settings.addView(panicSettingsHint);
TextView notificationsTitle = new TextView(getContext());
notificationsTitle.setPadding(pad, 0, pad, 0);
notificationsTitle.setTypeface(DEFAULT_BOLD);
notificationsTitle.setTextColor(titleText);
notificationsTitle.setText(R.string.notification_settings_title);
settings.addView(notificationsTitle);
underline = new HorizontalBorder(getContext());
underline.setBackgroundColor(titleUnderline);
settings.addView(underline);
settings.addView(new FixedVerticalSpace(getContext()));
notifyPrivateMessages = new CheckBox(getContext());
notifyPrivateMessages.setTextSize(18);
notifyPrivateMessages.setText(R.string.notify_private_messages_setting);
notifyPrivateMessages.setOnClickListener(this);
settings.addView(notifyPrivateMessages);
settings.addView(new FixedVerticalSpace(getContext()));
settings.addView(new HorizontalBorder(getContext()));
settings.addView(new FixedVerticalSpace(getContext()));
notifyForumPosts = new CheckBox(getContext());
notifyForumPosts.setTextSize(18);
notifyForumPosts.setText(R.string.notify_forum_posts_setting);
notifyForumPosts.setOnClickListener(this);
settings.addView(notifyForumPosts);
settings.addView(new FixedVerticalSpace(getContext()));
settings.addView(new HorizontalBorder(getContext()));
settings.addView(new FixedVerticalSpace(getContext()));
notifyVibration = new CheckBox(getContext());
notifyVibration.setTextSize(18);
notifyVibration.setText(R.string.notify_vibration_setting);
notifyVibration.setOnClickListener(this);
settings.addView(notifyVibration);
settings.addView(new FixedVerticalSpace(getContext()));
settings.addView(new HorizontalBorder(getContext()));
notifySound = new TextView(getContext());
notifySound.setPadding(pad, pad, pad, 0);
notifySound.setTextSize(18);
notifySound.setText(R.string.notify_sound_setting);
notifySound.setOnClickListener(this);
settings.addView(notifySound);
notifySoundHint = new TextView(getContext());
notifySoundHint.setPadding(pad, 0, pad, pad);
notifySoundHint.setOnClickListener(this);
settings.addView(notifySoundHint);
settings.addView(new HorizontalBorder(getContext()));
scroll.addView(settings);
scroll.setLayoutParams(MATCH_WRAP_1);
scroll.setVisibility(GONE);
layout.addView(scroll);
progress = new ListLoadingProgressBar(getContext());
layout.addView(progress);
layout.addView(new HorizontalBorder(getContext()));
public void onCreatePreferences(Bundle bundle, String s) {
addPreferencesFromResource(R.xml.settings);
enableBluetooth =
(ListPreference) findPreference("pref_key_bluetooth");
torOverMobile =
(ListPreference) findPreference("pref_key_tor_mobile");
notifyPrivateMessages = (CheckBoxPreference) findPreference(
"pref_key_notify_private_messages");
notifyForumPosts = (CheckBoxPreference) findPreference(
"pref_key_notify_forum_posts");
notifyVibration = (CheckBoxPreference) findPreference(
"pref_key_notify_vibration");
notifySound = findPreference("pref_key_notify_sound");
enableBluetooth.setOnPreferenceChangeListener(this);
torOverMobile.setOnPreferenceChangeListener(this);
notifyPrivateMessages.setOnPreferenceChangeListener(this);
notifyForumPosts.setOnPreferenceChangeListener(this);
notifyVibration.setOnPreferenceChangeListener(this);
notifySound.setOnPreferenceClickListener(
new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
String title =
getString(R.string.choose_ringtone_title);
Intent i = new Intent(ACTION_RINGTONE_PICKER);
i.putExtra(EXTRA_RINGTONE_TYPE, TYPE_NOTIFICATION);
i.putExtra(EXTRA_RINGTONE_TITLE, title);