Merge pull request #187 from ph4r05/pr/002-upgrade-android
Improve remote-reader
This commit is contained in:
@@ -1,14 +1,14 @@
|
|||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 23
|
compileSdkVersion 29
|
||||||
buildToolsVersion "23.0.1"
|
buildToolsVersion "23.0.3"
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "com.vsmartcard.remotesmartcardreader.app"
|
applicationId "com.vsmartcard.remotesmartcardreader.app"
|
||||||
// NFC reader mode was added in KitKat
|
// NFC reader mode was added in KitKat
|
||||||
minSdkVersion 19
|
minSdkVersion 19
|
||||||
targetSdkVersion 23
|
targetSdkVersion 29
|
||||||
versionCode 6
|
versionCode 6
|
||||||
versionName "2.2"
|
versionName "2.2"
|
||||||
}
|
}
|
||||||
@@ -38,7 +38,7 @@ android.applicationVariants.all { variant ->
|
|||||||
} else {
|
} else {
|
||||||
newApkName = "${appName}-${output.baseName}-${variant.versionName}-unaligned.apk"
|
newApkName = "${appName}-${output.baseName}-${variant.versionName}-unaligned.apk"
|
||||||
}
|
}
|
||||||
output.outputFile = new File(output.outputFile.parent, newApkName)
|
//output.outputFile = new File(output.outputFile.parent, newApkName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,12 +47,12 @@ repositories {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||||
testCompile 'junit:junit:4.12'
|
testImplementation 'junit:junit:4.12'
|
||||||
compile 'com.android.support:appcompat-v7:23.2.1'
|
implementation 'androidx.appcompat:appcompat:1.2.0'
|
||||||
compile 'com.android.support:design:23.2.1'
|
implementation 'com.google.android.material:material:1.3.0'
|
||||||
compile 'com.android.support:support-v4:23.2.1'
|
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||||
|
|
||||||
compile 'com.journeyapps:zxing-android-embedded:3.2.0@aar'
|
implementation 'com.journeyapps:zxing-android-embedded:3.2.0@aar'
|
||||||
compile 'com.google.zxing:core:3.2.1'
|
implementation 'com.google.zxing:core:3.2.1'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ package com.example.android.common.logger;
|
|||||||
|
|
||||||
import android.graphics.Typeface;
|
import android.graphics.Typeface;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.v4.app.Fragment;
|
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
import android.text.TextWatcher;
|
import android.text.TextWatcher;
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
@@ -42,6 +41,8 @@ import android.view.View;
|
|||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.ScrollView;
|
import android.widget.ScrollView;
|
||||||
|
|
||||||
|
import androidx.fragment.app.Fragment;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple fraggment which contains a LogView and uses is to output log data it receives
|
* Simple fraggment which contains a LogView and uses is to output log data it receives
|
||||||
* through the LogNode interface.
|
* through the LogNode interface.
|
||||||
|
|||||||
@@ -3,15 +3,16 @@ package com.vsmartcard.remotesmartcardreader.app;
|
|||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.preference.PreferenceActivity;
|
import android.preference.PreferenceActivity;
|
||||||
import android.support.annotation.LayoutRes;
|
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
import android.support.v7.app.ActionBar;
|
|
||||||
import android.support.v7.app.AppCompatDelegate;
|
|
||||||
import android.support.v7.widget.Toolbar;
|
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
|
|
||||||
|
import androidx.annotation.LayoutRes;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.appcompat.app.ActionBar;
|
||||||
|
import androidx.appcompat.app.AppCompatDelegate;
|
||||||
|
import androidx.appcompat.widget.Toolbar;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@link android.preference.PreferenceActivity} which implements and proxies the necessary calls
|
* A {@link android.preference.PreferenceActivity} which implements and proxies the necessary calls
|
||||||
* to be used with AppCompat.
|
* to be used with AppCompat.
|
||||||
|
|||||||
@@ -31,20 +31,21 @@ import android.os.Build;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.support.design.widget.FloatingActionButton;
|
|
||||||
import android.support.design.widget.Snackbar;
|
|
||||||
import android.support.v7.app.AlertDialog;
|
|
||||||
import android.support.v7.app.AppCompatActivity;
|
|
||||||
import android.support.v7.widget.Toolbar;
|
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.appcompat.widget.Toolbar;
|
||||||
|
|
||||||
import com.example.android.common.logger.Log;
|
import com.example.android.common.logger.Log;
|
||||||
import com.example.android.common.logger.LogFragment;
|
import com.example.android.common.logger.LogFragment;
|
||||||
import com.example.android.common.logger.LogWrapper;
|
import com.example.android.common.logger.LogWrapper;
|
||||||
import com.example.android.common.logger.MessageOnlyLogFilter;
|
import com.example.android.common.logger.MessageOnlyLogFilter;
|
||||||
|
|
||||||
|
import com.google.android.material.floatingactionbutton.FloatingActionButton;
|
||||||
|
import com.google.android.material.snackbar.Snackbar;
|
||||||
import com.vsmartcard.remotesmartcardreader.app.screaders.*;
|
import com.vsmartcard.remotesmartcardreader.app.screaders.*;
|
||||||
|
|
||||||
@TargetApi(Build.VERSION_CODES.KITKAT)
|
@TargetApi(Build.VERSION_CODES.KITKAT)
|
||||||
@@ -197,11 +198,12 @@ public class MainActivity extends AppCompatActivity implements NfcAdapter.Reader
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void vpcdConnect(SCReader scReader) {
|
private void vpcdConnect(SCReader scReader) {
|
||||||
SharedPreferences SP = PreferenceManager.getDefaultSharedPreferences(this);
|
final SharedPreferences SP = PreferenceManager.getDefaultSharedPreferences(this);
|
||||||
int port = Integer.parseInt(SP.getString("port", Integer.toString(VPCDWorker.DEFAULT_PORT)));
|
final int port = Integer.parseInt(SP.getString("port", Integer.toString(VPCDWorker.DEFAULT_PORT)));
|
||||||
String hostname = SP.getString("hostname", VPCDWorker.DEFAULT_HOSTNAME);
|
final String hostname = SP.getString("hostname", VPCDWorker.DEFAULT_HOSTNAME);
|
||||||
|
final boolean listen = SP.getBoolean("listen", VPCDWorker.DEFAULT_LISTEN);
|
||||||
vpcdTest = new VPCDWorker();
|
vpcdTest = new VPCDWorker();
|
||||||
vpcdTest.execute(new VPCDWorker.VPCDWorkerParams(hostname, port, scReader));
|
vpcdTest.execute(new VPCDWorker.VPCDWorkerParams(hostname, port, scReader, listen));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void vpcdDisconnect() {
|
private void vpcdDisconnect() {
|
||||||
@@ -231,6 +233,7 @@ public class MainActivity extends AppCompatActivity implements NfcAdapter.Reader
|
|||||||
@Override
|
@Override
|
||||||
public void onNewIntent(Intent intent) {
|
public void onNewIntent(Intent intent) {
|
||||||
// onResume gets called after this to handle the intent
|
// onResume gets called after this to handle the intent
|
||||||
|
super.onNewIntent(intent);
|
||||||
setIntent(intent);
|
setIntent(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,12 +23,12 @@ import android.content.ClipData;
|
|||||||
import android.content.ClipboardManager;
|
import android.content.ClipboardManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.design.widget.Snackbar;
|
|
||||||
import android.view.Menu;
|
import android.view.Menu;
|
||||||
import android.view.MenuInflater;
|
import android.view.MenuInflater;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
|
||||||
import com.example.android.common.logger.LogFragment;
|
import com.example.android.common.logger.LogFragment;
|
||||||
|
import com.google.android.material.snackbar.Snackbar;
|
||||||
|
|
||||||
public class MyLogFragment extends LogFragment {
|
public class MyLogFragment extends LogFragment {
|
||||||
|
|
||||||
|
|||||||
@@ -32,11 +32,13 @@ import android.preference.ListPreference;
|
|||||||
import android.preference.Preference;
|
import android.preference.Preference;
|
||||||
import android.preference.PreferenceActivity;
|
import android.preference.PreferenceActivity;
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.support.design.widget.Snackbar;
|
|
||||||
import android.support.v7.app.ActionBar;
|
|
||||||
import android.preference.PreferenceFragment;
|
import android.preference.PreferenceFragment;
|
||||||
import android.preference.PreferenceManager;
|
import android.preference.PreferenceManager;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
|
|
||||||
|
import androidx.appcompat.app.ActionBar;
|
||||||
|
|
||||||
|
import com.google.android.material.snackbar.Snackbar;
|
||||||
import com.google.zxing.integration.android.IntentIntegrator;
|
import com.google.zxing.integration.android.IntentIntegrator;
|
||||||
import com.google.zxing.integration.android.IntentResult;
|
import com.google.zxing.integration.android.IntentResult;
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,8 @@
|
|||||||
package com.vsmartcard.remotesmartcardreader.app;
|
package com.vsmartcard.remotesmartcardreader.app;
|
||||||
|
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
import com.example.android.common.logger.Log;
|
import com.example.android.common.logger.Log;
|
||||||
import com.vsmartcard.remotesmartcardreader.app.screaders.SCReader;
|
import com.vsmartcard.remotesmartcardreader.app.screaders.SCReader;
|
||||||
@@ -28,8 +29,17 @@ import com.vsmartcard.remotesmartcardreader.app.screaders.SCReader;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
import java.net.Inet4Address;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
|
import java.net.InterfaceAddress;
|
||||||
|
import java.net.NetworkInterface;
|
||||||
|
import java.net.ServerSocket;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
|
import java.net.SocketTimeoutException;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
class VPCDWorker extends AsyncTask<VPCDWorker.VPCDWorkerParams, Void, Void> {
|
class VPCDWorker extends AsyncTask<VPCDWorker.VPCDWorkerParams, Void, Void> {
|
||||||
|
|
||||||
@@ -37,18 +47,22 @@ class VPCDWorker extends AsyncTask<VPCDWorker.VPCDWorkerParams, Void, Void> {
|
|||||||
final String hostname;
|
final String hostname;
|
||||||
final int port;
|
final int port;
|
||||||
final SCReader reader;
|
final SCReader reader;
|
||||||
VPCDWorkerParams(String hostname, int port, SCReader reader) {
|
final boolean listen;
|
||||||
|
VPCDWorkerParams(String hostname, int port, SCReader reader, boolean listen) {
|
||||||
this.hostname = hostname;
|
this.hostname = hostname;
|
||||||
this.port = port;
|
this.port = port;
|
||||||
this.reader = reader;
|
this.reader = reader;
|
||||||
|
this.listen = listen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final int DEFAULT_PORT = 35963;
|
public static final int DEFAULT_PORT = 35963;
|
||||||
// default URI when used in emulator
|
// default URI when used in emulator
|
||||||
public static final String DEFAULT_HOSTNAME = "10.0.2.2";
|
public static final String DEFAULT_HOSTNAME = "10.0.2.2";
|
||||||
|
public static final boolean DEFAULT_LISTEN = false;
|
||||||
|
|
||||||
private SCReader reader;
|
private SCReader reader;
|
||||||
|
private ServerSocket listenSocket;
|
||||||
private Socket socket;
|
private Socket socket;
|
||||||
private InputStream inputStream;
|
private InputStream inputStream;
|
||||||
private OutputStream outputStream;
|
private OutputStream outputStream;
|
||||||
@@ -74,15 +88,22 @@ class VPCDWorker extends AsyncTask<VPCDWorker.VPCDWorkerParams, Void, Void> {
|
|||||||
public Void doInBackground(VPCDWorkerParams... params) {
|
public Void doInBackground(VPCDWorkerParams... params) {
|
||||||
try {
|
try {
|
||||||
reader = params[0].reader;
|
reader = params[0].reader;
|
||||||
Log.i(this.getClass().getName(), "Connecting to " + params[0].hostname + ":" + Integer.toString(params[0].port) + "...");
|
vpcdConnection(params[0]);
|
||||||
vpcdConnect(params[0].hostname, params[0].port);
|
|
||||||
Log.i(this.getClass().getName(), "Connected to VPCD");
|
|
||||||
|
|
||||||
while (!isCancelled()) {
|
while (!isCancelled()) {
|
||||||
|
vpcdAccept();
|
||||||
byte[] out = null;
|
byte[] out = null;
|
||||||
byte[] in = receiveFromVPCD();
|
byte[] in = receiveFromVPCD();
|
||||||
if (in == null)
|
if (in == null) {
|
||||||
|
if (listenSocket == null) {
|
||||||
|
Log.i(this.getClass().getName(), "End of stream, finishing");
|
||||||
break;
|
break;
|
||||||
|
} else {
|
||||||
|
Log.i(this.getClass().getName(), "End of stream, closing connection");
|
||||||
|
vpcdCloseClient();
|
||||||
|
continue; // back to accept
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (in.length == VPCD_CTRL_LEN) {
|
if (in.length == VPCD_CTRL_LEN) {
|
||||||
switch (in[0]) {
|
switch (in[0]) {
|
||||||
@@ -168,7 +189,79 @@ class VPCDWorker extends AsyncTask<VPCDWorker.VPCDWorkerParams, Void, Void> {
|
|||||||
outputStream.flush();
|
outputStream.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void vpcdConnection(VPCDWorkerParams params) throws IOException {
|
||||||
|
if (params.listen){
|
||||||
|
vpcdListen(params.port);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.i(this.getClass().getName(), "Connecting to " + params.hostname + ":" + Integer.toString(params.port) + "...");
|
||||||
|
vpcdConnect(params.hostname, params.port);
|
||||||
|
Log.i(this.getClass().getName(), "Connected to VPCD");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void vpcdListen(int port) throws IOException {
|
||||||
|
listenSocket = new ServerSocket(port);
|
||||||
|
|
||||||
|
final List<String> ifaceAddresses = new LinkedList<>();
|
||||||
|
final Enumeration<NetworkInterface> ifaces = NetworkInterface.getNetworkInterfaces();
|
||||||
|
while(ifaces.hasMoreElements()){
|
||||||
|
final NetworkInterface iface = ifaces.nextElement();
|
||||||
|
if (!iface.isUp() || iface.isLoopback() || iface.isVirtual()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for(InterfaceAddress addr : iface.getInterfaceAddresses()){
|
||||||
|
final InetAddress inetAddr = addr.getAddress();
|
||||||
|
ifaceAddresses.add(inetAddr.getHostAddress());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.i(this.getClass().getName(), "Listening on port " + port + ". Local addresses: " + join(", ", ifaceAddresses));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void vpcdAccept() throws IOException {
|
||||||
|
if(listenSocket == null){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (socket != null){
|
||||||
|
return; // Already accepted, only one client allowed
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.i(this.getClass().getName(),"Waiting for connections...");
|
||||||
|
while(!isCancelled()) {
|
||||||
|
listenSocket.setSoTimeout(1000);
|
||||||
|
try {
|
||||||
|
socket = listenSocket.accept();
|
||||||
|
} catch (SocketTimeoutException ignored){}
|
||||||
|
if (socket != null){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.i(this.getClass().getName(),"Connected, " + socket.getInetAddress());
|
||||||
|
listenSocket.setSoTimeout(0);
|
||||||
|
outputStream = socket.getOutputStream();
|
||||||
|
inputStream = socket.getInputStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void vpcdCloseClient(){
|
||||||
|
try {
|
||||||
|
outputStream.close();
|
||||||
|
} catch (IOException ignored) { }
|
||||||
|
try {
|
||||||
|
inputStream.close();
|
||||||
|
} catch (IOException ignored) { }
|
||||||
|
try {
|
||||||
|
socket.close();
|
||||||
|
} catch (IOException ignored) { }
|
||||||
|
outputStream = null;
|
||||||
|
inputStream = null;
|
||||||
|
socket = null;
|
||||||
|
}
|
||||||
|
|
||||||
private void vpcdConnect(String hostname, int port) throws IOException {
|
private void vpcdConnect(String hostname, int port) throws IOException {
|
||||||
|
listenSocket = null;
|
||||||
socket = new Socket(InetAddress.getByName(hostname), port);
|
socket = new Socket(InetAddress.getByName(hostname), port);
|
||||||
outputStream = socket.getOutputStream();
|
outputStream = socket.getOutputStream();
|
||||||
inputStream = socket.getInputStream();
|
inputStream = socket.getInputStream();
|
||||||
@@ -182,5 +275,25 @@ class VPCDWorker extends AsyncTask<VPCDWorker.VPCDWorkerParams, Void, Void> {
|
|||||||
socket.close();
|
socket.close();
|
||||||
Log.i(this.getClass().getName(), "Disconnected from VPCD");
|
Log.i(this.getClass().getName(), "Disconnected from VPCD");
|
||||||
}
|
}
|
||||||
|
if (listenSocket != null) {
|
||||||
|
Log.i(this.getClass().getName(), "Closing listening socket");
|
||||||
|
listenSocket.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Usage of API level 24+ would allow streams(), join can be removed.
|
||||||
|
*/
|
||||||
|
private static String join(String separator, List<String> input) {
|
||||||
|
if (input == null || input.size() <= 0) return "";
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (int i = 0; i < input.size(); i++) {
|
||||||
|
sb.append(input.get(i));
|
||||||
|
if (i != input.size() - 1) {
|
||||||
|
sb.append(separator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@@ -7,14 +7,14 @@
|
|||||||
android:fitsSystemWindows="true"
|
android:fitsSystemWindows="true"
|
||||||
tools:context="com.vsmartcard.remotesmartcardreader.app.MainActivity">
|
tools:context="com.vsmartcard.remotesmartcardreader.app.MainActivity">
|
||||||
|
|
||||||
<android.support.design.widget.AppBarLayout
|
<com.google.android.material.appbar.AppBarLayout
|
||||||
android:id="@+id/app_bar"
|
android:id="@+id/app_bar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="@dimen/app_bar_height"
|
android:layout_height="@dimen/app_bar_height"
|
||||||
android:fitsSystemWindows="true"
|
android:fitsSystemWindows="true"
|
||||||
android:theme="@style/AppTheme.AppBarOverlay">
|
android:theme="@style/AppTheme.AppBarOverlay">
|
||||||
|
|
||||||
<android.support.design.widget.CollapsingToolbarLayout
|
<com.google.android.material.appbar.CollapsingToolbarLayout
|
||||||
android:id="@+id/toolbar_layout"
|
android:id="@+id/toolbar_layout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
@@ -22,19 +22,19 @@
|
|||||||
app:contentScrim="?attr/colorPrimary"
|
app:contentScrim="?attr/colorPrimary"
|
||||||
app:layout_scrollFlags="scroll|exitUntilCollapsed">
|
app:layout_scrollFlags="scroll|exitUntilCollapsed">
|
||||||
|
|
||||||
<android.support.v7.widget.Toolbar
|
<androidx.appcompat.widget.Toolbar
|
||||||
android:id="@+id/toolbar"
|
android:id="@+id/toolbar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="?attr/actionBarSize"
|
android:layout_height="?attr/actionBarSize"
|
||||||
app:layout_collapseMode="pin"
|
app:layout_collapseMode="pin"
|
||||||
app:popupTheme="@style/AppTheme.PopupOverlay" />
|
app:popupTheme="@style/AppTheme.PopupOverlay" />
|
||||||
|
|
||||||
</android.support.design.widget.CollapsingToolbarLayout>
|
</com.google.android.material.appbar.CollapsingToolbarLayout>
|
||||||
</android.support.design.widget.AppBarLayout>
|
</com.google.android.material.appbar.AppBarLayout>
|
||||||
|
|
||||||
<include layout="@layout/content_main" />
|
<include layout="@layout/content_main" />
|
||||||
|
|
||||||
<android.support.design.widget.FloatingActionButton
|
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
android:id="@+id/fab"
|
android:id="@+id/fab"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@@ -43,4 +43,4 @@
|
|||||||
app:layout_anchor="@id/app_bar"
|
app:layout_anchor="@id/app_bar"
|
||||||
app:layout_anchorGravity="bottom|end" />
|
app:layout_anchorGravity="bottom|end" />
|
||||||
|
|
||||||
</android.support.design.widget.CoordinatorLayout>
|
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
@@ -9,11 +9,10 @@
|
|||||||
tools:showIn="@layout/activity_main">
|
tools:showIn="@layout/activity_main">
|
||||||
|
|
||||||
<fragment
|
<fragment
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:name="com.vsmartcard.remotesmartcardreader.app.MyLogFragment"
|
android:name="com.vsmartcard.remotesmartcardreader.app.MyLogFragment"
|
||||||
android:id="@+id/log_fragment"
|
android:id="@+id/log_fragment"
|
||||||
android:layout_margin="@dimen/text_margin"
|
android:layout_margin="@dimen/text_margin"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent" />
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
</android.support.v4.widget.NestedScrollView>
|
</androidx.core.widget.NestedScrollView>
|
||||||
@@ -13,6 +13,9 @@
|
|||||||
<item>500 milliseconds</item>
|
<item>500 milliseconds</item>
|
||||||
<item>1 second</item>
|
<item>1 second</item>
|
||||||
<item>2 seconds</item>
|
<item>2 seconds</item>
|
||||||
|
<item>4 seconds</item>
|
||||||
|
<item>10 seconds</item>
|
||||||
|
<item>30 seconds</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string-array name="intDelays">
|
<string-array name="intDelays">
|
||||||
<item>125</item>
|
<item>125</item>
|
||||||
@@ -20,6 +23,9 @@
|
|||||||
<item>500</item>
|
<item>500</item>
|
||||||
<item>1000</item>
|
<item>1000</item>
|
||||||
<item>2000</item>
|
<item>2000</item>
|
||||||
|
<item>4000</item>
|
||||||
|
<item>10000</item>
|
||||||
|
<item>30000</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string-array name="strTimeouts">
|
<string-array name="strTimeouts">
|
||||||
<item>125 milliseconds</item>
|
<item>125 milliseconds</item>
|
||||||
@@ -29,6 +35,8 @@
|
|||||||
<item>2 seconds</item>
|
<item>2 seconds</item>
|
||||||
<item>3 seconds</item>
|
<item>3 seconds</item>
|
||||||
<item>4 seconds</item>
|
<item>4 seconds</item>
|
||||||
|
<item>10 seconds</item>
|
||||||
|
<item>30 seconds</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
<string-array name="intTimeouts">
|
<string-array name="intTimeouts">
|
||||||
<item>125</item>
|
<item>125</item>
|
||||||
@@ -38,6 +46,8 @@
|
|||||||
<item>2000</item>
|
<item>2000</item>
|
||||||
<item>3000</item>
|
<item>3000</item>
|
||||||
<item>4000</item>
|
<item>4000</item>
|
||||||
|
<item>10000</item>
|
||||||
|
<item>30000</item>
|
||||||
</string-array>
|
</string-array>
|
||||||
|
|
||||||
<string name="action_settings">Settings</string>
|
<string name="action_settings">Settings</string>
|
||||||
@@ -45,5 +55,6 @@
|
|||||||
<string name="action_delete">Clear Log</string>
|
<string name="action_delete">Clear Log</string>
|
||||||
|
|
||||||
<string name="title_activity_settings">Settings</string>
|
<string name="title_activity_settings">Settings</string>
|
||||||
|
<string name="hint_vpcd_listen">Listen for connections</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -32,6 +32,12 @@
|
|||||||
android:inputType="number"
|
android:inputType="number"
|
||||||
android:hint="Default: 35963" />
|
android:hint="Default: 35963" />
|
||||||
|
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:key="listen"
|
||||||
|
android:defaultValue="false"
|
||||||
|
android:title="@string/hint_vpcd_listen"
|
||||||
|
android:hint="Default: false" />
|
||||||
|
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
<PreferenceCategory
|
<PreferenceCategory
|
||||||
|
|||||||
@@ -2,10 +2,11 @@
|
|||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
repositories {
|
repositories {
|
||||||
|
google()
|
||||||
jcenter()
|
jcenter()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:1.5.0'
|
classpath 'com.android.tools.build:gradle:4.1.2'
|
||||||
|
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
// in the individual module build.gradle files
|
// in the individual module build.gradle files
|
||||||
@@ -15,6 +16,7 @@ buildscript {
|
|||||||
allprojects {
|
allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
jcenter()
|
jcenter()
|
||||||
|
google()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,3 +16,5 @@
|
|||||||
# This option should only be used with decoupled projects. More details, visit
|
# This option should only be used with decoupled projects. More details, visit
|
||||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||||
# org.gradle.parallel=true
|
# org.gradle.parallel=true
|
||||||
|
android.enableJetifier=true
|
||||||
|
android.useAndroidX=true
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
#Wed Oct 21 11:34:03 PDT 2015
|
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-6.6-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.8-all.zip
|
|
||||||
|
|||||||
Reference in New Issue
Block a user