diff --git a/app/build.gradle b/app/build.gradle
index 35eacfea8..c6699eda9 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -40,7 +40,7 @@ dependencies {
compile "info.guardianproject.panic:panic:0.5"
compile 'commons-io:commons-io:2.5'
compile 'commons-net:commons-net:3.5'
- compile 'org.openhab.jmdns:jmdns:3.4.2'
+ compile 'org.jmdns:jmdns:3.5.3'
compile 'ch.acra:acra:4.9.1'
compile 'io.reactivex:rxjava:1.1.0'
compile 'io.reactivex:rxandroid:0.23.0'
@@ -137,7 +137,8 @@ if (!hasProperty('sourceDeps')) {
'info.guardianproject.panic:panic:a7ed9439826db2e9901649892cf9afbe76f00991b768d8f4c26332d7c9406cb2',
'io.reactivex:rxandroid:35c1a90f8c1f499db3c1f3d608e1f191ac8afddb10c02dd91ef04c03a0a4bcda',
'io.reactivex:rxjava:2c162afd78eba217cdfee78b60e85d3bfb667db61e12bc95e3cf2ddc5beeadf6',
- 'org.openhab.jmdns:jmdns:7a4b34b5606bbd2aff7fdfe629edcb0416fccd367fb59a099f210b9aba4f0bce',
+ 'org.jmdns:jmdns:24e7e3a50a579136400e8c9b0750399eb3c7558918bdf52c0ffa5e0fa5aad503',
+ 'org.slf4j:slf4j-api:e56288031f5e60652c06e7bb6e9fa410a61231ab54890f7b708fc6adc4107c5b',
]
}
@@ -181,7 +182,6 @@ def preDexEnabled = "true".equals(System.getProperty("pre-dex", "true"))
android {
compileSdkVersion 24
buildToolsVersion '25.0.3'
- useLibrary 'org.apache.http.legacy'
buildTypes {
// use proguard on debug too since we have unknowingly broken
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
index 517c234ec..06752191a 100644
--- a/app/proguard-rules.pro
+++ b/app/proguard-rules.pro
@@ -7,6 +7,9 @@
-dontwarn com.android.support.test.**
-dontwarn javax.naming.**
+-dontwarn org.slf4j.**
+-dontnote org.apache.http.**
+-dontnote android.net.http.**
-dontnote android.support.**
-dontnote **ILicensingService
diff --git a/app/src/main/java/javax/jmdns/impl/FDroidServiceInfo.java b/app/src/main/java/javax/jmdns/impl/FDroidServiceInfo.java
index 2851cb2d1..2fed8a798 100644
--- a/app/src/main/java/javax/jmdns/impl/FDroidServiceInfo.java
+++ b/app/src/main/java/javax/jmdns/impl/FDroidServiceInfo.java
@@ -4,12 +4,12 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
+import javax.jmdns.ServiceInfo;
+import javax.jmdns.impl.util.ByteWrangler;
import java.net.Inet4Address;
import java.net.Inet6Address;
import java.net.UnknownHostException;
-import javax.jmdns.ServiceInfo;
-
/**
* The ServiceInfo class needs to be serialized in order to be sent as an Android broadcast.
* In order to make it Parcelable (or Serializable for that matter), there are some package-scope
@@ -32,7 +32,7 @@ public class FDroidServiceInfo extends ServiceInfoImpl implements Parcelable {
if (data == null || data.length == 0) {
return null;
}
- String fingerprint = this.readUTF(data, 0, data.length);
+ String fingerprint = ByteWrangler.readUTF(data, 0, data.length);
if (TextUtils.isEmpty(fingerprint)) {
return null;
}
@@ -51,14 +51,14 @@ public class FDroidServiceInfo extends ServiceInfoImpl implements Parcelable {
public FDroidServiceInfo(Parcel in) {
super(
- in.readString(),
- in.readString(),
- in.readString(),
- in.readInt(),
- in.readInt(),
- in.readInt(),
- in.readByte() != 0,
- readBytes(in)
+ in.readString(),
+ in.readString(),
+ in.readString(),
+ in.readInt(),
+ in.readInt(),
+ in.readInt(),
+ in.readByte() != 0,
+ readBytes(in)
);
int addressCount = in.readInt();
diff --git a/app/src/main/java/org/fdroid/fdroid/UpdateService.java b/app/src/main/java/org/fdroid/fdroid/UpdateService.java
index ab0dc40dc..20360a5f8 100644
--- a/app/src/main/java/org/fdroid/fdroid/UpdateService.java
+++ b/app/src/main/java/org/fdroid/fdroid/UpdateService.java
@@ -47,6 +47,7 @@ import org.fdroid.fdroid.data.Repo;
import org.fdroid.fdroid.data.RepoProvider;
import org.fdroid.fdroid.data.Schema;
import org.fdroid.fdroid.installer.InstallManagerService;
+import org.fdroid.fdroid.net.BluetoothDownloader;
import org.fdroid.fdroid.net.ConnectivityMonitorService;
import org.fdroid.fdroid.views.main.MainActivity;
@@ -332,7 +333,7 @@ public class UpdateService extends IntentService {
boolean forcedUpdate = false;
String address = null;
if (intent != null) {
- address = intent.getStringExtra(EXTRA_ADDRESS);
+ address = intent.getStringExtra(EXTRA_ADDRESS); // TODO switch to Intent.setData()
manualUpdate = intent.getBooleanExtra(EXTRA_MANUAL_UPDATE, false);
forcedUpdate = intent.getBooleanExtra(EXTRA_FORCED_UPDATE, false);
}
@@ -340,7 +341,9 @@ public class UpdateService extends IntentService {
try {
// See if it's time to actually do anything yet...
int netState = ConnectivityMonitorService.getNetworkState(this);
- if (netState == ConnectivityMonitorService.FLAG_NET_UNAVAILABLE) {
+ if (address != null && address.startsWith(BluetoothDownloader.SCHEME)) {
+ Utils.debugLog(TAG, "skipping internet check, this is bluetooth");
+ } else if (netState == ConnectivityMonitorService.FLAG_NET_UNAVAILABLE) {
Utils.debugLog(TAG, "No internet, cannot update");
if (manualUpdate) {
sendNoInternetToast();
diff --git a/app/src/main/java/org/fdroid/fdroid/localrepo/SwapService.java b/app/src/main/java/org/fdroid/fdroid/localrepo/SwapService.java
index 6f8060b9d..b7e509179 100644
--- a/app/src/main/java/org/fdroid/fdroid/localrepo/SwapService.java
+++ b/app/src/main/java/org/fdroid/fdroid/localrepo/SwapService.java
@@ -1,8 +1,10 @@
package org.fdroid.fdroid.localrepo;
+import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
+import android.bluetooth.BluetoothAdapter;
import android.content.BroadcastReceiver;
import android.content.ContentValues;
import android.content.Context;
@@ -10,7 +12,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.net.Uri;
-import android.net.http.AndroidHttpClient;
+import android.net.wifi.WifiManager;
import android.os.AsyncTask;
import android.os.IBinder;
import android.support.annotation.IntDef;
@@ -20,11 +22,6 @@ import android.support.v4.app.NotificationCompat;
import android.support.v4.content.LocalBroadcastManager;
import android.text.TextUtils;
import android.util.Log;
-import org.apache.http.HttpHost;
-import org.apache.http.NameValuePair;
-import org.apache.http.client.entity.UrlEncodedFormEntity;
-import org.apache.http.client.methods.HttpPost;
-import org.apache.http.message.BasicNameValuePair;
import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.Preferences;
import org.fdroid.fdroid.R;
@@ -47,13 +44,14 @@ import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
import java.io.IOException;
-import java.io.UnsupportedEncodingException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
+import java.net.HttpURLConnection;
+import java.net.URL;
import java.util.Collections;
import java.util.HashSet;
-import java.util.List;
import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
@@ -67,10 +65,13 @@ import java.util.concurrent.ConcurrentHashMap;
public class SwapService extends Service {
private static final String TAG = "SwapService";
+
private static final String SHARED_PREFERENCES = "swap-state";
private static final String KEY_APPS_TO_SWAP = "appsToSwap";
private static final String KEY_BLUETOOTH_ENABLED = "bluetoothEnabled";
private static final String KEY_WIFI_ENABLED = "wifiEnabled";
+ private static final String KEY_BLUETOOTH_ENABLED_BEFORE_SWAP = "bluetoothEnabledBeforeSwap";
+ private static final String KEY_WIFI_ENABLED_BEFORE_SWAP = "wifiEnabledBeforeSwap";
@NonNull
private final Set appsToSwap = new HashSet<>();
@@ -80,6 +81,10 @@ public class SwapService extends Service {
*/
private static final ConcurrentHashMap INSTALLED_APPS = new ConcurrentHashMap<>();
+ private static SharedPreferences swapPreferences;
+ private static BluetoothAdapter bluetoothAdapter;
+ private static WifiManager wifiManager;
+
public static void stop(Context context) {
Intent intent = new Intent(context, SwapService.class);
context.stopService(intent);
@@ -93,16 +98,6 @@ public class SwapService extends Service {
INSTALLED_APPS.put(packageName, app);
}
- /**
- * Where relevant, the state of the swap process will be saved to disk using preferences.
- * Note that this is not always useful, for example saving the "current wifi network" is
- * bound to cause trouble when the user opens the swap process again and is connected to
- * a different network.
- */
- private SharedPreferences persistence() {
- return getSharedPreferences(SHARED_PREFERENCES, MODE_PRIVATE);
- }
-
// ==========================================================
// Search for peers to swap
// ==========================================================
@@ -208,55 +203,37 @@ public class SwapService extends Service {
UpdateService.updateRepoNow(this, peer.getRepoAddress());
}
+ @SuppressLint("StaticFieldLeak")
private void askServerToSwapWithUs(final Repo repo) {
- askServerToSwapWithUs(repo.address);
- }
-
- private void askServerToSwapWithUs(final String address) {
new AsyncTask() {
@Override
protected Void doInBackground(Void... args) {
- Uri repoUri = Uri.parse(address);
String swapBackUri = Utils.getLocalRepoUri(FDroidApp.repo).toString();
-
- AndroidHttpClient client = AndroidHttpClient.newInstance("F-Droid", SwapService.this);
- HttpPost request = new HttpPost("/request-swap");
- HttpHost host = new HttpHost(repoUri.getHost(), repoUri.getPort(), repoUri.getScheme());
-
+ HttpURLConnection conn = null;
try {
- Utils.debugLog(TAG, "Asking server at " + address + " to swap with us in return (by POSTing to \"/request-swap\" with repo \"" + swapBackUri + "\")...");
- populatePostParams(swapBackUri, request);
- client.execute(host, request);
+ URL url = new URL(repo.address.replace("/fdroid/repo", "/request-swap"));
+ conn = (HttpURLConnection) url.openConnection();
+ conn.setRequestMethod("POST");
+ conn.setDoInput(true);
+ conn.setDoOutput(true);
+
+ OutputStream outputStream = conn.getOutputStream();
+ OutputStreamWriter writer = new OutputStreamWriter(outputStream);
+ writer.write("repo=" + swapBackUri);
+ writer.flush();
+ writer.close();
+ outputStream.close();
+
+ int responseCode = conn.getResponseCode();
+ Utils.debugLog(TAG, "Asking server at " + repo.address + " to swap with us in return (by " +
+ "POSTing to \"/request-swap\" with repo \"" + swapBackUri + "\"): " + responseCode);
} catch (IOException e) {
- notifyOfErrorOnUiThread();
Log.e(TAG, "Error while asking server to swap with us", e);
} finally {
- client.close();
+ conn.disconnect();
}
return null;
}
-
- private void populatePostParams(String swapBackUri, HttpPost request) throws UnsupportedEncodingException {
- List params = new ArrayList<>();
- params.add(new BasicNameValuePair("repo", swapBackUri));
- UrlEncodedFormEntity encodedParams = new UrlEncodedFormEntity(params);
- request.setEntity(encodedParams);
- }
-
- private void notifyOfErrorOnUiThread() {
- // TODO: Broadcast error message so that whoever wants to can display a relevant
- // message in the UI. This service doesn't understand the concept of UI.
- /*runOnUiThread(new Runnable() {
- @Override
- public void run() {
- Toast.makeText(
- SwapService.this,
- R.string.swap_reciprocate_failed,
- Toast.LENGTH_LONG
- ).show();
- }
- });*/
- }
}.execute();
}
@@ -333,7 +310,7 @@ public class SwapService extends Service {
// ==========================================
private void persistAppsToSwap() {
- persistence().edit().putString(KEY_APPS_TO_SWAP, serializePackages(appsToSwap)).apply();
+ swapPreferences.edit().putString(KEY_APPS_TO_SWAP, serializePackages(appsToSwap)).apply();
}
/**
@@ -389,30 +366,36 @@ public class SwapService extends Service {
persistAppsToSwap();
}
- // =============================================================
- // Remember which swap technologies a user used in the past
- // =============================================================
-
- private final BroadcastReceiver receiveSwapStatusChanged = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- Utils.debugLog(TAG, "Remembering that Bluetooth swap " + (bluetoothSwap.isConnected() ? "IS" : "is NOT") +
- " connected and WiFi swap " + (wifiSwap.isConnected() ? "IS" : "is NOT") + " connected.");
- persistence().edit()
- .putBoolean(KEY_BLUETOOTH_ENABLED, bluetoothSwap.isConnected())
- .putBoolean(KEY_WIFI_ENABLED, wifiSwap.isConnected())
- .apply();
- }
- };
-
- /*
- private boolean wasBluetoothEnabled() {
- return persistence().getBoolean(KEY_BLUETOOTH_ENABLED, false);
+ public static boolean getBluetoothVisibleUserPreference() {
+ return swapPreferences.getBoolean(SwapService.KEY_BLUETOOTH_ENABLED, false);
}
- */
- private boolean wasWifiEnabled() {
- return persistence().getBoolean(KEY_WIFI_ENABLED, false);
+ public static void putBluetoothVisibleUserPreference(boolean visible) {
+ swapPreferences.edit().putBoolean(SwapService.KEY_BLUETOOTH_ENABLED, visible).apply();
+ }
+
+ public static boolean getWifiVisibleUserPreference() {
+ return swapPreferences.getBoolean(SwapService.KEY_WIFI_ENABLED, false);
+ }
+
+ public static void putWifiVisibleUserPreference(boolean visible) {
+ swapPreferences.edit().putBoolean(SwapService.KEY_WIFI_ENABLED, visible).apply();
+ }
+
+ public static boolean wasBluetoothEnabledBeforeSwap() {
+ return swapPreferences.getBoolean(SwapService.KEY_BLUETOOTH_ENABLED_BEFORE_SWAP, false);
+ }
+
+ public static void putBluetoothEnabledBeforeSwap(boolean visible) {
+ swapPreferences.edit().putBoolean(SwapService.KEY_BLUETOOTH_ENABLED_BEFORE_SWAP, visible).apply();
+ }
+
+ public static boolean wasWifiEnabledBeforeSwap() {
+ return swapPreferences.getBoolean(SwapService.KEY_WIFI_ENABLED_BEFORE_SWAP, false);
+ }
+
+ public static void putWifiEnabledBeforeSwap(boolean visible) {
+ swapPreferences.edit().putBoolean(SwapService.KEY_WIFI_ENABLED_BEFORE_SWAP, visible).apply();
}
/**
@@ -452,9 +435,6 @@ public class SwapService extends Service {
return wifiSwap.isConnected() && wifiSwap.getBonjour().isConnected();
}
- public static final String ACTION_PEER_FOUND = "org.fdroid.fdroid.SwapManager.ACTION_PEER_FOUND";
- public static final String EXTRA_PEER = "EXTRA_PEER";
-
// ===============================================================
// Old SwapService stuff being merged into that.
// ===============================================================
@@ -503,32 +483,39 @@ public class SwapService extends Service {
CacheSwapAppsService.startCaching(this);
- SharedPreferences preferences = getSharedPreferences(SHARED_PREFERENCES, Context.MODE_PRIVATE);
+ swapPreferences = getSharedPreferences(SHARED_PREFERENCES, Context.MODE_PRIVATE);
- appsToSwap.addAll(deserializePackages(preferences.getString(KEY_APPS_TO_SWAP, "")));
+ bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
+ if (bluetoothAdapter != null) {
+ SwapService.putBluetoothEnabledBeforeSwap(bluetoothAdapter.isEnabled());
+ }
+
+ wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
+ if (wifiManager != null) {
+ SwapService.putWifiEnabledBeforeSwap(wifiManager.isWifiEnabled());
+ }
+
+ appsToSwap.addAll(deserializePackages(swapPreferences.getString(KEY_APPS_TO_SWAP, "")));
bluetoothSwap = BluetoothSwap.create(this);
- wifiSwap = new WifiSwap(this);
+ wifiSwap = new WifiSwap(this, wifiManager);
Preferences.get().registerLocalRepoHttpsListeners(httpsEnabledListener);
- LocalBroadcastManager.getInstance(this).registerReceiver(onWifiChange, new IntentFilter(WifiStateChangeService.BROADCAST));
+ LocalBroadcastManager.getInstance(this).registerReceiver(onWifiChange,
+ new IntentFilter(WifiStateChangeService.BROADCAST));
- IntentFilter filter = new IntentFilter(BLUETOOTH_STATE_CHANGE);
- filter.addAction(WIFI_STATE_CHANGE);
- LocalBroadcastManager.getInstance(this).registerReceiver(receiveSwapStatusChanged, filter);
-
- /*
- if (wasBluetoothEnabled()) {
+ if (getBluetoothVisibleUserPreference()) {
Utils.debugLog(TAG, "Previously the user enabled Bluetooth swap, so enabling again automatically.");
- bluetoothSwap.startInBackground();
- }
- */
-
- if (wasWifiEnabled()) {
- Utils.debugLog(TAG, "Previously the user enabled WiFi swap, so enabling again automatically.");
- wifiSwap.startInBackground();
+ bluetoothSwap.startInBackground(); // TODO replace with Intent to SwapService
} else {
- Utils.debugLog(TAG, "WiFi was NOT enabled last time user swapped, so starting with WiFi not visible.");
+ Utils.debugLog(TAG, "Bluetooth was NOT enabled last time user swapped, starting not visible.");
+ }
+
+ if (getWifiVisibleUserPreference()) {
+ Utils.debugLog(TAG, "Previously the user enabled WiFi swap, so enabling again automatically.");
+ wifiSwap.startInBackground(); // TODO replace with Intent to SwapService
+ } else {
+ Utils.debugLog(TAG, "WiFi was NOT enabled last time user swapped, starting not visible.");
}
}
@@ -549,7 +536,14 @@ public class SwapService extends Service {
Utils.debugLog(TAG, "Destroying service, will disable swapping if required, and unregister listeners.");
Preferences.get().unregisterLocalRepoHttpsListeners(httpsEnabledListener);
LocalBroadcastManager.getInstance(this).unregisterReceiver(onWifiChange);
- LocalBroadcastManager.getInstance(this).unregisterReceiver(receiveSwapStatusChanged);
+
+ if (!SwapService.wasBluetoothEnabledBeforeSwap()) {
+ bluetoothAdapter.disable();
+ }
+
+ if (!SwapService.wasWifiEnabledBeforeSwap()) {
+ wifiManager.setWifiEnabled(false);
+ }
//TODO getBluetoothSwap().stopInBackground();
getWifiSwap().stopInBackground();
diff --git a/app/src/main/java/org/fdroid/fdroid/localrepo/type/BluetoothSwap.java b/app/src/main/java/org/fdroid/fdroid/localrepo/type/BluetoothSwap.java
index b81a3fb6e..7ab9735b1 100644
--- a/app/src/main/java/org/fdroid/fdroid/localrepo/type/BluetoothSwap.java
+++ b/app/src/main/java/org/fdroid/fdroid/localrepo/type/BluetoothSwap.java
@@ -8,7 +8,6 @@ import android.content.IntentFilter;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
-
import org.fdroid.fdroid.Utils;
import org.fdroid.fdroid.localrepo.SwapService;
import org.fdroid.fdroid.net.bluetooth.BluetoothServer;
@@ -59,8 +58,8 @@ public final class BluetoothSwap extends SwapType {
@Override
public synchronized void start() {
-
if (isConnected()) {
+ Utils.debugLog(TAG, "already running, quitting start()");
return;
}
@@ -171,10 +170,12 @@ public final class BluetoothSwap extends SwapType {
}
@Override
- public void start() { }
+ public void start() {
+ }
@Override
- public void stop() { }
+ public void stop() {
+ }
@Override
protected String getBroadcastAction() {
diff --git a/app/src/main/java/org/fdroid/fdroid/localrepo/type/WifiSwap.java b/app/src/main/java/org/fdroid/fdroid/localrepo/type/WifiSwap.java
index 152877aec..f76dbe042 100644
--- a/app/src/main/java/org/fdroid/fdroid/localrepo/type/WifiSwap.java
+++ b/app/src/main/java/org/fdroid/fdroid/localrepo/type/WifiSwap.java
@@ -2,6 +2,7 @@ package org.fdroid.fdroid.localrepo.type;
import android.annotation.SuppressLint;
import android.content.Context;
+import android.net.wifi.WifiManager;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
@@ -31,10 +32,12 @@ public class WifiSwap extends SwapType {
private Handler webServerThreadHandler;
private LocalHTTPD localHttpd;
private final BonjourBroadcast bonjourBroadcast;
+ private final WifiManager wifiManager;
- public WifiSwap(Context context) {
+ public WifiSwap(Context context, WifiManager wifiManager) {
super(context);
bonjourBroadcast = new BonjourBroadcast(context);
+ this.wifiManager = wifiManager;
}
protected String getBroadcastAction() {
@@ -47,6 +50,8 @@ public class WifiSwap extends SwapType {
@Override
public void start() {
+ wifiManager.setWifiEnabled(true);
+
Utils.debugLog(TAG, "Preparing swap webserver.");
sendBroadcast(SwapService.EXTRA_STARTING);
diff --git a/app/src/main/java/org/fdroid/fdroid/net/BluetoothDownloader.java b/app/src/main/java/org/fdroid/fdroid/net/BluetoothDownloader.java
index 85d4f4d84..225be7434 100644
--- a/app/src/main/java/org/fdroid/fdroid/net/BluetoothDownloader.java
+++ b/app/src/main/java/org/fdroid/fdroid/net/BluetoothDownloader.java
@@ -14,15 +14,27 @@ import org.fdroid.fdroid.net.bluetooth.httpish.Response;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
+import java.util.regex.Pattern;
+/**
+ * Download from a Bluetooth swap repo. Example URI:
+ * {@code bluetooth://84-CF-BF-8B-3E-34/fdroid/repo}
+ */
public class BluetoothDownloader extends Downloader {
private static final String TAG = "BluetoothDownloader";
+ public static final String SCHEME = "bluetooth";
+
private final BluetoothConnection connection;
private FileDetails fileDetails;
private final String sourcePath;
+ public static boolean isBluetoothUri(Uri uri) {
+ return SCHEME.equals(uri.getScheme())
+ && Pattern.matches("([0-9A-F]{2}-)+[0-9A-F]{2}", uri.getHost());
+ }
+
public BluetoothDownloader(Uri uri, File destFile) throws IOException {
super(uri, destFile);
String macAddress = uri.getHost().replace("-", ":");
diff --git a/app/src/main/java/org/fdroid/fdroid/net/HttpDownloader.java b/app/src/main/java/org/fdroid/fdroid/net/HttpDownloader.java
index 880d48fa5..619f48c00 100644
--- a/app/src/main/java/org/fdroid/fdroid/net/HttpDownloader.java
+++ b/app/src/main/java/org/fdroid/fdroid/net/HttpDownloader.java
@@ -122,16 +122,23 @@ public class HttpDownloader extends Downloader {
cacheTag = connection.getHeaderField(HEADER_FIELD_ETAG);
}
- private boolean isSwapUrl() {
- String host = sourceUrl.getHost();
- return sourceUrl.getPort() > 1023 // only root can use <= 1023, so never a swap repo
+ public static boolean isSwapUrl(Uri uri) {
+ return isSwapUrl(uri.getHost(), uri.getPort());
+ }
+
+ public static boolean isSwapUrl(URL url) {
+ return isSwapUrl(url.getHost(), url.getPort());
+ }
+
+ public static boolean isSwapUrl(String host, int port) {
+ return port > 1023 // only root can use <= 1023, so never a swap repo
&& host.matches("[0-9.]+") // host must be an IP address
&& FDroidApp.subnetInfo.isInRange(host); // on the same subnet as we are
}
private HttpURLConnection getConnection() throws SocketTimeoutException, IOException {
HttpURLConnection connection;
- if (isSwapUrl()) {
+ if (isSwapUrl(sourceUrl)) {
// swap never works with a proxy, its unrouted IP on the same subnet
connection = (HttpURLConnection) sourceUrl.openConnection();
} else {
diff --git a/app/src/main/java/org/fdroid/fdroid/net/bluetooth/BluetoothServer.java b/app/src/main/java/org/fdroid/fdroid/net/bluetooth/BluetoothServer.java
index 7ba308a3f..86d8a987d 100644
--- a/app/src/main/java/org/fdroid/fdroid/net/bluetooth/BluetoothServer.java
+++ b/app/src/main/java/org/fdroid/fdroid/net/bluetooth/BluetoothServer.java
@@ -66,7 +66,7 @@ public class BluetoothServer extends Thread {
public void run() {
isRunning = true;
- BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
+ final BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
try {
serverSocket = adapter.listenUsingInsecureRfcommWithServiceRecord("FDroid App Swap", BluetoothConstants.fdroidUuid());
@@ -83,6 +83,11 @@ public class BluetoothServer extends Thread {
break;
}
+ if (!adapter.isEnabled()) {
+ Utils.debugLog(TAG, "User disabled Bluetooth from outside, stopping.");
+ break;
+ }
+
try {
BluetoothSocket clientSocket = serverSocket.accept();
if (clientSocket != null) {
diff --git a/app/src/main/java/org/fdroid/fdroid/views/swap/SendFDroidView.java b/app/src/main/java/org/fdroid/fdroid/views/swap/SendFDroidView.java
new file mode 100644
index 000000000..60bf9fc02
--- /dev/null
+++ b/app/src/main/java/org/fdroid/fdroid/views/swap/SendFDroidView.java
@@ -0,0 +1,149 @@
+package org.fdroid.fdroid.views.swap;
+
+import android.annotation.SuppressLint;
+import android.annotation.TargetApi;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.graphics.LightingColorFilter;
+import android.support.annotation.ColorRes;
+import android.support.annotation.NonNull;
+import android.support.v4.content.LocalBroadcastManager;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.View;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.ScrollView;
+import android.widget.TextView;
+import org.fdroid.fdroid.FDroidApp;
+import org.fdroid.fdroid.Preferences;
+import org.fdroid.fdroid.QrGenAsyncTask;
+import org.fdroid.fdroid.R;
+import org.fdroid.fdroid.Utils;
+import org.fdroid.fdroid.localrepo.SwapService;
+import org.fdroid.fdroid.net.WifiStateChangeService;
+import org.fdroid.fdroid.views.swap.device.camera.CameraCharacteristicsChecker;
+
+public class SendFDroidView extends ScrollView implements SwapWorkflowActivity.InnerView {
+
+ private static final String TAG = "SendFDroidView";
+
+ public SendFDroidView(Context context) {
+ super(context);
+ }
+
+ public SendFDroidView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public SendFDroidView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ @TargetApi(21)
+ public SendFDroidView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ }
+
+ private SwapWorkflowActivity getActivity() {
+ return (SwapWorkflowActivity) getContext();
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ setUIFromWifi();
+ setUpWarningMessageQrScan();
+
+ ImageView qrImage = (ImageView) findViewById(R.id.wifi_qr_code);
+
+ // Replace all blacks with the background blue.
+ qrImage.setColorFilter(new LightingColorFilter(0xffffffff, getResources().getColor(R.color.swap_blue)));
+
+ Button useBluetooth = (Button) findViewById(R.id.btn_use_bluetooth);
+ useBluetooth.setOnClickListener(new Button.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ getActivity().showIntro();
+ getActivity().sendFDroidBluetooth();
+ }
+ });
+
+ LocalBroadcastManager.getInstance(getActivity()).registerReceiver(
+ onWifiStateChanged, new IntentFilter(WifiStateChangeService.BROADCAST));
+ }
+
+ private void setUpWarningMessageQrScan() {
+ final View qrWarningMessage = findViewById(R.id.warning_qr_scanner);
+ final boolean hasAutofocus = CameraCharacteristicsChecker.getInstance(getContext()).hasAutofocus();
+ final int visiblity = hasAutofocus ? GONE : VISIBLE;
+ qrWarningMessage.setVisibility(visiblity);
+ }
+
+
+ /**
+ * Remove relevant listeners/receivers/etc so that they do not receive and process events
+ * when this view is not in use.
+ */
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+
+ LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(onWifiStateChanged);
+ }
+
+ @Override
+ public boolean buildMenu(Menu menu, @NonNull MenuInflater inflater) {
+ return false;
+ }
+
+ @Override
+ public int getStep() {
+ return SwapService.STEP_INTRO;
+ }
+
+ @Override
+ public int getPreviousStep() {
+ return SwapService.STEP_INTRO;
+ }
+
+ @ColorRes
+ public int getToolbarColour() {
+ return R.color.swap_blue;
+ }
+
+ @Override
+ public String getToolbarTitle() {
+ return getResources().getString(R.string.swap_send_fdroid);
+ }
+
+ @SuppressLint("HardwareIds")
+ private void setUIFromWifi() {
+ if (TextUtils.isEmpty(FDroidApp.repo.address)) {
+ return;
+ }
+
+ String scheme = Preferences.get().isLocalRepoHttpsEnabled() ? "https://" : "http://";
+
+ // the fingerprint is not useful on the button label
+ String qrUriString = scheme + FDroidApp.ipAddressString + ":" + FDroidApp.port;
+ TextView ipAddressView = (TextView) findViewById(R.id.device_ip_address);
+ ipAddressView.setText(qrUriString);
+
+ Utils.debugLog(TAG, "Encoded swap URI in QR Code: " + qrUriString);
+ new QrGenAsyncTask(getActivity(), R.id.wifi_qr_code).execute(qrUriString);
+
+ }
+
+ private final BroadcastReceiver onWifiStateChanged = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ setUIFromWifi();
+ }
+ };
+
+}
diff --git a/app/src/main/java/org/fdroid/fdroid/views/swap/StartSwapView.java b/app/src/main/java/org/fdroid/fdroid/views/swap/StartSwapView.java
index 72270d387..1891468cd 100644
--- a/app/src/main/java/org/fdroid/fdroid/views/swap/StartSwapView.java
+++ b/app/src/main/java/org/fdroid/fdroid/views/swap/StartSwapView.java
@@ -324,6 +324,7 @@ public class StartSwapView extends RelativeLayout implements SwapWorkflowActivit
viewBluetoothId.setVisibility(View.GONE);
Utils.debugLog(TAG, "Received onCheckChanged(false) for Bluetooth swap, Bluetooth swap disabled successfully.");
}
+ SwapService.putBluetoothVisibleUserPreference(isChecked);
}
};
@@ -344,7 +345,8 @@ public class StartSwapView extends RelativeLayout implements SwapWorkflowActivit
// and the Bonjour service at the same time. Technically swap will work fine without
// Bonjour, and that is more of a convenience. Thus, we should show feedback once wifi
// is ready, even if Bonjour is not yet.
- LocalBroadcastManager.getInstance(getContext()).registerReceiver(onWifiSwapStateChanged, new IntentFilter(SwapService.WIFI_STATE_CHANGE));
+ LocalBroadcastManager.getInstance(getContext()).registerReceiver(onWifiSwapStateChanged,
+ new IntentFilter(SwapService.WIFI_STATE_CHANGE));
viewWifiNetwork.setOnClickListener(new OnClickListener() {
@Override
@@ -426,6 +428,7 @@ public class StartSwapView extends RelativeLayout implements SwapWorkflowActivit
Utils.debugLog(TAG, "Received onCheckChanged(false) for WiFi swap, disabling WiFi swap in background thread.");
getManager().getWifiSwap().stopInBackground();
}
+ SwapService.putWifiVisibleUserPreference(isChecked);
uiUpdateWifiNetwork();
}
};
diff --git a/app/src/main/java/org/fdroid/fdroid/views/swap/SwapWorkflowActivity.java b/app/src/main/java/org/fdroid/fdroid/views/swap/SwapWorkflowActivity.java
index 4bbfbd4f1..6098a58cd 100644
--- a/app/src/main/java/org/fdroid/fdroid/views/swap/SwapWorkflowActivity.java
+++ b/app/src/main/java/org/fdroid/fdroid/views/swap/SwapWorkflowActivity.java
@@ -1,5 +1,6 @@
package org.fdroid.fdroid.views.swap;
+import android.annotation.TargetApi;
import android.app.Activity;
import android.app.PendingIntent;
import android.bluetooth.BluetoothAdapter;
@@ -12,8 +13,10 @@ import android.content.ServiceConnection;
import android.net.Uri;
import android.net.wifi.WifiManager;
import android.os.AsyncTask;
+import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
+import android.provider.Settings;
import android.support.annotation.ColorRes;
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
@@ -29,10 +32,9 @@ import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
-
+import cc.mvdan.accesspoint.WifiApControl;
import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;
-
import org.fdroid.fdroid.BuildConfig;
import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.NfcHelper;
@@ -47,6 +49,8 @@ import org.fdroid.fdroid.installer.Installer;
import org.fdroid.fdroid.localrepo.LocalRepoManager;
import org.fdroid.fdroid.localrepo.SwapService;
import org.fdroid.fdroid.localrepo.peers.Peer;
+import org.fdroid.fdroid.net.BluetoothDownloader;
+import org.fdroid.fdroid.net.HttpDownloader;
import java.util.Arrays;
import java.util.Date;
@@ -57,8 +61,6 @@ import java.util.Set;
import java.util.Timer;
import java.util.TimerTask;
-import cc.mvdan.accesspoint.WifiApControl;
-
/**
* This activity will do its best to show the most relevant screen about swapping to the user.
* The problem comes when there are two competing goals - 1) Show the user a list of apps from another
@@ -111,6 +113,7 @@ public class SwapWorkflowActivity extends AppCompatActivity {
private static final int REQUEST_BLUETOOTH_ENABLE_FOR_SWAP = 2;
private static final int REQUEST_BLUETOOTH_DISCOVERABLE = 3;
private static final int REQUEST_BLUETOOTH_ENABLE_FOR_SEND = 4;
+ private static final int REQUEST_WRITE_SETTINGS_PERMISSION = 5;
private Toolbar toolbar;
private InnerView currentView;
@@ -118,6 +121,7 @@ public class SwapWorkflowActivity extends AppCompatActivity {
private PrepareSwapRepo updateSwappableAppsTask;
private NewRepoConfig confirmSwapConfig;
private LocalBroadcastManager localBroadcastManager;
+ private WifiManager wifiManager;
@NonNull
private final ServiceConnection serviceConnection = new ServiceConnection() {
@@ -183,6 +187,7 @@ public class SwapWorkflowActivity extends AppCompatActivity {
container = (ViewGroup) findViewById(R.id.fragment_container);
localBroadcastManager = LocalBroadcastManager.getInstance(this);
+ wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
new SwapDebug().logStatus();
}
@@ -197,7 +202,7 @@ public class SwapWorkflowActivity extends AppCompatActivity {
public boolean onPrepareOptionsMenu(Menu menu) {
menu.clear();
boolean parent = super.onPrepareOptionsMenu(menu);
- boolean inner = currentView != null && currentView.buildMenu(menu, getMenuInflater());
+ boolean inner = currentView != null && currentView.buildMenu(menu, getMenuInflater());
return parent || inner;
}
@@ -209,8 +214,20 @@ public class SwapWorkflowActivity extends AppCompatActivity {
showRelevantView();
}
+ /**
+ * Check whether incoming {@link Intent} is a swap repo, and ensure that
+ * it is a valid swap URL. The hostname can only be either an IP or
+ * Bluetooth address.
+ */
private void checkIncomingIntent() {
Intent intent = getIntent();
+ Uri uri = intent.getData();
+ if (uri != null && !HttpDownloader.isSwapUrl(uri) && !BluetoothDownloader.isBluetoothUri(uri)) {
+ String msg = getString(R.string.swap_toast_invalid_url, uri);
+ Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
+ return;
+ }
+
if (intent.getBooleanExtra(EXTRA_CONFIRM, false) && !intent.getBooleanExtra(EXTRA_SWAP_INTENT_HANDLED, false)) {
// Storing config in this variable will ensure that when showRelevantView() is next
// run, it will show the connect swap view (if the service is available).
@@ -239,32 +256,40 @@ public class SwapWorkflowActivity extends AppCompatActivity {
public void onClick(DialogInterface dialog, int which) {
// Do nothing
}
- }
- ).setPositiveButton(R.string.wifi, new DialogInterface.OnClickListener() {
+ })
+ .setPositiveButton(R.string.wifi, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
- startActivity(new Intent(WifiManager.ACTION_PICK_WIFI_NETWORK));
+ SwapService.putWifiEnabledBeforeSwap(wifiManager.isWifiEnabled());
+ wifiManager.setWifiEnabled(true);
+ Intent intent = new Intent(WifiManager.ACTION_PICK_WIFI_NETWORK);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ startActivity(intent);
}
- }
- ).setNegativeButton(R.string.wifi_ap, new DialogInterface.OnClickListener() {
+ })
+ .setNegativeButton(R.string.wifi_ap, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
- promptToSetupWifiAP();
+ if (Build.VERSION.SDK_INT >= 26) {
+ showTetheringSettings();
+ } else if (Build.VERSION.SDK_INT >= 23 && !Settings.System.canWrite(getBaseContext())) {
+ requestWriteSettingsPermission();
+ } else {
+ setupWifiAP();
+ }
}
- }
- ).create().show();
+ })
+ .create().show();
}
- private void promptToSetupWifiAP() {
- WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
+ private void setupWifiAP() {
WifiApControl ap = WifiApControl.getInstance(this);
wifiManager.setWifiEnabled(false);
- if (!ap.enable()) {
- Log.e(TAG, "Could not enable WiFi AP.");
- // TODO: Feedback to user?
+ if (ap.enable()) {
+ Toast.makeText(this, R.string.swap_toast_hotspot_enabled, Toast.LENGTH_SHORT).show();
} else {
- Utils.debugLog(TAG, "WiFi AP enabled.");
- // TODO: Seems to be broken some times...
+ Toast.makeText(this, R.string.swap_toast_could_not_enable_hotspot, Toast.LENGTH_LONG).show();
+ Log.e(TAG, "Could not enable WiFi AP.");
}
}
@@ -408,29 +433,52 @@ public class SwapWorkflowActivity extends AppCompatActivity {
inflateInnerView(R.layout.swap_select_apps);
}
+ /**
+ * On {@code android-26}, only apps with privileges can access
+ * {@code WRITE_SETTINGS}. So this just shows the tethering settings
+ * for the user to do it themselves.
+ */
+ public void showTetheringSettings() {
+ final Intent intent = new Intent(Intent.ACTION_MAIN, null);
+ intent.addCategory(Intent.CATEGORY_LAUNCHER);
+ final ComponentName cn = new ComponentName("com.android.settings",
+ "com.android.settings.TetherSettings");
+ intent.setComponent(cn);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ startActivity(intent);
+ }
+
+ @TargetApi(23)
+ public void requestWriteSettingsPermission() {
+ Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS,
+ Uri.parse("package:" + getPackageName()));
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ startActivityForResult(intent, REQUEST_WRITE_SETTINGS_PERMISSION);
+ }
+
public void sendFDroid() {
- // If Bluetooth has not been enabled/turned on, then enabling device discoverability
- // will automatically enable Bluetooth.
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
- if (adapter != null) {
- if (adapter.getState() != BluetoothAdapter.STATE_ON) {
- Intent discoverBt = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
- discoverBt.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 120);
- startActivityForResult(discoverBt, REQUEST_BLUETOOTH_ENABLE_FOR_SEND);
- } else {
- sendFDroidApk();
- }
+ if (adapter == null
+ || Build.VERSION.SDK_INT >= 23 // TODO make Bluetooth work with content:// URIs
+ || (!adapter.isEnabled() && getService().getWifiSwap().isConnected())) {
+ showSendFDroid();
} else {
- new AlertDialog.Builder(this)
- .setTitle(R.string.bluetooth_unavailable)
- .setMessage(R.string.swap_cant_send_no_bluetooth)
- .setNegativeButton(
- R.string.cancel,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) { }
- }
- ).create().show();
+ sendFDroidBluetooth();
+ }
+ }
+
+ /**
+ * Send the F-Droid APK via Bluetooth. If Bluetooth has not been
+ * enabled/turned on, then enabling device discoverability will
+ * automatically enable Bluetooth.
+ */
+ public void sendFDroidBluetooth() {
+ if (BluetoothAdapter.getDefaultAdapter().isEnabled()) {
+ sendFDroidApk();
+ } else {
+ Intent discoverBt = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
+ discoverBt.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 120);
+ startActivityForResult(discoverBt, REQUEST_BLUETOOTH_ENABLE_FOR_SEND);
}
}
@@ -483,6 +531,10 @@ public class SwapWorkflowActivity extends AppCompatActivity {
inflateInnerView(R.layout.swap_wifi_qr);
}
+ public void showSendFDroid() {
+ inflateInnerView(R.layout.swap_send_fdroid);
+ }
+
public void showSwapConnected() {
inflateInnerView(R.layout.swap_success);
}
@@ -557,23 +609,28 @@ public class SwapWorkflowActivity extends AppCompatActivity {
}
} else if (requestCode == CONNECT_TO_SWAP && resultCode == Activity.RESULT_OK) {
finish();
+ } else if (requestCode == REQUEST_WRITE_SETTINGS_PERMISSION) {
+ if (Build.VERSION.SDK_INT >= 23 && Settings.System.canWrite(this)) {
+ setupWifiAP();
+ }
} else if (requestCode == REQUEST_BLUETOOTH_ENABLE_FOR_SWAP) {
if (resultCode == RESULT_OK) {
Utils.debugLog(TAG, "User enabled Bluetooth, will make sure we are discoverable.");
ensureBluetoothDiscoverableThenStart();
} else {
- // Didn't enable bluetooth
- Utils.debugLog(TAG, "User chose not to enable Bluetooth, so doing nothing (i.e. sticking with wifi).");
+ Utils.debugLog(TAG, "User chose not to enable Bluetooth, so doing nothing");
+ SwapService.putBluetoothVisibleUserPreference(false);
}
} else if (requestCode == REQUEST_BLUETOOTH_DISCOVERABLE) {
if (resultCode != RESULT_CANCELED) {
Utils.debugLog(TAG, "User made Bluetooth discoverable, will proceed to start bluetooth server.");
- getState().getBluetoothSwap().startInBackground();
+ getState().getBluetoothSwap().startInBackground(); // TODO replace with Intent to SwapService
} else {
- Utils.debugLog(TAG, "User chose not to make Bluetooth discoverable, so doing nothing (i.e. sticking with wifi).");
+ Utils.debugLog(TAG, "User chose not to make Bluetooth discoverable, so doing nothing");
+ SwapService.putBluetoothVisibleUserPreference(false);
}
} else if (requestCode == REQUEST_BLUETOOTH_ENABLE_FOR_SEND) {
@@ -583,12 +640,13 @@ public class SwapWorkflowActivity extends AppCompatActivity {
/**
* The process for setting up bluetooth is as follows:
- * * Assume we have bluetooth available (otherwise the button which allowed us to start
- * the bluetooth process should not have been available).
- * * Ask user to enable (if not enabled yet).
- * * Start bluetooth server socket.
- * * Enable bluetooth discoverability, so that people can connect to our server socket.
- *
+ *
+ *
Assume we have bluetooth available (otherwise the button which allowed us to start
+ * the bluetooth process should not have been available)
+ *
Ask user to enable (if not enabled yet)
+ *
Start bluetooth server socket
+ *
Enable bluetooth discoverability, so that people can connect to our server socket.
+ *
* Note that this is a little different than the usual process for bluetooth _clients_, which
* involves pairing and connecting with other devices.
*/
@@ -629,12 +687,12 @@ public class SwapWorkflowActivity extends AppCompatActivity {
throw new IllegalStateException("Can't start Bluetooth swap because service is null for some strange reason.");
}
- service.getBluetoothSwap().startInBackground();
+ service.getBluetoothSwap().startInBackground(); // TODO replace with Intent to SwapService
}
class PrepareInitialSwapRepo extends PrepareSwapRepo {
PrepareInitialSwapRepo() {
- super(new HashSet<>(Arrays.asList(new String[] {BuildConfig.APPLICATION_ID})));
+ super(new HashSet<>(Arrays.asList(new String[]{BuildConfig.APPLICATION_ID})));
}
}
diff --git a/app/src/main/java/org/fdroid/fdroid/views/swap/WifiQrView.java b/app/src/main/java/org/fdroid/fdroid/views/swap/WifiQrView.java
index dd73267c6..8ec198c8b 100644
--- a/app/src/main/java/org/fdroid/fdroid/views/swap/WifiQrView.java
+++ b/app/src/main/java/org/fdroid/fdroid/views/swap/WifiQrView.java
@@ -7,6 +7,7 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.LightingColorFilter;
import android.net.Uri;
+import android.os.Build;
import android.support.annotation.ColorRes;
import android.support.annotation.NonNull;
import android.support.v4.content.LocalBroadcastManager;
@@ -19,9 +20,6 @@ import android.widget.Button;
import android.widget.ImageView;
import android.widget.ScrollView;
import android.widget.TextView;
-
-import org.apache.http.NameValuePair;
-import org.apache.http.client.utils.URLEncodedUtils;
import org.fdroid.fdroid.FDroidApp;
import org.fdroid.fdroid.Preferences;
import org.fdroid.fdroid.QrGenAsyncTask;
@@ -31,9 +29,8 @@ import org.fdroid.fdroid.localrepo.SwapService;
import org.fdroid.fdroid.net.WifiStateChangeService;
import org.fdroid.fdroid.views.swap.device.camera.CameraCharacteristicsChecker;
-import java.net.URI;
-import java.util.List;
import java.util.Locale;
+import java.util.Set;
public class WifiQrView extends ScrollView implements SwapWorkflowActivity.InnerView {
@@ -142,32 +139,34 @@ public class WifiQrView extends ScrollView implements SwapWorkflowActivity.Inner
ipAddressView.setText(buttonLabel);
Uri sharingUri = Utils.getSharingUri(FDroidApp.repo);
- String qrUriString = scheme + sharingUri.getHost();
+ StringBuilder qrUrlBuilder = new StringBuilder(scheme);
+ qrUrlBuilder.append(sharingUri.getHost());
if (sharingUri.getPort() != 80) {
- qrUriString += ":" + sharingUri.getPort();
+ qrUrlBuilder.append(':');
+ qrUrlBuilder.append(sharingUri.getPort());
}
- qrUriString += sharingUri.getPath();
+ qrUrlBuilder.append(sharingUri.getPath());
boolean first = true;
- // Andorid provides an API for getting the query parameters and iterating over them:
- // Uri.getQueryParameterNames()
- // But it is only available on later Android versions. As such we use URLEncodedUtils instead.
- List parameters = URLEncodedUtils.parse(URI.create(sharingUri.toString()), "UTF-8");
- for (NameValuePair parameter : parameters) {
- if (!"ssid".equals(parameter.getName())) {
- if (first) {
- qrUriString += "?";
- first = false;
- } else {
- qrUriString += "&";
+ if (Build.VERSION.SDK_INT > 10) {
+ Set names = sharingUri.getQueryParameterNames();
+ for (String name : names) {
+ if (!"ssid".equals(name)) {
+ if (first) {
+ qrUrlBuilder.append('?');
+ first = false;
+ } else {
+ qrUrlBuilder.append('&');
+ }
+ qrUrlBuilder.append(name.toUpperCase(Locale.ENGLISH));
+ qrUrlBuilder.append('=');
+ qrUrlBuilder.append(sharingUri.getQueryParameter(name).toUpperCase(Locale.ENGLISH));
}
- qrUriString += parameter.getName().toUpperCase(Locale.ENGLISH) + "=" +
- parameter.getValue().toUpperCase(Locale.ENGLISH);
}
}
+ String qrUriString = qrUrlBuilder.toString();
Utils.debugLog(TAG, "Encoded swap URI in QR Code: " + qrUriString);
-
new QrGenAsyncTask(getActivity(), R.id.wifi_qr_code).execute(qrUriString);
}
diff --git a/app/src/main/res/layout/swap_blank.xml b/app/src/main/res/layout/swap_blank.xml
index 6266be168..55493c486 100644
--- a/app/src/main/res/layout/swap_blank.xml
+++ b/app/src/main/res/layout/swap_blank.xml
@@ -58,7 +58,7 @@
@@ -114,7 +114,7 @@
diff --git a/app/src/main/res/layout/swap_send_fdroid.xml b/app/src/main/res/layout/swap_send_fdroid.xml
new file mode 100644
index 000000000..79f1736e5
--- /dev/null
+++ b/app/src/main/res/layout/swap_send_fdroid.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values-af/strings.xml b/app/src/main/res/values-af/strings.xml
index 673be7b21..ba3a5f903 100644
--- a/app/src/main/res/values-af/strings.xml
+++ b/app/src/main/res/values-af/strings.xml
@@ -333,10 +333,6 @@
Verbind en deel programme met mense naby jou.Bevestig uitruilDie QR kode jy geskandeer het lyk nie soos \'n uitruil kode nie.
- Bluetooth nie beskikbaar nie
- "Kan nie F-Droid stuur nie, omdat Bluetooth is nie beskikbaar is op
- hierdie toestel nie."
- Laai tans…\'n Fout het plaasgevind tydens koppeling met die toestel, dit lyk nie asof ons kan uitruil nie!Uitruil nie geaktiveer nie
diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml
index 11225dd33..591a72490 100644
--- a/app/src/main/res/values-ar/strings.xml
+++ b/app/src/main/res/values-ar/strings.xml
@@ -287,8 +287,6 @@
جاري الاتصالتأكيد المبادلةرمز الاستجابة السريعة الذي تم التقاطه لا يبدو وكأنه رمز المبادلة.
- البلوتوث غير متاح
- لا يمكن إرسال اف-درويد، بسبب أن البلوتوث غير متاح على هذا الجهاز.يتم التحميل…حدث خطأ أثناء الاتصال بالجهاز، ولا يمكن أن يجري المبادلة معه!المبادلة غير فعالة
diff --git a/app/src/main/res/values-ast/strings.xml b/app/src/main/res/values-ast/strings.xml
index 9eafa2865..cc1889180 100644
--- a/app/src/main/res/values-ast/strings.xml
+++ b/app/src/main/res/values-ast/strings.xml
@@ -176,15 +176,11 @@
¿Quies trocar esta aplicación pola versión de fábrica?Quiciabes esto te cueste perresCargando…
- Nun pue unviase F-droid porque\'l Bluetooth nun ta disponible nesti
- preséu.
- Coneutando¿Nun pues alcontrar a quien tas guetando?Unviar F-droidEl códigu QR qu\'escaniesti nun paez ser un códigu d\'intercambéu.Asocedió un fallu entrín se coneutaba col preséu, ¡nun podemos facer l\'intercambiu con elli!
- Bluetooth non disponibleConfirmar intercambéuNome del preséuVisible pente Bluetooth
diff --git a/app/src/main/res/values-be/strings.xml b/app/src/main/res/values-be/strings.xml
index d58dbc583..7d30f28e0 100644
--- a/app/src/main/res/values-be/strings.xml
+++ b/app/src/main/res/values-be/strings.xml
@@ -324,10 +324,6 @@
ЗлучэннеПацвердзіць абменQR-код, які вы адсканавалі, не выглядае як код абмену.
- Bluetooth не даступны
- Немагчыма адправіць F-Droid, бо Bluetooth не даступны на гэтай
- прыладзе.
- Загрузка…Здарылася памылка падчас злучэння з прыладай. Немагчыма прадоўжыць абмен!Абмен не ўключаны
diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml
index abd6b581b..5fb00f9c4 100644
--- a/app/src/main/res/values-bg/strings.xml
+++ b/app/src/main/res/values-bg/strings.xml
@@ -220,10 +220,6 @@
Забранена размяна
- Изпращането на F-Droid не е възможно защото липсва Bluetooth
- функционалност.
-
- Липсва BluetoothРазмяна с устройства наоколоF-Droid e в готовност за размянаНатиснете за детайли или да позволите размяна на приложение.
diff --git a/app/src/main/res/values-bo/strings.xml b/app/src/main/res/values-bo/strings.xml
index e9805069a..4506217c6 100644
--- a/app/src/main/res/values-bo/strings.xml
+++ b/app/src/main/res/values-bo/strings.xml
@@ -314,8 +314,6 @@
མཐུད་བཞིན་པ།བརྗེ་ལེན་གཏན་འཁེལ།ཁྱེད་རང་གིས་འཚག་རྒྱག་པའི་QR ཨང་རྟགས་འདི་བརྗེ་ལེན་ཨང་རྟགས་དང་འདྲ་མཚུངས་མིན་འདུག
- བྷུ་ལུ་ཊོཐ་མིན་འདུག
- ཨེཕ་རོཌ་གཏོང་ཐུབ་ཀྱི་མིན་འདུག གང་ཡིན་ཟེར་ན་ཡོ་བྱད་འདིའི་སྒང་ལ་བྷུ་ལུ་ཊོཐ་མིན་འདུགབཅུག་བཞིན་པ།..…ཡོ་བྱད་ལ་མཐུད་པའི་སྐབས་སུ་སྐྱོན་ཤོར་སོང་བས་དེ་དང་མཉམ་དུ་བརྗེ་ལེན་བྱེད་ཐུབ་ཀྱི་མིན་འདུག!བརྗེ་ལེན་སྒོ་ཕྱེས་མིན་འདུག
diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml
index fa2cd7a2b..538d55ad4 100644
--- a/app/src/main/res/values-ca/strings.xml
+++ b/app/src/main/res/values-ca/strings.xml
@@ -273,8 +273,6 @@
ConnectantConfirmeu l\'intercanviEl codi QR que heu escanejat no sembla un codi d\'intercanvi.
- El Bluetooth no està disponible
- No s\'ha pogut enviar l\'F-Droid perquè el Bluetooth no està disponible en aquest dispositiu.S\'està carregant…S\'ha produït un error en connectar-se al dispositiu. No us podeu connectar!Intercanvi no activat
diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml
index eda4129e1..c99b90b15 100644
--- a/app/src/main/res/values-cs/strings.xml
+++ b/app/src/main/res/values-cs/strings.xml
@@ -242,10 +242,6 @@
PřipojováníPotvrdit výměnuNaskenovaný QR kód nevypadá jako výměnný kód.
- Bluetooth nedostupné
- F-Droid nelze odeslat, protože na tomto přístroji není Bluetooth
- dostupné.
- Načítání…Výměna není povolenaPřed výměnou je třeba zviditelnit přístroj.
diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml
index 97320a011..f6f1ff92e 100644
--- a/app/src/main/res/values-da/strings.xml
+++ b/app/src/main/res/values-da/strings.xml
@@ -279,9 +279,6 @@
ForbinderBekræft udvekslingDen QR-kode du skannede ligner ikke en udvekslingskode.
- Bluetooth utilgængelig
- Kan ikke sende F-Droid fordi Bluetooth er utilgængeligt på denne enhed.
- Indlæser…Der opstod en fejl under forbindelsen til enheden, kan udveksle med den!Udveksling ikke aktiveret
diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml
index b8f38fc83..f700070fb 100644
--- a/app/src/main/res/values-de/strings.xml
+++ b/app/src/main/res/values-de/strings.xml
@@ -192,7 +192,6 @@
Deinstallieren
- Bluetooth nicht verfügbarNeuNeu:Stündlich
@@ -276,9 +275,6 @@
Sie keinen gemeinsamen Netzwerkzugang haben, kann einer von Ihnen einen WLAN-Hotspot einrichten.
Tausch in der Nähe
- F-Droid kann nicht gesendet werden, da Bluetooth auf diesem Gerät nicht
- verfügbar ist.
- Ladevorgang …Fehler bei der Verbindungsaufnahme zum Zielgerät. Tausch ist nicht möglich!Tauschen ist nicht aktiviert
diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml
index 40fc55787..08a0dae50 100644
--- a/app/src/main/res/values-el/strings.xml
+++ b/app/src/main/res/values-el/strings.xml
@@ -267,10 +267,6 @@
ΣύνδεσηΕπιβεβαίωση ανταλλαγήςΟ κώδικας QR που σαρώσατε δεν μοιάζει με έναν κωδικό ανταλλαγής.
- Το Bluetooth δεν είναι διαθέσιμο
- Δεν μπορείτε να στείλετε το F-Droid επειδή το Bluetooth δεν είναι
- διαθέσιμο σε αυτήν τη συσκευή.
- Φόρτωση…Παρουσιάστηκε σφάλμα κατά τη σύνδεση με την συσκευή, φαίνεται ότι δεν μπορούμε να ανταλλάξουμε με αυτή!Η ανταλλαγή δεν είναι ενεργοποιημένη
diff --git a/app/src/main/res/values-eo/strings.xml b/app/src/main/res/values-eo/strings.xml
index 3b24f5d9e..e7517d7ec 100644
--- a/app/src/main/res/values-eo/strings.xml
+++ b/app/src/main/res/values-eo/strings.xml
@@ -272,10 +272,6 @@
KonektadoKonfirmi interŝanĝonLa skanita QR-kodo ne estas interŝanĝa kodo.
- Bludento ne disponebla
- Ne povas sendi F-Droid, ĉar Bludento ne estas disponebla en via
- aparato.
- Prilaborado…Eraro okazis dum konektado al aparato, ne povas interŝanĝi kun ĝi!Interŝanĝo malaktiva
diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml
index b6bdeef0a..c1dfd3184 100644
--- a/app/src/main/res/values-es/strings.xml
+++ b/app/src/main/res/values-es/strings.xml
@@ -236,8 +236,6 @@
ConectandoConfirmar intercambioEl código QR escaneado no parece un código de intercambio.
- Bluetooth no disponible
- No se puede enviar F-Droid porque no está disponible Bluetooth en este dispositivo.Cargando…Ocurrió un error mientras se conectaba al dispositivo. ¡No podemos intercambiar con él!Intercambio no activado
diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml
index 0191dec3a..9b2374d71 100644
--- a/app/src/main/res/values-et/strings.xml
+++ b/app/src/main/res/values-et/strings.xml
@@ -302,9 +302,6 @@
Ühenduse loomineKinnita vahetusSkannitud QR-kood ei paista olevat vahetamise kood.
- Bluetooth ei ole saadaval
- F-Droidi ei saa saata, sest Bluetooth ei ole selles seadmes saadaval.
- Laadimine…Vahetamine ei ole lubatudEnne vahetamist pead tegema seadme nähtavaks.
diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml
index a7f04da8b..a0eaf147f 100644
--- a/app/src/main/res/values-eu/strings.xml
+++ b/app/src/main/res/values-eu/strings.xml
@@ -293,10 +293,6 @@
sare berera konektatzerik zuetako batek Wi-Fi gune bat sor dezake.
Eskaneatu duzun QR kodea ez diruri truke kode bat.
- Bluetooth ez dago eskuragarri
- Ezin da F-Droid bidali, Bluetooth ez dagoelako erabilgarri gailu
- honetan.
- Errore bat gertatu da gailura konektatzean, ezin dugu honekin trukatu!Trukea ez dago gaitutaTrukatu aurretik, gailua ikusgai jarri behar duzu.
diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml
index aea17c272..95ccd1637 100644
--- a/app/src/main/res/values-fa/strings.xml
+++ b/app/src/main/res/values-fa/strings.xml
@@ -274,8 +274,6 @@
اگر دوستتان افدروید دارد و NFC اش روشن است، دستگاه هایتان را با هم تماس بدهید.برای تبادل با استفاده از وایفای، مطمئن شوید که روی شبکهٔ یکسانی هستید. اگر به شبکهٔ یکسان دسترسی ندارید، یکی از شما میتواند یک هاتسپات وایفای ایجاد کند.رمز QR ای که اسکن کردید، شبیه یک رمز تبادل نیست.
- بلوتوث موجود نیست
- نمیتوان افدروید را فرستاد، زیرا بلوتوث روی این دستگاه موجود نیست.در حال بارگزاری…هنگام اتّصال به دستگاه خطایی رخ داد، نمیتوان تبادل کرد!تبادل فعّال نیست
diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml
index 9e6270bdb..947a84f0e 100644
--- a/app/src/main/res/values-fi/strings.xml
+++ b/app/src/main/res/values-fi/strings.xml
@@ -313,10 +313,6 @@
YhdistetäänVahvista vaihtoSkannaamasi QR-koodi ei näytä vaihtamiseen tarkoitetulta koodilta.
- Bluetooth ei ole saatavilla
- Ei voida lähettää F-Droidia, koska Bluetooth ei ole saatavilla tällä
- laitteella.
- Tapahtui virhe yhdistettäessä laitteeseen, vaihtaminen ei onnistu.
Vaihtaminen ei ole käytössä
diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml
index 5c23e5e81..4e35cd8d0 100644
--- a/app/src/main/res/values-fr/strings.xml
+++ b/app/src/main/res/values-fr/strings.xml
@@ -260,10 +260,6 @@
ConnexionConfirmez l\'échangeLe code QR que vous avez scanné ne ressemble pas à un code d\'échange.
- Bluetooth indisponible
- Impossible d\'envoyer F-Droid : le Bluetooth n\'est pas disponible sur
- cet appareil.
- Votre appareil doit être visible avant de pouvoir commencer l\'échange.Toutes les heures
diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml
index bf8683294..00e516f02 100644
--- a/app/src/main/res/values-gl/strings.xml
+++ b/app/src/main/res/values-gl/strings.xml
@@ -191,7 +191,6 @@
Enviar F-DroidConectandoConfirma o intercambio
- O Bluetooth non está dispoñibleCargando…NovoTodo
@@ -290,9 +289,6 @@
O código QR que escaneaches non parece corresponder a un código de
intercambio.
- Non se pode enviar, porque o Bluetooth non está dispoñible neste
- dispositivo.
- Ocurriu un erro durante a conexión co dispositivo, non se pode realizar o intercambio!Intercambio non dispoñibleAntes do intercambio, o teu dispositivo debe estar visible.
diff --git a/app/src/main/res/values-he/strings.xml b/app/src/main/res/values-he/strings.xml
index 12443e8db..cdd93053e 100644
--- a/app/src/main/res/values-he/strings.xml
+++ b/app/src/main/res/values-he/strings.xml
@@ -227,7 +227,6 @@
לא גלוי דרך רשת אלחוטיתשם התקןמתבצע חיבור
- Bluetooth לא זמיןבטעינה…אף פעם
@@ -249,7 +248,6 @@
שליחת F-Droidאימות ההחלפהקוד ה־QR שסרקת לא נראה כמו קוד החלפה.
- אין אפשרות לשלוח את F-Droid כיוון שה־Bluetooth אינו זמין בהתקן זה.ההחלפה מנוטרלתבטרם ביצוע החלפה, על מכשירך להיות גלוי.
diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml
index 97db44093..897f473e3 100644
--- a/app/src/main/res/values-hi/strings.xml
+++ b/app/src/main/res/values-hi/strings.xml
@@ -96,9 +96,6 @@
लोड हो रहा है…यन्त्र को जोड़ने मैं एक समस्या आ गयी| यन्त्र से अदला-बदली नहीं हो सकती|
- ब्लूटूथ अनुपलब्ध
- फ-द्रोइड नहीं भेज सकते, क्योंकि ब्लूटूथ इस यन्त्र पे उपलब्ध नहीं है|
- जुड़ रहा हैअदला-बदली की पुष्टि करेQR कोड जो अपने स्कैन किया है वह अदला-बदली का code नहीं है|
diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml
index 7ab55381a..04eba82e3 100644
--- a/app/src/main/res/values-hr/strings.xml
+++ b/app/src/main/res/values-hr/strings.xml
@@ -315,9 +315,6 @@
SpajanjePotvrdi razmjenuČini se da QR kod koji ste skenirali nije kod za razmjenu.
- Bluetooth nedostupan
- Nije uspjelo slanje F-Droida, Bluetooth nije dostupan na ovom uređaju.
- Učitavanje…Došlo je do greške prilikom spajanja na uređaj, čini se da razmjena nije
moguća.
diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml
index 8868d0f5f..0df166b5b 100644
--- a/app/src/main/res/values-hu/strings.xml
+++ b/app/src/main/res/values-hu/strings.xml
@@ -269,10 +269,6 @@
Nem találja, amit keres?Az F-Droid küldéseKapcsolódás
- A Bluetooth nem érhető el
- Az F-Droid küldése sikertelen, mivel a Bluetooth nem érhető el ezen az
- eszközön.
- Várakozás a letöltés elkezdésére…Telepítés…Eltávolítás…
diff --git a/app/src/main/res/values-id/strings.xml b/app/src/main/res/values-id/strings.xml
index 592c3f8a5..ff62f40b9 100644
--- a/app/src/main/res/values-id/strings.xml
+++ b/app/src/main/res/values-id/strings.xml
@@ -294,10 +294,6 @@
MenyambungKonfirmasi swapKode QR yang kamu pindai tidak terlihat seperti kode swap.
- Bluetooth tidak tersedia
- Tidak dapat mengirim F-Droid, karena Bluetooth tidak tersedia diperangkat
- ini.
- Memuat…Galat terjadi ketika menyambungkan ke perangkat, tidak bisa melakukan pertukaran!Swap dinonaktifkan
diff --git a/app/src/main/res/values-is/strings.xml b/app/src/main/res/values-is/strings.xml
index a6aa69455..1824e3226 100644
--- a/app/src/main/res/values-is/strings.xml
+++ b/app/src/main/res/values-is/strings.xml
@@ -220,7 +220,6 @@
Gat ekki fundið neinn í nágrenninu til að býtta við.TengistStaðfesta býtti
- Bluetooth er ekki tiltæktHleð inn…Forritabýtti eru óvirkþarf aðgang að
@@ -369,8 +368,6 @@
Hjálpaðu vini þínum að tengjast tengipunktinum þínumEinn aðili þarf að skanna QR-kóðann, eða slá slóð hins inn í vafra.
- Get ekki sent F-Droid, því Bluetooth er ekki til taks á þessu tæki.
- Villa kom upp við að tengjast við tækið, ekki er hægt að nota það við býtti!Áður en farið er í að býtta þarf að gera tækið þitt sýnilegt.
diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml
index 134552013..5c87d6245 100644
--- a/app/src/main/res/values-it/strings.xml
+++ b/app/src/main/res/values-it/strings.xml
@@ -200,7 +200,6 @@
non saranno rimossi. L\'app dopo l\'aggiornamento avrà accesso a:
Caricamento…
- Bluetooth non disponibileConnessione in corsoNome del dispositivoNon riesci a trovare chi stai cercando?
@@ -320,9 +319,6 @@
browser.
Invia F-Droid
- Impossibile inviare F-Droid, perché il Bluetooth non è disponibile su
- questo dispositivo.
- È avvenuto un errore durante la connessione al dispositivo, non sembra possibile effettuare lo scambio!Scambio non abilitatoVuoi installare una versione aggiornata
diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml
index f4ef846be..c3f9a5250 100644
--- a/app/src/main/res/values-ja/strings.xml
+++ b/app/src/main/res/values-ja/strings.xml
@@ -210,8 +210,6 @@
接続中交換の確認読み取ったQRコードは交換コードではないようです。
- Bluetoothが利用できません
- この端末ではBluetoothが利用できないため、F-Droidを送信できません。読み込み中ダウンロード中
diff --git a/app/src/main/res/values-kab/strings.xml b/app/src/main/res/values-kab/strings.xml
index b43d55067..6af7e20b4 100644
--- a/app/src/main/res/values-kab/strings.xml
+++ b/app/src/main/res/values-kab/strings.xml
@@ -156,7 +156,6 @@
Fren AsnasIsem n yibenkSentem ambaddal
- Bluetooth yellaWarǧin1 n umalasYal tikelt
diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml
index 7a3147942..234cb224c 100644
--- a/app/src/main/res/values-ko/strings.xml
+++ b/app/src/main/res/values-ko/strings.xml
@@ -249,8 +249,6 @@
연결 중교환 확인스캔한 QR 코드는 교환 코드가 아닌 것으로 파악됩니다.
- 블루투스를 사용할 수 없음
- F-Droid를 보낼 수 없습니다. 이 장치에서 블루투스를 사용할 수 없기 때문입니다.불러오는 중…장치에 연결하는 동안 오류가 발생했습니다. 교환할 수 없습니다!교환이 활성화되어 있지 않음
diff --git a/app/src/main/res/values-ml/strings.xml b/app/src/main/res/values-ml/strings.xml
index 34825d4cb..3e2e4d5d9 100644
--- a/app/src/main/res/values-ml/strings.xml
+++ b/app/src/main/res/values-ml/strings.xml
@@ -328,8 +328,6 @@
ബന്ധിപ്പിക്കുന്നുകെെമാറ്റം സ്ഥിരീകരിക്കുകനിങ്ങൾ സ്കാന് ചെയ്ത QR കോഡ് ഒരു സ്വാപ്പ് കോഡ് പോലെ തോന്നുന്നില്ല.
- ബ്ലൂടൂത്ത് ലഭ്യമല്ല
- ബ്ലൂടൂത്ത് ഈ ഉപകരണത്തിൽ ലഭ്യമല്ലാത്തതിനാൽ എഫ്-ഡ്രോയ്ഡ് അയയ്ക്കാൻ കഴിയില്ല.ലോഡുചെയ്യുന്നു…ഉപകരണത്തിലേക്ക് കണക്റ്റുചെയ്യുമ്പോൾ പിശക് സംഭവിച്ചു, അതുമായി കെെമാറ്റം ചെയ്യാന് പറ്റുന്നില്ല!കെെമാറ്റം സജ്ജമല്ല
diff --git a/app/src/main/res/values-my/strings.xml b/app/src/main/res/values-my/strings.xml
index bd2ec72a3..470c24f08 100644
--- a/app/src/main/res/values-my/strings.xml
+++ b/app/src/main/res/values-my/strings.xml
@@ -215,7 +215,6 @@
သင္ရွာေနတာကိုမေတြ႕ဘူးလား?F-Droid ပို႔မည္ခ်ိတ္ဆက္ေနသည္
- ဘလူးသုဒ္မရရွိႏိုင္ပါဖြင့္ေနသည္အသစ္အားလံုး
diff --git a/app/src/main/res/values-nb/strings.xml b/app/src/main/res/values-nb/strings.xml
index 6d70969b3..93e5b6590 100644
--- a/app/src/main/res/values-nb/strings.xml
+++ b/app/src/main/res/values-nb/strings.xml
@@ -212,10 +212,6 @@
Finner du ikke den du leter etter?Oversend F-DroidKobler til
- Blåtann utilgjengelig
- Kan ikke sende F-Droid siden Blåtann ikke er tilgjengelig på denne
- enheten.
- Laster inn…tilgang tilNy
diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml
index 47d4633a5..7f9377f97 100644
--- a/app/src/main/res/values-nl/strings.xml
+++ b/app/src/main/res/values-nl/strings.xml
@@ -223,10 +223,6 @@
VerbindenBevestig uitwisselingDe QR-code die je gescand hebt lijkt geen uitwisselcode te zijn.
- Bluetooth niet beschikbaar
- Kon F-Droid niet verzenden omdat Bluetooth niet beschikbaar is op dit
- apparaat.
- Laden…Fout bij verbinden met apparaat, we kunnen er niet mee uit te wisselen!Uitwisselen niet ingeschakeld
diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml
index 2d2f52aaf..d376c6862 100644
--- a/app/src/main/res/values-pl/strings.xml
+++ b/app/src/main/res/values-pl/strings.xml
@@ -234,10 +234,6 @@
ŁączeniePotwierdź wymianęKod QR który został zeskanowany nie wygląda na kod do wymiany aplikacji.
- Bluetooth nie jest dostępny
- Nie udało się wysłać F-Droida ponieważ Bluetooth nie jest dostępny na
- Twoim urządzeniu.
- Ładowanie…Wystąpił błąd podczas łączenia się z urządzeniem wymiana nie powiodła się!Wymiana nie jest włączona
diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml
index e1c77fc70..883d4774b 100644
--- a/app/src/main/res/values-pt-rBR/strings.xml
+++ b/app/src/main/res/values-pt-rBR/strings.xml
@@ -250,10 +250,6 @@
ConectandoConfirmar a permutaO código QR que você escaneou não parece com um código de permuta.
- Bluetooth não está disponível
- Não é possível enviar F-Droid, porque o Bluetooth não está disponível
- neste dispositivo.
- Carregando…Ocorreu um erro ao conectar o dispositivo, não foi possível trocar com ele!Permuta não habilitada
diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml
index 3ac4e5143..2b400aaec 100644
--- a/app/src/main/res/values-pt-rPT/strings.xml
+++ b/app/src/main/res/values-pt-rPT/strings.xml
@@ -301,10 +301,6 @@
Não foram encontradas pessoas na sua vizinhança.Confirmação de trocaO código QR digitalizado não parece ser um código de troca.
- Bluetooth não disponível
- Não pode enviar o F-Droid porque o Bluetooth não está ativo no
- dispositivo.
- Ocorreu um erro ao estabelecer a ligação e não será possível a troca!Troca não ativaAntes de trocar, o seu dispositivo tem que estar disponível.
diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml
index 95f9b5fa2..f028ffb29 100644
--- a/app/src/main/res/values-ro/strings.xml
+++ b/app/src/main/res/values-ro/strings.xml
@@ -259,7 +259,6 @@
Folosește TorDepozitOprire Wi-Fi…
- Bluetooth indisponibilDepozit: %sDescarcă automat actualizările
@@ -451,7 +450,6 @@
Atinge pentru a vedea rețelele deschise disponibileO persoană trebuie să scaneze codul sau să introducă URL-ul celuilalt într-un browser.Codul QR scanat nu arată ca un cod de schimb.
- Nu s-a putut trimite F-Droid, deoarece conexiunea Bluetooth nu este valabilă pe acest dispozitiv.Eroare produsă în timpul conectării la dispozitiv, nu se poate face schimbul!Înaintea schimbului, dispozitivul tău trebuie făcut vizibil.
diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml
index 0b63c8bac..3523cdd8b 100644
--- a/app/src/main/res/values-ru/strings.xml
+++ b/app/src/main/res/values-ru/strings.xml
@@ -308,8 +308,6 @@
Не удается найти людей рядом, чтобы обменяться с ними.Подтвердить обменQR-код, который вы отсканировали, не похож на код обмена.
- Bluetooth не доступен
- Не удается отправить F-Droid, так как Bluetooth не доступен на данном устройстве.При подключении к устройству произошла ошибка, невозможно провести с ним обмен!Обмен не включенДля выполнения обмена следует сделать ваше устройство видимым.
diff --git a/app/src/main/res/values-sc/strings.xml b/app/src/main/res/values-sc/strings.xml
index 4362f1ef5..408213ca3 100644
--- a/app/src/main/res/values-sc/strings.xml
+++ b/app/src/main/res/values-sc/strings.xml
@@ -252,10 +252,6 @@
ConnetendeCunfirma cumpartziduraSu còdighe QR iscansidu non paret unu còdighe de cumpartzidura.
- Bluetooth non disponìbile
- Impossìbile imbiare F-Droid, ca su Bluetooth no est disponìbile in custu
- dispositivu.
- Carrighende…Cumpartzidura non abilitadaIn antis de cumpartzire, su dispositivu depet èssere postu visìbile.
diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml
index f29a8cec2..42f2afa69 100644
--- a/app/src/main/res/values-sk/strings.xml
+++ b/app/src/main/res/values-sk/strings.xml
@@ -232,7 +232,6 @@
Nemôžete nájsť koho hľadáte?Poslať F-DroidPripájam
- Bluetooth nedostupnýNačítavam…vyžaduje prístup kVšetky
@@ -257,9 +256,6 @@
TémyNie je viditeľný cez BluetoothNie je viditeľný cez Wi-Fi
- Nemožno poslať F-Droid, pretože Bluetooh nie je dostupný na tomto
- zariadení.
- Môže stáť peniazeFlattr
diff --git a/app/src/main/res/values-sn/strings.xml b/app/src/main/res/values-sn/strings.xml
index cd5338238..1fb85db94 100644
--- a/app/src/main/res/values-sn/strings.xml
+++ b/app/src/main/res/values-sn/strings.xml
@@ -344,10 +344,6 @@
KuhakiraTsinhira kutsinhanaMurau weQR wawanzvera hausi kuita kunge murau wekutsinhana.
- Bluetooth haipo
- Hatisi kukwanisa kutumira F-Droid, nekuti Bluetooth haipo pamuchina
- uyu.
- Kuzadza…Pane kanganiso yaitika pakuhakira kumuchina, hatisi kukwanisa kutsinhana
nayo.
diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml
index b892d549d..97dca789f 100644
--- a/app/src/main/res/values-sr/strings.xml
+++ b/app/src/main/res/values-sr/strings.xml
@@ -206,7 +206,6 @@
Пошаљи Ф-дроидПовезујем сеПотврди размену
- Блутут није доступанУчитавам…Размена није укљученаНово
@@ -238,8 +237,6 @@
Пре размене, ваш уређај мора бити видљив.
- Не могу да пошаљем Ф-дроида, блутут није доступан на овом уређају.
- Видљив преко блутутаНисам видљив преко блутутаВидљив преко бежичног
diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml
index ddee8cd5f..dad729a02 100644
--- a/app/src/main/res/values-sv/strings.xml
+++ b/app/src/main/res/values-sv/strings.xml
@@ -266,8 +266,6 @@
AnsluterBekräfta utbyteQR-koden du läst av ser inte ut som en utbytarkod.
- Bluetooth inte tillgänglig
- Det går inte att skicka F-Droid eftersom Bluetooth är otillgänglig på den här enheten.Öppnar…Fel uppstod under enhetsanslutning, går inte att utföra utbyte med den!Utbyta inte aktiverat
diff --git a/app/src/main/res/values-th/strings.xml b/app/src/main/res/values-th/strings.xml
index afbbd28ba..166a185ba 100644
--- a/app/src/main/res/values-th/strings.xml
+++ b/app/src/main/res/values-th/strings.xml
@@ -176,8 +176,6 @@
ส่งต่อโปรแกรม F-Droidกำลังเชื่อมต่อยืนยันการส่งต่อ
- ไม่สามารถใช้บลูทูธได้
- ไม่สามารถส่งต่อโปรแกรม F-Droid ได้ เนื่องจากไม่สามารถใช้บลูทูธกำลังโหลด…การเชื่อมต่อกับอีกเครื่องล้มเหลว, ไม่สามารถส่งต่อโปรแกรมได้ไม่เปิดใช้การส่งต่อโปรแกรม
diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml
index ca89293ef..7e316232c 100644
--- a/app/src/main/res/values-tr/strings.xml
+++ b/app/src/main/res/values-tr/strings.xml
@@ -261,8 +261,6 @@
BağlanıyorTakası onaylayınTaradığınız QR kodu bir takas kodu gibi görünmüyor.
- Bluetooth kullanılabilir değil
- F-Droid gönderilemiyor, çünkü bu aygıtta Bluetooth kullanılabilir değil.Yükleniyor…Aygıta bağlanılırken hata oluştu, onunla takas yapılamaz!Takas etkinleştirilmemiş
diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml
index f6167b45a..56a199e10 100644
--- a/app/src/main/res/values-uk/strings.xml
+++ b/app/src/main/res/values-uk/strings.xml
@@ -161,10 +161,6 @@
Назва пристроюВідправити F-DroidПідключення
- Bluetooth не доступний
- Неможливо надіслати F-Droid, тому що Bluetooth не доступний на цьому
- пристрої.
- Завантаження…НовіВсі
diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml
index bcf6434b5..3b03b47c5 100644
--- a/app/src/main/res/values-vi/strings.xml
+++ b/app/src/main/res/values-vi/strings.xml
@@ -242,8 +242,6 @@
Đang kết nốiXác nhận trao đổiMã QR đã quét không phải là mã trao đổi.
- Không có Bluetooth
- Không thể gửi F-Droid vì thiết bị này không có Bluetooth.Đang tải…Trao đổi đang tắtĐã xảy ra lỗi khi kết nối, không thể trao đổi ứng dụng!
diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml
index b59feeaa3..d40ed23f0 100644
--- a/app/src/main/res/values-zh-rCN/strings.xml
+++ b/app/src/main/res/values-zh-rCN/strings.xml
@@ -246,8 +246,6 @@
连接中确认交换你扫描的二维码似乎不是一个交换代码。
- 蓝牙不可用
- 不能发送 F-Droid,因为该设备蓝牙不可用。加载中…连接设备时出错,无法交换应用!未启用交换功能
diff --git a/app/src/main/res/values-zh-rHK/strings.xml b/app/src/main/res/values-zh-rHK/strings.xml
index e24662495..bfbbd4b64 100644
--- a/app/src/main/res/values-zh-rHK/strings.xml
+++ b/app/src/main/res/values-zh-rHK/strings.xml
@@ -209,8 +209,6 @@
沒有啟用交換功能與裝置連接時發生了問題,未能進行交換!正在載入…
- 因為此裝置沒有藍牙功能,未能傳送 F-Droid。
- 藍牙不可用您所掃描的 QR 碼不是一個交換碼。確定交換找不到附近的人進行交換。
diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml
index dfc9e0d7d..a02a3c7c7 100644
--- a/app/src/main/res/values-zh-rTW/strings.xml
+++ b/app/src/main/res/values-zh-rTW/strings.xml
@@ -220,8 +220,6 @@
傳送 F-Droid找不到附近的人來進行交換。確認交換
- 藍牙不可用
- 無法傳送 F-Droid,因為此裝置沒有藍牙功能。沒有啟用交換功能您想要解除安裝此應用程式嗎?下載失敗!
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index a38fd786a..67f5475b9 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -453,13 +453,14 @@ This often occurs with apps installed via Google Play or other sources, if they
ConnectingConfirm swapThe QR code you scanned doesn\'t look like a swap code.
- Bluetooth unavailable
- Cannot send F-Droid, because Bluetooth is unavailable on this device.
-
+ Use BluetoothLoading…Error occurred while connecting to device, can\'t swap with it!Swapping not enabledBefore swapping, your device must be made visible.
+ Invalid URL for swapping: %1$s
+ Wi-Fi Hotspot enabled
+ Could not enable Wi-Fi Hotspot!needs access toDo you want to install an update
diff --git a/app/src/test/java/org/fdroid/fdroid/net/HttpDownloaderTest.java b/app/src/test/java/org/fdroid/fdroid/net/HttpDownloaderTest.java
new file mode 100644
index 000000000..d5aee05c8
--- /dev/null
+++ b/app/src/test/java/org/fdroid/fdroid/net/HttpDownloaderTest.java
@@ -0,0 +1,36 @@
+package org.fdroid.fdroid.net;
+
+import android.net.Uri;
+import org.apache.commons.net.util.SubnetUtils;
+import org.fdroid.fdroid.BuildConfig;
+import org.fdroid.fdroid.FDroidApp;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RobolectricTestRunner;
+import org.robolectric.annotation.Config;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertFalse;
+
+@Config(constants = BuildConfig.class, sdk = 24)
+@RunWith(RobolectricTestRunner.class)
+@SuppressWarnings("LineLength")
+public class HttpDownloaderTest {
+
+ @Test
+ public void testIsSwapUri() throws MalformedURLException {
+ FDroidApp.subnetInfo = new SubnetUtils("192.168.0.112/24").getInfo();
+ String urlString = "http://192.168.0.112:8888/fdroid/repo?fingerprint=113F56CBFA967BA825DD13685A06E35730E0061C6BB046DF88A";
+ assertTrue(HttpDownloader.isSwapUrl("192.168.0.112", 8888)); // NOPMD
+ assertTrue(HttpDownloader.isSwapUrl(Uri.parse(urlString)));
+ assertTrue(HttpDownloader.isSwapUrl(new URL(urlString)));
+
+ assertFalse(HttpDownloader.isSwapUrl("192.168.1.112", 8888)); // NOPMD
+ assertFalse(HttpDownloader.isSwapUrl("192.168.0.112", 80)); // NOPMD
+ assertFalse(HttpDownloader.isSwapUrl(Uri.parse("https://malware.com:8888")));
+ assertFalse(HttpDownloader.isSwapUrl(new URL("https://www.google.com")));
+ }
+}