WIP: Refactored wifi QR fragment into view.
As per the select apps list, there is quite a bit of business logic in this class, which is now spread between the activity and the view. The activity needs to handle some stuff, because the zxing library routes intents to either an activity or a fragment.
This commit is contained in:
parent
97994c5e43
commit
38eafdeedd
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
<ScrollView
|
<org.fdroid.fdroid.views.swap.views.WifiQrView
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
@ -50,4 +50,4 @@
|
|||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
</ScrollView>
|
</org.fdroid.fdroid.views.swap.views.WifiQrView>
|
@ -1,7 +1,9 @@
|
|||||||
package org.fdroid.fdroid.views.swap;
|
package org.fdroid.fdroid.views.swap;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
import android.app.ProgressDialog;
|
import android.app.ProgressDialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@ -15,11 +17,16 @@ import android.view.View;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.google.zxing.integration.android.IntentIntegrator;
|
||||||
|
import com.google.zxing.integration.android.IntentResult;
|
||||||
|
|
||||||
|
import org.fdroid.fdroid.FDroid;
|
||||||
import org.fdroid.fdroid.FDroidApp;
|
import org.fdroid.fdroid.FDroidApp;
|
||||||
import org.fdroid.fdroid.NfcHelper;
|
import org.fdroid.fdroid.NfcHelper;
|
||||||
import org.fdroid.fdroid.Preferences;
|
import org.fdroid.fdroid.Preferences;
|
||||||
import org.fdroid.fdroid.R;
|
import org.fdroid.fdroid.R;
|
||||||
import org.fdroid.fdroid.Utils;
|
import org.fdroid.fdroid.Utils;
|
||||||
|
import org.fdroid.fdroid.data.NewRepoConfig;
|
||||||
import org.fdroid.fdroid.localrepo.LocalRepoManager;
|
import org.fdroid.fdroid.localrepo.LocalRepoManager;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
@ -39,6 +46,8 @@ public class SwapWorkflowActivity extends FragmentActivity {
|
|||||||
boolean buildMenu(Menu menu, @NonNull MenuInflater inflater);
|
boolean buildMenu(Menu menu, @NonNull MenuInflater inflater);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final int CONNECT_TO_SWAP = 1;
|
||||||
|
|
||||||
private State currentState = State.INTRO;
|
private State currentState = State.INTRO;
|
||||||
private InnerView currentView;
|
private InnerView currentView;
|
||||||
private boolean hasPreparedLocalRepo = false;
|
private boolean hasPreparedLocalRepo = false;
|
||||||
@ -115,10 +124,14 @@ public class SwapWorkflowActivity extends FragmentActivity {
|
|||||||
public void onJoinWifiComplete() {
|
public void onJoinWifiComplete() {
|
||||||
ensureLocalRepoRunning();
|
ensureLocalRepoRunning();
|
||||||
if (!attemptToShowNfc()) {
|
if (!attemptToShowNfc()) {
|
||||||
// showWifiQr();
|
showWifiQr();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void showWifiQr() {
|
||||||
|
inflateInnerView(R.layout.swap_wifi_qr);
|
||||||
|
}
|
||||||
|
|
||||||
private boolean attemptToShowNfc() {
|
private boolean attemptToShowNfc() {
|
||||||
// TODO: What if NFC is disabled? Hook up with NfcNotEnabledActivity? Or maybe only if they
|
// TODO: What if NFC is disabled? Hook up with NfcNotEnabledActivity? Or maybe only if they
|
||||||
// click a relevant button?
|
// click a relevant button?
|
||||||
@ -169,6 +182,23 @@ public class SwapWorkflowActivity extends FragmentActivity {
|
|||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
|
||||||
|
IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, intent);
|
||||||
|
if (scanResult != null) {
|
||||||
|
if (scanResult.getContents() != null) {
|
||||||
|
NewRepoConfig repoConfig = new NewRepoConfig(this, scanResult.getContents());
|
||||||
|
if (repoConfig.isValidRepo()) {
|
||||||
|
startActivityForResult(new Intent(FDroid.ACTION_ADD_REPO, Uri.parse(scanResult.getContents()), this, ConnectSwapActivity.class), CONNECT_TO_SWAP);
|
||||||
|
} else {
|
||||||
|
Toast.makeText(this, "The QR code you scanned doesn't look like a swap code.", Toast.LENGTH_SHORT).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (requestCode == CONNECT_TO_SWAP && resultCode == Activity.RESULT_OK) {
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class UpdateAsyncTask extends AsyncTask<Void, String, Void> {
|
class UpdateAsyncTask extends AsyncTask<Void, String, Void> {
|
||||||
|
|
||||||
@SuppressWarnings("UnusedDeclaration")
|
@SuppressWarnings("UnusedDeclaration")
|
||||||
|
@ -36,6 +36,11 @@ public class NfcView extends RelativeLayout implements SwapWorkflowActivity.Inne
|
|||||||
super(context, attrs, defStyleAttr, defStyleRes);
|
super(context, attrs, defStyleAttr, defStyleRes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private SwapWorkflowActivity getActivity() {
|
||||||
|
// TODO: Try and find a better way to get to the SwapActivity, which makes less asumptions.
|
||||||
|
return (SwapWorkflowActivity)getContext();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onFinishInflate() {
|
protected void onFinishInflate() {
|
||||||
super.onFinishInflate();
|
super.onFinishInflate();
|
||||||
@ -56,7 +61,7 @@ public class NfcView extends RelativeLayout implements SwapWorkflowActivity.Inne
|
|||||||
next.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
next.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public boolean onMenuItemClick(MenuItem item) {
|
public boolean onMenuItemClick(MenuItem item) {
|
||||||
// TODO: Show QR Code.
|
getActivity().showWifiQr();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
159
F-Droid/src/org/fdroid/fdroid/views/swap/views/WifiQrView.java
Normal file
159
F-Droid/src/org/fdroid/fdroid/views/swap/views/WifiQrView.java
Normal file
@ -0,0 +1,159 @@
|
|||||||
|
package org.fdroid.fdroid.views.swap.views;
|
||||||
|
|
||||||
|
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.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.v4.content.LocalBroadcastManager;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.util.Log;
|
||||||
|
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 com.google.zxing.integration.android.IntentIntegrator;
|
||||||
|
|
||||||
|
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;
|
||||||
|
import org.fdroid.fdroid.R;
|
||||||
|
import org.fdroid.fdroid.Utils;
|
||||||
|
import org.fdroid.fdroid.net.WifiStateChangeService;
|
||||||
|
import org.fdroid.fdroid.views.swap.SwapWorkflowActivity;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
public class WifiQrView extends ScrollView implements SwapWorkflowActivity.InnerView {
|
||||||
|
|
||||||
|
private static final String TAG = "WifiQrView";
|
||||||
|
|
||||||
|
public WifiQrView(Context context) {
|
||||||
|
super(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
public WifiQrView(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public WifiQrView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||||
|
super(context, attrs, defStyleAttr);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
|
||||||
|
public WifiQrView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||||
|
super(context, attrs, defStyleAttr, defStyleRes);
|
||||||
|
}
|
||||||
|
|
||||||
|
private SwapWorkflowActivity getActivity() {
|
||||||
|
// TODO: Try and find a better way to get to the SwapActivity, which makes less asumptions.
|
||||||
|
return (SwapWorkflowActivity)getContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onFinishInflate() {
|
||||||
|
super.onFinishInflate();
|
||||||
|
setUIFromWifi();
|
||||||
|
|
||||||
|
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 openQr = (Button)findViewById(R.id.btn_qr_scanner);
|
||||||
|
openQr.setOnClickListener(new Button.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
IntentIntegrator integrator = new IntentIntegrator(getActivity());
|
||||||
|
integrator.initiateScan();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Button cancel = (Button)findViewById(R.id.btn_cancel_swap);
|
||||||
|
cancel.setOnClickListener(new Button.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
getActivity().stopSwapping();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
LocalBroadcastManager.getInstance(getActivity()).registerReceiver(
|
||||||
|
new BroadcastReceiver() {
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
setUIFromWifi();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
new IntentFilter(WifiStateChangeService.BROADCAST)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean buildMenu(Menu menu, @NonNull MenuInflater inflater) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 buttonLabel = scheme + FDroidApp.ipAddressString + ":" + FDroidApp.port;
|
||||||
|
TextView ipAddressView = (TextView) findViewById(R.id.device_ip_address);
|
||||||
|
ipAddressView.setText(buttonLabel);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set URL to UPPER for compact QR Code, FDroid will translate it back.
|
||||||
|
* Remove the SSID from the query string since SSIDs are case-sensitive.
|
||||||
|
* Instead the receiver will have to rely on the BSSID to find the right
|
||||||
|
* wifi AP to join. Lots of QR Scanners are buggy and do not respect
|
||||||
|
* custom URI schemes, so we have to use http:// or https:// :-(
|
||||||
|
*/
|
||||||
|
Uri sharingUri = Utils.getSharingUri(FDroidApp.repo);
|
||||||
|
String qrUriString = (scheme + sharingUri.getHost()).toUpperCase(Locale.ENGLISH);
|
||||||
|
if (sharingUri.getPort() != 80) {
|
||||||
|
qrUriString += ":" + sharingUri.getPort();
|
||||||
|
}
|
||||||
|
qrUriString += sharingUri.getPath().toUpperCase(Locale.ENGLISH);
|
||||||
|
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 (!parameter.getName().equals("ssid")) {
|
||||||
|
if (first) {
|
||||||
|
qrUriString += "?";
|
||||||
|
first = false;
|
||||||
|
} else {
|
||||||
|
qrUriString += "&";
|
||||||
|
}
|
||||||
|
qrUriString += parameter.getName().toUpperCase(Locale.ENGLISH) + "=" +
|
||||||
|
parameter.getValue().toUpperCase(Locale.ENGLISH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.i(TAG, "Encoded swap URI in QR Code: " + qrUriString);
|
||||||
|
|
||||||
|
new QrGenAsyncTask(getActivity(), R.id.wifi_qr_code).execute(qrUriString);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user