mirror of
https://github.com/syncthing/syncthing-android.git
synced 2024-11-22 12:21:15 +00:00
Add syncthing preferences to app settings.
This commit is contained in:
parent
870c451477
commit
edea290ea6
7 changed files with 260 additions and 8 deletions
|
@ -9,34 +9,64 @@ import android.net.Uri;
|
|||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.preference.CheckBoxPreference;
|
||||
import android.preference.EditTextPreference;
|
||||
import android.preference.Preference;
|
||||
import android.preference.PreferenceActivity;
|
||||
import android.preference.PreferenceScreen;
|
||||
import android.support.v4.app.NavUtils;
|
||||
import android.text.InputType;
|
||||
import android.util.Log;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import com.nutomic.syncthingandroid.syncthing.RestApi;
|
||||
import com.nutomic.syncthingandroid.syncthing.SyncthingService;
|
||||
import com.nutomic.syncthingandroid.syncthing.SyncthingServiceBinder;
|
||||
|
||||
public class SettingsActivity extends PreferenceActivity {
|
||||
public class SettingsActivity extends PreferenceActivity
|
||||
implements Preference.OnPreferenceChangeListener {
|
||||
|
||||
private static final String REPORT_ISSUE_KEY = "report_issue";
|
||||
|
||||
private static final String SYNCTHING_OPTIONS_KEY = "syncthing_options";
|
||||
|
||||
private static final String SYNCTHING_GUI_KEY = "syncthing_gui";
|
||||
|
||||
private static final String SYNCTHING_VERSION_KEY = "syncthing_version";
|
||||
|
||||
private Preference mVersion;
|
||||
|
||||
private PreferenceScreen mOptionsScreen;
|
||||
|
||||
private PreferenceScreen mGuiScreen;
|
||||
|
||||
private SyncthingService mSyncthingService;
|
||||
|
||||
/**
|
||||
* Binds to service and sets version name. The version name can not be retrieved if the service
|
||||
* is just started (as we don't wait until the api is up).
|
||||
* Binds to service and sets syncthing preferences from Rest API.
|
||||
*/
|
||||
private ServiceConnection mSyncthingServiceConnection = new ServiceConnection() {
|
||||
|
||||
public void onServiceConnected(ComponentName className, IBinder service) {
|
||||
SyncthingServiceBinder binder = (SyncthingServiceBinder) service;
|
||||
mSyncthingService = binder.getService();
|
||||
Preference version = getPreferenceScreen().findPreference(SYNCTHING_VERSION_KEY);
|
||||
version.setSummary(mSyncthingService.getApi().getVersion());
|
||||
mVersion.setSummary(mSyncthingService.getApi().getVersion());
|
||||
|
||||
for (int i = 0; i < mOptionsScreen.getPreferenceCount(); i++) {
|
||||
Preference pref = mOptionsScreen.getPreference(i);
|
||||
pref.setOnPreferenceChangeListener(SettingsActivity.this);
|
||||
String value = mSyncthingService.getApi()
|
||||
.getValue(RestApi.TYPE_OPTIONS, pref.getKey());
|
||||
applyPreference(pref, value);
|
||||
}
|
||||
|
||||
for (int i = 0; i < mGuiScreen.getPreferenceCount(); i++) {
|
||||
Preference pref = mGuiScreen.getPreference(i);
|
||||
pref.setOnPreferenceChangeListener(SettingsActivity.this);
|
||||
String value = mSyncthingService.getApi()
|
||||
.getValue(RestApi.TYPE_GUI, pref.getKey());
|
||||
applyPreference(pref, value);
|
||||
}
|
||||
}
|
||||
|
||||
public void onServiceDisconnected(ComponentName className) {
|
||||
|
@ -44,6 +74,22 @@ public class SettingsActivity extends PreferenceActivity {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Applies the given value to the preference.
|
||||
*
|
||||
* If pref is an EditTextPreference, setText is used and the value shown as summary. If pref is
|
||||
* a CheckBoxPreference, setChecked is used (by parsing value as Boolean).
|
||||
*/
|
||||
private void applyPreference(Preference pref, String value) {
|
||||
if (pref instanceof EditTextPreference) {
|
||||
((EditTextPreference) pref).setText(value);
|
||||
pref.setSummary(value);
|
||||
}
|
||||
else if (pref instanceof CheckBoxPreference) {
|
||||
((CheckBoxPreference) pref).setChecked(Boolean.parseBoolean(value));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads layout, sets version from Rest API.
|
||||
*
|
||||
|
@ -64,6 +110,10 @@ public class SettingsActivity extends PreferenceActivity {
|
|||
mSyncthingServiceConnection, Context.BIND_AUTO_CREATE);
|
||||
|
||||
addPreferencesFromResource(R.xml.settings);
|
||||
PreferenceScreen screen = getPreferenceScreen();
|
||||
mVersion = screen.findPreference(SYNCTHING_VERSION_KEY);
|
||||
mOptionsScreen = (PreferenceScreen) screen.findPreference(SYNCTHING_OPTIONS_KEY);
|
||||
mGuiScreen = (PreferenceScreen) screen.findPreference(SYNCTHING_GUI_KEY);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -99,4 +149,30 @@ public class SettingsActivity extends PreferenceActivity {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the updated value to {@link }RestApi}, and sets it as the summary
|
||||
* for EditTextPreference.
|
||||
*/
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object o) {
|
||||
if (preference instanceof EditTextPreference) {
|
||||
String value = (String) o;
|
||||
preference.setSummary(value);
|
||||
EditTextPreference etp = (EditTextPreference) preference;
|
||||
if (etp.getEditText().getInputType() == InputType.TYPE_CLASS_NUMBER) {
|
||||
o = Integer.parseInt((String) o);
|
||||
}
|
||||
}
|
||||
|
||||
if (mOptionsScreen.findPreference(preference.getKey()) != null) {
|
||||
mSyncthingService.getApi().setValue(RestApi.TYPE_OPTIONS, preference.getKey(), o,
|
||||
preference.getKey().equals("ListenAddress"));
|
||||
return true;
|
||||
}
|
||||
else if (mGuiScreen.findPreference(preference.getKey()) != null) {
|
||||
mSyncthingService.getApi().setValue(RestApi.TYPE_GUI, preference.getKey(), o, false);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,8 @@ public class GetTask extends AsyncTask<String, Void, String> {
|
|||
|
||||
private static final String TAG = "GetTask";
|
||||
|
||||
public static final String URI_CONFIG = "/rest/config";
|
||||
|
||||
public static final String URI_VERSION = "/rest/version";
|
||||
|
||||
/**
|
||||
|
|
|
@ -6,6 +6,7 @@ import android.util.Log;
|
|||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.entity.StringEntity;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
import org.apache.http.message.BasicHeader;
|
||||
|
||||
|
@ -20,10 +21,13 @@ public class PostTask extends AsyncTask<String, Void, Void> {
|
|||
|
||||
public static final String URI_SHUTDOWN = "/rest/shutdown";
|
||||
|
||||
public static final String URI_CONFIG = "/rest/config";
|
||||
|
||||
/**
|
||||
* params[0] Syncthing hostname
|
||||
* params[1] URI to call
|
||||
* params[2] Syncthing API key
|
||||
* params[3] The request content
|
||||
*/
|
||||
@Override
|
||||
protected Void doInBackground(String... params) {
|
||||
|
@ -33,6 +37,7 @@ public class PostTask extends AsyncTask<String, Void, Void> {
|
|||
HttpPost post = new HttpPost(fullUri);
|
||||
post.addHeader(new BasicHeader("X-API-Key", params[2]));
|
||||
try {
|
||||
post.setEntity(new StringEntity(params[3]));
|
||||
httpclient.execute(post);
|
||||
}
|
||||
catch (IOException e) {
|
||||
|
|
|
@ -5,6 +5,13 @@ import android.util.Log;
|
|||
|
||||
import com.nutomic.syncthingandroid.R;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Provides functions to interact with the syncthing REST API.
|
||||
*/
|
||||
|
@ -12,12 +19,24 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener {
|
|||
|
||||
private static final String TAG = "RestApi";
|
||||
|
||||
/**
|
||||
* Parameter for {@link #getValue} or {@link #setValue} referring to "options" config item.
|
||||
*/
|
||||
public static final String TYPE_OPTIONS = "Options";
|
||||
|
||||
/**
|
||||
* Parameter for {@link #getValue} or {@link #setValue} referring to "gui" config item.
|
||||
*/
|
||||
public static final String TYPE_GUI = "GUI";
|
||||
|
||||
private String mVersion;
|
||||
|
||||
private String mUrl;
|
||||
|
||||
private String mApiKey;
|
||||
|
||||
private JSONObject mConfig;
|
||||
|
||||
public RestApi(String url, String apiKey) {
|
||||
mUrl = url;
|
||||
mApiKey = apiKey;
|
||||
|
@ -39,6 +58,17 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener {
|
|||
Log.i(TAG, "Syncthing version is " + mVersion);
|
||||
}
|
||||
}.execute(mUrl, GetTask.URI_VERSION, mApiKey);
|
||||
new GetTask() {
|
||||
@Override
|
||||
protected void onPostExecute(String config) {
|
||||
try {
|
||||
mConfig = new JSONObject(config);
|
||||
}
|
||||
catch (JSONException e) {
|
||||
Log.w(TAG, "Failed to parse config", e);
|
||||
}
|
||||
}
|
||||
}.execute(mUrl, GetTask.URI_CONFIG, mApiKey);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -52,7 +82,69 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener {
|
|||
* Stops syncthing. You should probably use SyncthingService.stopService() instead.
|
||||
*/
|
||||
public void shutdown() {
|
||||
new PostTask().execute(mUrl, PostTask.URI_SHUTDOWN, mApiKey);
|
||||
new PostTask().execute(mUrl, PostTask.URI_SHUTDOWN, mApiKey, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a value from config,
|
||||
*
|
||||
* Booleans are returned as {@link }Boolean#toString}, arrays as space seperated string.
|
||||
*
|
||||
* @param name {@link #TYPE_OPTIONS} or {@link #TYPE_GUI}
|
||||
* @param key The key to read from.
|
||||
* @return The value as a String, or null on failure.
|
||||
*/
|
||||
public String getValue(String name, String key) {
|
||||
try {
|
||||
Object value = mConfig.getJSONObject(name).get(key);
|
||||
return (value instanceof JSONArray)
|
||||
// TODO: also remove "
|
||||
? ((JSONArray) value).join(" ").replace("\"", "")
|
||||
: String.valueOf(value);
|
||||
}
|
||||
catch (JSONException e) {
|
||||
Log.w(TAG, "Failed to get value for " + key, e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a value to config and sends it via Rest API.
|
||||
*
|
||||
* Booleans must be passed as {@link Boolean}, arrays as space seperated string
|
||||
* with isArray true.
|
||||
*
|
||||
* @param name {@link #TYPE_OPTIONS} or {@link #TYPE_GUI}
|
||||
* @param key The key to write to.
|
||||
* @param value The new value to set, either String, Boolean or Integer.
|
||||
* @param isArray True iff value is a space seperated String that should be converted to array.
|
||||
*/
|
||||
public <T> void setValue(String name, String key, T value, boolean isArray) {
|
||||
try {
|
||||
if (isArray) {
|
||||
JSONArray json = new JSONArray();
|
||||
for (String s : ((String) value).split(" ")) {
|
||||
json.put(s);
|
||||
}
|
||||
mConfig.getJSONObject(name).put(key, json);
|
||||
}
|
||||
else {
|
||||
mConfig.getJSONObject(name).put(key, value);
|
||||
}
|
||||
configUpdated();
|
||||
}
|
||||
catch (JSONException e) {
|
||||
Log.w(TAG, "Failed to set value for " + key, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends the updated mConfig via Rest API to syncthing.
|
||||
*
|
||||
* TODO: Show a restart notification
|
||||
*/
|
||||
private void configUpdated() {
|
||||
new PostTask().execute(mUrl, PostTask.URI_CONFIG, mConfig.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -347,7 +347,7 @@ public class SyncthingService extends Service {
|
|||
// HACK: Make sure there is no syncthing binary left running from an improper
|
||||
// shutdown (eg Play Store update).
|
||||
// NOTE: This will log an exception if syncthing is not actually running.
|
||||
new PostTask().execute(mApi.getUrl(), PostTask.URI_SHUTDOWN, urlAndKey.second);
|
||||
new PostTask().execute(mApi.getUrl(), PostTask.URI_SHUTDOWN, urlAndKey.second, "");
|
||||
registerOnWebGuiAvailableListener(mApi);
|
||||
new PollWebGuiAvailableTask().execute();
|
||||
new Thread(new SyncthingRunnable()).start();
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<address>127.0.0.1:8080</address>
|
||||
</gui>
|
||||
<options>
|
||||
<listenAddress>:22000</listenAddress>
|
||||
<listenAddress>0.0.0.0:22000</listenAddress>
|
||||
<globalAnnounceServer>194.126.249.5:22025</globalAnnounceServer>
|
||||
<globalAnnounceEnabled>true</globalAnnounceEnabled>
|
||||
<localAnnounceEnabled>true</localAnnounceEnabled>
|
||||
|
|
|
@ -1,6 +1,83 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<PreferenceScreen
|
||||
android:key="syncthing_options"
|
||||
android:title="Syncthing Options"
|
||||
android:persistent="false" >
|
||||
|
||||
<EditTextPreference
|
||||
android:key="ListenAddress"
|
||||
android:title="Sync Protocol Listen Addresses"
|
||||
android:defaultValue="0.0.0.0:22000" />
|
||||
|
||||
<EditTextPreference
|
||||
android:key="MaxSendKbps"
|
||||
android:title="Outgoing Rate Limit (KiB/s)"
|
||||
android:numeric="integer" />
|
||||
|
||||
<EditTextPreference
|
||||
android:key="RescanIntervalS"
|
||||
android:title="Rescan Interval (s)"
|
||||
android:numeric="integer" />
|
||||
|
||||
<EditTextPreference
|
||||
android:key="ReconnectIntervalS"
|
||||
android:title="Reconnect Interval (s)"
|
||||
android:numeric="integer" />
|
||||
|
||||
<EditTextPreference
|
||||
android:key="ParallelRequests"
|
||||
android:title="Max Outstanding Requests"
|
||||
android:numeric="integer" />
|
||||
|
||||
<EditTextPreference
|
||||
android:key="MaxChangeKbps"
|
||||
android:title="Max File Change Rate (KiB/s)"
|
||||
android:numeric="integer" />
|
||||
|
||||
<CheckBoxPreference
|
||||
android:key="GlobalAnnEnabled"
|
||||
android:title="Global Discovery" />
|
||||
|
||||
<CheckBoxPreference
|
||||
android:key="LocalAnnEnabled"
|
||||
android:title="Local Discovery" />
|
||||
|
||||
<EditTextPreference
|
||||
android:key="LocalAnnPort"
|
||||
android:title="Local Discovery Port"
|
||||
android:numeric="integer" />
|
||||
|
||||
<CheckBoxPreference
|
||||
android:key="UPnPEnabled"
|
||||
android:title="Enable UPnP" />
|
||||
|
||||
</PreferenceScreen>
|
||||
|
||||
<PreferenceScreen
|
||||
android:key="syncthing_gui"
|
||||
android:title="Syncthing GUI"
|
||||
android:persistent="false" >
|
||||
|
||||
<EditTextPreference
|
||||
android:key="Address"
|
||||
android:title="GUI Listen Addresses" />
|
||||
|
||||
<EditTextPreference
|
||||
android:key="User"
|
||||
android:title="GUI Authentication User" />
|
||||
|
||||
<EditTextPreference
|
||||
android:key="Password"
|
||||
android:title="GUI Authentication Password" />
|
||||
|
||||
<CheckBoxPreference
|
||||
android:key="UseTLS"
|
||||
android:title="Use HTTPS for GUI" />
|
||||
|
||||
</PreferenceScreen>
|
||||
|
||||
<Preference
|
||||
android:key="report_issue"
|
||||
android:title="@string/report_issue_title"
|
||||
|
|
Loading…
Reference in a new issue