Merge branch 'first-swap-overhaul' into 'master'
First swap overhaul Closes #656, #612, and #586 See merge request fdroid/fdroidclient!671
This commit is contained in:
commit
714a44ad5d
@ -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
|
||||
|
3
app/proguard-rules.pro
vendored
3
app/proguard-rules.pro
vendored
@ -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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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<String> appsToSwap = new HashSet<>();
|
||||
@ -80,6 +81,10 @@ public class SwapService extends Service {
|
||||
*/
|
||||
private static final ConcurrentHashMap<String, App> 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<Void, Void, Void>() {
|
||||
@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<NameValuePair> 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();
|
||||
public static boolean getBluetoothVisibleUserPreference() {
|
||||
return swapPreferences.getBoolean(SwapService.KEY_BLUETOOTH_ENABLED, false);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
private boolean wasBluetoothEnabled() {
|
||||
return persistence().getBoolean(KEY_BLUETOOTH_ENABLED, false);
|
||||
public static void putBluetoothVisibleUserPreference(boolean visible) {
|
||||
swapPreferences.edit().putBoolean(SwapService.KEY_BLUETOOTH_ENABLED, visible).apply();
|
||||
}
|
||||
*/
|
||||
|
||||
private boolean wasWifiEnabled() {
|
||||
return persistence().getBoolean(KEY_WIFI_ENABLED, false);
|
||||
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();
|
||||
|
@ -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() {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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("-", ":");
|
||||
|
@ -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 {
|
||||
|
@ -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) {
|
||||
|
@ -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();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
@ -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();
|
||||
}
|
||||
};
|
||||
|
@ -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();
|
||||
}
|
||||
@ -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) {
|
||||
if (adapter == null
|
||||
|| Build.VERSION.SDK_INT >= 23 // TODO make Bluetooth work with content:// URIs
|
||||
|| (!adapter.isEnabled() && getService().getWifiSwap().isConnected())) {
|
||||
showSendFDroid();
|
||||
} else {
|
||||
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);
|
||||
} else {
|
||||
sendFDroidApk();
|
||||
}
|
||||
} 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();
|
||||
}
|
||||
}
|
||||
|
||||
@ -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.
|
||||
*
|
||||
* <ul>
|
||||
* <li>Assume we have bluetooth available (otherwise the button which allowed us to start
|
||||
* the bluetooth process should not have been available)</li>
|
||||
* <li>Ask user to enable (if not enabled yet)</li>
|
||||
* <li>Start bluetooth server socket</li>
|
||||
* <li>Enable bluetooth discoverability, so that people can connect to our server socket.</li>
|
||||
* </ul>
|
||||
* 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})));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<NameValuePair> parameters = URLEncodedUtils.parse(URI.create(sharingUri.toString()), "UTF-8");
|
||||
for (NameValuePair parameter : parameters) {
|
||||
if (!"ssid".equals(parameter.getName())) {
|
||||
if (Build.VERSION.SDK_INT > 10) {
|
||||
Set<String> names = sharingUri.getQueryParameterNames();
|
||||
for (String name : names) {
|
||||
if (!"ssid".equals(name)) {
|
||||
if (first) {
|
||||
qrUriString += "?";
|
||||
qrUrlBuilder.append('?');
|
||||
first = false;
|
||||
} else {
|
||||
qrUriString += "&";
|
||||
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);
|
||||
|
||||
}
|
||||
|
@ -58,7 +58,7 @@
|
||||
<android.support.v7.widget.SwitchCompat
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
tools:checked="true"
|
||||
android:enabled="false"
|
||||
android:id="@+id/switch_bluetooth" />
|
||||
|
||||
</LinearLayout>
|
||||
@ -114,7 +114,7 @@
|
||||
<android.support.v7.widget.SwitchCompat
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
tools:checked="false"
|
||||
android:enabled="false"
|
||||
android:id="@+id/switch_wifi" />
|
||||
|
||||
</LinearLayout>
|
||||
|
50
app/src/main/res/layout/swap_send_fdroid.xml
Normal file
50
app/src/main/res/layout/swap_send_fdroid.xml
Normal file
@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<org.fdroid.fdroid.views.swap.SendFDroidView
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:background="@color/swap_blue"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_width="wrap_content">
|
||||
|
||||
<LinearLayout android:orientation="vertical"
|
||||
android:gravity="center"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="250dp"
|
||||
android:layout_height="250dp"
|
||||
android:maxHeight="20dp"
|
||||
android:id="@+id/wifi_qr_code"
|
||||
tools:src="@drawable/swap_qr_example"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/swap_scan_or_type_url"
|
||||
style="@style/SwapTheme.Wizard.MainText"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/device_ip_address"
|
||||
tools:text="http://255.255.255.255:8888"
|
||||
style="@style/SwapTheme.Wizard.LocalIpAddress"/>
|
||||
|
||||
<Button style="@style/SwapTheme.Wizard.OptionButton"
|
||||
android:text="@string/use_bluetooth"
|
||||
android:layout_gravity="center"
|
||||
android:id="@+id/btn_use_bluetooth"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/warning_qr_scanner"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/warning_scaning_qr_code"
|
||||
android:visibility="gone"
|
||||
style="@style/SwapTheme.Wizard.QRScanWarningText"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</org.fdroid.fdroid.views.swap.SendFDroidView>
|
@ -333,10 +333,6 @@
|
||||
<string name="swap_intro">Verbind en deel programme met mense naby jou.</string>
|
||||
<string name="swap_confirm">Bevestig uitruil</string>
|
||||
<string name="swap_qr_isnt_for_swap">Die QR kode jy geskandeer het lyk nie soos \'n uitruil kode nie.</string>
|
||||
<string name="bluetooth_unavailable">Bluetooth nie beskikbaar nie</string>
|
||||
<string name="swap_cant_send_no_bluetooth">"Kan nie F-Droid stuur nie, omdat Bluetooth is nie beskikbaar is op
|
||||
hierdie toestel nie."
|
||||
</string>
|
||||
<string name="loading">Laai tans…</string>
|
||||
<string name="swap_connection_misc_error">\'n Fout het plaasgevind tydens koppeling met die toestel, dit lyk nie asof ons kan uitruil nie!</string>
|
||||
<string name="swap_not_enabled">Uitruil nie geaktiveer nie</string>
|
||||
|
@ -287,8 +287,6 @@
|
||||
<string name="swap_connecting">جاري الاتصال</string>
|
||||
<string name="swap_confirm">تأكيد المبادلة</string>
|
||||
<string name="swap_qr_isnt_for_swap">رمز الاستجابة السريعة الذي تم التقاطه لا يبدو وكأنه رمز المبادلة.</string>
|
||||
<string name="bluetooth_unavailable">البلوتوث غير متاح</string>
|
||||
<string name="swap_cant_send_no_bluetooth">لا يمكن إرسال اف-درويد، بسبب أن البلوتوث غير متاح على هذا الجهاز.</string>
|
||||
<string name="loading">يتم التحميل…</string>
|
||||
<string name="swap_connection_misc_error">حدث خطأ أثناء الاتصال بالجهاز، ولا يمكن أن يجري المبادلة معه!</string>
|
||||
<string name="swap_not_enabled">المبادلة غير فعالة</string>
|
||||
|
@ -176,15 +176,11 @@
|
||||
<string name="uninstall_update_confirm">¿Quies trocar esta aplicación pola versión de fábrica?</string>
|
||||
<string name="perm_costs_money">Quiciabes esto te cueste perres</string>
|
||||
<string name="loading">Cargando…</string>
|
||||
<string name="swap_cant_send_no_bluetooth">Nun pue unviase F-droid porque\'l Bluetooth nun ta disponible nesti
|
||||
preséu.
|
||||
</string>
|
||||
<string name="swap_connecting">Coneutando</string>
|
||||
<string name="swap_cant_find_peers">¿Nun pues alcontrar a quien tas guetando?</string>
|
||||
<string name="swap_send_fdroid">Unviar F-droid</string>
|
||||
<string name="swap_qr_isnt_for_swap">El códigu QR qu\'escaniesti nun paez ser un códigu d\'intercambéu.</string>
|
||||
<string name="swap_connection_misc_error">Asocedió un fallu entrín se coneutaba col preséu, ¡nun podemos facer l\'intercambiu con elli!</string>
|
||||
<string name="bluetooth_unavailable">Bluetooth non disponible</string>
|
||||
<string name="swap_confirm">Confirmar intercambéu</string>
|
||||
<string name="swap_wifi_device_name">Nome del preséu</string>
|
||||
<string name="swap_visible_bluetooth">Visible pente Bluetooth</string>
|
||||
|
@ -324,10 +324,6 @@
|
||||
<string name="swap_connecting">Злучэнне</string>
|
||||
<string name="swap_confirm">Пацвердзіць абмен</string>
|
||||
<string name="swap_qr_isnt_for_swap">QR-код, які вы адсканавалі, не выглядае як код абмену.</string>
|
||||
<string name="bluetooth_unavailable">Bluetooth не даступны</string>
|
||||
<string name="swap_cant_send_no_bluetooth">Немагчыма адправіць F-Droid, бо Bluetooth не даступны на гэтай
|
||||
прыладзе.
|
||||
</string>
|
||||
<string name="loading">Загрузка…</string>
|
||||
<string name="swap_connection_misc_error">Здарылася памылка падчас злучэння з прыладай. Немагчыма прадоўжыць абмен!</string>
|
||||
<string name="swap_not_enabled">Абмен не ўключаны</string>
|
||||
|
@ -220,10 +220,6 @@
|
||||
</string>
|
||||
|
||||
<string name="swap_not_enabled">Забранена размяна</string>
|
||||
<string name="swap_cant_send_no_bluetooth">Изпращането на F-Droid не е възможно защото липсва Bluetooth
|
||||
функционалност.
|
||||
</string>
|
||||
<string name="bluetooth_unavailable">Липсва Bluetooth</string>
|
||||
<string name="swap_nearby">Размяна с устройства наоколо</string>
|
||||
<string name="local_repo_running">F-Droid e в готовност за размяна</string>
|
||||
<string name="touch_to_configure_local_repo">Натиснете за детайли или да позволите размяна на приложение.</string>
|
||||
|
@ -314,8 +314,6 @@
|
||||
<string name="swap_connecting">མཐུད་བཞིན་པ།</string>
|
||||
<string name="swap_confirm">བརྗེ་ལེན་གཏན་འཁེལ།</string>
|
||||
<string name="swap_qr_isnt_for_swap">ཁྱེད་རང་གིས་འཚག་རྒྱག་པའི་QR ཨང་རྟགས་འདི་བརྗེ་ལེན་ཨང་རྟགས་དང་འདྲ་མཚུངས་མིན་འདུག</string>
|
||||
<string name="bluetooth_unavailable">བྷུ་ལུ་ཊོཐ་མིན་འདུག</string>
|
||||
<string name="swap_cant_send_no_bluetooth">ཨེཕ་རོཌ་གཏོང་ཐུབ་ཀྱི་མིན་འདུག གང་ཡིན་ཟེར་ན་ཡོ་བྱད་འདིའི་སྒང་ལ་བྷུ་ལུ་ཊོཐ་མིན་འདུག</string>
|
||||
<string name="loading">བཅུག་བཞིན་པ།..…</string>
|
||||
<string name="swap_connection_misc_error">ཡོ་བྱད་ལ་མཐུད་པའི་སྐབས་སུ་སྐྱོན་ཤོར་སོང་བས་དེ་དང་མཉམ་དུ་བརྗེ་ལེན་བྱེད་ཐུབ་ཀྱི་མིན་འདུག!</string>
|
||||
<string name="swap_not_enabled">བརྗེ་ལེན་སྒོ་ཕྱེས་མིན་འདུག</string>
|
||||
|
@ -273,8 +273,6 @@
|
||||
<string name="swap_connecting">Connectant</string>
|
||||
<string name="swap_confirm">Confirmeu l\'intercanvi</string>
|
||||
<string name="swap_qr_isnt_for_swap">El codi QR que heu escanejat no sembla un codi d\'intercanvi.</string>
|
||||
<string name="bluetooth_unavailable">El Bluetooth no està disponible</string>
|
||||
<string name="swap_cant_send_no_bluetooth">No s\'ha pogut enviar l\'F-Droid perquè el Bluetooth no està disponible en aquest dispositiu.</string>
|
||||
<string name="loading">S\'està carregant…</string>
|
||||
<string name="swap_connection_misc_error">S\'ha produït un error en connectar-se al dispositiu. No us podeu connectar!</string>
|
||||
<string name="swap_not_enabled">Intercanvi no activat</string>
|
||||
|
@ -242,10 +242,6 @@
|
||||
<string name="swap_connecting">Připojování</string>
|
||||
<string name="swap_confirm">Potvrdit výměnu</string>
|
||||
<string name="swap_qr_isnt_for_swap">Naskenovaný QR kód nevypadá jako výměnný kód.</string>
|
||||
<string name="bluetooth_unavailable">Bluetooth nedostupné</string>
|
||||
<string name="swap_cant_send_no_bluetooth">F-Droid nelze odeslat, protože na tomto přístroji není Bluetooth
|
||||
dostupné.
|
||||
</string>
|
||||
<string name="loading">Načítání…</string>
|
||||
<string name="swap_not_enabled">Výměna není povolena</string>
|
||||
<string name="swap_not_enabled_description">Před výměnou je třeba zviditelnit přístroj.</string>
|
||||
|
@ -279,9 +279,6 @@
|
||||
<string name="swap_connecting">Forbinder</string>
|
||||
<string name="swap_confirm">Bekræft udveksling</string>
|
||||
<string name="swap_qr_isnt_for_swap">Den QR-kode du skannede ligner ikke en udvekslingskode.</string>
|
||||
<string name="bluetooth_unavailable">Bluetooth utilgængelig</string>
|
||||
<string name="swap_cant_send_no_bluetooth">Kan ikke sende F-Droid fordi Bluetooth er utilgængeligt på denne enhed.
|
||||
</string>
|
||||
<string name="loading">Indlæser…</string>
|
||||
<string name="swap_connection_misc_error">Der opstod en fejl under forbindelsen til enheden, kan udveksle med den!</string>
|
||||
<string name="swap_not_enabled">Udveksling ikke aktiveret</string>
|
||||
|
@ -192,7 +192,6 @@
|
||||
|
||||
<string name="system_uninstall_button">Deinstallieren</string>
|
||||
|
||||
<string name="bluetooth_unavailable">Bluetooth nicht verfügbar</string>
|
||||
<string name="newPerms">Neu</string>
|
||||
<string name="perms_new_perm_prefix">Neu:</string>
|
||||
<string name="interval_1h">Stündlich</string>
|
||||
@ -276,9 +275,6 @@
|
||||
Sie keinen gemeinsamen Netzwerkzugang haben, kann einer von Ihnen einen WLAN-Hotspot einrichten.
|
||||
</string>
|
||||
<string name="swap_nearby">Tausch in der Nähe</string>
|
||||
<string name="swap_cant_send_no_bluetooth">F-Droid kann nicht gesendet werden, da Bluetooth auf diesem Gerät nicht
|
||||
verfügbar ist.
|
||||
</string>
|
||||
<string name="loading">Ladevorgang …</string>
|
||||
<string name="swap_connection_misc_error">Fehler bei der Verbindungsaufnahme zum Zielgerät. Tausch ist nicht möglich!</string>
|
||||
<string name="swap_not_enabled">Tauschen ist nicht aktiviert</string>
|
||||
|
@ -267,10 +267,6 @@
|
||||
<string name="swap_connecting">Σύνδεση</string>
|
||||
<string name="swap_confirm">Επιβεβαίωση ανταλλαγής</string>
|
||||
<string name="swap_qr_isnt_for_swap">Ο κώδικας QR που σαρώσατε δεν μοιάζει με έναν κωδικό ανταλλαγής.</string>
|
||||
<string name="bluetooth_unavailable">Το Bluetooth δεν είναι διαθέσιμο</string>
|
||||
<string name="swap_cant_send_no_bluetooth">Δεν μπορείτε να στείλετε το F-Droid επειδή το Bluetooth δεν είναι
|
||||
διαθέσιμο σε αυτήν τη συσκευή.
|
||||
</string>
|
||||
<string name="loading">Φόρτωση…</string>
|
||||
<string name="swap_connection_misc_error">Παρουσιάστηκε σφάλμα κατά τη σύνδεση με την συσκευή, φαίνεται ότι δεν μπορούμε να ανταλλάξουμε με αυτή!</string>
|
||||
<string name="swap_not_enabled">Η ανταλλαγή δεν είναι ενεργοποιημένη</string>
|
||||
|
@ -272,10 +272,6 @@
|
||||
<string name="swap_connecting">Konektado</string>
|
||||
<string name="swap_confirm">Konfirmi interŝanĝon</string>
|
||||
<string name="swap_qr_isnt_for_swap">La skanita QR-kodo ne estas interŝanĝa kodo.</string>
|
||||
<string name="bluetooth_unavailable">Bludento ne disponebla</string>
|
||||
<string name="swap_cant_send_no_bluetooth">Ne povas sendi F-Droid, ĉar Bludento ne estas disponebla en via
|
||||
aparato.
|
||||
</string>
|
||||
<string name="loading">Prilaborado…</string>
|
||||
<string name="swap_connection_misc_error">Eraro okazis dum konektado al aparato, ne povas interŝanĝi kun ĝi!</string>
|
||||
<string name="swap_not_enabled">Interŝanĝo malaktiva</string>
|
||||
|
@ -236,8 +236,6 @@
|
||||
<string name="swap_connecting">Conectando</string>
|
||||
<string name="swap_confirm">Confirmar intercambio</string>
|
||||
<string name="swap_qr_isnt_for_swap">El código QR escaneado no parece un código de intercambio.</string>
|
||||
<string name="bluetooth_unavailable">Bluetooth no disponible</string>
|
||||
<string name="swap_cant_send_no_bluetooth">No se puede enviar F-Droid porque no está disponible Bluetooth en este dispositivo.</string>
|
||||
<string name="loading">Cargando…</string>
|
||||
<string name="swap_connection_misc_error">Ocurrió un error mientras se conectaba al dispositivo. ¡No podemos intercambiar con él!</string>
|
||||
<string name="swap_not_enabled">Intercambio no activado</string>
|
||||
|
@ -302,9 +302,6 @@
|
||||
<string name="swap_connecting">Ühenduse loomine</string>
|
||||
<string name="swap_confirm">Kinnita vahetus</string>
|
||||
<string name="swap_qr_isnt_for_swap">Skannitud QR-kood ei paista olevat vahetamise kood.</string>
|
||||
<string name="bluetooth_unavailable">Bluetooth ei ole saadaval</string>
|
||||
<string name="swap_cant_send_no_bluetooth">F-Droidi ei saa saata, sest Bluetooth ei ole selles seadmes saadaval.
|
||||
</string>
|
||||
<string name="loading">Laadimine…</string>
|
||||
<string name="swap_not_enabled">Vahetamine ei ole lubatud</string>
|
||||
<string name="swap_not_enabled_description">Enne vahetamist pead tegema seadme nähtavaks.</string>
|
||||
|
@ -293,10 +293,6 @@
|
||||
sare berera konektatzerik zuetako batek Wi-Fi gune bat sor dezake.
|
||||
</string>
|
||||
<string name="swap_qr_isnt_for_swap">Eskaneatu duzun QR kodea ez diruri truke kode bat.</string>
|
||||
<string name="bluetooth_unavailable">Bluetooth ez dago eskuragarri</string>
|
||||
<string name="swap_cant_send_no_bluetooth">Ezin da F-Droid bidali, Bluetooth ez dagoelako erabilgarri gailu
|
||||
honetan.
|
||||
</string>
|
||||
<string name="swap_connection_misc_error">Errore bat gertatu da gailura konektatzean, ezin dugu honekin trukatu!</string>
|
||||
<string name="swap_not_enabled">Trukea ez dago gaituta</string>
|
||||
<string name="swap_not_enabled_description">Trukatu aurretik, gailua ikusgai jarri behar duzu.</string>
|
||||
|
@ -274,8 +274,6 @@
|
||||
<string name="swap_nfc_description">اگر دوستتان افدروید دارد و NFC اش روشن است، دستگاه هایتان را با هم تماس بدهید.</string>
|
||||
<string name="swap_join_same_wifi_desc">برای تبادل با استفاده از وایفای، مطمئن شوید که روی شبکهٔ یکسانی هستید. اگر به شبکهٔ یکسان دسترسی ندارید، یکی از شما میتواند یک هاتسپات وایفای ایجاد کند.</string>
|
||||
<string name="swap_qr_isnt_for_swap">رمز QR ای که اسکن کردید، شبیه یک رمز تبادل نیست.</string>
|
||||
<string name="bluetooth_unavailable">بلوتوث موجود نیست</string>
|
||||
<string name="swap_cant_send_no_bluetooth">نمیتوان افدروید را فرستاد، زیرا بلوتوث روی این دستگاه موجود نیست.</string>
|
||||
<string name="loading">در حال بارگزاری…</string>
|
||||
<string name="swap_connection_misc_error">هنگام اتّصال به دستگاه خطایی رخ داد، نمیتوان تبادل کرد!</string>
|
||||
<string name="swap_not_enabled">تبادل فعّال نیست</string>
|
||||
|
@ -313,10 +313,6 @@
|
||||
<string name="swap_connecting">Yhdistetään</string>
|
||||
<string name="swap_confirm">Vahvista vaihto</string>
|
||||
<string name="swap_qr_isnt_for_swap">Skannaamasi QR-koodi ei näytä vaihtamiseen tarkoitetulta koodilta.</string>
|
||||
<string name="bluetooth_unavailable">Bluetooth ei ole saatavilla</string>
|
||||
<string name="swap_cant_send_no_bluetooth">Ei voida lähettää F-Droidia, koska Bluetooth ei ole saatavilla tällä
|
||||
laitteella.
|
||||
</string>
|
||||
<string name="swap_connection_misc_error">Tapahtui virhe yhdistettäessä laitteeseen, vaihtaminen ei onnistu.
|
||||
</string>
|
||||
<string name="swap_not_enabled">Vaihtaminen ei ole käytössä</string>
|
||||
|
@ -260,10 +260,6 @@
|
||||
<string name="swap_connecting">Connexion</string>
|
||||
<string name="swap_confirm">Confirmez l\'échange</string>
|
||||
<string name="swap_qr_isnt_for_swap">Le code QR que vous avez scanné ne ressemble pas à un code d\'échange.</string>
|
||||
<string name="bluetooth_unavailable">Bluetooth indisponible</string>
|
||||
<string name="swap_cant_send_no_bluetooth">Impossible d\'envoyer F-Droid : le Bluetooth n\'est pas disponible sur
|
||||
cet appareil.
|
||||
</string>
|
||||
<string name="swap_not_enabled_description">Votre appareil doit être visible avant de pouvoir commencer l\'échange.</string>
|
||||
|
||||
<string name="interval_1h">Toutes les heures</string>
|
||||
|
@ -191,7 +191,6 @@
|
||||
<string name="swap_send_fdroid">Enviar F-Droid</string>
|
||||
<string name="swap_connecting">Conectando</string>
|
||||
<string name="swap_confirm">Confirma o intercambio</string>
|
||||
<string name="bluetooth_unavailable">O Bluetooth non está dispoñible</string>
|
||||
<string name="loading">Cargando…</string>
|
||||
<string name="newPerms">Novo</string>
|
||||
<string name="allPerms">Todo</string>
|
||||
@ -290,9 +289,6 @@
|
||||
<string name="swap_qr_isnt_for_swap">O código QR que escaneaches non parece corresponder a un código de
|
||||
intercambio.
|
||||
</string>
|
||||
<string name="swap_cant_send_no_bluetooth">Non se pode enviar, porque o Bluetooth non está dispoñible neste
|
||||
dispositivo.
|
||||
</string>
|
||||
<string name="swap_connection_misc_error">Ocurriu un erro durante a conexión co dispositivo, non se pode realizar o intercambio!</string>
|
||||
<string name="swap_not_enabled">Intercambio non dispoñible</string>
|
||||
<string name="swap_not_enabled_description">Antes do intercambio, o teu dispositivo debe estar visible.</string>
|
||||
|
@ -227,7 +227,6 @@
|
||||
<string name="swap_not_visible_wifi">לא גלוי דרך רשת אלחוטית</string>
|
||||
<string name="swap_wifi_device_name">שם התקן</string>
|
||||
<string name="swap_connecting">מתבצע חיבור</string>
|
||||
<string name="bluetooth_unavailable">Bluetooth לא זמין</string>
|
||||
<string name="loading">בטעינה…</string>
|
||||
|
||||
<string name="interval_never">אף פעם</string>
|
||||
@ -249,7 +248,6 @@
|
||||
<string name="swap_send_fdroid">שליחת F-Droid</string>
|
||||
<string name="swap_confirm">אימות ההחלפה</string>
|
||||
<string name="swap_qr_isnt_for_swap">קוד ה־QR שסרקת לא נראה כמו קוד החלפה.</string>
|
||||
<string name="swap_cant_send_no_bluetooth">אין אפשרות לשלוח את F-Droid כיוון שה־Bluetooth אינו זמין בהתקן זה.</string>
|
||||
<string name="swap_not_enabled">ההחלפה מנוטרלת</string>
|
||||
<string name="swap_not_enabled_description">בטרם ביצוע החלפה, על מכשירך להיות גלוי.</string>
|
||||
|
||||
|
@ -96,9 +96,6 @@
|
||||
<string name="loading">लोड हो रहा है…</string>
|
||||
<string name="swap_connection_misc_error">यन्त्र को जोड़ने मैं एक समस्या आ गयी| यन्त्र से अदला-बदली नहीं हो सकती|
|
||||
</string>
|
||||
<string name="bluetooth_unavailable">ब्लूटूथ अनुपलब्ध</string>
|
||||
<string name="swap_cant_send_no_bluetooth">फ-द्रोइड नहीं भेज सकते, क्योंकि ब्लूटूथ इस यन्त्र पे उपलब्ध नहीं है|
|
||||
</string>
|
||||
<string name="swap_connecting">जुड़ रहा है</string>
|
||||
<string name="swap_confirm">अदला-बदली की पुष्टि करे</string>
|
||||
<string name="swap_qr_isnt_for_swap">QR कोड जो अपने स्कैन किया है वह अदला-बदली का code नहीं है|</string>
|
||||
|
@ -315,9 +315,6 @@
|
||||
<string name="swap_connecting">Spajanje</string>
|
||||
<string name="swap_confirm">Potvrdi razmjenu</string>
|
||||
<string name="swap_qr_isnt_for_swap">Čini se da QR kod koji ste skenirali nije kod za razmjenu.</string>
|
||||
<string name="bluetooth_unavailable">Bluetooth nedostupan</string>
|
||||
<string name="swap_cant_send_no_bluetooth">Nije uspjelo slanje F-Droida, Bluetooth nije dostupan na ovom uređaju.
|
||||
</string>
|
||||
<string name="loading">Učitavanje…</string>
|
||||
<string name="swap_connection_misc_error">Došlo je do greške prilikom spajanja na uređaj, čini se da razmjena nije
|
||||
moguća.
|
||||
|
@ -269,10 +269,6 @@
|
||||
<string name="swap_cant_find_peers">Nem találja, amit keres?</string>
|
||||
<string name="swap_send_fdroid">Az F-Droid küldése</string>
|
||||
<string name="swap_connecting">Kapcsolódás</string>
|
||||
<string name="bluetooth_unavailable">A Bluetooth nem érhető el</string>
|
||||
<string name="swap_cant_send_no_bluetooth">Az F-Droid küldése sikertelen, mivel a Bluetooth nem érhető el ezen az
|
||||
eszközön.
|
||||
</string>
|
||||
<string name="download_pending">Várakozás a letöltés elkezdésére…</string>
|
||||
<string name="installing">Telepítés…</string>
|
||||
<string name="uninstalling">Eltávolítás…</string>
|
||||
|
@ -294,10 +294,6 @@
|
||||
<string name="swap_connecting">Menyambung</string>
|
||||
<string name="swap_confirm">Konfirmasi swap</string>
|
||||
<string name="swap_qr_isnt_for_swap">Kode QR yang kamu pindai tidak terlihat seperti kode swap.</string>
|
||||
<string name="bluetooth_unavailable">Bluetooth tidak tersedia</string>
|
||||
<string name="swap_cant_send_no_bluetooth">Tidak dapat mengirim F-Droid, karena Bluetooth tidak tersedia diperangkat
|
||||
ini.
|
||||
</string>
|
||||
<string name="loading">Memuat…</string>
|
||||
<string name="swap_connection_misc_error">Galat terjadi ketika menyambungkan ke perangkat, tidak bisa melakukan pertukaran!</string>
|
||||
<string name="swap_not_enabled">Swap dinonaktifkan</string>
|
||||
|
@ -220,7 +220,6 @@
|
||||
<string name="swap_no_peers_nearby">Gat ekki fundið neinn í nágrenninu til að býtta við.</string>
|
||||
<string name="swap_connecting">Tengist</string>
|
||||
<string name="swap_confirm">Staðfesta býtti</string>
|
||||
<string name="bluetooth_unavailable">Bluetooth er ekki tiltækt</string>
|
||||
<string name="loading">Hleð inn…</string>
|
||||
<string name="swap_not_enabled">Forritabýtti eru óvirk</string>
|
||||
<string name="install_confirm">þarf aðgang að</string>
|
||||
@ -369,8 +368,6 @@
|
||||
</string>
|
||||
<string name="swap_join_this_hotspot">Hjálpaðu vini þínum að tengjast tengipunktinum þínum</string>
|
||||
<string name="swap_scan_or_type_url">Einn aðili þarf að skanna QR-kóðann, eða slá slóð hins inn í vafra.</string>
|
||||
<string name="swap_cant_send_no_bluetooth">Get ekki sent F-Droid, því Bluetooth er ekki til taks á þessu tæki.
|
||||
</string>
|
||||
<string name="swap_connection_misc_error">Villa kom upp við að tengjast við tækið, ekki er hægt að nota það við býtti!</string>
|
||||
<string name="swap_not_enabled_description">Áður en farið er í að býtta þarf að gera tækið þitt sýnilegt.</string>
|
||||
|
||||
|
@ -200,7 +200,6 @@
|
||||
non saranno rimossi. L\'app dopo l\'aggiornamento avrà accesso a:
|
||||
</string>
|
||||
<string name="loading">Caricamento…</string>
|
||||
<string name="bluetooth_unavailable">Bluetooth non disponibile</string>
|
||||
<string name="swap_connecting">Connessione in corso</string>
|
||||
<string name="swap_wifi_device_name">Nome del dispositivo</string>
|
||||
<string name="swap_cant_find_peers">Non riesci a trovare chi stai cercando?</string>
|
||||
@ -320,9 +319,6 @@
|
||||
browser.
|
||||
</string>
|
||||
<string name="swap_send_fdroid">Invia F-Droid</string>
|
||||
<string name="swap_cant_send_no_bluetooth">Impossibile inviare F-Droid, perché il Bluetooth non è disponibile su
|
||||
questo dispositivo.
|
||||
</string>
|
||||
<string name="swap_connection_misc_error">È avvenuto un errore durante la connessione al dispositivo, non sembra possibile effettuare lo scambio!</string>
|
||||
<string name="swap_not_enabled">Scambio non abilitato</string>
|
||||
<string name="install_confirm_update_no_perms">Vuoi installare una versione aggiornata
|
||||
|
@ -210,8 +210,6 @@
|
||||
<string name="swap_connecting">接続中</string>
|
||||
<string name="swap_confirm">交換の確認</string>
|
||||
<string name="swap_qr_isnt_for_swap">読み取ったQRコードは交換コードではないようです。</string>
|
||||
<string name="bluetooth_unavailable">Bluetoothが利用できません</string>
|
||||
<string name="swap_cant_send_no_bluetooth">この端末ではBluetoothが利用できないため、F-Droidを送信できません。</string>
|
||||
<string name="loading">読み込み中</string>
|
||||
|
||||
<string name="downloading">ダウンロード中</string>
|
||||
|
@ -156,7 +156,6 @@
|
||||
<string name="swap_choose_apps">Fren Asnas</string>
|
||||
<string name="swap_wifi_device_name">Isem n yibenk</string>
|
||||
<string name="swap_confirm">Sentem ambaddal</string>
|
||||
<string name="bluetooth_unavailable">Bluetooth yella</string>
|
||||
<string name="interval_never">Warǧin</string>
|
||||
<string name="keep_week">1 n umalas</string>
|
||||
<string name="keep_forever">Yal tikelt</string>
|
||||
|
@ -249,8 +249,6 @@
|
||||
<string name="swap_connecting">연결 중</string>
|
||||
<string name="swap_confirm">교환 확인</string>
|
||||
<string name="swap_qr_isnt_for_swap">스캔한 QR 코드는 교환 코드가 아닌 것으로 파악됩니다.</string>
|
||||
<string name="bluetooth_unavailable">블루투스를 사용할 수 없음</string>
|
||||
<string name="swap_cant_send_no_bluetooth">F-Droid를 보낼 수 없습니다. 이 장치에서 블루투스를 사용할 수 없기 때문입니다.</string>
|
||||
<string name="loading">불러오는 중…</string>
|
||||
<string name="swap_connection_misc_error">장치에 연결하는 동안 오류가 발생했습니다. 교환할 수 없습니다!</string>
|
||||
<string name="swap_not_enabled">교환이 활성화되어 있지 않음</string>
|
||||
|
@ -328,8 +328,6 @@
|
||||
<string name="swap_connecting">ബന്ധിപ്പിക്കുന്നു</string>
|
||||
<string name="swap_confirm">കെെമാറ്റം സ്ഥിരീകരിക്കുക</string>
|
||||
<string name="swap_qr_isnt_for_swap">നിങ്ങൾ സ്കാന് ചെയ്ത QR കോഡ് ഒരു സ്വാപ്പ് കോഡ് പോലെ തോന്നുന്നില്ല.</string>
|
||||
<string name="bluetooth_unavailable">ബ്ലൂടൂത്ത് ലഭ്യമല്ല</string>
|
||||
<string name="swap_cant_send_no_bluetooth">ബ്ലൂടൂത്ത് ഈ ഉപകരണത്തിൽ ലഭ്യമല്ലാത്തതിനാൽ എഫ്-ഡ്രോയ്ഡ് അയയ്ക്കാൻ കഴിയില്ല.</string>
|
||||
<string name="loading">ലോഡുചെയ്യുന്നു…</string>
|
||||
<string name="swap_connection_misc_error">ഉപകരണത്തിലേക്ക് കണക്റ്റുചെയ്യുമ്പോൾ പിശക് സംഭവിച്ചു, അതുമായി കെെമാറ്റം ചെയ്യാന് പറ്റുന്നില്ല!</string>
|
||||
<string name="swap_not_enabled">കെെമാറ്റം സജ്ജമല്ല</string>
|
||||
|
@ -215,7 +215,6 @@
|
||||
<string name="swap_cant_find_peers">သင္ရွာေနတာကိုမေတြ႕ဘူးလား?</string>
|
||||
<string name="swap_send_fdroid">F-Droid ပို႔မည္</string>
|
||||
<string name="swap_connecting">ခ်ိတ္ဆက္ေနသည္</string>
|
||||
<string name="bluetooth_unavailable">ဘလူးသုဒ္မရရွိႏိုင္ပါ</string>
|
||||
<string name="loading">ဖြင့္ေနသည္</string>
|
||||
<string name="newPerms">အသစ္</string>
|
||||
<string name="allPerms">အားလံုး</string>
|
||||
|
@ -212,10 +212,6 @@
|
||||
<string name="swap_cant_find_peers">Finner du ikke den du leter etter?</string>
|
||||
<string name="swap_send_fdroid">Oversend F-Droid</string>
|
||||
<string name="swap_connecting">Kobler til</string>
|
||||
<string name="bluetooth_unavailable">Blåtann utilgjengelig</string>
|
||||
<string name="swap_cant_send_no_bluetooth">Kan ikke sende F-Droid siden Blåtann ikke er tilgjengelig på denne
|
||||
enheten.
|
||||
</string>
|
||||
<string name="loading">Laster inn…</string>
|
||||
<string name="install_confirm">tilgang til</string>
|
||||
<string name="newPerms">Ny</string>
|
||||
|
@ -223,10 +223,6 @@
|
||||
<string name="swap_connecting">Verbinden</string>
|
||||
<string name="swap_confirm">Bevestig uitwisseling</string>
|
||||
<string name="swap_qr_isnt_for_swap">De QR-code die je gescand hebt lijkt geen uitwisselcode te zijn.</string>
|
||||
<string name="bluetooth_unavailable">Bluetooth niet beschikbaar</string>
|
||||
<string name="swap_cant_send_no_bluetooth">Kon F-Droid niet verzenden omdat Bluetooth niet beschikbaar is op dit
|
||||
apparaat.
|
||||
</string>
|
||||
<string name="loading">Laden…</string>
|
||||
<string name="swap_connection_misc_error">Fout bij verbinden met apparaat, we kunnen er niet mee uit te wisselen!</string>
|
||||
<string name="swap_not_enabled">Uitwisselen niet ingeschakeld</string>
|
||||
|
@ -234,10 +234,6 @@
|
||||
<string name="swap_connecting">Łączenie</string>
|
||||
<string name="swap_confirm">Potwierdź wymianę</string>
|
||||
<string name="swap_qr_isnt_for_swap">Kod QR który został zeskanowany nie wygląda na kod do wymiany aplikacji.</string>
|
||||
<string name="bluetooth_unavailable">Bluetooth nie jest dostępny</string>
|
||||
<string name="swap_cant_send_no_bluetooth">Nie udało się wysłać F-Droida ponieważ Bluetooth nie jest dostępny na
|
||||
Twoim urządzeniu.
|
||||
</string>
|
||||
<string name="loading">Ładowanie…</string>
|
||||
<string name="swap_connection_misc_error">Wystąpił błąd podczas łączenia się z urządzeniem wymiana nie powiodła się!</string>
|
||||
<string name="swap_not_enabled">Wymiana nie jest włączona</string>
|
||||
|
@ -250,10 +250,6 @@
|
||||
<string name="swap_connecting">Conectando</string>
|
||||
<string name="swap_confirm">Confirmar a permuta</string>
|
||||
<string name="swap_qr_isnt_for_swap">O código QR que você escaneou não parece com um código de permuta.</string>
|
||||
<string name="bluetooth_unavailable">Bluetooth não está disponível</string>
|
||||
<string name="swap_cant_send_no_bluetooth">Não é possível enviar F-Droid, porque o Bluetooth não está disponível
|
||||
neste dispositivo.
|
||||
</string>
|
||||
<string name="loading">Carregando…</string>
|
||||
<string name="swap_connection_misc_error">Ocorreu um erro ao conectar o dispositivo, não foi possível trocar com ele!</string>
|
||||
<string name="swap_not_enabled">Permuta não habilitada</string>
|
||||
|
@ -301,10 +301,6 @@
|
||||
<string name="swap_no_peers_nearby">Não foram encontradas pessoas na sua vizinhança.</string>
|
||||
<string name="swap_confirm">Confirmação de troca</string>
|
||||
<string name="swap_qr_isnt_for_swap">O código QR digitalizado não parece ser um código de troca.</string>
|
||||
<string name="bluetooth_unavailable">Bluetooth não disponível</string>
|
||||
<string name="swap_cant_send_no_bluetooth">Não pode enviar o F-Droid porque o Bluetooth não está ativo no
|
||||
dispositivo.
|
||||
</string>
|
||||
<string name="swap_connection_misc_error">Ocorreu um erro ao estabelecer a ligação e não será possível a troca!</string>
|
||||
<string name="swap_not_enabled">Troca não ativa</string>
|
||||
<string name="swap_not_enabled_description">Antes de trocar, o seu dispositivo tem que estar disponível.</string>
|
||||
|
@ -259,7 +259,6 @@
|
||||
<string name="useTor">Folosește Tor</string>
|
||||
<string name="repo_details">Depozit</string>
|
||||
<string name="swap_stopping_wifi">Oprire Wi-Fi…</string>
|
||||
<string name="bluetooth_unavailable">Bluetooth indisponibil</string>
|
||||
<string name="repo_provider">Depozit: %s</string>
|
||||
|
||||
<string name="update_auto_download">Descarcă automat actualizările</string>
|
||||
@ -451,7 +450,6 @@
|
||||
<string name="swap_view_available_networks">Atinge pentru a vedea rețelele deschise disponibile</string>
|
||||
<string name="swap_scan_or_type_url">O persoană trebuie să scaneze codul sau să introducă URL-ul celuilalt într-un browser.</string>
|
||||
<string name="swap_qr_isnt_for_swap">Codul QR scanat nu arată ca un cod de schimb.</string>
|
||||
<string name="swap_cant_send_no_bluetooth">Nu s-a putut trimite F-Droid, deoarece conexiunea Bluetooth nu este valabilă pe acest dispozitiv.</string>
|
||||
<string name="swap_connection_misc_error">Eroare produsă în timpul conectării la dispozitiv, nu se poate face schimbul!</string>
|
||||
<string name="swap_not_enabled_description">Înaintea schimbului, dispozitivul tău trebuie făcut vizibil.</string>
|
||||
|
||||
|
@ -308,8 +308,6 @@
|
||||
<string name="swap_no_peers_nearby">Не удается найти людей рядом, чтобы обменяться с ними.</string>
|
||||
<string name="swap_confirm">Подтвердить обмен</string>
|
||||
<string name="swap_qr_isnt_for_swap">QR-код, который вы отсканировали, не похож на код обмена.</string>
|
||||
<string name="bluetooth_unavailable">Bluetooth не доступен</string>
|
||||
<string name="swap_cant_send_no_bluetooth">Не удается отправить F-Droid, так как Bluetooth не доступен на данном устройстве.</string>
|
||||
<string name="swap_connection_misc_error">При подключении к устройству произошла ошибка, невозможно провести с ним обмен!</string>
|
||||
<string name="swap_not_enabled">Обмен не включен</string>
|
||||
<string name="swap_not_enabled_description">Для выполнения обмена следует сделать ваше устройство видимым.</string>
|
||||
|
@ -252,10 +252,6 @@
|
||||
<string name="swap_connecting">Connetende</string>
|
||||
<string name="swap_confirm">Cunfirma cumpartzidura</string>
|
||||
<string name="swap_qr_isnt_for_swap">Su còdighe QR iscansidu non paret unu còdighe de cumpartzidura.</string>
|
||||
<string name="bluetooth_unavailable">Bluetooth non disponìbile</string>
|
||||
<string name="swap_cant_send_no_bluetooth">Impossìbile imbiare F-Droid, ca su Bluetooth no est disponìbile in custu
|
||||
dispositivu.
|
||||
</string>
|
||||
<string name="loading">Carrighende…</string>
|
||||
<string name="swap_not_enabled">Cumpartzidura non abilitada</string>
|
||||
<string name="swap_not_enabled_description">In antis de cumpartzire, su dispositivu depet èssere postu visìbile.</string>
|
||||
|
@ -232,7 +232,6 @@
|
||||
<string name="swap_cant_find_peers">Nemôžete nájsť koho hľadáte?</string>
|
||||
<string name="swap_send_fdroid">Poslať F-Droid</string>
|
||||
<string name="swap_connecting">Pripájam</string>
|
||||
<string name="bluetooth_unavailable">Bluetooth nedostupný</string>
|
||||
<string name="loading">Načítavam…</string>
|
||||
<string name="install_confirm">vyžaduje prístup k</string>
|
||||
<string name="allPerms">Všetky</string>
|
||||
@ -257,9 +256,6 @@
|
||||
<string name="category_Theming">Témy</string>
|
||||
<string name="swap_not_visible_bluetooth">Nie je viditeľný cez Bluetooth</string>
|
||||
<string name="swap_not_visible_wifi">Nie je viditeľný cez Wi-Fi</string>
|
||||
<string name="swap_cant_send_no_bluetooth">Nemožno poslať F-Droid, pretože Bluetooh nie je dostupný na tomto
|
||||
zariadení.
|
||||
</string>
|
||||
<string name="perm_costs_money">Môže stáť peniaze</string>
|
||||
<string name="menu_flattr">Flattr</string>
|
||||
|
||||
|
@ -344,10 +344,6 @@
|
||||
<string name="swap_connecting">Kuhakira</string>
|
||||
<string name="swap_confirm">Tsinhira kutsinhana</string>
|
||||
<string name="swap_qr_isnt_for_swap">Murau weQR wawanzvera hausi kuita kunge murau wekutsinhana.</string>
|
||||
<string name="bluetooth_unavailable">Bluetooth haipo</string>
|
||||
<string name="swap_cant_send_no_bluetooth">Hatisi kukwanisa kutumira F-Droid, nekuti Bluetooth haipo pamuchina
|
||||
uyu.
|
||||
</string>
|
||||
<string name="loading">Kuzadza…</string>
|
||||
<string name="swap_connection_misc_error">Pane kanganiso yaitika pakuhakira kumuchina, hatisi kukwanisa kutsinhana
|
||||
nayo.
|
||||
|
@ -206,7 +206,6 @@
|
||||
<string name="swap_send_fdroid">Пошаљи Ф-дроид</string>
|
||||
<string name="swap_connecting">Повезујем се</string>
|
||||
<string name="swap_confirm">Потврди размену</string>
|
||||
<string name="bluetooth_unavailable">Блутут није доступан</string>
|
||||
<string name="loading">Учитавам…</string>
|
||||
<string name="swap_not_enabled">Размена није укључена</string>
|
||||
<string name="newPerms">Ново</string>
|
||||
@ -238,8 +237,6 @@
|
||||
|
||||
<string name="swap_not_enabled_description">Пре размене, ваш уређај мора бити видљив.</string>
|
||||
|
||||
<string name="swap_cant_send_no_bluetooth">Не могу да пошаљем Ф-дроида, блутут није доступан на овом уређају.
|
||||
</string>
|
||||
<string name="swap_visible_bluetooth">Видљив преко блутута</string>
|
||||
<string name="swap_not_visible_bluetooth">Нисам видљив преко блутута</string>
|
||||
<string name="swap_visible_wifi">Видљив преко бежичног</string>
|
||||
|
@ -266,8 +266,6 @@
|
||||
<string name="swap_connecting">Ansluter</string>
|
||||
<string name="swap_confirm">Bekräfta utbyte</string>
|
||||
<string name="swap_qr_isnt_for_swap">QR-koden du läst av ser inte ut som en utbytarkod.</string>
|
||||
<string name="bluetooth_unavailable">Bluetooth inte tillgänglig</string>
|
||||
<string name="swap_cant_send_no_bluetooth">Det går inte att skicka F-Droid eftersom Bluetooth är otillgänglig på den här enheten.</string>
|
||||
<string name="loading">Öppnar…</string>
|
||||
<string name="swap_connection_misc_error">Fel uppstod under enhetsanslutning, går inte att utföra utbyte med den!</string>
|
||||
<string name="swap_not_enabled">Utbyta inte aktiverat</string>
|
||||
|
@ -176,8 +176,6 @@
|
||||
<string name="swap_send_fdroid">ส่งต่อโปรแกรม F-Droid</string>
|
||||
<string name="swap_connecting">กำลังเชื่อมต่อ</string>
|
||||
<string name="swap_confirm">ยืนยันการส่งต่อ</string>
|
||||
<string name="bluetooth_unavailable">ไม่สามารถใช้บลูทูธได้</string>
|
||||
<string name="swap_cant_send_no_bluetooth">ไม่สามารถส่งต่อโปรแกรม F-Droid ได้ เนื่องจากไม่สามารถใช้บลูทูธ</string>
|
||||
<string name="loading">กำลังโหลด…</string>
|
||||
<string name="swap_connection_misc_error">การเชื่อมต่อกับอีกเครื่องล้มเหลว, ไม่สามารถส่งต่อโปรแกรมได้</string>
|
||||
<string name="swap_not_enabled">ไม่เปิดใช้การส่งต่อโปรแกรม</string>
|
||||
|
@ -261,8 +261,6 @@
|
||||
<string name="swap_connecting">Bağlanıyor</string>
|
||||
<string name="swap_confirm">Takası onaylayın</string>
|
||||
<string name="swap_qr_isnt_for_swap">Taradığınız QR kodu bir takas kodu gibi görünmüyor.</string>
|
||||
<string name="bluetooth_unavailable">Bluetooth kullanılabilir değil</string>
|
||||
<string name="swap_cant_send_no_bluetooth">F-Droid gönderilemiyor, çünkü bu aygıtta Bluetooth kullanılabilir değil.</string>
|
||||
<string name="loading">Yükleniyor…</string>
|
||||
<string name="swap_connection_misc_error">Aygıta bağlanılırken hata oluştu, onunla takas yapılamaz!</string>
|
||||
<string name="swap_not_enabled">Takas etkinleştirilmemiş</string>
|
||||
|
@ -161,10 +161,6 @@
|
||||
<string name="swap_wifi_device_name">Назва пристрою</string>
|
||||
<string name="swap_send_fdroid">Відправити F-Droid</string>
|
||||
<string name="swap_connecting">Підключення</string>
|
||||
<string name="bluetooth_unavailable">Bluetooth не доступний</string>
|
||||
<string name="swap_cant_send_no_bluetooth">Неможливо надіслати F-Droid, тому що Bluetooth не доступний на цьому
|
||||
пристрої.
|
||||
</string>
|
||||
<string name="loading">Завантаження…</string>
|
||||
<string name="newPerms">Нові</string>
|
||||
<string name="allPerms">Всі</string>
|
||||
|
@ -242,8 +242,6 @@
|
||||
<string name="swap_connecting">Đang kết nối</string>
|
||||
<string name="swap_confirm">Xác nhận trao đổi</string>
|
||||
<string name="swap_qr_isnt_for_swap">Mã QR đã quét không phải là mã trao đổi.</string>
|
||||
<string name="bluetooth_unavailable">Không có Bluetooth</string>
|
||||
<string name="swap_cant_send_no_bluetooth">Không thể gửi F-Droid vì thiết bị này không có Bluetooth.</string>
|
||||
<string name="loading">Đang tải…</string>
|
||||
<string name="swap_not_enabled">Trao đổi đang tắt</string>
|
||||
<string name="swap_connection_misc_error">Đã xảy ra lỗi khi kết nối, không thể trao đổi ứng dụng!</string>
|
||||
|
@ -246,8 +246,6 @@
|
||||
<string name="swap_connecting">连接中</string>
|
||||
<string name="swap_confirm">确认交换</string>
|
||||
<string name="swap_qr_isnt_for_swap">你扫描的二维码似乎不是一个交换代码。</string>
|
||||
<string name="bluetooth_unavailable">蓝牙不可用</string>
|
||||
<string name="swap_cant_send_no_bluetooth">不能发送 F-Droid,因为该设备蓝牙不可用。</string>
|
||||
<string name="loading">加载中…</string>
|
||||
<string name="swap_connection_misc_error">连接设备时出错,无法交换应用!</string>
|
||||
<string name="swap_not_enabled">未启用交换功能</string>
|
||||
|
@ -209,8 +209,6 @@
|
||||
<string name="swap_not_enabled">沒有啟用交換功能</string>
|
||||
<string name="swap_connection_misc_error">與裝置連接時發生了問題,未能進行交換!</string>
|
||||
<string name="loading">正在載入…</string>
|
||||
<string name="swap_cant_send_no_bluetooth">因為此裝置沒有藍牙功能,未能傳送 F-Droid。</string>
|
||||
<string name="bluetooth_unavailable">藍牙不可用</string>
|
||||
<string name="swap_qr_isnt_for_swap">您所掃描的 QR 碼不是一個交換碼。</string>
|
||||
<string name="swap_confirm">確定交換</string>
|
||||
<string name="swap_no_peers_nearby">找不到附近的人進行交換。</string>
|
||||
|
@ -220,8 +220,6 @@
|
||||
<string name="swap_send_fdroid">傳送 F-Droid</string>
|
||||
<string name="swap_no_peers_nearby">找不到附近的人來進行交換。</string>
|
||||
<string name="swap_confirm">確認交換</string>
|
||||
<string name="bluetooth_unavailable">藍牙不可用</string>
|
||||
<string name="swap_cant_send_no_bluetooth">無法傳送 F-Droid,因為此裝置沒有藍牙功能。</string>
|
||||
<string name="swap_not_enabled">沒有啟用交換功能</string>
|
||||
<string name="uninstall_confirm">您想要解除安裝此應用程式嗎?</string>
|
||||
<string name="download_error">下載失敗!</string>
|
||||
|
@ -453,13 +453,14 @@ This often occurs with apps installed via Google Play or other sources, if they
|
||||
<string name="swap_connecting">Connecting</string>
|
||||
<string name="swap_confirm">Confirm swap</string>
|
||||
<string name="swap_qr_isnt_for_swap">The QR code you scanned doesn\'t look like a swap code.</string>
|
||||
<string name="bluetooth_unavailable">Bluetooth unavailable</string>
|
||||
<string name="swap_cant_send_no_bluetooth">Cannot send F-Droid, because Bluetooth is unavailable on this device.
|
||||
</string>
|
||||
<string name="use_bluetooth">Use Bluetooth</string>
|
||||
<string name="loading">Loading…</string>
|
||||
<string name="swap_connection_misc_error">Error occurred while connecting to device, can\'t swap with it!</string>
|
||||
<string name="swap_not_enabled">Swapping not enabled</string>
|
||||
<string name="swap_not_enabled_description">Before swapping, your device must be made visible.</string>
|
||||
<string name="swap_toast_invalid_url">Invalid URL for swapping: %1$s</string>
|
||||
<string name="swap_toast_hotspot_enabled">Wi-Fi Hotspot enabled</string>
|
||||
<string name="swap_toast_could_not_enable_hotspot">Could not enable Wi-Fi Hotspot!</string>
|
||||
|
||||
<string name="install_confirm">needs access to</string>
|
||||
<string name="install_confirm_update">Do you want to install an update
|
||||
|
@ -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")));
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user