Commit fd13fca2 authored by dimitrisCBR's avatar dimitrisCBR
Browse files

Update public demo with v1.4.0 and update UI

parent 83b68550
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
android {
compileSdkVersion 31
......@@ -9,13 +10,12 @@ android {
applicationId "com.futurae.futuraedemo"
minSdkVersion 21
targetSdkVersion 31
versionCode 6
versionName "1.0.0"
versionCode 7
versionName "1.0.1"
resConfigs "en", "el"
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
}
// Latest Butterknife requires Java 8.
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
......@@ -23,14 +23,24 @@ android {
buildTypes {
debug {
minifyEnabled false
signingConfig signingConfigs.debug
}
release {
minifyEnabled true
proguardFile 'proguard/futurae.pro'
proguardFile getDefaultProguardFile('proguard-android.txt')
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.debug
}
}
buildFeatures {
viewBinding true
}
}
repositories {
......@@ -45,36 +55,40 @@ repositories {
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation "androidx.core:core-ktx:1.6.0"
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation "androidx.core:core-ktx:1.7.0"
implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
implementation 'com.google.android.material:material:1.5.0'
implementation 'com.google.android.gms:play-services-vision:20.1.3'
implementation 'com.jakewharton:butterknife:10.2.3'
annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.3'
testImplementation 'junit:junit:4.13'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
implementation platform('com.google.firebase:firebase-bom:29.0.1')
implementation 'com.google.firebase:firebase-messaging'
implementation 'com.jakewharton.timber:timber:5.0.1'
implementation 'com.futurae.sdk:futuraekit:1.4.0'
// Use these if you are NOT using Maven
// implementation 'com.squareup.retrofit2:retrofit:2.4.0'
// Use these if you are NOT using Maven
// implementation 'com.squareup.retrofit2:retrofit:2.9.0'
// implementation 'com.squareup.retrofit2:converter-moshi:2.4.0'
// implementation 'com.squareup.moshi:moshi-adapters:1.6.0'
// implementation 'com.squareup.okhttp3:okhttp:3.11.0'
// implementation 'com.squareup.okhttp3:logging-interceptor:3.11.0'
// implementation 'com.squareup.okhttp3:okhttp:4.9.1'
// implementation 'com.squareup.okhttp3:logging-interceptor:4.9.1'
// implementation 'com.github.nisrulz:easydeviceinfo-base:2.4.1'
// implementation 'com.google.code.gson:gson:2.8.6'
// implementation files('../../futuraekit.aar')
// implementation 'com.google.code.gson:gson:2.8.9'
// implementation platform('com.google.firebase:firebase-bom:29.0.1')
// implementation 'com.google.firebase:firebase-messaging'
// implementation 'com.google.firebase:firebase-iid'
// implementation "androidx.room:room-runtime:2.4.1"
// implementation "androidx.room:room-ktx:2.4.1"
// kapt "androidx.room:room-compiler:2.4.1"
// implementation "androidx.work:work-runtime-ktx:2.7.1"
// implementation files('libs/futuraekit.aar')
}
......
-keep public enum com.futurae.sdk.model.Account$** {
**[] $VALUES;
public *;
}
-keep class com.futurae.sdk.DeviceInfo {
*;
}
-keep public class com.futurae.sdk.model.AccountsMigrationResource$* {
*;
}
\ No newline at end of file
......@@ -6,6 +6,9 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
......@@ -34,7 +37,7 @@
</intent-filter>
</service>
<activity android:name=".ui.MainActivity"
<activity android:name=".ui.HomeActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
......
......@@ -15,7 +15,7 @@ public class AppMain extends Application {
super.onCreate();
Timber.plant(new Timber.DebugTree());
FuturaeClient.launch(this, (Kit)null);
boolean adaptiveEnabled = false;
FuturaeClient.launch(this, adaptiveEnabled, (Kit)null);
}
}
......@@ -18,289 +18,279 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.Camera;
import android.os.Bundle;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.widget.Toast;
import butterknife.BindView;
import butterknife.ButterKnife;
import androidx.appcompat.app.AppCompatActivity;
import com.futurae.futuraedemo.R;
import com.futurae.futuraedemo.databinding.ActivityQrcodeBinding;
import com.futurae.futuraedemo.ui.camera.BarcodeGraphic;
import com.futurae.futuraedemo.ui.camera.BarcodeTrackerFactory;
import com.futurae.futuraedemo.ui.camera.CameraSource;
import com.futurae.futuraedemo.ui.camera.CameraSourcePreview;
import com.futurae.futuraedemo.ui.camera.CaptureGestureListener;
import com.futurae.futuraedemo.ui.camera.GraphicOverlay;
import com.futurae.futuraedemo.ui.camera.QRCapturable;
import com.futurae.futuraedemo.ui.camera.ScaleListener;
import com.google.android.gms.vision.MultiProcessor;
import com.google.android.gms.vision.barcode.Barcode;
import com.google.android.gms.vision.barcode.BarcodeDetector;
import java.io.IOException;
public class FTRQRCodeActivity extends AppCompatActivity implements QRCapturable {
// constants
private static final String TAG = FTRQRCodeActivity.class.getSimpleName();
public static final int RESULT_BARCODE = 10000;
public static final int RESULT_BARCODE_AUTH = 20000;
public static final int RESULT_BARCODE_OFFLINE = 30000;
public static final int RESULT_BARCODE_GENERIC = 40000;
public static final String PARAM_BARCODE = "ftr_barcode";
public static final String PARAM_AUTOFOCUS = "ftr_autofocus";
public static final String PARAM_USE_FLASH = "ftr_use_flash";
// constants
private static final String TAG = FTRQRCodeActivity.class.getSimpleName();
// Barcode scanner settings
private static final int SCANNER_BARCODE_FORMAT = Barcode.QR_CODE;
public static final int RESULT_BARCODE = 10000;
public static final int RESULT_BARCODE_AUTH = 20000;
public static final int RESULT_BARCODE_OFFLINE = 30000;
public static final int RESULT_BARCODE_GENERIC = 40000;
// attributes
private CameraSource cameraSource;
private GestureDetector gestureDetector;
private ScaleGestureDetector scaleGestureDetector;
public static final String PARAM_BARCODE = "ftr_barcode";
public static final String PARAM_AUTOFOCUS = "ftr_autofocus";
public static final String PARAM_USE_FLASH = "ftr_use_flash";
@BindView(R.id.qrcode_preview)
protected CameraSourcePreview preview;
// Barcode scanner settings
private static final int SCANNER_BARCODE_FORMAT = Barcode.QR_CODE;
@BindView(R.id.qrcode_overlay)
protected GraphicOverlay<BarcodeGraphic> graphicOverlay;
// attributes
private CameraSource cameraSource;
private GestureDetector gestureDetector;
private ScaleGestureDetector scaleGestureDetector;
// static public
public static Intent getIntent(Context context) {
private ActivityQrcodeBinding binding;
return getIntent(context, false, false);
}
// static public
public static Intent getIntent(Context context) {
public static Intent getIntent(Context context, boolean autofocus, boolean useFlash) {
return getIntent(context, false, false);
}
Intent intent = new Intent(context, FTRQRCodeActivity.class);
intent.putExtra(PARAM_AUTOFOCUS, autofocus);
intent.putExtra(PARAM_USE_FLASH, useFlash);
public static Intent getIntent(Context context, boolean autofocus, boolean useFlash) {
return intent;
}
// overrides
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_qrcode);
ButterKnife.bind(this);
ActionBar actionBar = getSupportActionBar();
actionBar.setTitle(R.string.qrcode_title);
actionBar.setDisplayHomeAsUpEnabled(true);
Intent intent = getIntent();
// read parameters from the intent used to launch the activity.
boolean autoFocus = intent.getBooleanExtra(PARAM_AUTOFOCUS, false);
boolean useFlash = intent.getBooleanExtra(PARAM_USE_FLASH, false);
createCameraSource(autoFocus, useFlash);
gestureDetector = new GestureDetector(this, new CaptureGestureListener(this));
scaleGestureDetector = new ScaleGestureDetector(this, new ScaleListener(cameraSource));
}
@Override
protected void onResume() {
super.onResume();
startCameraSource();
}
@Override
protected void onPause() {
super.onPause();
if (preview != null) {
preview.stop();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (preview != null) {
preview.release();
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public boolean onTouchEvent(MotionEvent e) {
boolean b = scaleGestureDetector.onTouchEvent(e);
boolean c = gestureDetector.onTouchEvent(e);
return b || c || super.onTouchEvent(e);
}
// handlers - QRCapturable
/**
* Creates and starts the camera. Note that this uses a higher resolution in comparison
* to other detection examples to enable the barcode detector to detect small barcodes
* at long distances.
* <p/>
* Suppressing InlinedApi since there is a check that the minimum version is met before using
* the constant.
*/
@Override
@SuppressLint("InlinedApi")
public void createCameraSource(boolean autoFocus, boolean useFlash) {
// A barcode detector is created to track barcodes. An associated multi-processor instance
// is set to receive the barcode detection results, track the barcodes, and maintain
// graphics for each barcode on screen. The factory is used by the multi-processor to
// create a separate tracker instance for each barcode.
// NOTE: We pass the activity itself as an extra argument so that the tracker object
// can call the doCaptureBarcode to automatically trigger the capture process, instead
// of waiting the user to manually tap on the screen
BarcodeDetector barcodeDetector = new BarcodeDetector.Builder(this)
.setBarcodeFormats(SCANNER_BARCODE_FORMAT).build();
BarcodeTrackerFactory barcodeFactory = new BarcodeTrackerFactory(graphicOverlay, this);
barcodeDetector.setProcessor(new MultiProcessor.Builder<>(barcodeFactory).build());
if (!barcodeDetector.isOperational()) {
// Note: The first time that an app using the barcode or face API is installed on a
// device, GMS will download a native libraries to the device in order to do detection.
// Usually this completes before the app is run for the first time. But if that
// download has not yet completed, then the above call will not detect any barcodes
// and/or faces.
//
// isOperational() can be used to check if the required native libraries are currently
// available. The detectors will automatically become operational once the library
// downloads complete on device.
Log.w(TAG, "Detector dependencies are not yet available.");
// Check for low storage. If there is low storage, the native library will not be
// downloaded, so detection will not become operational.
IntentFilter lowstorageFilter = new IntentFilter(Intent.ACTION_DEVICE_STORAGE_LOW);
boolean hasLowStorage = registerReceiver(null, lowstorageFilter) != null;
if (hasLowStorage) {
Toast.makeText(this, R.string.error_low_storage, Toast.LENGTH_LONG).show();
Log.w(TAG, getString(R.string.error_low_storage));
}
}
// Creates and starts the camera. Note that this uses a higher resolution in comparison
// to other detection examples to enable the barcode detector to detect small barcodes
// at long distances.
CameraSource.Builder builder = new CameraSource.Builder(this,
barcodeDetector)
.setFacing(CameraSource.CAMERA_FACING_BACK)
.setRequestedPreviewSize(1600, 1024)
.setRequestedFps(15.0f);
// make sure that auto focus is an available option
this.cameraSource = builder
.setFlashMode(useFlash ? Camera.Parameters.FLASH_MODE_TORCH : null)
.setFocusMode(autoFocus ? Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE : null)
.build();
}
/**
* doCaptureBarcode is called by the respective BarcodeGraphicTracker
* to capture the first barcode detected and
* return it to the caller.
*
* @return true if the activity is ending.
*/
@Override
public boolean doCaptureBarcode() {
BarcodeGraphic graphic = graphicOverlay.getFirstGraphic();
if (graphic == null) {
Log.d(TAG, "no barcode detected");
return false;
}
Barcode barcode = graphic.getBarcode();
if (barcode == null) {
Log.d(TAG, "barcode data is null");
return false;
}
finishActivity(barcode);
return true;
}
/**
* onTap is called to capture the oldest barcode currently detected and
* return it to the caller.
*
* @param rawX - the raw position of the tap
* @param rawY - the raw position of the tap.
* @return true if the activity is ending.
*/
@Override
public boolean onTap(float rawX, float rawY) {
BarcodeGraphic graphic = graphicOverlay.getFirstGraphic();
if (graphic == null) {
Log.d(TAG, "no barcode detected");
return false;
}
Barcode barcode = graphic.getBarcode();
if (barcode == null) {
Log.d(TAG, "barcode data is null");
return false;
}
finishActivity(barcode);
return true;
}
/**
* Starts or restarts the camera source, if it exists. If the camera source doesn't exist yet
* (e.g., because onResume was called before the camera source was created), this will be called
* again when the camera source is created.
*/
@Override
public void startCameraSource() throws SecurityException {
if (cameraSource == null) {
return;
}
try {
preview.start(cameraSource, graphicOverlay);
} catch (IOException e) {
Log.e(TAG, "Unable to start camera source.", e);
cameraSource.release();
cameraSource = null;
}
}
// private
private void finishActivity(Barcode barcode) {
Intent data = new Intent();
data.putExtra(PARAM_BARCODE, barcode);
setResult(Activity.RESULT_OK, data);
finish();
}
Intent intent = new Intent(context, FTRQRCodeActivity.class);
intent.putExtra(PARAM_AUTOFOCUS, autofocus);
intent.putExtra(PARAM_USE_FLASH, useFlash);
return intent;
}
// overrides
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityQrcodeBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
Intent intent = getIntent();
// read parameters from the intent used to launch the activity.
boolean autoFocus = intent.getBooleanExtra(PARAM_AUTOFOCUS, false);
boolean useFlash = intent.getBooleanExtra(PARAM_USE_FLASH, false);
createCameraSource(autoFocus, useFlash);
gestureDetector = new GestureDetector(this, new CaptureGestureListener(this));
scaleGestureDetector = new ScaleGestureDetector(this, new ScaleListener(cameraSource));
}
@Override
protected void onResume() {
super.onResume();
startCameraSource();
}
@Override
protected void onPause() {
super.onPause();
if (binding.qrcodePreview != null) {
binding.qrcodePreview.stop();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (binding.qrcodePreview != null) {
binding.qrcodePreview.release();
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public boolean onTouchEvent(MotionEvent e) {
boolean b = scaleGestureDetector.onTouchEvent(e);
boolean c = gestureDetector.onTouchEvent(e);
return b || c || super.onTouchEvent(e);
}
// handlers - QRCapturable
/**
* Creates and starts the camera. Note that this uses a higher resolution in comparison
* to other detection examples to enable the barcode detector to detect small barcodes
* at long distances.
* <p/>
* Suppressing InlinedApi since there is a check that the minimum version is met before using
* the constant.
*/
@Override
@SuppressLint("InlinedApi")
public void createCameraSource(boolean autoFocus, boolean useFlash) {
// A barcode detector is created to track barcodes. An associated multi-processor instance
// is set to receive the barcode detection results, track the barcodes, and maintain
// graphics for each barcode on screen. The factory is used by the multi-processor to
// create a separate tracker instance for each barcode.
// NOTE: We pass the activity itself as an extra argument so that the tracker object
// can call the doCaptureBarcode to automatically trigger the capture process, instead
// of waiting the user to manually tap on the screen
BarcodeDetector barcodeDetector = new BarcodeDetector.Builder(this)
.setBarcodeFormats(SCANNER_BARCODE_FORMAT).build();
BarcodeTrackerFactory barcodeFactory = new BarcodeTrackerFactory(binding.qrcodeOverlay, this);
barcodeDetector.setProcessor(new MultiProcessor.Builder<>(barcodeFactory).build());
if (!barcodeDetector.isOperational()) {
// Note: The first time that an app using the barcode or face API is installed on a
// device, GMS will download a native libraries to the device in order to do detection.
// Usually this completes before the app is run for the first time. But if that
// download has not yet completed, then the above call will not detect any barcodes
// and/or faces.
//
// isOperational() can be used to check if the required native libraries are currently
// available. The detectors will automatically become operational once the library
// downloads complete on device.
Log.w(TAG, "Detector dependencies are not yet available.");
// Check for low storage. If there is low storage, the native library will not be
// downloaded, so detection will not become operational.