diff --git a/README.md b/README.md index 3d114f51..10846198 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,16 @@ To clean up all files generated during build, use the following commands: `./gradlew clean` +### Development Notes + +It is recommended to change the GUI and Listen Address ports for the debug app, e.g. to 8385 and 22001 respectively. + +The Syncthing native used for this android application provides a web interface by default. It can be accessed via the Settings menu -> 'Web GUI'. It is quite helpful to access this web interface from your development machine. Read android documentation on how to access the network of your emulator. Or use the following command to connect to the single currently running emulator/AVD. + +adb forward tcp:18384 tcp:8384 + +Start Syncthing app on your emulator and access the web interface from you favorite browser of your development machine via https://127.0.0.1:18384 + # License The project is licensed under the [MPLv2](LICENSE). diff --git a/adb_forward_webui.cmd b/adb_forward_webui.cmd new file mode 100644 index 00000000..88619987 --- /dev/null +++ b/adb_forward_webui.cmd @@ -0,0 +1,7 @@ +@echo off +REM +REM adb forward local_port to emulator_port +echo Running ADB to setup port forwarding on the emulated Android device ... +adb forward tcp:18384 tcp:8384 +echo Done. +timeout 3 diff --git a/app/src/main/java/com/nutomic/syncthingandroid/activities/DeviceActivity.java b/app/src/main/java/com/nutomic/syncthingandroid/activities/DeviceActivity.java index 0f90bdaa..880f52ed 100644 --- a/app/src/main/java/com/nutomic/syncthingandroid/activities/DeviceActivity.java +++ b/app/src/main/java/com/nutomic/syncthingandroid/activities/DeviceActivity.java @@ -1,12 +1,14 @@ package com.nutomic.syncthingandroid.activities; import android.app.Dialog; +import android.content.ComponentName; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.graphics.drawable.Drawable; import android.os.Bundle; +import android.os.IBinder; import android.support.v4.content.ContextCompat; import android.support.v7.app.AlertDialog; import android.support.v7.widget.SwitchCompat; @@ -32,6 +34,7 @@ import com.nutomic.syncthingandroid.model.Device; import com.nutomic.syncthingandroid.service.Constants; import com.nutomic.syncthingandroid.service.RestApi; import com.nutomic.syncthingandroid.service.SyncthingService; +import com.nutomic.syncthingandroid.service.SyncthingServiceBinder; import com.nutomic.syncthingandroid.SyncthingApp; import com.nutomic.syncthingandroid.util.Compression; import com.nutomic.syncthingandroid.util.ConfigRouter; @@ -57,7 +60,6 @@ import static com.nutomic.syncthingandroid.util.Compression.METADATA; public class DeviceActivity extends SyncthingActivity implements View.OnClickListener, - SyncthingActivity.OnServiceConnectedListener, SyncthingService.OnServiceStateChangeListener { public static final String EXTRA_NOTIFICATION_ID = @@ -197,7 +199,6 @@ public class DeviceActivity extends SyncthingActivity mIsCreateMode = getIntent().getBooleanExtra(EXTRA_IS_CREATE, false); setTitle(mIsCreateMode ? R.string.add_device : R.string.edit_device); - registerOnServiceConnectedListener(this); mIdContainer = findViewById(R.id.idContainer); mIdView = findViewById(R.id.id); @@ -263,82 +264,16 @@ public class DeviceActivity extends SyncthingActivity } } - @Override - public void onDestroy() { - super.onDestroy(); - SyncthingService syncthingService = getService(); - if (syncthingService != null) { - syncthingService.getNotificationHandler().cancelConsentNotification(getIntent().getIntExtra(EXTRA_NOTIFICATION_ID, 0)); - syncthingService.unregisterOnServiceStateChangeListener(this::onServiceStateChange); - } - mIdView.removeTextChangedListener(mIdTextWatcher); - mNameView.removeTextChangedListener(mNameTextWatcher); - mAddressesView.removeTextChangedListener(mAddressesTextWatcher); - } - - @Override - public void onPause() { - super.onPause(); - - // We don't want to update every time a TextView's character changes, - // so we hold off until the view stops being visible to the user. - if (mDeviceNeedsToUpdate) { - updateDevice(); - } - } - - /** - * Save current settings in case we are in create mode and they aren't yet stored in the config. - */ - @Override - public void onSaveInstanceState(Bundle outState) { - super.onSaveInstanceState(outState); - outState.putString("device", new Gson().toJson(mDevice)); - if (mIsCreateMode){ - outState.putBoolean(IS_SHOWING_DISCARD_DIALOG, mDiscardDialog != null && mDiscardDialog.isShowing()); - Util.dismissDialogSafe(mDiscardDialog, this); - } - - outState.putBoolean(IS_SHOWING_COMPRESSION_DIALOG, mCompressionDialog != null && mCompressionDialog.isShowing()); - Util.dismissDialogSafe(mCompressionDialog, this); - - outState.putBoolean(IS_SHOWING_DELETE_DIALOG, mDeleteDialog != null && mDeleteDialog.isShowing()); - Util.dismissDialogSafe(mDeleteDialog, this); - } - /** * Register for service state change events. */ @Override - public void onServiceConnected() { - Log.v(TAG, "onServiceConnected"); - SyncthingService syncthingService = (SyncthingService) getService(); + public void onServiceConnected(ComponentName componentName, IBinder iBinder) { + super.onServiceConnected(componentName, iBinder); + SyncthingServiceBinder syncthingServiceBinder = (SyncthingServiceBinder) iBinder; + SyncthingService syncthingService = (SyncthingService) syncthingServiceBinder.getService(); syncthingService.getNotificationHandler().cancelConsentNotification(getIntent().getIntExtra(EXTRA_NOTIFICATION_ID, 0)); - syncthingService.registerOnServiceStateChangeListener(this); - } - - /** - * Sets version and current address of the device. - * NOTE: This is only called once on startup, should be called more often to properly display - * version/address changes. - */ - private void onReceiveConnections(Connections connections) { - if (connections == null || connections.connections == null) { - Log.e(TAG, "onReceiveConnections: connections == null || connections.connections == null"); - return; - } - if (mDevice == null) { - Log.e(TAG, "onReceiveConnections: mDevice == null"); - return; - } - - boolean viewsExist = mSyncthingVersionView != null && mCurrentAddressView != null; - if (viewsExist && connections.connections.containsKey(mDevice.deviceID)) { - mCurrentAddressView.setVisibility(VISIBLE); - mSyncthingVersionView.setVisibility(VISIBLE); - mCurrentAddressView.setText(connections.connections.get(mDevice.deviceID).address); - mSyncthingVersionView.setText(connections.connections.get(mDevice.deviceID).clientVersion); - } + syncthingService.registerOnServiceStateChangeListener(DeviceActivity.this); } @Override @@ -366,6 +301,83 @@ public class DeviceActivity extends SyncthingActivity updateViewsAndSetListeners(); } + @Override + public void onBackPressed() { + if (mIsCreateMode) { + showDiscardDialog(); + } + else { + super.onBackPressed(); + } + } + + @Override + public void onPause() { + super.onPause(); + + // We don't want to update every time a TextView's character changes, + // so we hold off until the view stops being visible to the user. + if (mDeviceNeedsToUpdate) { + updateDevice(); + } + } + + @Override + public void onDestroy() { + super.onDestroy(); + SyncthingService syncthingService = getService(); + if (syncthingService != null) { + syncthingService.getNotificationHandler().cancelConsentNotification(getIntent().getIntExtra(EXTRA_NOTIFICATION_ID, 0)); + syncthingService.unregisterOnServiceStateChangeListener(DeviceActivity.this); + } + mIdView.removeTextChangedListener(mIdTextWatcher); + mNameView.removeTextChangedListener(mNameTextWatcher); + mAddressesView.removeTextChangedListener(mAddressesTextWatcher); + } + + /** + * Save current settings in case we are in create mode and they aren't yet stored in the config. + */ + @Override + public void onSaveInstanceState(Bundle outState) { + super.onSaveInstanceState(outState); + outState.putString("device", new Gson().toJson(mDevice)); + if (mIsCreateMode){ + outState.putBoolean(IS_SHOWING_DISCARD_DIALOG, mDiscardDialog != null && mDiscardDialog.isShowing()); + Util.dismissDialogSafe(mDiscardDialog, this); + } + + outState.putBoolean(IS_SHOWING_COMPRESSION_DIALOG, mCompressionDialog != null && mCompressionDialog.isShowing()); + Util.dismissDialogSafe(mCompressionDialog, this); + + outState.putBoolean(IS_SHOWING_DELETE_DIALOG, mDeleteDialog != null && mDeleteDialog.isShowing()); + Util.dismissDialogSafe(mDeleteDialog, this); + } + + /** + * Sets version and current address of the device. + * NOTE: This is only called once on startup, should be called more often to properly display + * version/address changes. + */ + private void onReceiveConnections(Connections connections) { + if (connections == null || connections.connections == null) { + Log.e(TAG, "onReceiveConnections: connections == null || connections.connections == null"); + return; + } + if (mDevice == null) { + Log.e(TAG, "onReceiveConnections: mDevice == null"); + return; + } + + boolean viewsExist = mSyncthingVersionView != null && mCurrentAddressView != null; + if (viewsExist && connections.connections.containsKey(mDevice.deviceID)) { + mCurrentAddressView.setVisibility(VISIBLE); + mSyncthingVersionView.setVisibility(VISIBLE); + mCurrentAddressView.setText(connections.connections.get(mDevice.deviceID).address); + mSyncthingVersionView.setText(connections.connections.get(mDevice.deviceID).clientVersion); + } + } + private void updateViewsAndSetListeners() { mIdView.removeTextChangedListener(mIdTextWatcher); mNameView.removeTextChangedListener(mNameTextWatcher); @@ -609,16 +621,6 @@ public class DeviceActivity extends SyncthingActivity shareIntent, context.getString(R.string.send_device_id_to))); } - @Override - public void onBackPressed() { - if (mIsCreateMode) { - showDiscardDialog(); - } - else { - super.onBackPressed(); - } - } - private void showDiscardDialog(){ mDiscardDialog = createDiscardDialog(); mDiscardDialog.show(); diff --git a/app/src/main/java/com/nutomic/syncthingandroid/activities/FolderActivity.java b/app/src/main/java/com/nutomic/syncthingandroid/activities/FolderActivity.java index 1f66b97c..ba22733c 100644 --- a/app/src/main/java/com/nutomic/syncthingandroid/activities/FolderActivity.java +++ b/app/src/main/java/com/nutomic/syncthingandroid/activities/FolderActivity.java @@ -4,11 +4,13 @@ import android.annotation.SuppressLint; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; +import android.content.ComponentName; import android.content.Intent; import android.content.SharedPreferences; import android.net.Uri; import android.os.Build; import android.os.Bundle; +import android.os.IBinder; import android.support.v4.provider.DocumentFile; import android.support.v7.widget.SwitchCompat; import android.text.Editable; @@ -35,6 +37,7 @@ import com.nutomic.syncthingandroid.model.FolderIgnoreList; import com.nutomic.syncthingandroid.service.Constants; import com.nutomic.syncthingandroid.service.RestApi; import com.nutomic.syncthingandroid.service.SyncthingService; +import com.nutomic.syncthingandroid.service.SyncthingServiceBinder; import com.nutomic.syncthingandroid.SyncthingApp; import com.nutomic.syncthingandroid.util.ConfigRouter; import com.nutomic.syncthingandroid.util.FileUtils; @@ -60,7 +63,7 @@ import static com.nutomic.syncthingandroid.service.SyncthingService.State.ACTIVE * Shows folder details and allows changing them. */ public class FolderActivity extends SyncthingActivity - implements SyncthingActivity.OnServiceConnectedListener, SyncthingService.OnServiceStateChangeListener { + implements SyncthingService.OnServiceStateChangeListener { public static final String EXTRA_NOTIFICATION_ID = "com.nutomic.syncthingandroid.activities.FolderActivity.NOTIFICATION_ID"; @@ -181,7 +184,6 @@ public class FolderActivity extends SyncthingActivity mIsCreateMode = getIntent().getBooleanExtra(EXTRA_IS_CREATE, false); setTitle(mIsCreateMode ? R.string.create_folder : R.string.edit_folder); - registerOnServiceConnectedListener(this); mLabelView = findViewById(R.id.label); mIdView = findViewById(R.id.id); @@ -339,16 +341,13 @@ public class FolderActivity extends SyncthingActivity } @Override - public void onDestroy() { - super.onDestroy(); - SyncthingService syncthingService = getService(); - if (syncthingService != null) { - syncthingService.getNotificationHandler().cancelConsentNotification(getIntent().getIntExtra(EXTRA_NOTIFICATION_ID, 0)); - syncthingService.unregisterOnServiceStateChangeListener(this::onServiceStateChange); + public void onBackPressed() { + if (mIsCreateMode) { + showDiscardDialog(); + } + else { + super.onBackPressed(); } - mLabelView.removeTextChangedListener(mTextWatcher); - mIdView.removeTextChangedListener(mTextWatcher); - mEditIgnoreListContent.removeTextChangedListener(mTextWatcher); } @Override @@ -369,6 +368,19 @@ public class FolderActivity extends SyncthingActivity } } + @Override + public void onDestroy() { + super.onDestroy(); + SyncthingService syncthingService = getService(); + if (syncthingService != null) { + syncthingService.getNotificationHandler().cancelConsentNotification(getIntent().getIntExtra(EXTRA_NOTIFICATION_ID, 0)); + syncthingService.unregisterOnServiceStateChangeListener(FolderActivity.this); + } + mLabelView.removeTextChangedListener(mTextWatcher); + mIdView.removeTextChangedListener(mTextWatcher); + mEditIgnoreListContent.removeTextChangedListener(mTextWatcher); + } + @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); @@ -385,11 +397,12 @@ public class FolderActivity extends SyncthingActivity * Register for service state change events. */ @Override - public void onServiceConnected() { - Log.v(TAG, "onServiceConnected"); - SyncthingService syncthingService = (SyncthingService) getService(); + public void onServiceConnected(ComponentName componentName, IBinder iBinder) { + super.onServiceConnected(componentName, iBinder); + SyncthingServiceBinder syncthingServiceBinder = (SyncthingServiceBinder) iBinder; + SyncthingService syncthingService = (SyncthingService) syncthingServiceBinder.getService(); syncthingService.getNotificationHandler().cancelConsentNotification(getIntent().getIntExtra(EXTRA_NOTIFICATION_ID, 0)); - syncthingService.registerOnServiceStateChangeListener(this); + syncthingService.registerOnServiceStateChangeListener(FolderActivity.this); } @Override @@ -755,16 +768,6 @@ public class FolderActivity extends SyncthingActivity mConfig.updateFolder(restApi, mFolder); } - @Override - public void onBackPressed() { - if (mIsCreateMode) { - showDiscardDialog(); - } - else { - super.onBackPressed(); - } - } - private void showDiscardDialog(){ mDiscardDialog = createDiscardDialog(); mDiscardDialog.show(); diff --git a/app/src/main/java/com/nutomic/syncthingandroid/activities/FolderPickerActivity.java b/app/src/main/java/com/nutomic/syncthingandroid/activities/FolderPickerActivity.java index b2e092d8..e0a23611 100644 --- a/app/src/main/java/com/nutomic/syncthingandroid/activities/FolderPickerActivity.java +++ b/app/src/main/java/com/nutomic/syncthingandroid/activities/FolderPickerActivity.java @@ -98,12 +98,6 @@ public class FolderPickerActivity extends SyncthingActivity } else { displayRoot(); } - - Boolean prefUseRoot = PreferenceManager.getDefaultSharedPreferences(this).getBoolean(Constants.PREF_USE_ROOT, false); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && !prefUseRoot) { - Toast.makeText(this, R.string.kitkat_external_storage_warning, Toast.LENGTH_LONG) - .show(); - } } /** diff --git a/app/src/main/java/com/nutomic/syncthingandroid/activities/SettingsActivity.java b/app/src/main/java/com/nutomic/syncthingandroid/activities/SettingsActivity.java index 9a9e76f0..0cd36f58 100644 --- a/app/src/main/java/com/nutomic/syncthingandroid/activities/SettingsActivity.java +++ b/app/src/main/java/com/nutomic/syncthingandroid/activities/SettingsActivity.java @@ -2,12 +2,14 @@ package com.nutomic.syncthingandroid.activities; import android.Manifest; import android.app.AlertDialog; +import android.content.ComponentName; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; +import android.os.IBinder; import android.preference.CheckBoxPreference; import android.preference.EditTextPreference; import android.preference.ListPreference; @@ -34,6 +36,7 @@ import com.nutomic.syncthingandroid.service.Constants; import com.nutomic.syncthingandroid.service.NotificationHandler; import com.nutomic.syncthingandroid.service.RestApi; import com.nutomic.syncthingandroid.service.SyncthingService; +import com.nutomic.syncthingandroid.service.SyncthingServiceBinder; import com.nutomic.syncthingandroid.util.Languages; import com.nutomic.syncthingandroid.util.Util; import com.nutomic.syncthingandroid.views.WifiSsidPreference; @@ -49,18 +52,22 @@ import eu.chainfire.libsuperuser.Shell; public class SettingsActivity extends SyncthingActivity { + private static final String TAG = "SettingsActivity"; + + private SettingsFragment mSettingsFragment; + public static final String EXTRA_OPEN_SUB_PREF_SCREEN = "com.nutomic.syncthingandroid.activities.SettingsActivity.OPEN_SUB_PREF_SCREEN"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - SettingsFragment settingsFragment = new SettingsFragment(); + mSettingsFragment = new SettingsFragment(); Bundle bundle = new Bundle(); bundle.putString(EXTRA_OPEN_SUB_PREF_SCREEN, getIntent().getStringExtra(EXTRA_OPEN_SUB_PREF_SCREEN)); - settingsFragment.setArguments(bundle); + mSettingsFragment.setArguments(bundle); getFragmentManager().beginTransaction() - .replace(android.R.id.content, settingsFragment) + .replace(android.R.id.content, mSettingsFragment) .commit(); } @@ -84,10 +91,19 @@ public class SettingsActivity extends SyncthingActivity { } } + @Override + public void onServiceConnected(ComponentName componentName, IBinder iBinder) { + super.onServiceConnected(componentName, iBinder); + SyncthingServiceBinder syncthingServiceBinder = (SyncthingServiceBinder) iBinder; + SyncthingService syncthingService = (SyncthingService) syncthingServiceBinder.getService(); + mSettingsFragment.setService(syncthingService); + syncthingService.registerOnServiceStateChangeListener(mSettingsFragment); + } + public static class SettingsFragment extends PreferenceFragment - implements SyncthingActivity.OnServiceConnectedListener, - SyncthingService.OnServiceStateChangeListener, Preference.OnPreferenceChangeListener, - Preference.OnPreferenceClickListener { + implements SyncthingService.OnServiceStateChangeListener, + Preference.OnPreferenceChangeListener, + Preference.OnPreferenceClickListener { private static final String TAG = "SettingsFragment"; private static final String KEY_EXPORT_CONFIG = "export_config"; @@ -150,7 +166,6 @@ public class SettingsActivity extends SyncthingActivity { public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); ((SyncthingApp) getActivity().getApplication()).component().inject(this); - ((SyncthingActivity) getActivity()).registerOnServiceConnectedListener(this); } /** @@ -304,14 +319,8 @@ public class SettingsActivity extends SyncthingActivity { } } - @Override - public void onServiceConnected() { - Log.v(TAG, "onServiceConnected"); - if (getActivity() == null) - return; - - mSyncthingService = ((SyncthingActivity) getActivity()).getService(); - mSyncthingService.registerOnServiceStateChangeListener(this); + public void setService(SyncthingService syncthingService) { + mSyncthingService = syncthingService; } @Override diff --git a/app/src/main/java/com/nutomic/syncthingandroid/activities/ShareActivity.java b/app/src/main/java/com/nutomic/syncthingandroid/activities/ShareActivity.java index 3913dab0..b49bdcb3 100644 --- a/app/src/main/java/com/nutomic/syncthingandroid/activities/ShareActivity.java +++ b/app/src/main/java/com/nutomic/syncthingandroid/activities/ShareActivity.java @@ -1,12 +1,14 @@ package com.nutomic.syncthingandroid.activities; import android.app.ProgressDialog; +import android.content.ComponentName; import android.content.ContentResolver; import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; +import android.os.IBinder; import android.preference.PreferenceManager; import android.provider.MediaStore; import android.text.TextUtils; @@ -24,7 +26,10 @@ import android.widget.Toast; import com.google.common.io.Files; import com.nutomic.syncthingandroid.R; import com.nutomic.syncthingandroid.model.Folder; +import com.nutomic.syncthingandroid.service.RestApi; import com.nutomic.syncthingandroid.service.SyncthingService; +import com.nutomic.syncthingandroid.service.SyncthingServiceBinder; +import com.nutomic.syncthingandroid.util.ConfigRouter; import com.nutomic.syncthingandroid.util.Util; import java.io.File; @@ -46,23 +51,33 @@ import java.util.Map; * ownCloud Android {@see https://github.com/owncloud/android/blob/79664304fdb762b2e04f1ac505f50d0923ddd212/src/com/owncloud/android/utils/UriUtils.java#L193} */ public class ShareActivity extends SyncthingActivity - implements SyncthingActivity.OnServiceConnectedListener, SyncthingService.OnServiceStateChangeListener { + implements SyncthingService.OnServiceStateChangeListener { private static final String TAG = "ShareActivity"; private static final String PREF_PREVIOUSLY_SELECTED_SYNCTHING_FOLDER = "previously_selected_syncthing_folder"; public static final String PREF_FOLDER_SAVED_SUBDIRECTORY = "saved_sub_directory_"; - private TextView mSubDirectoryTextView; + private ConfigRouter mConfig; private Spinner mFoldersSpinner; + private SyncthingService mSyncthingService = null; + + private TextView mSubDirectoryTextView; + + @Override + public void onServiceConnected(ComponentName componentName, IBinder iBinder) { + super.onServiceConnected(componentName, iBinder); + SyncthingServiceBinder syncthingServiceBinder = (SyncthingServiceBinder) iBinder; + SyncthingService syncthingService = (SyncthingService) syncthingServiceBinder.getService(); + syncthingService.registerOnServiceStateChangeListener(ShareActivity.this); + mSyncthingService = syncthingService; + } + @Override public void onServiceStateChange(SyncthingService.State currentState) { - if (currentState != SyncthingService.State.ACTIVE || getApi() == null) - return; - - List folders = getApi().getFolders(); + List folders = mConfig.getFolders(getApi()); // Get the index of the previously selected folder. int folderIndex = 0; @@ -84,11 +99,6 @@ public class ShareActivity extends SyncthingActivity sItems.setSelection(folderIndex); } - @Override - public void onServiceConnected() { - getService().registerOnServiceStateChangeListener(this); - } - @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); @@ -100,10 +110,9 @@ public class ShareActivity extends SyncthingActivity @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + mConfig = new ConfigRouter(ShareActivity.this); setContentView(R.layout.activity_share); - registerOnServiceConnectedListener(this); - Button mShareButton = findViewById(R.id.share_button); Button mCancelButton = findViewById(R.id.cancel_button); Button browseButton = findViewById(R.id.browse_button); @@ -113,7 +122,6 @@ public class ShareActivity extends SyncthingActivity mSubDirectoryTextView = findViewById(R.id.sub_directory_Textview); mFoldersSpinner = findViewById(R.id.folders); - // TODO: add support for EXTRA_TEXT (notes, memos sharing) ArrayList extrasToCopy = new ArrayList<>(); if (getIntent().getAction().equals(Intent.ACTION_SEND)) { Uri uri = getIntent().getParcelableExtra(Intent.EXTRA_STREAM); @@ -179,6 +187,42 @@ public class ShareActivity extends SyncthingActivity mSubDirectoryTextView.setText(getSavedSubDirectory()); } + @Override + protected void onPause() { + super.onPause(); + if (mFoldersSpinner.getSelectedItem() != null) { + Folder selectedFolder = (Folder) mFoldersSpinner.getSelectedItem(); + PreferenceManager.getDefaultSharedPreferences(this).edit() + .putString(PREF_PREVIOUSLY_SELECTED_SYNCTHING_FOLDER, selectedFolder.id) + .apply(); + } + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (requestCode == FolderPickerActivity.DIRECTORY_REQUEST_CODE && resultCode == RESULT_OK) { + Folder selectedFolder = (Folder) mFoldersSpinner.getSelectedItem(); + String folderDirectory = Util.formatPath(selectedFolder.path); + String subDirectory = data.getStringExtra(FolderPickerActivity.EXTRA_RESULT_DIRECTORY); + //Remove the parent directory from the string, so it is only the Sub directory that is displayed to the user. + subDirectory = subDirectory.replace(folderDirectory, ""); + mSubDirectoryTextView.setText(subDirectory); + + PreferenceManager.getDefaultSharedPreferences(this) + .edit().putString(PREF_FOLDER_SAVED_SUBDIRECTORY + selectedFolder.id, subDirectory) + .apply(); + } + } + + @Override + protected void onDestroy() { + if (mSyncthingService != null) { + mSyncthingService.unregisterOnServiceStateChangeListener(ShareActivity.this); + } + super.onDestroy(); + } + /** * Generate file name for new file. */ @@ -357,32 +401,4 @@ public class ShareActivity extends SyncthingActivity shareActivity.finish(); } } - - @Override - protected void onPause() { - super.onPause(); - if (mFoldersSpinner.getSelectedItem() != null) { - Folder selectedFolder = (Folder) mFoldersSpinner.getSelectedItem(); - PreferenceManager.getDefaultSharedPreferences(this).edit() - .putString(PREF_PREVIOUSLY_SELECTED_SYNCTHING_FOLDER, selectedFolder.id) - .apply(); - } - } - - @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - super.onActivityResult(requestCode, resultCode, data); - if (requestCode == FolderPickerActivity.DIRECTORY_REQUEST_CODE && resultCode == RESULT_OK) { - Folder selectedFolder = (Folder) mFoldersSpinner.getSelectedItem(); - String folderDirectory = Util.formatPath(selectedFolder.path); - String subDirectory = data.getStringExtra(FolderPickerActivity.EXTRA_RESULT_DIRECTORY); - //Remove the parent directory from the string, so it is only the Sub directory that is displayed to the user. - subDirectory = subDirectory.replace(folderDirectory, ""); - mSubDirectoryTextView.setText(subDirectory); - - PreferenceManager.getDefaultSharedPreferences(this) - .edit().putString(PREF_FOLDER_SAVED_SUBDIRECTORY + selectedFolder.id, subDirectory) - .apply(); - } - } } diff --git a/app/src/main/java/com/nutomic/syncthingandroid/activities/SyncthingActivity.java b/app/src/main/java/com/nutomic/syncthingandroid/activities/SyncthingActivity.java index eb9ad5eb..63ccf611 100644 --- a/app/src/main/java/com/nutomic/syncthingandroid/activities/SyncthingActivity.java +++ b/app/src/main/java/com/nutomic/syncthingandroid/activities/SyncthingActivity.java @@ -8,6 +8,7 @@ import android.os.Bundle; import android.os.IBinder; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; +// import android.util.Log; import com.annimon.stream.Stream; import com.nutomic.syncthingandroid.R; @@ -22,17 +23,10 @@ import java.util.LinkedList; */ public abstract class SyncthingActivity extends AppCompatActivity implements ServiceConnection { + private static final String TAG = "SyncthingActivity"; + private SyncthingService mSyncthingService; - private final LinkedList mServiceConnectedListeners = new LinkedList<>(); - - /** - * To be used for Fragments. - */ - public interface OnServiceConnectedListener { - void onServiceConnected(); - } - /** * Look for a Toolbar in the layout and bind it as the activity's actionbar with reasonable * defaults. @@ -69,8 +63,6 @@ public abstract class SyncthingActivity extends AppCompatActivity implements Ser public void onServiceConnected(ComponentName componentName, IBinder iBinder) { SyncthingServiceBinder syncthingServiceBinder = (SyncthingServiceBinder) iBinder; mSyncthingService = syncthingServiceBinder.getService(); - Stream.of(mServiceConnectedListeners).forEach(OnServiceConnectedListener::onServiceConnected); - mServiceConnectedListeners.clear(); } @Override @@ -78,17 +70,6 @@ public abstract class SyncthingActivity extends AppCompatActivity implements Ser mSyncthingService = null; } - /** - * Used for Fragments to use the Activity's service connection. - */ - void registerOnServiceConnectedListener(OnServiceConnectedListener listener) { - if (mSyncthingService != null) { - listener.onServiceConnected(); - } else { - mServiceConnectedListeners.addLast(listener); - } - } - /** * Returns service object (or null if not bound). */ diff --git a/app/src/main/java/com/nutomic/syncthingandroid/service/SyncthingService.java b/app/src/main/java/com/nutomic/syncthingandroid/service/SyncthingService.java index 3ed78d10..fee4c21a 100644 --- a/app/src/main/java/com/nutomic/syncthingandroid/service/SyncthingService.java +++ b/app/src/main/java/com/nutomic/syncthingandroid/service/SyncthingService.java @@ -322,7 +322,7 @@ public class SyncthingService extends Service { * This is the moment, when the reset delta index work was completed and Web UI came up. * 3.2 The shutdown gets deferred until State.ACTIVE was reached and then syncthing native will * be shutdown synchronously. - */ + */ Log.i(TAG, "Invoking reset of delta indexes"); if (mCurrentState != State.DISABLED) { // Shutdown synchronously. @@ -756,8 +756,10 @@ public class SyncthingService extends Service { Boolean failSuccess = true; Log.v(TAG, "exportConfig BEGIN"); - // Shutdown synchronously. - shutdown(State.DISABLED); + if (mCurrentState != State.DISABLED) { + // Shutdown synchronously. + shutdown(State.DISABLED); + } // Copy config, privateKey and/or publicKey to export path. Constants.EXPORT_PATH_OBJ.mkdirs(); @@ -858,8 +860,10 @@ public class SyncthingService extends Service { Boolean failSuccess = true; Log.v(TAG, "importConfig BEGIN"); - // Shutdown synchronously. - shutdown(State.DISABLED); + if (mCurrentState != State.DISABLED) { + // Shutdown synchronously. + shutdown(State.DISABLED); + } // Import config, privateKey and/or publicKey. try { diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index b5676ff1..9e98d94a 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -288,9 +288,6 @@ Избор на папка - - Внимание: Версията на Android не позволява синхронизиране с външни устройства за съхранение на данни - Директорията е празна diff --git a/app/src/main/res/values-ca-rES/strings.xml b/app/src/main/res/values-ca-rES/strings.xml index fecc1aef..b853d4ff 100644 --- a/app/src/main/res/values-ca-rES/strings.xml +++ b/app/src/main/res/values-ca-rES/strings.xml @@ -543,9 +543,6 @@ Ens podeu informar dels problemes que trobeu a través de Github. Selector de carpetes - - Avís: la vostra versió de l\'Android no us permet sincronitzar a dispositius d\'emmagatzematge externs - El directori és buit diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index ac0525b5..f9bcb38b 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -334,9 +334,6 @@ Všechny zaznamenané chyby prosím hlašte přes Github. Výběr adresáře - - Varování: Tato verze Androidu nepovoluje synchronizaci na externí úložiště - Adresář je prázdný diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index 2ec6c635..1183d9dc 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -330,9 +330,6 @@ Vær venlig at rapportere ethvert problem, du støder på, via Github. Mappe Vælger - - Advarsel: Din Android version tillader ikke at synkronisere til eksterne lagringsenheder - Katalog er Tomt diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index a5097b29..4e09c8c7 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -565,9 +565,6 @@ Bitte melden Sie auftretende Probleme via GitHub. Verzeichnisauswahl - - Warnung: Deine Andoid-Version erlaubt kein Synchronisieren auf externe Datenträger - Verzeichnis ist leer diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 7541d83f..31095eab 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -330,9 +330,6 @@ Επιλογέας φακέλων - - Προσοχή: η έκδοση του Android σας δεν επιτρέπει τον συγχρονισμό προς εξωτερικές συσκευές αποθήκευσης - Ο φάκελος είναι κενός diff --git a/app/src/main/res/values-es-rMX/strings.xml b/app/src/main/res/values-es-rMX/strings.xml index 2e3bea80..6a5819fe 100644 --- a/app/src/main/res/values-es-rMX/strings.xml +++ b/app/src/main/res/values-es-rMX/strings.xml @@ -262,9 +262,6 @@ Seleccionador de Carpetas - - Advertencia: Su versión de Android no permite sincronizar con dispositivos de almacenamiento externo - El directorio está vacío diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 81419de6..e9d3dcd6 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -299,9 +299,6 @@ Seleccionador de carpetas - - Aviso: Tu versión de Android no permite la sincronización con dispositivos de almacenamiento externos - El directorio esta vacío diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index efba74f9..48975e05 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -314,9 +314,6 @@ Ilmoitathan ystävällisesti kaikista havaitsemistasi ongelmista Githubin kautta Kansionvalitsin - - Varoitus: Käytössä oleva Android-versio ei salli synkronointia ulkoisille massamuisteille. - Hakemisto on tyhjä diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index d3a9db4b..840d0dcb 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -396,9 +396,6 @@ S\'il vous plaît, soumettez les problèmes que vous rencontrez via Github. Sélection du répertoire - - Attention: votre version Android n\'autorise pas la synchronisation avec des périphériques de stockages externes. - Le répertoire est vide diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index c1fbf62d..f6a849cd 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -392,9 +392,6 @@ VIGYÁZAT! Más alkalmazások kiolvashatják a backupból a titkos kulcsot, és Mappaválasztó - - Figyelem: Az általad használt Android verzió nem támogatja a külső eszközre (pl. memóriakártyára) történő szinkronizálást - A mappa üres diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index 7465e8ff..64a05af8 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -311,9 +311,6 @@ Jika ada masalah silakan laporkan lewat Github. Pemilih Folder - - Peringatan: Versi Android anda tidak mengijinkan penyelarasan ke perangkat storage eksternal - Direktori ini Kosong diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 5f655f24..54d205c1 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -393,9 +393,6 @@ Si prega di segnalare eventuali problemi che si incontrano via Github. Selezione Cartella - - Attenzione: La tua versione di Android non permette la sincronizzazione con dispositivi esterni di archiviazione - Cartella Vuota diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index d7c07470..11fe4b06 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -331,9 +331,6 @@ フォルダーを選択 - - 警告: お使いの Android のバージョンは外部ストレージに同期することができません - ディレクトリーは空です diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 6711307e..e747edfa 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -329,9 +329,6 @@ 폴더 선택기 - - 경고: 사용하는 Android 버전에서는 외부 저장소에의 동기화를 지원하지 않습니다 - 디렉토리가 비어 있습니다 diff --git a/app/src/main/res/values-nb/strings.xml b/app/src/main/res/values-nb/strings.xml index b1d44e30..e9598227 100644 --- a/app/src/main/res/values-nb/strings.xml +++ b/app/src/main/res/values-nb/strings.xml @@ -271,9 +271,6 @@ Mappe-velger - - Advarsel: Din versjon av Android tillater ikke synkronisering til eksterne lagringsenheter. - Katalogen er tom diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index b9f7c26a..a84b7a64 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -415,9 +415,6 @@ Als je problemen tegenkomt, meld ze dan via GitHub. Mapkiezer - - Waarschuwing: je Android-versie laat synchroniseren naar externe opslagapparaten niet toe - Map is leeg diff --git a/app/src/main/res/values-nn/strings.xml b/app/src/main/res/values-nn/strings.xml index 8f5d2283..34057b74 100644 --- a/app/src/main/res/values-nn/strings.xml +++ b/app/src/main/res/values-nn/strings.xml @@ -271,9 +271,6 @@ Mappeveljar - - Åtvaring: Din versjon av Android tillèt ikkje synkronisering av eksterne lagringseiningar. - Mappa er tom diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 420475d0..28e3430f 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -334,9 +334,6 @@ Proszę zgłaszać napotkane błędy programu za pośrednictwem serwisu Github.< Wybieranie katalogu - - Ostrzeżenie: aktualna wersja systemu Android nie pozwala na synchronizowanie zewnętrznych pamięci masowych - Katalog jest pusty diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 077b444f..82cf7a80 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -375,9 +375,6 @@ Por favor, nos avise sobre quaisquer problemas que você encontrar via Github. Seletor de pasta - - Aviso: a versão do seu Android não suporta sincronização de dispositivos externos de armazenamento - A pasta está vazia diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index df248b0d..52daeaf5 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -297,9 +297,6 @@ Reporte, através do Github, quaisquer problemas que encontre, por favor. Selector de pasta - - Aviso: A sua versão de Android não permite sincronizar com dispositivos de armazenamento externo - A pasta está vazia diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 339035df..5977ab6d 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -425,9 +425,6 @@ Vă rugăm să raportați orice problemă întâlniți, prin intermediul GitHub. Selector de director - - Atenție: Versiunea dumneavoastră de Android nu permite sincronizarea la locațiile de stocare externe - Directorul este gol diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 7017375e..5dd881d7 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -451,9 +451,6 @@ Выбор Папки - - Внимание: Ваша версия Android не позволяет синхронизацию на внешние хранилища - Папка пуста diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index 07ae3acb..13bbbdfe 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -240,9 +240,6 @@ Výver Adresára - - Varovanie: Verzia Androidu na Vašom zariadení nedovoľuje synchronizáciu externého úložiska - Adresár je Prázdny diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index b566d431..bbad55b2 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -510,9 +510,6 @@ Vänligen rapportera eventuella problem du stöter på via Github. Mappväljare - - Varning: Din Android version tillåter inte synkronisering till externa lagringsenheter - Katalogen är tom diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index cf8a57e9..1ba42416 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -288,9 +288,6 @@ Eğer herhangi bir sorunla karşılaşırsan Github aracılığıyla bildir. Klasör Seçici - - Uyarı: Android sürümünüz, harici depolama aygıtlarına eşzamanlama yapılmasına izin vermiyor. - Dizin Boş diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 1d0bd0f1..6a69483d 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -262,9 +262,6 @@ Trình chọn th.mục - - Cảnh báo: Ph.bản Android của bạn không cho phép đ.bộ vào các th.bị lưu trữ ngoại vi - Thư mục rỗng diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 2c1a34fe..d79332ff 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -333,9 +333,6 @@ 文件夹选择器 - - 警告:您的系统版本不允许同步文件至外部存储器 - 目录为空 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index e601000e..40abbc3c 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -329,9 +329,6 @@ 資料夾選擇器 - - 警告:你的 Android 版本不允許同步外部儲存裝置 - 資料夾為空 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 540e7058..d2d4133a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -573,9 +573,6 @@ Please report any problems you encounter via Github. Folder Picker - - Warning: Your Android version does not allow syncing to external storage devices - Directory is Empty