diff --git a/app/src/main/java/com/nutomic/syncthingandroid/service/SyncthingRunnable.java b/app/src/main/java/com/nutomic/syncthingandroid/service/SyncthingRunnable.java index 0a2e82325..a8eee9c8c 100644 --- a/app/src/main/java/com/nutomic/syncthingandroid/service/SyncthingRunnable.java +++ b/app/src/main/java/com/nutomic/syncthingandroid/service/SyncthingRunnable.java @@ -4,6 +4,8 @@ import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; +import android.net.ConnectivityManager; +import android.net.Network; import android.net.wifi.WifiManager; import android.net.wifi.WifiManager.MulticastLock; import android.os.Build; @@ -118,12 +120,42 @@ public SyncthingRunnable(Context context, Command command) { @Override public void run() { try { + bindNetwork(); run(false); + clearBindNetwork(); } catch (ExecutableNotFoundException e) { throw new RuntimeException(e.getMessage()); } } + /** + * Avoid the following two situations: + * 1. Fake WiFi: User wants only syncing via WiFi, but connects to a WiFi without internet connection, + * Android will auto route the request through the mobile network. + * 2. User only wants to sync through mobile network, but not use WiFi. + */ + private void bindNetwork() { + clearBindNetwork(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + boolean runOnWifi = mPreferences.getBoolean(Constants.PREF_RUN_ON_WIFI, true); + boolean runOnMobileData = mPreferences.getBoolean(Constants.PREF_RUN_ON_MOBILE_DATA, true); + if ((runOnWifi && !runOnMobileData) || (!runOnWifi && runOnMobileData)) { + ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); + Network network = cm.getActiveNetwork(); + cm.bindProcessToNetwork(network); + } + } + } + + private void clearBindNetwork() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + ConnectivityManager cm = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE); + if (cm.getBoundNetworkForProcess() != null) { + cm.bindProcessToNetwork(null); + } + } + } + @SuppressLint("WakelockTimeout") public String run(boolean returnStdOut) throws ExecutableNotFoundException { Boolean sendStopToService = false; @@ -403,6 +435,7 @@ public void killSyncthing() { SystemClock.sleep(50); } Log.d(TAG, "killSyncthing: Complete."); + clearBindNetwork(); } /**