Skip to content

Commit

Permalink
Add ZXing barcode library for open variant
Browse files Browse the repository at this point in the history
  • Loading branch information
niknetniko committed May 25, 2022
1 parent 4f8dcb3 commit 67e6b75
Show file tree
Hide file tree
Showing 9 changed files with 194 additions and 33 deletions.
1 change: 1 addition & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ dependencies {

// Dependencies for open version.
openImplementation 'org.osmdroid:osmdroid-android:6.1.11'
openImplementation 'com.journeyapps:zxing-android-embedded:4.3.0'

if (props.getProperty("hydra.debug.leaks").toBoolean()) {
logger.info("Leak tracking enabled...")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,10 @@
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import androidx.annotation.Nullable;

import androidx.activity.result.ActivityResultLauncher;

import java.util.List;
import java.util.function.Consumer;

import be.ugent.zeus.hydra.common.request.Result;

/**
* Ask some service to scan for barcodes.
*
Expand All @@ -41,22 +37,33 @@
* @author Niko Strijbol
*/
public interface BarcodeScanner {

String RESULT_BARCODE = "activity_result_barcode";
String RESULT_ERROR_MESSAGE = "activity_result_error_message";

/**
* If this barcode scanner needs to launch an activity or not.
*/
boolean needsActivity();


/**
* Get an activity to launch, which will give the barcode
* as a result.
*/
Intent getActivityIntent(Activity activity);

/**
* @return Get the request code to use when launching an activity.
*/
int getRequestCode();

/**
* Get the barcode from the activity launch from the intent from
* {@link #getActivityIntent(Activity)}.
*
* @param data The result data.
*
* @return The barcode, or null.
*/
@Nullable
String interpretActivityResult(Intent data, int resultCode);

/**
* Get a barcode without activity.
*
Expand Down
8 changes: 7 additions & 1 deletion app/src/main/java/be/ugent/zeus/hydra/wpi/WpiActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public void onPageSelected(int position) {
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(ActivityWpiBinding::inflate);
setTitle(AccountManager.getUsername(this));
setTitle();

pageAdapter = new WpiPagerAdapter(this);
ViewPager2 viewPager = binding.viewPager;
Expand Down Expand Up @@ -119,8 +119,13 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {
String balance = currencyFormatter.format(user.getBalanceDecimal());
String orders = decimalFormatter.format(user.getOrders());
binding.profileDescription.setText(getString(R.string.wpi_user_description, balance, orders));
setTitle();
}));
}

private void setTitle() {
setTitle(AccountManager.getUsername(this));
}

@Override
protected void onStart() {
Expand Down Expand Up @@ -168,6 +173,7 @@ protected void onActivityResult(int requestCode, int resultCode, @Nullable Inten
if (requestCode == ACTIVITY_DO_REFRESH && resultCode == Activity.RESULT_OK) {
Log.i(TAG, "onActivityResult: refreshing for result...");
combinedUserViewModel.onRefresh();

if (pageAdapter != null) {
pageAdapter.notifyDataSetChanged();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

package be.ugent.zeus.hydra.wpi.tap.cart;

import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.*;
Expand Down Expand Up @@ -79,24 +80,12 @@ protected void onCreate(@Nullable Bundle savedInstanceState) {

binding.scanAdd.setOnClickListener(v -> {
BarcodeScanner scanner = Manager.getScanner();
scanner.getBarcode(CartActivity.this, s -> {
if (viewModel.getLastCart() == null) {
// There is no cart yet.
Log.w(TAG, "onCreate: cart not ready yet...");
Snackbar.make(binding.getRoot(), "Product niet gevonden.", Snackbar.LENGTH_LONG)
.show();
return;
}
Product foundProduct = viewModel.getLastCart().getProductFor(s);
if (foundProduct == null) {
Log.w(TAG, "onCreate: barcode niet gevonden in map " + s);
Snackbar.make(binding.getRoot(), "Product niet gevonden.", Snackbar.LENGTH_LONG)
.show();
return;
}
Cart newCart = viewModel.getLastCart().addProduct(foundProduct);
saveCart(newCart, false);
}, this::onError);
if (scanner.needsActivity()) {
Intent intent = scanner.getActivityIntent(CartActivity.this);
startActivityForResult(intent, scanner.getRequestCode());
} else {
scanner.getBarcode(CartActivity.this, this::onBarcodeScan, this::onError);
}
});
binding.manualAdd.setOnClickListener(v -> {
ProductPickerDialogFragment productPicker = new ProductPickerDialogFragment();
Expand Down Expand Up @@ -202,6 +191,39 @@ private void onError(Throwable throwable) {
.setAction(getString(R.string.action_again), v -> viewModel.onRefresh())
.show();
}

private void onBarcodeScan(String barcode) {
if (barcode == null) {
return;
}
if (viewModel.getLastCart() == null) {
// There is no cart yet.
Log.w(TAG, "onCreate: cart not ready yet...");
Snackbar.make(binding.getRoot(), "Product niet gevonden.", Snackbar.LENGTH_LONG)
.show();
return;
}
Product foundProduct = viewModel.getLastCart().getProductFor(barcode);
if (foundProduct == null) {
Log.w(TAG, "onCreate: barcode niet gevonden in map " + barcode);
Snackbar.make(binding.getRoot(), "Product niet gevonden.", Snackbar.LENGTH_LONG)
.show();
return;
}
Cart newCart = viewModel.getLastCart().addProduct(foundProduct);
saveCart(newCart, false);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
if (requestCode == Manager.getScanner().getRequestCode()) {
// Handle it.
String barcode = Manager.getScanner().interpretActivityResult(data, resultCode);
onBarcodeScan(barcode);
return;
}
super.onActivityResult(requestCode, resultCode, data);
}

private void updateCartSummary(Cart cart) {
BigDecimal totalAmount = BigDecimal.ZERO;
Expand Down
4 changes: 2 additions & 2 deletions app/src/main/res/layout/activity_wpi.xml
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@
android:layout_margin="16dp"
app:icon="@drawable/ic_bank_transfer"
android:text="@string/wpi_start_transfer"
app:layout_behavior=".common.ui.ShrinkExtendedFabBehavior"
app:layout_behavior="be.ugent.zeus.hydra.common.ui.ShrinkExtendedFabBehavior"
tools:ignore="ContentDescription" />

<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
Expand All @@ -118,7 +118,7 @@
android:layout_margin="16dp"
android:text="@string/wpi_start_cart"
app:icon="@drawable/ic_shopping_cart"
app:layout_behavior=".common.ui.ShrinkExtendedFabBehavior"
app:layout_behavior="be.ugent.zeus.hydra.common.ui.ShrinkExtendedFabBehavior"
tools:ignore="ContentDescription" />


Expand Down
12 changes: 10 additions & 2 deletions app/src/open/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,17 @@
-->

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="be.ugent.zeus.hydra">

<!-- Permissions for OpenStreetMap -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
tools:ignore="CoarseFineLocation" />

<application tools:ignore="MissingApplicationIcon">
<activity
android:name="com.journeyapps.barcodescanner.CaptureActivity"
android:screenOrientation="fullSensor"
tools:replace="screenOrientation" />
</application>
</manifest>
37 changes: 37 additions & 0 deletions app/src/open/java/be/ugent/zeus/hydra/common/barcode/Manager.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright (c) 2022 Niko Strijbol
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

package be.ugent.zeus.hydra.common.barcode;

import be.ugent.zeus.hydra.common.scanner.BarcodeScanner;

/**
* Get a barcode scanner.
*
* @author Niko Strijbol
*/
public class Manager {

public static BarcodeScanner getScanner() {
return new OpenBarcodeScanner();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/*
* Copyright (c) 2022 Niko Strijbol
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

package be.ugent.zeus.hydra.common.barcode;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import androidx.annotation.Nullable;

import java.util.function.Consumer;

import be.ugent.zeus.hydra.common.scanner.BarcodeScanner;
import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;

/**
* @author Niko Strijbol
*/
class OpenBarcodeScanner implements BarcodeScanner {

@Override
public boolean needsActivity() {
return true;
}

@Override
public Intent getActivityIntent(Activity activity) {
IntentIntegrator integrator = new IntentIntegrator(activity);
integrator.setDesiredBarcodeFormats(IntentIntegrator.PRODUCT_CODE_TYPES);
return integrator.createScanIntent();
}

public int getRequestCode() {
return IntentIntegrator.REQUEST_CODE;
}

@Override
@Nullable
public String interpretActivityResult(Intent data, int resultCode) {
IntentResult result = IntentIntegrator.parseActivityResult(resultCode, data);
return result.getContents();
}

@Override
public void getBarcode(Context context, Consumer<String> onSuccess, Consumer<Exception> onError) {
throw new UnsupportedOperationException("This Barcode Scanner requires an activity.");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import android.content.Intent;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import java.util.Objects;
import java.util.concurrent.ExecutionException;
Expand Down Expand Up @@ -58,6 +59,17 @@ public Intent getActivityIntent(Activity activity) {
throw new UnsupportedOperationException("This Barcode Scanner does not use an activity.");
}

@Override
public int getRequestCode() {
throw new UnsupportedOperationException("This Barcode Scanner does not use an activity.");
}

@Nullable
@Override
public String interpretActivityResult(Intent data, int resultCode) {
throw new UnsupportedOperationException("This Barcode Scanner does not use an activity.");
}

@Override
public void getBarcode(Context context, Consumer<String> onSuccess, Consumer<Exception> onError) {
GmsBarcodeScannerOptions options = new GmsBarcodeScannerOptions.Builder()
Expand Down

0 comments on commit 67e6b75

Please sign in to comment.