Compare commits

..

66 Commits

Author SHA1 Message Date
Ralf Kistner d09b7c76c3 Merge pull request #726 from yuchan2215/patch-1
Fix Typo
2022-10-21 10:40:04 +02:00
yuchan2215 3a2db7ffc6 Fix Typo 2022-10-21 12:04:14 +09:00
Ralf Kistner 2a65a6c973 Merge pull request #708 from amirrudd/patch-1
Remove duplicate in ReadMe
2022-06-16 15:14:09 +02:00
Amir Rudd 3c77f1d6c8 Remove duplicate in ReadMe 2022-06-16 15:24:55 +04:30
Ralf Kistner b6c6421dd5 Merge pull request #696 from saifkhichi96/patch-1
Added ability to customize colors in barcodes generated with BarcodeEncoder.
2022-02-21 09:58:04 +02:00
Muhammad Saif Ullah Khan 8173d4a8b2 Added color customization instructions in README 2022-02-08 18:27:41 +01:00
Muhammad Saif Ullah Khan 8fdbbbef5e Support custom colors in BarcodeEncoder.java. 2022-02-08 18:17:58 +01:00
Conrad Hofmeyr 2324a5403e Update README.md 2021-12-22 12:29:22 -07:00
Ralf Kistner c752130405 Merge pull request #673 from juliansteenbakker/make-initializeAttributes-public
imp: make initializeAttributes public
2021-11-17 10:32:59 +02:00
juliansteenbakker 1c27c8fe2d imp: make initializeAttributes public 2021-11-17 08:52:37 +01:00
Ralf Kistner aa129af542 Merge pull request #666 from journeyapps/update-readme-sdk-version
Update notes on minSdkVersion
2021-10-26 16:19:21 +02:00
Ralf Kistner 90b5db5fcd Update notes on minSdkVersion. 2021-10-26 10:49:40 +02:00
Ralf Kistner 24d02945fe Merge pull request #665 from journeyapps/fixes
v4.3.0
2021-10-25 15:54:10 +02:00
Ralf Kistner 6ccf3a9d1a Fix lint report location. 2021-10-25 15:46:32 +02:00
Ralf Kistner 23f29e5a56 Ignore lint error. 2021-10-25 15:41:21 +02:00
Ralf Kistner 1a8d949325 Tweaks. 2021-10-25 15:37:09 +02:00
Ralf Kistner f1554b7478 Use GitHub Actions. 2021-10-25 15:32:46 +02:00
Ralf Kistner cc12c103e0 v4.3.0 and cleanup. 2021-10-25 15:22:01 +02:00
Ralf Kistner a13ce2b161 Cleanup. 2021-10-25 15:06:58 +02:00
Ralf Kistner 0c97cf70cc ScanOptions and ScanContract. 2021-10-25 14:57:43 +02:00
Ralf Kistner 9beeac7960 minSdkVersion 19. Multidex and desugaring. 2021-10-25 13:53:35 +02:00
Ralf Kistner cc34502f13 Smaller libs. 2021-10-25 13:53:25 +02:00
Ralf Kistner 2221621de9 Some cleanup. 2021-10-25 13:03:59 +02:00
Ralf Kistner 4d4c5a2c4e Disable jetifier. 2021-10-25 13:03:51 +02:00
Ralf Kistner 65d2716c71 Upgrade tooling. 2021-10-25 13:01:17 +02:00
Ralf Kistner 7fd1ab8794 Fix lint issues. 2021-10-25 13:00:40 +02:00
Ralf Kistner 630e3cc0f8 Fix API 19 crash. 2021-10-25 13:00:19 +02:00
Ralf Kistner 40260272fc Merge pull request #617 from journeyapps/maven-central
Maven Central
2021-03-15 17:45:32 +02:00
Ralf Kistner f54615e43a Update metadata and scripts for Maven Central. 2021-03-15 11:18:34 +02:00
Ralf Kistner 1acc3a6f4f Merge pull request #605 from devzeze/devzeze-fix556
fix #556 add licenses to POM
2021-02-12 10:32:22 +02:00
Ralf Kistner 73093b9b4f Merge pull request #587 from ANewGalaxy/master
Fixing MediaPlayer warnings;
2021-02-12 10:30:32 +02:00
Ralf Kistner db85816b3d Merge pull request #609 from nodh/feature/preventclassclash
Move CameraConfigurationUtils to prevent clash with other ZXing libraries
2021-02-12 10:29:37 +02:00
Christian Kollmann 6a3d857019 Move CameraConfigurationUtils to prevent clash with com.google.zxing:android-core 2021-02-12 07:26:12 +01:00
devzeze 6c8ea7e3fd fix #556 2021-02-03 16:07:17 +01:00
ANewGalaxy 35ee545f8b Replaced setAudioStreamType method call with setAudioAttributes call to fix warnings about stream types. Also removed unused import. 2020-12-11 22:00:01 -05:00
ANewGalaxy 5d9e2c3756 Added reset calls before each release call 2020-12-11 21:57:36 -05:00
ANewGalaxy cce2a300ef Fixing MediaPlayer warnings; 2020-12-11 21:48:29 -05:00
Ralf Kistner 13440ad875 Update readme. 2020-02-11 09:55:51 +02:00
Ralf Kistner 5a2470f034 Merge branch 'master' of github.com:journeyapps/zxing-android-embedded 2020-02-11 09:52:51 +02:00
Ralf Kistner 545672bb8f Update README.md
Fix the version.
2020-01-31 17:24:51 +02:00
Ralf Kistner 542dc66090 Merge pull request #530 from lukassos/master
correct release version 4.0.2
2020-01-17 14:44:06 +02:00
Lukassos ea414a236e correct release version 4.0.2
After two days of headaches, looked into CHANGES.md where 4.0.0 is marked as broken - we should use 4.0.2
2020-01-17 12:14:32 +01:00
Ralf Kistner 1ba1ded540 Merge pull request #529 from hannesa2/ReduceTravisBuilds
Reduce Travis builds
2020-01-08 17:05:52 +02:00
Ralf Kistner 4893bcc194 Merge pull request #528 from hannesa2/AndroidStudio-3.5.3
Android Studio 3.5.3
2020-01-08 10:13:54 +02:00
Hannes Achleitner 6498fad6a7 Reduce Travis builds 2020-01-07 19:52:44 +01:00
Hannes Achleitner f7f779d7ac Android Studio 3.5.3 2020-01-07 19:49:36 +01:00
Ralf Kistner c555ffbe05 Release 4.1.0 2020-01-07 14:24:05 +02:00
Andre Ippisch e0d340952d Camera permission behaviour (#505)
* Remove unused else

* Remove SDK version check since we are on minimum 24 already

* Add intent key about missing camera permission

* Add boolean value to show error dialog

- always true for the beginning to keep current behaviour

* Make displaying an error dialog for missing camera permissions optional

* Add intent extras for Intent initialisation

* Initialise camera permission dialog visibility from Intent

* Add original intent to IntentResult

* Use original intent in IntentResult

* Make onRequestPermissionResult public again

* Forward onRequestPermissionResult

* React on Intent information

- for example on the missing camera permission

* Revert "Remove SDK version check since we are on minimum 24 already"

This reverts commit 8f79f56a

* Add missing imports
2020-01-07 14:00:51 +02:00
Ralf Kistner 9b924e6875 Merge pull request #511 from hannesa2/AndroidStudio-3.5.2
Android Studio 3.5.2
2020-01-07 13:55:48 +02:00
Ralf Kistner 8df0cb554a Merge pull request #527 from yands11/master
Apply space convention after 'if'
2020-01-07 13:54:55 +02:00
Ralf Kistner 09d992ddfa Merge pull request #519 from bekabot/master
Remove unneeded type casts & fix comment typo in DecoratedBarcodeView.java
2020-01-07 13:54:27 +02:00
Ralf Kistner 95cd4a3a4d Merge pull request #512 from hannesa2/SomeCodeCleanup
some code cleanup
2020-01-07 13:54:02 +02:00
youngseok 7e5bbd2997 Apply space convention after 'if' 2020-01-07 14:37:28 +09:00
bekabot 8d8cd7d445 remove unneeded type casts 2019-12-10 13:40:43 +06:00
bekabot bd857c68eb fix comment 2019-12-10 13:35:13 +06:00
Hannes Achleitner 0fdfbce9fb some code cleanup 2019-11-17 13:49:59 +01:00
Hannes Achleitner eba457ee9e Android Studio 3.5.2 2019-11-17 13:42:27 +01:00
Ralf Kistner 9319110de8 Merge pull request #504 from anipp100/default-method
Use default annotation for optional interface method
2019-10-24 09:33:31 +02:00
Ralf Kistner ee4b181f23 Merge pull request #506 from anipp100/lambda-runnable
Use lambda for standalone Runnables
2019-10-24 09:33:12 +02:00
Ralf Kistner a4f751500c Fix instructions for min-sdk 14.
Fixes #507.
2019-10-22 10:05:01 +02:00
Andre Ippisch 75b4aa57f5 Use lambda for standalone Runnables 2019-10-18 14:39:58 +02:00
Andre Ippisch eb4cbd5095 Use default annotation for optional interface method 2019-10-18 12:48:47 +02:00
Andre Ippisch aa4fca5dae Let visibility of "laser scanner" be set (#503)
* Add laser visibility attribute

* Add laser visibility attribute usage to sample project

- set to true to stick with the current behavior
- included for didactic reasons

* Add laser visibility attribute to ViewfinderView and set it accordingly

* Draw "laser scanner" only if wanted

* Let laser visibility be changed programmatically

* Add sample code to show how laser visibility can be changed programmatically
2019-10-17 14:21:23 +02:00
Ralf Kistner d22b581cd3 Merge pull request #495 from journeyapps/release-401
Release v4.0.2
2019-09-07 19:04:30 +02:00
Ralf Kistner 9349b31ab3 v4.0.2. 2019-09-07 19:01:10 +02:00
Ralf Kistner c0c8363f85 More publishing fixes. 2019-09-07 19:00:32 +02:00
53 changed files with 1184 additions and 595 deletions
+21
View File
@@ -0,0 +1,21 @@
name: Build Android
on: [pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-java@v2
with:
distribution: 'temurin'
java-version: '11'
- name: Build and Lint with Gradle
run: ./gradlew build
- name: Archive lint results
uses: actions/upload-artifact@v2
with:
name: lint-results
path: "**/build/reports/lint-results*"
+3
View File
@@ -8,3 +8,6 @@ maven-repository
local.properties
mvn-clone
*.keystore
.project
.settings
.classpath
-31
View File
@@ -1,31 +0,0 @@
language: android
jdk: oraclejdk8
android:
components:
# Install tools twice to get the latest update
- tools
- tools
- platform-tools
- build-tools-28.0.3
- extra-android-support
- extra-android-m2repository
- extra-google-m2repository
licenses:
- 'android-sdk-preview-license-.+'
- 'android-sdk-license-.+'
- 'google-gdk-license-.+'
before_install:
# Android SDK installation is a mess, especially with licenses. Not sure if all of this is required, but it works.
- echo "$ANDROID_HOME"
- mkdir -p "$ANDROID_HOME/licenses"
- echo -e "\n8933bad161af4178b1185d1a37fbf41ea5269c55" > "$ANDROID_HOME/licenses/android-sdk-license"
- echo -e "\n84831b9409646a918e30573bab4c9c91346d8abd" > "$ANDROID_HOME/licenses/android-sdk-preview-license"
- yes | sdkmanager "platforms;android-27"
script:
# build includes lint and test
- TERM=dumb ./gradlew build
after_failure:
- cat **/build/reports/lint-results.xml
+23 -3
View File
@@ -1,4 +1,24 @@
### 4.0.1 (2019-09-07)
### 4.3.0 (2021-10-25)
* Minimum SDK version 19, but requires additional config (see readme) for < 24 compatibility.
* Add ScanOptions and ScanContract for use with `registerForActivityResult()`.
* Deprecates IntentIntegrator.
* Use minimal AndroidX libraries.
### 4.2.0 (2021-03-15)
* Fix MediaPlayer warnings (#587).
* Prevent CameraConfigurationUtils clash (#609).
* Add licenses to POM (#556).
* Bug: Crashes on SDK versions older than 21 (#645).
### 4.1.0 (2020-01-07)
* Ability to hide the laser in ViewfinderView (#503).
* Make possibleResultPoints method in BarcodeCallback optional (#504).
* Ability to customize or disable the permission error dialog (#505).
### 4.0.2 (2019-09-07)
* Use androidx.
* Use zxing:core 3.4.0 by default.
@@ -6,9 +26,9 @@
* Fix ArithmeticException.
* Fix ResultPoint locations when camera is mirrored.
### 4.0.0 (2019-09-07)
### 4.0.0 / 4.0.1 (2019-09-07)
* Broken release - use 4.0.1.
* Broken release - use 4.0.2.
### 3.6.0 (2018-03-04)
+109 -68
View File
@@ -13,55 +13,102 @@ Features:
A sample application is available in [Releases](https://github.com/journeyapps/zxing-android-embedded/releases).
By default, Android SDK 24+ is required because of `zxing:core` 3.4.0.
To support SDK 14+, downgrade `zxing:core` to 3.3.0 -
see [instructions](#adding-aar-dependency-with-gradle). You'll also need this in your Android manifest:
```xml
<uses-sdk android:minSdkVersion="14" tools:overrideLibrary="com.google.zxing.client.android" />
```
No guarantees are made on support for older SDK versions - you'll have to test to make sure it's compatible.
By default, Android SDK 24+ is required because of `zxing:core` 3.4.x.
SDK 19+ is supported with additional configuration, see [Older SDK versions](#older-sdk-versions).
## Adding aar dependency with Gradle
From version 4.0.0, only Android SDK 24+ is supported by default, and androidx is required.
Add the following to your `build.gradle` file:
```groovy
// Config for SDK 24+
repositories {
jcenter()
mavenCentral()
}
dependencies {
implementation 'com.journeyapps:zxing-android-embedded:4.0.0'
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'com.journeyapps:zxing-android-embedded:4.3.0'
}
android {
buildToolsVersion '28.0.3' // Older versions may give compile errors
}
```
For Android 14+ support, downgrade `zxing:core` to 3.3.0 or earlier:
## Older SDK versions
By default, only SDK 24+ will work, even though the library specifies 19 as the minimum version.
For SDK versions 19+, one of the changes below are required.
Some older SDK versions below 19 may work, but this is not tested or supported.
### Option 1. Downgrade zxing:core to 3.3.0
```groovy
repositories {
jcenter()
mavenCentral()
}
dependencies {
implementation('com.journeyapps:zxing-android-embedded:3.6.0') { transitive = false }
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation('com.journeyapps:zxing-android-embedded:4.3.0') { transitive = false }
implementation 'com.google.zxing:core:3.3.0'
}
```
### Option 2: Desugaring (Advanced)
This option does not require changing library versions, but may complicate the build process.
This requires Android Gradle Plugin version 4.0.0 or later.
See [Java 8+ API desugaring support](https://developer.android.com/studio/write/java8-support#library-desugaring).
Example for SDK 21+:
```groovy
android {
buildToolsVersion '28.0.3'
defaultConfig {
minSdkVersion 21
}
compileOptions {
// Flag to enable support for the new language APIs
coreLibraryDesugaringEnabled true
// Sets Java compatibility to Java 8
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation 'com.journeyapps:zxing-android-embedded:4.3.0'
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
}
```
SDK 19+ additionally requires multiDex. In addition to these gradle config changes, the Application
class must also be changed. See for details: [Configure your app for multidex](https://developer.android.com/studio/build/multidex#mdex-gradle).
```groovy
android {
defaultConfig {
multiDexEnabled true
minSdkVersion 19
}
compileOptions {
// Flag to enable support for the new language APIs
coreLibraryDesugaringEnabled true
// Sets Java compatibility to Java 8
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation 'com.journeyapps:zxing-android-embedded:4.3.0'
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
implementation "androidx.multidex:multidex:2.0.1"
}
```
## Hardware Acceleration
@@ -74,48 +121,42 @@ Make sure it is enabled in your manifest file:
<application android:hardwareAccelerated="true" ... >
```
## Usage with IntentIntegrator
## Usage with ScanContract
Note: `startActivityForResult` is deprecated, so this example uses `registerForActivityResult` instead.
See for details: https://developer.android.com/training/basics/intents/result
`startActivityForResult` can still be used via `IntentIntegrator`, but that is not recommended anymore.
Launch the intent with the default options:
```java
new IntentIntegrator(this).initiateScan(); // `this` is the current Activity
// Register the launcher and result handler
private final ActivityResultLauncher<ScanOptions> barcodeLauncher = registerForActivityResult(new ScanContract(),
result -> {
if(result.getContents() == null) {
Toast.makeText(MyActivity.this, "Cancelled", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(MyActivity.this, "Scanned: " + result.getContents(), Toast.LENGTH_LONG).show();
}
});
// Get the results:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
if(result != null) {
if(result.getContents() == null) {
Toast.makeText(this, "Cancelled", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, "Scanned: " + result.getContents(), Toast.LENGTH_LONG).show();
}
} else {
super.onActivityResult(requestCode, resultCode, data);
}
// Launch
public void onButtonClick(View view) {
barcodeLauncher.launch(new ScanOptions());
}
```
Use from a Fragment:
```java
IntentIntegrator.forFragment(this).initiateScan(); // `this` is the current Fragment
// If you're using the support library, use IntentIntegrator.forSupportFragment(this) instead.
```
Customize options:
```java
IntentIntegrator integrator = new IntentIntegrator(this);
integrator.setDesiredBarcodeFormats(IntentIntegrator.ONE_D_CODE_TYPES);
integrator.setPrompt("Scan a barcode");
integrator.setCameraId(0); // Use a specific camera of the device
integrator.setBeepEnabled(false);
integrator.setBarcodeImageEnabled(true);
integrator.initiateScan();
ScanOptions options = new ScanOptions();
options.setDesiredBarcodeFormats(ScanOptions.ONE_D_CODE_TYPES);
options.setPrompt("Scan a barcode");
options.setCameraId(0); // Use a specific camera of the device
options.setBeepEnabled(false);
options.setBarcodeImageEnabled(true);
barcodeLauncher.launch(options);
```
See [IntentIntegrator][5] for more options.
See [BarcodeOptions][5] for more options.
### Generate Barcode example
@@ -131,12 +172,14 @@ try {
} catch(Exception e) {
}
No customization of the image is currently supported, including changing colors or padding. If you
require more customization, copy and modify the source for the encoder.
```
To customize the generated barcode image, use the `setBackgroundColor` and `setForegroundColor` functions of the
`BarcodeEncoder` class with a [`@ColorInt`](https://developer.android.com/reference/androidx/annotation/ColorInt)
value to update the background and foreground colors of the barcode respectively. By default, the barcode has a
white background and black foreground.
### Changing the orientation
To change the orientation, specify the orientation in your `AndroidManifest.xml` and let the `ManifestMerger` to update the Activity's definition.
@@ -151,9 +194,9 @@ Sample:
```
```java
IntentIntegrator integrator = new IntentIntegrator(this);
integrator.setOrientationLocked(false);
integrator.initiateScan();
ScanOptions options = new ScanOptions();
options.setOrientationLocked(false);
barcodeLauncher.launch(options);
```
### Customization and advanced options
@@ -190,14 +233,14 @@ You can then use your local version by specifying in your `build.gradle` file:
## Sponsored by
[JourneyApps][1] - Creating business solutions with mobile apps. Fast.
[JourneyApps][1]
## License
Licensed under the [Apache License 2.0][7]
Copyright (C) 2012-2018 ZXing authors, Journey Mobile
Copyright (C) 2012-2022 ZXing authors, Journey Mobile
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -215,7 +258,5 @@ Licensed under the [Apache License 2.0][7]
[1]: http://journeyapps.com
[2]: https://github.com/zxing/zxing/
[3]: https://github.com/zxing/zxing/wiki/Scanning-Via-Intent
[4]: https://github.com/journeyapps/zxing-android-embedded/blob/2.x/README.md
[5]: zxing-android-embedded/src/com/google/zxing/integration/android/IntentIntegrator.java
[5]: zxing-android-embedded/src/com/journeyapps/barcodescanner/ScanOptions.java
[7]: http://www.apache.org/licenses/LICENSE-2.0
+6 -12
View File
@@ -1,30 +1,24 @@
buildscript {
repositories {
google()
jcenter()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.0'
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4'
classpath 'com.android.tools.build:gradle:7.0.3'
}
}
subprojects {
repositories {
google()
jcenter()
mavenLocal()
mavenCentral()
}
version = '4.0.1'
version = '4.3.0'
group = 'com.journeyapps'
ext.androidBuildTools = '28.0.3'
ext.androidTargetSdk = 28
ext.zxingCore = 'com.google.zxing:core:3.4.0'
ext.androidTargetSdk = 30
ext.zxingCore = 'com.google.zxing:core:3.4.1'
}
repositories {
google()
}
+1 -1
View File
@@ -1,3 +1,3 @@
android.enableJetifier=true
android.enableJetifier=false
android.useAndroidX=true
org.gradle.jvmargs=-Xmx1536M
Binary file not shown.
+1 -2
View File
@@ -1,6 +1,5 @@
#Sat Sep 07 15:17:02 SAST 2019
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
Vendored
+42 -23
View File
@@ -1,4 +1,20 @@
#!/usr/bin/env bash
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
@@ -28,16 +44,16 @@ APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
warn () {
echo "$*"
}
die ( ) {
die () {
echo
echo "$*"
echo
@@ -109,8 +125,8 @@ if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
@@ -138,27 +154,30 @@ if $cygwin ; then
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
i=`expr $i + 1`
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
APP_ARGS=`save "$@"`
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
exec "$JAVACMD" "$@"
Vendored
+100 -90
View File
@@ -1,90 +1,100 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
-1
View File
@@ -1 +0,0 @@
/build
+24 -11
View File
@@ -2,13 +2,13 @@ apply plugin: 'com.android.application'
android {
compileSdkVersion project.androidTargetSdk
buildToolsVersion project.androidBuildTools
defaultConfig {
minSdkVersion 24
multiDexEnabled true
minSdkVersion 19
targetSdkVersion project.androidTargetSdk
versionCode 401
versionName "4.0.1"
versionCode 411
versionName "4.1.1"
}
def validConfig
@@ -22,9 +22,9 @@ android {
keystoreFile = properties.getProperty('keystore.file')
keystorePassword = properties.getProperty('keystore.password')
keystoreAlias = properties.getProperty('keystore.alias')
validConfig = keystoreFile != null && keystorePassword != null && keystoreAlias != null;
validConfig = keystoreFile != null && keystorePassword != null && keystoreAlias != null
} catch (error) {
validConfig = false;
validConfig = false
}
if (validConfig) {
@@ -51,26 +51,39 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
}
}
compileOptions {
coreLibraryDesugaringEnabled true
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
lintOptions {
// Error: The lint detector
// androidx.appcompat.view.OnClickXmlDetector
// called context.getMainProject() during module analysis.
disable 'UsingOnClickInXml'
}
}
dependencies {
// If you use this from an external project, use the following instead:
// compile 'com.journeyapps:zxing-android-embedded:<version>'
// implementation 'com.journeyapps:zxing-android-embedded:<version>'
implementation project(':zxing-android-embedded')
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'androidx.legacy:legacy-support-v13:1.0.0'
implementation "androidx.activity:activity:1.3.1"
// Desugaring and multidex is required for API < 21.
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
implementation 'androidx.multidex:multidex:2.0.1'
// leakcanary is for development purposes only
// https://github.com/square/leakcanary
debugImplementation 'com.squareup.leakcanary:leakcanary-android:1.5'
releaseImplementation 'com.squareup.leakcanary:leakcanary-android-no-op:1.5'
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.7'
// AboutLibraries
implementation "com.mikepenz:aboutlibraries:6.2.3"
implementation 'com.mikepenz:aboutlibraries:6.2.3'
}
@@ -24,7 +24,6 @@ import java.util.List;
* a barcode is scanned.
*/
public class ContinuousCaptureActivity extends Activity {
private static final String TAG = ContinuousCaptureActivity.class.getSimpleName();
private DecoratedBarcodeView barcodeView;
private BeepManager beepManager;
private String lastText;
@@ -43,7 +42,7 @@ public class ContinuousCaptureActivity extends Activity {
beepManager.playBeepSoundAndVibrate();
//Added preview of scanned barcode
ImageView imageView = (ImageView) findViewById(R.id.barcodePreview);
ImageView imageView = findViewById(R.id.barcodePreview);
imageView.setImageBitmap(result.getBitmapWithResultPoints(Color.YELLOW));
}
@@ -58,7 +57,7 @@ public class ContinuousCaptureActivity extends Activity {
setContentView(R.layout.continuous_scan);
barcodeView = (DecoratedBarcodeView) findViewById(R.id.barcode_scanner);
barcodeView = findViewById(R.id.barcode_scanner);
Collection<BarcodeFormat> formats = Arrays.asList(BarcodeFormat.QR_CODE, BarcodeFormat.CODE_39);
barcodeView.getBarcodeView().setDecoderFactory(new DefaultDecoderFactory(formats));
barcodeView.initializeFromIntent(getIntent());
@@ -8,6 +8,8 @@ import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import androidx.annotation.NonNull;
import com.journeyapps.barcodescanner.CaptureManager;
import com.journeyapps.barcodescanner.DecoratedBarcodeView;
import com.journeyapps.barcodescanner.ViewfinderView;
@@ -30,12 +32,12 @@ public class CustomScannerActivity extends Activity implements
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_custom_scanner);
barcodeScannerView = (DecoratedBarcodeView)findViewById(R.id.zxing_barcode_scanner);
barcodeScannerView = findViewById(R.id.zxing_barcode_scanner);
barcodeScannerView.setTorchListener(this);
switchFlashlightButton = (Button)findViewById(R.id.switch_flashlight);
switchFlashlightButton = findViewById(R.id.switch_flashlight);
viewfinderView = (ViewfinderView) findViewById(R.id.zxing_viewfinder_view);
viewfinderView = findViewById(R.id.zxing_viewfinder_view);
// if the device does not have flashlight in its camera,
// then remove the switch flashlight button...
@@ -45,9 +47,11 @@ public class CustomScannerActivity extends Activity implements
capture = new CaptureManager(this, barcodeScannerView);
capture.initializeFromIntent(getIntent(), savedInstanceState);
capture.setShowMissingCameraPermissionDialog(false);
capture.decode();
changeMaskColor(null);
changeLaserVisibility(true);
}
@Override
@@ -102,6 +106,10 @@ public class CustomScannerActivity extends Activity implements
viewfinderView.setMaskColor(color);
}
public void changeLaserVisibility(boolean visible) {
viewfinderView.setLaserVisibility(visible);
}
@Override
public void onTorchOn() {
switchFlashlightButton.setText(R.string.turn_off_flashlight);
@@ -111,4 +119,9 @@ public class CustomScannerActivity extends Activity implements
public void onTorchOff() {
switchFlashlightButton.setText(R.string.turn_on_flashlight);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
capture.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
@@ -3,8 +3,6 @@ package example.zxing;
import android.content.Intent;
import android.hardware.Camera;
import android.os.Bundle;
import androidx.fragment.app.Fragment;
import androidx.appcompat.app.AppCompatActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -13,14 +11,33 @@ import android.widget.Button;
import android.widget.Toast;
import com.google.zxing.client.android.Intents;
import com.google.zxing.integration.android.IntentIntegrator;
import com.google.zxing.integration.android.IntentResult;
import com.journeyapps.barcodescanner.ScanContract;
import com.journeyapps.barcodescanner.ScanOptions;
import com.mikepenz.aboutlibraries.LibsBuilder;
import androidx.activity.result.ActivityResultLauncher;
import androidx.appcompat.app.AppCompatActivity;
import androidx.fragment.app.Fragment;
public class MainActivity extends AppCompatActivity {
private final ActivityResultLauncher<ScanOptions> barcodeLauncher = registerForActivityResult(new ScanContract(),
result -> {
if(result.getContents() == null) {
Intent originalIntent = result.getOriginalIntent();
if (originalIntent == null) {
Log.d("MainActivity", "Cancelled scan");
Toast.makeText(MainActivity.this, "Cancelled", Toast.LENGTH_LONG).show();
} else if(originalIntent.hasExtra(Intents.Scan.MISSING_CAMERA_PERMISSION)) {
Log.d("MainActivity", "Cancelled scan due to missing camera permission");
Toast.makeText(MainActivity.this, "Cancelled due to missing camera permission", Toast.LENGTH_LONG).show();
}
} else {
Log.d("MainActivity", "Scanned");
Toast.makeText(MainActivity.this, "Scanned: " + result.getContents(), Toast.LENGTH_LONG).show();
}
});
public final int CUSTOMIZED_REQUEST_CODE = 0x0000ffff;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -29,49 +46,45 @@ public class MainActivity extends AppCompatActivity {
}
public void scanBarcode(View view) {
new IntentIntegrator(this).initiateScan();
}
public void scanBarcodeWithCustomizedRequestCode(View view) {
new IntentIntegrator(this).setRequestCode(CUSTOMIZED_REQUEST_CODE).initiateScan();
barcodeLauncher.launch(new ScanOptions());
}
public void scanBarcodeInverted(View view){
IntentIntegrator integrator = new IntentIntegrator(this);
integrator.addExtra(Intents.Scan.SCAN_TYPE, Intents.Scan.INVERTED_SCAN);
integrator.initiateScan();
ScanOptions options = new ScanOptions();
options.addExtra(Intents.Scan.SCAN_TYPE, Intents.Scan.INVERTED_SCAN);
barcodeLauncher.launch(options);
}
public void scanMixedBarcodes(View view){
IntentIntegrator integrator = new IntentIntegrator(this);
integrator.addExtra(Intents.Scan.SCAN_TYPE, Intents.Scan.MIXED_SCAN);
integrator.initiateScan();
ScanOptions options = new ScanOptions();
options.addExtra(Intents.Scan.SCAN_TYPE, Intents.Scan.MIXED_SCAN);
barcodeLauncher.launch(options);
}
public void scanBarcodeCustomLayout(View view) {
IntentIntegrator integrator = new IntentIntegrator(this);
integrator.setCaptureActivity(AnyOrientationCaptureActivity.class);
integrator.setDesiredBarcodeFormats(IntentIntegrator.ONE_D_CODE_TYPES);
integrator.setPrompt("Scan something");
integrator.setOrientationLocked(false);
integrator.setBeepEnabled(false);
integrator.initiateScan();
ScanOptions options = new ScanOptions();
options.setCaptureActivity(AnyOrientationCaptureActivity.class);
options.setDesiredBarcodeFormats(ScanOptions.ONE_D_CODE_TYPES);
options.setPrompt("Scan something");
options.setOrientationLocked(false);
options.setBeepEnabled(false);
barcodeLauncher.launch(options);
}
public void scanPDF417(View view) {
IntentIntegrator integrator = new IntentIntegrator(this);
integrator.setDesiredBarcodeFormats(IntentIntegrator.PDF_417);
integrator.setPrompt("Scan something");
integrator.setOrientationLocked(false);
integrator.setBeepEnabled(false);
integrator.initiateScan();
ScanOptions options = new ScanOptions();
options.setDesiredBarcodeFormats(ScanOptions.PDF_417);
options.setPrompt("Scan something");
options.setOrientationLocked(false);
options.setBeepEnabled(false);
barcodeLauncher.launch(options);
}
public void scanBarcodeFrontCamera(View view) {
IntentIntegrator integrator = new IntentIntegrator(this);
integrator.setCameraId(Camera.CameraInfo.CAMERA_FACING_FRONT);
integrator.initiateScan();
ScanOptions options = new ScanOptions();
options.setCameraId(Camera.CameraInfo.CAMERA_FACING_FRONT);
barcodeLauncher.launch(options);
}
public void scanContinuous(View view) {
@@ -80,24 +93,26 @@ public class MainActivity extends AppCompatActivity {
}
public void scanToolbar(View view) {
new IntentIntegrator(this).setCaptureActivity(ToolbarCaptureActivity.class).initiateScan();
ScanOptions options = new ScanOptions().setCaptureActivity(ToolbarCaptureActivity.class);
barcodeLauncher.launch(options);
}
public void scanCustomScanner(View view) {
new IntentIntegrator(this).setOrientationLocked(false).setCaptureActivity(CustomScannerActivity.class).initiateScan();
ScanOptions options = new ScanOptions().setOrientationLocked(false).setCaptureActivity(CustomScannerActivity.class);
barcodeLauncher.launch(options);
}
public void scanMarginScanner(View view) {
IntentIntegrator integrator = new IntentIntegrator(this);
integrator.setOrientationLocked(false);
integrator.setCaptureActivity(SmallCaptureActivity.class);
integrator.initiateScan();
ScanOptions options = new ScanOptions();
options.setOrientationLocked(false);
options.setCaptureActivity(SmallCaptureActivity.class);
barcodeLauncher.launch(options);
}
public void scanWithTimeout(View view) {
IntentIntegrator integrator = new IntentIntegrator(this);
integrator.setTimeout(8000);
integrator.initiateScan();
ScanOptions options = new ScanOptions();
options.setTimeout(8000);
barcodeLauncher.launch(options);
}
public void tabs(View view) {
@@ -109,87 +124,33 @@ public class MainActivity extends AppCompatActivity {
new LibsBuilder().start(this);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode != CUSTOMIZED_REQUEST_CODE && requestCode != IntentIntegrator.REQUEST_CODE) {
// This is important, otherwise the result will not be passed to the fragment
super.onActivityResult(requestCode, resultCode, data);
return;
}
switch (requestCode) {
case CUSTOMIZED_REQUEST_CODE: {
Toast.makeText(this, "REQUEST_CODE = " + requestCode, Toast.LENGTH_LONG).show();
break;
}
default:
break;
}
IntentResult result = IntentIntegrator.parseActivityResult(resultCode, data);
if(result.getContents() == null) {
Log.d("MainActivity", "Cancelled scan");
Toast.makeText(this, "Cancelled", Toast.LENGTH_LONG).show();
} else {
Log.d("MainActivity", "Scanned");
Toast.makeText(this, "Scanned: " + result.getContents(), Toast.LENGTH_LONG).show();
}
}
/**
* Sample of scanning from a Fragment
*/
public static class ScanFragment extends Fragment {
private String toast;
private final ActivityResultLauncher<ScanOptions> fragmentLauncher = registerForActivityResult(new ScanContract(),
result -> {
if(result.getContents() == null) {
Toast.makeText(getContext(), "Cancelled from fragment", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getContext(), "Scanned from fragment: " + result.getContents(), Toast.LENGTH_LONG).show();
}
});
public ScanFragment() {
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
displayToast();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_scan, container, false);
Button scan = (Button) view.findViewById(R.id.scan_from_fragment);
scan.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
scanFromFragment();
}
});
Button scan = view.findViewById(R.id.scan_from_fragment);
scan.setOnClickListener(v -> scanFromFragment());
return view;
}
public void scanFromFragment() {
IntentIntegrator.forSupportFragment(this).initiateScan();
}
private void displayToast() {
if(getActivity() != null && toast != null) {
Toast.makeText(getActivity(), toast, Toast.LENGTH_LONG).show();
toast = null;
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
if(result != null) {
if(result.getContents() == null) {
toast = "Cancelled from fragment";
} else {
toast = "Scanned from fragment: " + result.getContents();
}
// At this point we may or may not have a reference to the activity
displayToast();
}
fragmentLauncher.launch(new ScanOptions());
}
}
}
@@ -1,16 +1,13 @@
package example.zxing;
import android.app.Application;
import com.squareup.leakcanary.LeakCanary;
import androidx.multidex.MultiDexApplication;
/**
*
*/
public class SampleApplication extends Application {
public class SampleApplication extends MultiDexApplication {
@Override
public void onCreate() {
super.onCreate();
LeakCanary.install(this);
}
}
@@ -19,7 +19,6 @@ import com.journeyapps.barcodescanner.CameraPreview;
import com.journeyapps.barcodescanner.DecoratedBarcodeView;
public class TabbedScanning extends AppCompatActivity implements ActionBar.TabListener {
private static final String TAG = TabbedScanning.class.getSimpleName();
/**
* The {@link PagerAdapter} that will provide
@@ -46,7 +45,7 @@ public class TabbedScanning extends AppCompatActivity implements ActionBar.TabLi
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (ViewPager) findViewById(R.id.container);
mViewPager = findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
// Set up the action bar.
@@ -114,7 +113,7 @@ public class TabbedScanning extends AppCompatActivity implements ActionBar.TabLi
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_tabbed_scanning, container, false);
barcodeView = (DecoratedBarcodeView)rootView.findViewById(R.id.barcode_view);
barcodeView = rootView.findViewById(R.id.barcode_view);
return rootView;
}
@@ -167,7 +166,7 @@ public class TabbedScanning extends AppCompatActivity implements ActionBar.TabLi
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_tabbed_camera, container, false);
cameraPreview = (CameraPreview)rootView.findViewById(R.id.camera_preview);
cameraPreview = rootView.findViewById(R.id.camera_preview);
return rootView;
}
@@ -20,12 +20,12 @@ public class ToolbarCaptureActivity extends AppCompatActivity {
super.onCreate(savedInstanceState);
setContentView(R.layout.capture_appcompat);
Toolbar toolbar = (Toolbar) findViewById(R.id.my_awesome_toolbar);
Toolbar toolbar = findViewById(R.id.my_awesome_toolbar);
toolbar.setTitle("Scan Barcode");
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
barcodeScannerView = (DecoratedBarcodeView)findViewById(R.id.zxing_barcode_scanner);
barcodeScannerView = findViewById(R.id.zxing_barcode_scanner);
capture = new CaptureManager(this, barcodeScannerView);
capture.initializeFromIntent(getIntent(), savedInstanceState);
@@ -25,12 +25,6 @@
android:text="Scan PDF417"
android:onClick="scanPDF417"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/scan_barcode_with_request_code"
android:onClick="scanBarcodeWithCustomizedRequestCode"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -17,6 +17,7 @@
app:zxing_possible_result_points="@color/zxing_custom_possible_result_points"
app:zxing_result_view="@color/zxing_custom_result_view"
app:zxing_viewfinder_laser="@color/zxing_custom_viewfinder_laser"
app:zxing_viewfinder_laser_visibility="true"
app:zxing_viewfinder_mask="@color/zxing_custom_viewfinder_mask"/>
<TextView
+78 -26
View File
@@ -1,23 +1,48 @@
apply plugin: 'com.android.library'
apply plugin: 'maven-publish'
apply plugin: 'com.jfrog.bintray'
apply plugin: 'signing'
ext.artifactId = 'zxing-android-embedded'
// Publishing config from https://getstream.io/blog/publishing-libraries-to-mavencentral-2021/
ext["signing.keyId"] = ''
ext["signing.password"] = ''
ext["signing.secretKeyRingFile"] = ''
ext["ossrhUsername"] = ''
ext["ossrhPassword"] = ''
ext["sonatypeStagingProfileId"] = ''
File secretPropsFile = project.rootProject.file('local.properties')
if (secretPropsFile.exists()) {
Properties p = new Properties()
p.load(new FileInputStream(secretPropsFile))
p.each { name, value ->
ext[name] = value
}
} else {
ext["signing.keyId"] = System.getenv('SIGNING_KEY_ID')
ext["signing.password"] = System.getenv('SIGNING_PASSWORD')
ext["signing.secretKeyRingFile"] = System.getenv('SIGNING_SECRET_KEY_RING_FILE')
ext["ossrhUsername"] = System.getenv('OSSRH_USERNAME')
ext["ossrhPassword"] = System.getenv('OSSRH_PASSWORD')
ext["sonatypeStagingProfileId"] = System.getenv('SONATYPE_STAGING_PROFILE_ID')
}
dependencies {
api project.zxingCore
api 'androidx.legacy:legacy-support-v4:1.0.0'
implementation 'androidx.core:core:1.6.0'
implementation 'androidx.fragment:fragment:1.3.6'
testImplementation 'junit:junit:4.12'
testImplementation "org.mockito:mockito-core:1.9.5"
testImplementation 'junit:junit:4.13.1'
testImplementation 'org.mockito:mockito-core:1.9.5'
}
android {
resourcePrefix 'zxing_'
compileSdkVersion project.androidTargetSdk
buildToolsVersion project.androidBuildTools
sourceSets {
main {
@@ -26,7 +51,7 @@ android {
res.srcDirs = ['res-orig', 'res']
assets.srcDirs = ['assets']
}
test.setRoot('test');
test.setRoot('test')
}
// This is bad practice - we should fix the warnings instead.
@@ -45,8 +70,9 @@ android {
// We test with primitives such as Rect, and rely on their default behaviour working.
unitTests.returnDefaultValues = true
}
defaultConfig {
minSdkVersion 24
minSdkVersion 19
}
buildTypes {
@@ -73,6 +99,35 @@ project.afterEvaluate {
artifactId project.artifactId
artifact sourceJar
pom {
name = project.artifactId
description = 'Barcode scanner library for Android, based on the ZXing decoder'
url = 'https://github.com/journeyapps/zxing-android-embedded'
licenses {
license {
name = 'The Apache License, Version 2.0'
url = 'https://github.com/journeyapps/zxing-android-embedded/blob/master/COPYING'
}
}
developers {
developer {
id = ''
name = 'Ralf Kistner'
email = 'ralf@journeyapps.com'
organization = 'Journey Mobile, Inc'
organizationUrl = 'https://journeyapps.com'
}
}
scm {
connection = 'scm:git:github.com/journeyapps/zxing-android-embedded.git'
developerConnection = 'scm:git:ssh://github.com/journeyapps/zxing-android-embedded.git'
url = 'https://github.com/journeyapps/zxing-android-embedded'
}
}
pom.withXml {
// HACK to add dependencies to POM.
@@ -80,34 +135,31 @@ project.afterEvaluate {
// remove this section.
def deps = asNode().appendNode('dependencies')
project.configurations.compile.allDependencies.each { dep ->
project.configurations.api.allDependencies.each { dep ->
def node = deps.appendNode('dependency')
node.appendNode('groupId', dep.group)
node.appendNode('artifactId', dep.name)
node.appendNode('version', dep.version)
node.appendNode('scope', 'compile')
node.appendNode('scope', 'api')
}
}
}
}
repositories {
maven {
name = "sonatype"
url = "https://oss.sonatype.org/service/local/staging/deploy/maven2/"
credentials {
username ossrhUsername
password ossrhPassword
}
}
}
}
}
// To release, place bintray_user and bintray_key properties in ~/.gradle/gradle.properties,
// and run ./gradlew clean assembleRelease bintrayUpload
if(project.hasProperty('bintray_user') && project.hasProperty('bintray_key')) {
bintray {
user = bintray_user
key = bintray_key
publications = ['maven']
publish = true
pkg {
userOrg = 'journeyapps'
repo = 'maven'
name = 'zxing-android-embedded'
}
}
signing {
sign publishing.publications
}
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="ResourceName" >
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="ResourceName,UnusedResources" >
<string name="define_zxingandroidembedded" translatable="false" />
<!-- Author section -->
<string name="library_zxingandroidembedded_author" translatable="false">JourneyApps</string>
@@ -21,6 +21,7 @@
<attr name="zxing_result_view" format="color"/>
<attr name="zxing_viewfinder_laser" format="color"/>
<attr name="zxing_viewfinder_mask" format="color"/>
<attr name="zxing_viewfinder_laser_visibility" format="boolean"/>
</declare-styleable>
</resources>
@@ -71,12 +71,7 @@ public final class AmbientLightManager implements SensorEventListener {
}
private void setTorch(final boolean on) {
handler.post(new Runnable() {
@Override
public void run() {
cameraManager.setTorch(on);
}
});
handler.post(() -> cameraManager.setTorch(on));
}
@Override
@@ -20,12 +20,13 @@ import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Build;
import android.os.Vibrator;
import android.util.Log;
import java.io.Closeable;
import java.io.IOException;
/**
@@ -94,23 +95,25 @@ public final class BeepManager {
public MediaPlayer playBeepSound() {
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
mp.stop();
mp.release();
}
if (Build.VERSION.SDK_INT >= 21) {
mediaPlayer.setAudioAttributes(new AudioAttributes.Builder().setContentType(
AudioAttributes.CONTENT_TYPE_MUSIC).build());
} else {
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
}
mediaPlayer.setOnCompletionListener(mp -> {
mp.stop();
mp.reset();
mp.release();
});
mediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
Log.w(TAG, "Failed to beep " + what + ", " + extra);
// possibly media player error, so release and recreate
mp.stop();
mp.release();
return true;
}
mediaPlayer.setOnErrorListener((mp, what, extra) -> {
Log.w(TAG, "Failed to beep " + what + ", " + extra);
// possibly media player error, so release and recreate
mp.stop();
mp.reset();
mp.release();
return true;
});
try {
AssetFileDescriptor file = context.getResources().openRawResourceFd(R.raw.zxing_beep);
@@ -125,6 +128,7 @@ public final class BeepManager {
return mediaPlayer;
} catch (IOException ioe) {
Log.w(TAG, ioe);
mediaPlayer.reset();
mediaPlayer.release();
return null;
}
@@ -108,12 +108,7 @@ public final class InactivityTimer {
// 0 indicates that we're on battery
final boolean onBatteryNow = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) <= 0;
// post on handler to run in main thread
handler.post(new Runnable() {
@Override
public void run() {
onBattery(onBatteryNow);
}
});
handler.post(() -> onBattery(onBatteryNow));
}
}
}
@@ -115,6 +115,21 @@ public final class Intents {
*/
public static final String TIMEOUT = "TIMEOUT";
/**
* Set the time to finish the scan screen.
*/
public static final String MISSING_CAMERA_PERMISSION = "MISSING_CAMERA_PERMISSION";
/**
* Set the time to finish the scan screen.
*/
public static final String SHOW_MISSING_CAMERA_PERMISSION_DIALOG = "SHOW_MISSING_CAMERA_PERMISSION_DIALOG";
/**
* Set the time to finish the scan screen.
*/
public static final String MISSING_CAMERA_PERMISSION_DIALOG_MESSAGE = "MISSING_CAMERA_PERMISSION_DIALOG_MESSAGE";
/**
* Whether or not the orientation should be locked when the activity is first started.
* Defaults to true.
@@ -39,6 +39,7 @@ import java.util.Map;
* @author Isaac Potoczny-Jones
* @author Brad Drehmer
* @author gcstang
* @deprecated Use ScanOptions and ScanContract instead.
*/
@SuppressWarnings("unused")
public class IntentIntegrator {
@@ -353,6 +354,7 @@ public class IntentIntegrator {
* @return null if the event handled here was not related to this class, or
* else an {@link IntentResult} containing the result of the scan. If the user cancelled scanning,
* the fields will be null.
* @deprecated Not compatible with setRequestCode(). Use parseActivityResult(resultCode, intent) instead.
*/
public static IntentResult parseActivityResult(int requestCode, int resultCode, Intent intent) {
if (requestCode == REQUEST_CODE) {
@@ -383,9 +385,10 @@ public class IntentIntegrator {
rawBytes,
orientation,
errorCorrectionLevel,
barcodeImagePath);
barcodeImagePath,
intent);
}
return new IntentResult();
return new IntentResult(intent);
}
private static List<String> list(String... values) {
@@ -16,6 +16,8 @@
package com.google.zxing.integration.android;
import android.content.Intent;
/**
* <p>Encapsulates the result of a barcode scan invoked through {@link IntentIntegrator}.</p>
*
@@ -29,9 +31,14 @@ public final class IntentResult {
private final Integer orientation;
private final String errorCorrectionLevel;
private final String barcodeImagePath;
private final Intent originalIntent;
IntentResult() {
this(null, null, null, null, null, null);
this(null, null, null, null, null, null, null);
}
IntentResult(Intent intent) {
this(null, null, null, null, null, null, intent);
}
IntentResult(String contents,
@@ -39,13 +46,15 @@ public final class IntentResult {
byte[] rawBytes,
Integer orientation,
String errorCorrectionLevel,
String barcodeImagePath) {
String barcodeImagePath,
Intent originalIntent) {
this.contents = contents;
this.formatName = formatName;
this.rawBytes = rawBytes;
this.orientation = orientation;
this.errorCorrectionLevel = errorCorrectionLevel;
this.barcodeImagePath = barcodeImagePath;
this.originalIntent = originalIntent;
}
/**
@@ -90,6 +99,13 @@ public final class IntentResult {
return barcodeImagePath;
}
/**
* @return the original intent
*/
public Intent getOriginalIntent() {
return originalIntent;
}
@Override
public String toString() {
int rawBytesLength = rawBytes == null ? 0 : rawBytes.length;
@@ -98,6 +114,7 @@ public final class IntentResult {
"Raw bytes: (" + rawBytesLength + " bytes)\n" +
"Orientation: " + orientation + '\n' +
"EC level: " + errorCorrectionLevel + '\n' +
"Barcode image: " + barcodeImagePath + '\n';
"Barcode image: " + barcodeImagePath + '\n' +
"Original intent: " + originalIntent + '\n';
}
}
@@ -22,7 +22,10 @@ public interface BarcodeCallback {
*
* Do not depend on this being called at any specific point in the decode cycle.
*
* This is a default method and can be omitted by the implementing class.
*
* @param resultPoints points potentially identifying a barcode
*/
void possibleResultPoints(List<ResultPoint> resultPoints);
default void possibleResultPoints(List<ResultPoint> resultPoints) {
}
}
@@ -19,13 +19,21 @@ import java.util.Map;
* Licensed under the Apache License, Version 2.0.
*/
public class BarcodeEncoder {
private static final int WHITE = 0xFFFFFFFF;
private static final int BLACK = 0xFF000000;
private int bgColor = 0xFFFFFFFF;
private int fgColor = 0xFF000000;
public BarcodeEncoder() {
}
public void setBackgroundColor(int bgColor) {
this.bgColor = bgColor;
}
public void setForegroundColor(int fgColor) {
this.fgColor = fgColor;
}
public Bitmap createBitmap(BitMatrix matrix) {
int width = matrix.getWidth();
int height = matrix.getHeight();
@@ -33,7 +41,7 @@ public class BarcodeEncoder {
for (int y = 0; y < height; y++) {
int offset = y * width;
for (int x = 0; x < width; x++) {
pixels[offset + x] = matrix.get(x, y) ? BLACK : WHITE;
pixels[offset + x] = matrix.get(x, y) ? fgColor : bgColor;
}
}
@@ -209,7 +209,7 @@ public class CameraPreview extends ViewGroup {
pause();
fireState.cameraError(error);
}
} else if(message.what == R.id.zxing_camera_closed) {
} else if (message.what == R.id.zxing_camera_closed) {
fireState.cameraClosed();
}
return false;
@@ -220,12 +220,7 @@ public class CameraPreview extends ViewGroup {
@Override
public void onRotationChanged(int rotation) {
// Make sure this is run on the main thread.
stateHandler.postDelayed(new Runnable() {
@Override
public void run() {
rotationChanged();
}
}, ROTATION_LISTENER_DELAY_MS);
stateHandler.postDelayed(() -> rotationChanged(), ROTATION_LISTENER_DELAY_MS);
}
};
@@ -271,7 +266,7 @@ public class CameraPreview extends ViewGroup {
*
* @param attrs the attributes
*/
protected void initializeAttributes(AttributeSet attrs) {
public void initializeAttributes(AttributeSet attrs) {
TypedArray styledAttributes = getContext().obtainStyledAttributes(attrs, R.styleable.zxing_camera_preview);
int framingRectWidth = (int) styledAttributes.getDimension(R.styleable.zxing_camera_preview_zxing_framing_rect_width, -1);
@@ -285,11 +280,11 @@ public class CameraPreview extends ViewGroup {
// See zxing_attrs.xml for the enum values
int scalingStrategyNumber = styledAttributes.getInteger(R.styleable.zxing_camera_preview_zxing_preview_scaling_strategy, -1);
if(scalingStrategyNumber == 1) {
if (scalingStrategyNumber == 1) {
previewScalingStrategy = new CenterCropStrategy();
} else if(scalingStrategyNumber == 2) {
} else if (scalingStrategyNumber == 2) {
previewScalingStrategy = new FitCenterStrategy();
} else if(scalingStrategyNumber == 3) {
} else if (scalingStrategyNumber == 3) {
previewScalingStrategy = new FitXYStrategy();
}
@@ -298,14 +293,14 @@ public class CameraPreview extends ViewGroup {
private void rotationChanged() {
// Confirm that it did actually change
if(isActive() && getDisplayRotation() != openedOrientation) {
if (isActive() && getDisplayRotation() != openedOrientation) {
pause();
resume();
}
}
private void setupSurfaceView() {
if(useTextureView) {
if (useTextureView) {
textureView = new TextureView(getContext());
textureView.setSurfaceTextureListener(surfaceTextureListener());
addView(textureView);
@@ -436,7 +431,7 @@ public class CameraPreview extends ViewGroup {
displayConfiguration.setPreviewScalingStrategy(getPreviewScalingStrategy());
cameraInstance.setDisplayConfiguration(displayConfiguration);
cameraInstance.configureCamera();
if(torchOn) {
if (torchOn) {
cameraInstance.setTorch(torchOn);
}
}
@@ -456,14 +451,14 @@ public class CameraPreview extends ViewGroup {
* Override this to specify a different preview scaling strategy.
*/
public PreviewScalingStrategy getPreviewScalingStrategy() {
if(previewScalingStrategy != null) {
if (previewScalingStrategy != null) {
return previewScalingStrategy;
}
// If we are using SurfaceTexture, it is safe to use centerCrop.
// For SurfaceView, it's better to use fitCenter, otherwise the preview may overlap to
// other views.
if(textureView != null) {
if (textureView != null) {
return new CenterCropStrategy();
} else {
return new FitCenterStrategy();
@@ -526,8 +521,8 @@ public class CameraPreview extends ViewGroup {
if (currentSurfaceSize != null && previewSize != null && surfaceRect != null) {
if (surfaceView != null && currentSurfaceSize.equals(new Size(surfaceRect.width(), surfaceRect.height()))) {
startCameraPreview(new CameraSurface(surfaceView.getHolder()));
} else if(textureView != null && textureView.getSurfaceTexture() != null) {
if(previewSize != null) {
} else if (textureView != null && textureView.getSurfaceTexture() != null) {
if (previewSize != null) {
Matrix transform = calculateTextureTransform(new Size(textureView.getWidth(), textureView.getHeight()), previewSize);
textureView.setTransform(transform);
}
@@ -544,7 +539,7 @@ public class CameraPreview extends ViewGroup {
protected void onLayout(boolean changed, int l, int t, int r, int b) {
containerSized(new Size(r - l, b - t));
if(surfaceView != null) {
if (surfaceView != null) {
if (surfaceRect == null) {
// Match the container, to reduce the risk of issues. The preview should never be drawn
// while the surface has this size.
@@ -552,7 +547,7 @@ public class CameraPreview extends ViewGroup {
} else {
surfaceView.layout(surfaceRect.left, surfaceRect.top, surfaceRect.right, surfaceRect.bottom);
}
} else if(textureView != null) {
} else if (textureView != null) {
textureView.layout(0, 0, getWidth(), getHeight());
}
}
@@ -622,11 +617,11 @@ public class CameraPreview extends ViewGroup {
// The activity was paused but not stopped, so the surface still exists. Therefore
// surfaceCreated() won't be called, so init the camera here.
startPreviewIfReady();
} else if(surfaceView != null) {
} else if (surfaceView != null) {
// Install the callback and wait for surfaceCreated() to init the camera.
surfaceView.getHolder().addCallback(surfaceCallback);
} else if(textureView != null) {
if(textureView.isAvailable()) {
} else if (textureView != null) {
if (textureView.isAvailable()) {
surfaceTextureListener().onSurfaceTextureAvailable(textureView.getSurfaceTexture(), textureView.getWidth(), textureView.getHeight());
} else {
textureView.setSurfaceTextureListener(surfaceTextureListener());
@@ -661,7 +656,7 @@ public class CameraPreview extends ViewGroup {
SurfaceHolder surfaceHolder = surfaceView.getHolder();
surfaceHolder.removeCallback(surfaceCallback);
}
if(currentSurfaceSize == null && textureView != null) {
if (currentSurfaceSize == null && textureView != null) {
textureView.setSurfaceTextureListener(null);
}
@@ -683,7 +678,7 @@ public class CameraPreview extends ViewGroup {
pause();
long startTime = System.nanoTime();
while(instance != null && !instance.isCameraClosed()) {
if(System.nanoTime() - startTime > 2000000000) {
if (System.nanoTime() - startTime > 2000000000) {
// Don't wait for longer than 2 seconds
break;
}
@@ -719,7 +714,7 @@ public class CameraPreview extends ViewGroup {
* @param marginFraction the fraction
*/
public void setMarginFraction(double marginFraction) {
if(marginFraction >= 0.5d) {
if (marginFraction >= 0.5d) {
throw new IllegalArgumentException("The margin fraction must be less than 0.5");
}
this.marginFraction = marginFraction;
@@ -840,7 +835,7 @@ public class CameraPreview extends ViewGroup {
Rect intersection = new Rect(container);
boolean intersects = intersection.intersect(surface);
if(framingRectSize != null) {
if (framingRectSize != null) {
// Specific size is specified. Make sure it's not larger than the container or surface.
int horizontalMargin = Math.max(0, (intersection.width() - framingRectSize.width) / 2);
int verticalMargin = Math.max(0, (intersection.height() - framingRectSize.height) / 2);
@@ -869,7 +864,7 @@ public class CameraPreview extends ViewGroup {
@Override
protected void onRestoreInstanceState(Parcelable state) {
if(!(state instanceof Bundle)) {
if (!(state instanceof Bundle)) {
super.onRestoreInstanceState(state);
return;
}
@@ -4,7 +4,6 @@ import android.Manifest;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
@@ -13,14 +12,15 @@ import android.graphics.Bitmap;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.util.Log;
import android.view.Display;
import android.view.Surface;
import android.view.Window;
import android.view.WindowManager;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.google.zxing.ResultMetadataType;
import com.google.zxing.ResultPoint;
import com.google.zxing.client.android.BeepManager;
@@ -61,6 +61,9 @@ public class CaptureManager {
private static final String SAVED_ORIENTATION_LOCK = "SAVED_ORIENTATION_LOCK";
private boolean returnBarcodeImagePath = false;
private boolean showDialogIfMissingCameraPermission = true;
private String missingCameraPermissionDialogMessage = "";
private boolean destroyed = false;
private InactivityTimer inactivityTimer;
@@ -76,13 +79,7 @@ public class CaptureManager {
barcodeView.pause();
beepManager.playBeepSoundAndVibrate();
handler.post(new Runnable() {
@Override
public void run() {
returnResult(result);
}
});
handler.post(() -> returnResult(result));
}
@Override
@@ -109,12 +106,14 @@ public class CaptureManager {
@Override
public void cameraError(Exception error) {
displayFrameworkBugMessageAndExit();
displayFrameworkBugMessageAndExit(
activity.getString(R.string.zxing_msg_camera_framework_bug)
);
}
@Override
public void cameraClosed() {
if(finishWhenClosed) {
if (finishWhenClosed) {
Log.d(TAG, "Camera closed; finishing activity");
finish();
}
@@ -128,12 +127,9 @@ public class CaptureManager {
handler = new Handler();
inactivityTimer = new InactivityTimer(activity, new Runnable() {
@Override
public void run() {
Log.d(TAG, "Finishing due to inactivity");
finish();
}
inactivityTimer = new InactivityTimer(activity, () -> {
Log.d(TAG, "Finishing due to inactivity");
finish();
});
beepManager = new BeepManager(activity);
@@ -156,7 +152,7 @@ public class CaptureManager {
this.orientationLock = savedInstanceState.getInt(SAVED_ORIENTATION_LOCK, ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}
if(intent != null) {
if (intent != null) {
// Only lock the orientation if it's not locked to something else yet
boolean orientationLocked = intent.getBooleanExtra(Intents.Scan.ORIENTATION_LOCKED, true);
if (orientationLocked) {
@@ -171,14 +167,15 @@ public class CaptureManager {
beepManager.setBeepEnabled(false);
}
if (intent.hasExtra(Intents.Scan.SHOW_MISSING_CAMERA_PERMISSION_DIALOG)) {
setShowMissingCameraPermissionDialog(
intent.getBooleanExtra(Intents.Scan.SHOW_MISSING_CAMERA_PERMISSION_DIALOG, true),
intent.getStringExtra(Intents.Scan.MISSING_CAMERA_PERMISSION_DIALOG_MESSAGE)
);
}
if (intent.hasExtra(Intents.Scan.TIMEOUT)) {
Runnable runnable = new Runnable() {
@Override
public void run() {
returnResultTimeout();
}
};
handler.postDelayed(runnable, intent.getLongExtra(Intents.Scan.TIMEOUT, 0L));
handler.postDelayed(this::returnResultTimeout, intent.getLongExtra(Intents.Scan.TIMEOUT, 0L));
}
if (intent.getBooleanExtra(Intents.Scan.BARCODE_IMAGE_ENABLED, false)) {
@@ -229,7 +226,7 @@ public class CaptureManager {
* Call from Activity#onResume().
*/
public void onResume() {
if(Build.VERSION.SDK_INT >= 23) {
if (Build.VERSION.SDK_INT >= 23) {
openCameraWithPermission();
} else {
barcodeView.resume();
@@ -244,14 +241,12 @@ public class CaptureManager {
if (ContextCompat.checkSelfPermission(this.activity, Manifest.permission.CAMERA)
== PackageManager.PERMISSION_GRANTED) {
barcodeView.resume();
} else if(!askedPermission) {
} else if (!askedPermission) {
ActivityCompat.requestPermissions(this.activity,
new String[]{Manifest.permission.CAMERA},
cameraPermissionReqCode);
askedPermission = true;
} else {
// Wait for permission result
}
} // else wait for permission result
}
/**
@@ -263,13 +258,18 @@ public class CaptureManager {
* or {@link android.content.pm.PackageManager#PERMISSION_DENIED}. Never null.
*/
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
if(requestCode == cameraPermissionReqCode) {
if (requestCode == cameraPermissionReqCode) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted
barcodeView.resume();
} else {
// TODO: display better error message.
displayFrameworkBugMessageAndExit();
setMissingCameraPermissionResult();
if (showDialogIfMissingCameraPermission) {
displayFrameworkBugMessageAndExit(missingCameraPermissionDialogMessage);
} else {
closeAndFinish();
}
}
}
}
@@ -374,7 +374,7 @@ public class CaptureManager {
}
protected void closeAndFinish() {
if(barcodeView.getBarcodeView().isCameraClosed()) {
if (barcodeView.getBarcodeView().isCameraClosed()) {
finish();
} else {
finishWhenClosed = true;
@@ -384,6 +384,12 @@ public class CaptureManager {
inactivityTimer.cancel();
}
private void setMissingCameraPermissionResult() {
Intent intent = new Intent(Intents.Scan.ACTION);
intent.putExtra(Intents.Scan.MISSING_CAMERA_PERMISSION, true);
activity.setResult(Activity.RESULT_CANCELED, intent);
}
protected void returnResultTimeout() {
Intent intent = new Intent(Intents.Scan.ACTION);
intent.putExtra(Intents.Scan.TIMEOUT, true);
@@ -397,25 +403,20 @@ public class CaptureManager {
closeAndFinish();
}
protected void displayFrameworkBugMessageAndExit() {
protected void displayFrameworkBugMessageAndExit(String message) {
if (activity.isFinishing() || this.destroyed || finishWhenClosed) {
return;
}
if (message.isEmpty()) {
message = activity.getString(R.string.zxing_msg_camera_framework_bug);
}
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setTitle(activity.getString(R.string.zxing_app_name));
builder.setMessage(activity.getString(R.string.zxing_msg_camera_framework_bug));
builder.setPositiveButton(R.string.zxing_button_ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
finish();
}
});
builder.setMessage(message);
builder.setPositiveButton(R.string.zxing_button_ok, (dialog, which) -> finish());
builder.setOnCancelListener(dialog -> finish());
builder.show();
}
@@ -426,4 +427,29 @@ public class CaptureManager {
public static void setCameraPermissionReqCode(int cameraPermissionReqCode) {
CaptureManager.cameraPermissionReqCode = cameraPermissionReqCode;
}
/**
* If set to true, shows the default error dialog if camera permission is missing.
* <p>
* If set to false, instead the capture manager just finishes.
* <p>
* In both cases, the activity result is set to {@link Intents.Scan#MISSING_CAMERA_PERMISSION}
* and cancelled
*/
public void setShowMissingCameraPermissionDialog(boolean visible) {
setShowMissingCameraPermissionDialog(visible, "");
}
/**
* If set to true, shows the specified error dialog message if camera permission is missing.
* <p>
* If set to false, instead the capture manager just finishes.
* <p>
* In both cases, the activity result is set to {@link Intents.Scan#MISSING_CAMERA_PERMISSION}
* and cancelled
*/
public void setShowMissingCameraPermissionDialog(boolean visible, String message) {
showDialogIfMissingCameraPermission = visible;
missingCameraPermissionDialogMessage = message != null ? message : "";
}
}
@@ -26,7 +26,7 @@ public class DecoderResultPointCallback implements ResultPointCallback {
@Override
public void foundPossibleResultPoint(ResultPoint point) {
if(decoder != null) {
if (decoder != null) {
decoder.foundPossibleResultPoint(point);
}
}
@@ -36,7 +36,7 @@ public class DecoderThread {
public boolean handleMessage(Message message) {
if (message.what == R.id.zxing_decode) {
decode((SourceData) message.obj);
} else if(message.what == R.id.zxing_preview_failed) {
} else if (message.what == R.id.zxing_preview_failed) {
// Error already logged. Try again.
requestNextPreview();
}
@@ -142,7 +142,7 @@ public class DecoderThread {
sourceData.setCropRect(cropRect);
LuminanceSource source = createSource(sourceData);
if(source != null) {
if (source != null) {
rawResult = decoder.decode(source);
}
@@ -90,7 +90,7 @@ public class DecoratedBarcodeView extends FrameLayout {
inflate(getContext(), scannerLayout, this);
barcodeView = (BarcodeView) findViewById(R.id.zxing_barcode_surface);
barcodeView = findViewById(R.id.zxing_barcode_surface);
if (barcodeView == null) {
throw new IllegalArgumentException(
@@ -102,7 +102,7 @@ public class DecoratedBarcodeView extends FrameLayout {
barcodeView.initializeAttributes(attrs);
viewFinder = (ViewfinderView) findViewById(R.id.zxing_viewfinder_view);
viewFinder = findViewById(R.id.zxing_viewfinder_view);
if (viewFinder == null) {
throw new IllegalArgumentException(
@@ -113,11 +113,11 @@ public class DecoratedBarcodeView extends FrameLayout {
viewFinder.setCameraPreview(barcodeView);
// statusView is optional
statusView = (TextView) findViewById(R.id.zxing_status_view);
statusView = findViewById(R.id.zxing_status_view);
}
/**
* Initialize with no custom attributes setted.
* Initialize with no custom attributes set.
*/
private void initialize() {
initialize(null);
@@ -143,7 +143,7 @@ public class DecoratedBarcodeView extends FrameLayout {
}
if (intent.hasExtra(Intents.Scan.TORCH_ENABLED)) {
if(intent.getBooleanExtra(Intents.Scan.TORCH_ENABLED, false)) {
if (intent.getBooleanExtra(Intents.Scan.TORCH_ENABLED, false)) {
this.setTorchOn();
}
}
@@ -183,7 +183,7 @@ public class DecoratedBarcodeView extends FrameLayout {
public void setStatusText(String text) {
// statusView is optional when using a custom layout
if(statusView != null) {
if (statusView != null) {
statusView.setText(text);
}
}
@@ -210,7 +210,7 @@ public class DecoratedBarcodeView extends FrameLayout {
}
public BarcodeView getBarcodeView() {
return (BarcodeView) findViewById(R.id.zxing_barcode_surface);
return findViewById(R.id.zxing_barcode_surface);
}
public ViewfinderView getViewFinder() {
@@ -39,11 +39,11 @@ public class DefaultDecoderFactory implements DecoderFactory {
hints.putAll(baseHints);
if(this.hints != null) {
if (this.hints != null) {
hints.putAll(this.hints);
}
if(this.decodeFormats != null) {
if (this.decodeFormats != null) {
hints.put(DecodeHintType.POSSIBLE_FORMATS, decodeFormats);
}
@@ -40,7 +40,7 @@ public class RotationListener {
public void onOrientationChanged(int orientation) {
WindowManager localWindowManager = windowManager;
RotationCallback localCallback = RotationListener.this.callback;
if(windowManager != null && localCallback != null) {
if (windowManager != null && localCallback != null) {
int newRotation = localWindowManager.getDefaultDisplay().getRotation();
if (newRotation != lastRotation) {
lastRotation = newRotation;
@@ -57,7 +57,7 @@ public class RotationListener {
public void stop() {
// To reduce the effect of possible leaks, we clear any references we have to external
// objects.
if(this.orientationEventListener != null) {
if (this.orientationEventListener != null) {
this.orientationEventListener.disable();
}
this.orientationEventListener = null;
@@ -0,0 +1,21 @@
package com.journeyapps.barcodescanner;
import android.content.Context;
import android.content.Intent;
import androidx.activity.result.contract.ActivityResultContract;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
public class ScanContract extends ActivityResultContract<ScanOptions, ScanIntentResult> {
@NonNull
@Override
public Intent createIntent(@NonNull Context context, ScanOptions input) {
return input.createScanIntent(context);
}
@Override
public ScanIntentResult parseResult(int resultCode, @Nullable Intent intent) {
return ScanIntentResult.parseActivityResult(resultCode, intent);
}
}
@@ -0,0 +1,155 @@
/*
* Based on IntentResult.
*
* Copyright 2009 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.journeyapps.barcodescanner;
import android.app.Activity;
import android.content.Intent;
import com.google.zxing.client.android.Intents;
import com.google.zxing.integration.android.IntentResult;
/**
* <p>Encapsulates the result of a barcode scan invoked through {@link ScanContract}.</p>
*
* @author Sean Owen
*/
public final class ScanIntentResult {
private final String contents;
private final String formatName;
private final byte[] rawBytes;
private final Integer orientation;
private final String errorCorrectionLevel;
private final String barcodeImagePath;
private final Intent originalIntent;
ScanIntentResult() {
this(null, null, null, null, null, null, null);
}
ScanIntentResult(Intent intent) {
this(null, null, null, null, null, null, intent);
}
ScanIntentResult(String contents,
String formatName,
byte[] rawBytes,
Integer orientation,
String errorCorrectionLevel,
String barcodeImagePath,
Intent originalIntent) {
this.contents = contents;
this.formatName = formatName;
this.rawBytes = rawBytes;
this.orientation = orientation;
this.errorCorrectionLevel = errorCorrectionLevel;
this.barcodeImagePath = barcodeImagePath;
this.originalIntent = originalIntent;
}
/**
* @return raw content of barcode
*/
public String getContents() {
return contents;
}
/**
* @return name of format, like "QR_CODE", "UPC_A". See {@code BarcodeFormat} for more format names.
*/
public String getFormatName() {
return formatName;
}
/**
* @return raw bytes of the barcode content, if applicable, or null otherwise
*/
public byte[] getRawBytes() {
return rawBytes;
}
/**
* @return rotation of the image, in degrees, which resulted in a successful scan. May be null.
*/
public Integer getOrientation() {
return orientation;
}
/**
* @return name of the error correction level used in the barcode, if applicable
*/
public String getErrorCorrectionLevel() {
return errorCorrectionLevel;
}
/**
* @return path to a temporary file containing the barcode image, if applicable, or null otherwise
*/
public String getBarcodeImagePath() {
return barcodeImagePath;
}
/**
* @return the original intent
*/
public Intent getOriginalIntent() {
return originalIntent;
}
@Override
public String toString() {
int rawBytesLength = rawBytes == null ? 0 : rawBytes.length;
return "Format: " + formatName + '\n' +
"Contents: " + contents + '\n' +
"Raw bytes: (" + rawBytesLength + " bytes)\n" +
"Orientation: " + orientation + '\n' +
"EC level: " + errorCorrectionLevel + '\n' +
"Barcode image: " + barcodeImagePath + '\n' +
"Original intent: " + originalIntent + '\n';
}
/**
* Parse activity result, without checking the request code.
*
* @param resultCode result code from {@code onActivityResult()}
* @param intent {@link Intent} from {@code onActivityResult()}
* @return an {@link IntentResult} containing the result of the scan. If the user cancelled scanning,
* the fields will be null.
*/
public static ScanIntentResult parseActivityResult(int resultCode, Intent intent) {
if (resultCode == Activity.RESULT_OK) {
String contents = intent.getStringExtra(Intents.Scan.RESULT);
String formatName = intent.getStringExtra(Intents.Scan.RESULT_FORMAT);
byte[] rawBytes = intent.getByteArrayExtra(Intents.Scan.RESULT_BYTES);
int intentOrientation = intent.getIntExtra(Intents.Scan.RESULT_ORIENTATION, Integer.MIN_VALUE);
Integer orientation = intentOrientation == Integer.MIN_VALUE ? null : intentOrientation;
String errorCorrectionLevel = intent.getStringExtra(Intents.Scan.RESULT_ERROR_CORRECTION_LEVEL);
String barcodeImagePath = intent.getStringExtra(Intents.Scan.RESULT_BARCODE_IMAGE_PATH);
return new ScanIntentResult(contents,
formatName,
rawBytes,
orientation,
errorCorrectionLevel,
barcodeImagePath,
intent);
}
return new ScanIntentResult(intent);
}
}
@@ -0,0 +1,262 @@
/*
* Based on IntentIntegrator, Copyright 2009 ZXing authors.
*
*/
package com.journeyapps.barcodescanner;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import com.google.zxing.client.android.Intents;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ScanOptions {
// supported barcode formats
// Product Codes
public static final String UPC_A = "UPC_A";
public static final String UPC_E = "UPC_E";
public static final String EAN_8 = "EAN_8";
public static final String EAN_13 = "EAN_13";
public static final String RSS_14 = "RSS_14";
// Other 1D
public static final String CODE_39 = "CODE_39";
public static final String CODE_93 = "CODE_93";
public static final String CODE_128 = "CODE_128";
public static final String ITF = "ITF";
public static final String RSS_EXPANDED = "RSS_EXPANDED";
// 2D
public static final String QR_CODE = "QR_CODE";
public static final String DATA_MATRIX = "DATA_MATRIX";
public static final String PDF_417 = "PDF_417";
public static final Collection<String> PRODUCT_CODE_TYPES = list(UPC_A, UPC_E, EAN_8, EAN_13, RSS_14);
public static final Collection<String> ONE_D_CODE_TYPES =
list(UPC_A, UPC_E, EAN_8, EAN_13, RSS_14, CODE_39, CODE_93, CODE_128,
ITF, RSS_14, RSS_EXPANDED);
public static final Collection<String> ALL_CODE_TYPES = null;
private final Map<String, Object> moreExtras = new HashMap<>(3);
private Collection<String> desiredBarcodeFormats;
private Class<?> captureActivity;
protected Class<?> getDefaultCaptureActivity() {
return CaptureActivity.class;
}
public ScanOptions() {
}
public Class<?> getCaptureActivity() {
if (captureActivity == null) {
captureActivity = getDefaultCaptureActivity();
}
return captureActivity;
}
/**
* Set the Activity class to use. It can be any activity, but should handle the intent extras
* as used here.
*
* @param captureActivity the class
*/
public ScanOptions setCaptureActivity(Class<?> captureActivity) {
this.captureActivity = captureActivity;
return this;
}
public Map<String, ?> getMoreExtras() {
return moreExtras;
}
public final ScanOptions addExtra(String key, Object value) {
moreExtras.put(key, value);
return this;
}
/**
* Set a prompt to display on the capture screen, instead of using the default.
*
* @param prompt the prompt to display
*/
public final ScanOptions setPrompt(String prompt) {
if (prompt != null) {
addExtra(Intents.Scan.PROMPT_MESSAGE, prompt);
}
return this;
}
/**
* By default, the orientation is locked. Set to false to not lock.
*
* @param locked true to lock orientation
*/
public ScanOptions setOrientationLocked(boolean locked) {
addExtra(Intents.Scan.ORIENTATION_LOCKED, locked);
return this;
}
/**
* Use the specified camera ID.
*
* @param cameraId camera ID of the camera to use. A negative value means "no preference".
* @return this
*/
public ScanOptions setCameraId(int cameraId) {
if (cameraId >= 0) {
addExtra(Intents.Scan.CAMERA_ID, cameraId);
}
return this;
}
/**
* Set to true to enable initial torch
*
* @param enabled true to enable initial torch
* @return this
*/
public ScanOptions setTorchEnabled(boolean enabled) {
addExtra(Intents.Scan.TORCH_ENABLED, enabled);
return this;
}
/**
* Set to false to disable beep on scan.
*
* @param enabled false to disable beep
* @return this
*/
public ScanOptions setBeepEnabled(boolean enabled) {
addExtra(Intents.Scan.BEEP_ENABLED, enabled);
return this;
}
/**
* Set to true to enable saving the barcode image and sending its path in the result Intent.
*
* @param enabled true to enable barcode image
* @return this
*/
public ScanOptions setBarcodeImageEnabled(boolean enabled) {
addExtra(Intents.Scan.BARCODE_IMAGE_ENABLED, enabled);
return this;
}
/**
* Set the desired barcode formats to scan.
*
* @param desiredBarcodeFormats names of {@code BarcodeFormat}s to scan for
* @return this
*/
public ScanOptions setDesiredBarcodeFormats(Collection<String> desiredBarcodeFormats) {
this.desiredBarcodeFormats = desiredBarcodeFormats;
return this;
}
/**
* Set the desired barcode formats to scan.
*
* @param desiredBarcodeFormats names of {@code BarcodeFormat}s to scan for
* @return this
*/
public ScanOptions setDesiredBarcodeFormats(String... desiredBarcodeFormats) {
this.desiredBarcodeFormats = Arrays.asList(desiredBarcodeFormats);
return this;
}
/**
* Initiates a scan for all known barcode types with the default camera.
* And starts a timer to finish on timeout
*
* @return Activity.RESULT_CANCELED and true on parameter TIMEOUT.
*/
public ScanOptions setTimeout(long timeout) {
addExtra(Intents.Scan.TIMEOUT, timeout);
return this;
}
/**
* Create an scan intent with the specified options.
*
* @return the intent
*/
public Intent createScanIntent(Context context) {
Intent intentScan = new Intent(context, getCaptureActivity());
intentScan.setAction(Intents.Scan.ACTION);
// check which types of codes to scan for
if (desiredBarcodeFormats != null) {
// set the desired barcode types
StringBuilder joinedByComma = new StringBuilder();
for (String format : desiredBarcodeFormats) {
if (joinedByComma.length() > 0) {
joinedByComma.append(',');
}
joinedByComma.append(format);
}
intentScan.putExtra(Intents.Scan.FORMATS, joinedByComma.toString());
}
intentScan.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intentScan.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
attachMoreExtras(intentScan);
return intentScan;
}
private static List<String> list(String... values) {
return Collections.unmodifiableList(Arrays.asList(values));
}
private void attachMoreExtras(Intent intent) {
for (Map.Entry<String, Object> entry : moreExtras.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
// Kind of hacky
if (value instanceof Integer) {
intent.putExtra(key, (Integer) value);
} else if (value instanceof Long) {
intent.putExtra(key, (Long) value);
} else if (value instanceof Boolean) {
intent.putExtra(key, (Boolean) value);
} else if (value instanceof Double) {
intent.putExtra(key, (Double) value);
} else if (value instanceof Float) {
intent.putExtra(key, (Float) value);
} else if (value instanceof Bundle) {
intent.putExtra(key, (Bundle) value);
} else if (value instanceof int[]) {
intent.putExtra(key, (int[]) value);
} else if (value instanceof long[]) {
intent.putExtra(key, (long[]) value);
} else if (value instanceof boolean[]) {
intent.putExtra(key, (boolean[]) value);
} else if (value instanceof double[]) {
intent.putExtra(key, (double[]) value);
} else if (value instanceof float[]) {
intent.putExtra(key, (float[]) value);
} else if (value instanceof String[]) {
intent.putExtra(key, (String[]) value);
} else {
intent.putExtra(key, value.toString());
}
}
}
}
@@ -43,7 +43,7 @@ public class Size implements Comparable<Size> {
* @return the scaled size
*/
public Size scaleFit(Size into) {
if(width * into.height >= into.width * height) {
if (width * into.height >= into.width * height) {
// match width
return new Size(into.width, height * into.width / width);
} else {
@@ -59,7 +59,7 @@ public class Size implements Comparable<Size> {
* @return the scaled size
*/
public Size scaleCrop(Size into) {
if(width * into.height <= into.width * height) {
if (width * into.height <= into.width * height) {
// match width
return new Size(into.width, height * into.width / width);
} else {
@@ -45,7 +45,7 @@ public class SourceData {
this.data = new RawImageData(data, dataWidth, dataHeight);
this.rotation = rotation;
this.imageFormat = imageFormat;
if(dataWidth * dataHeight > data.length) {
if (dataWidth * dataHeight > data.length) {
throw new IllegalArgumentException("Image data does not match the resolution. " + dataWidth + "x" + dataHeight + " > " + data.length);
}
}
@@ -150,7 +150,7 @@ public class SourceData {
public Bitmap getBitmap(Rect cropRect, int scaleFactor) {
if (cropRect == null) {
cropRect = new Rect(0, 0, data.getWidth(), data.getHeight());
} else if(isRotated()) {
} else if (isRotated()) {
//noinspection SuspiciousNameCombination
cropRect = new Rect(cropRect.top, cropRect.left, cropRect.bottom, cropRect.right);
}
@@ -16,7 +16,6 @@
package com.journeyapps.barcodescanner;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
@@ -54,6 +53,7 @@ public class ViewfinderView extends View {
protected final int resultColor;
protected final int laserColor;
protected final int resultPointColor;
protected boolean laserVisibility;
protected int scannerAlpha;
protected List<ResultPoint> possibleResultPoints;
protected List<ResultPoint> lastPossibleResultPoints;
@@ -73,7 +73,7 @@ public class ViewfinderView extends View {
Resources resources = getResources();
// Get setted attributes on view
// Get set attributes on view
TypedArray attributes = getContext().obtainStyledAttributes(attrs, R.styleable.zxing_finder);
this.maskColor = attributes.getColor(R.styleable.zxing_finder_zxing_viewfinder_mask,
@@ -84,6 +84,8 @@ public class ViewfinderView extends View {
resources.getColor(R.color.zxing_viewfinder_laser));
this.resultPointColor = attributes.getColor(R.styleable.zxing_finder_zxing_possible_result_points,
resources.getColor(R.color.zxing_possible_result_points));
this.laserVisibility = attributes.getBoolean(R.styleable.zxing_finder_zxing_viewfinder_laser_visibility,
true);
attributes.recycle();
@@ -124,12 +126,12 @@ public class ViewfinderView extends View {
}
protected void refreshSizes() {
if(cameraPreview == null) {
if (cameraPreview == null) {
return;
}
Rect framingRect = cameraPreview.getFramingRect();
Size previewSize = cameraPreview.getPreviewSize();
if(framingRect != null && previewSize != null) {
if (framingRect != null && previewSize != null) {
this.framingRect = framingRect;
this.previewSize = previewSize;
}
@@ -145,8 +147,8 @@ public class ViewfinderView extends View {
final Rect frame = framingRect;
final Size previewSize = this.previewSize;
final int width = canvas.getWidth();
final int height = canvas.getHeight();
final int width = getWidth();
final int height = getHeight();
// Draw the exterior (i.e. outside the framing rect) darkened
paint.setColor(resultBitmap != null ? resultColor : maskColor);
@@ -160,13 +162,16 @@ public class ViewfinderView extends View {
paint.setAlpha(CURRENT_POINT_OPACITY);
canvas.drawBitmap(resultBitmap, null, frame, paint);
} else {
// If wanted, draw a red "laser scanner" line through the middle to show decoding is active
if (laserVisibility) {
paint.setColor(laserColor);
// Draw a red "laser scanner" line through the middle to show decoding is active
paint.setColor(laserColor);
paint.setAlpha(SCANNER_ALPHA[scannerAlpha]);
scannerAlpha = (scannerAlpha + 1) % SCANNER_ALPHA.length;
final int middle = frame.height() / 2 + frame.top;
canvas.drawRect(frame.left + 2, middle - 1, frame.right - 1, middle + 2, paint);
paint.setAlpha(SCANNER_ALPHA[scannerAlpha]);
scannerAlpha = (scannerAlpha + 1) % SCANNER_ALPHA.length;
final int middle = frame.height() / 2 + frame.top;
canvas.drawRect(frame.left + 2, middle - 1, frame.right - 1, middle + 2, paint);
}
final float scaleX = this.getWidth() / (float) previewSize.width;
final float scaleY = this.getHeight() / (float) previewSize.height;
@@ -247,4 +252,8 @@ public class ViewfinderView extends View {
public void setMaskColor(int maskColor) {
this.maskColor = maskColor;
}
public void setLaserVisibility(boolean visible) {
this.laserVisibility = visible;
}
}
@@ -64,12 +64,9 @@ public final class AutoFocusManager {
private final Camera.AutoFocusCallback autoFocusCallback = new Camera.AutoFocusCallback() {
@Override
public void onAutoFocus(boolean success, Camera theCamera) {
handler.post(new Runnable() {
@Override
public void run() {
focusing = false;
autoFocusAgainLater();
}
handler.post(() -> {
focusing = false;
autoFocusAgainLater();
});
}
};
@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.google.zxing.client.android.camera;
package com.journeyapps.barcodescanner.camera;
import android.annotation.TargetApi;
import android.graphics.Rect;
@@ -138,12 +138,7 @@ public class CameraInstance {
Util.validateMainThread();
if (open) {
cameraThread.enqueue(new Runnable() {
@Override
public void run() {
cameraManager.setTorch(on);
}
});
cameraThread.enqueue(() -> cameraManager.setTorch(on));
}
}
@@ -156,12 +151,7 @@ public class CameraInstance {
Util.validateMainThread();
if (open) {
cameraThread.enqueue(new Runnable() {
@Override
public void run() {
cameraManager.changeCameraParameters(callback);
}
});
cameraThread.enqueue(() -> cameraManager.changeCameraParameters(callback));
}
}
@@ -186,21 +176,13 @@ public class CameraInstance {
}
public void requestPreview(final PreviewCallback callback) {
mainHandler.post(new Runnable() {
@Override
public void run() {
if(!open) {
Log.d(TAG, "Camera is closed, not requesting preview");
return;
}
cameraThread.enqueue(new Runnable() {
@Override
public void run() {
cameraManager.requestPreviewFrame(callback);
}
});
mainHandler.post(() -> {
if (!open) {
Log.d(TAG, "Camera is closed, not requesting preview");
return;
}
cameraThread.enqueue(() -> cameraManager.requestPreviewFrame(callback));
});
}
@@ -24,7 +24,6 @@ import android.view.Surface;
import android.view.SurfaceHolder;
import com.google.zxing.client.android.AmbientLightManager;
import com.google.zxing.client.android.camera.CameraConfigurationUtils;
import com.google.zxing.client.android.camera.open.OpenCameraInterface;
import com.journeyapps.barcodescanner.Size;
import com.journeyapps.barcodescanner.SourceData;
@@ -97,7 +96,7 @@ public final class CameraManager {
PreviewCallback callback = this.callback;
if (cameraResolution != null && callback != null) {
try {
if(data == null) {
if (data == null) {
throw new NullPointerException("No preview data received");
}
int format = camera.getParameters().getPreviewFormat();
@@ -116,7 +115,7 @@ public final class CameraManager {
}
} else {
Log.d(TAG, "Got preview callback, but no handler or resolution available");
if(callback != null) {
if (callback != null) {
// Should generally not happen
callback.onPreviewError(new Exception("No resolution available"));
}
@@ -157,7 +156,7 @@ public final class CameraManager {
* Must be called from camera thread.
*/
public void configure() {
if(camera == null) {
if (camera == null) {
throw new RuntimeException("Camera not open");
}
setParameters();
@@ -227,7 +226,7 @@ public final class CameraManager {
* @return true if the camera rotation is perpendicular to the current display rotation.
*/
public boolean isCameraRotated() {
if(rotationDegrees == -1) {
if (rotationDegrees == -1) {
throw new IllegalStateException("Rotation not calculated yet. Call configure() first.");
}
return rotationDegrees % 180 != 0;
@@ -281,11 +280,9 @@ public final class CameraManager {
}
if (settings.isMeteringEnabled()) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
CameraConfigurationUtils.setVideoStabilization(parameters);
CameraConfigurationUtils.setFocusArea(parameters);
CameraConfigurationUtils.setMetering(parameters);
}
CameraConfigurationUtils.setVideoStabilization(parameters);
CameraConfigurationUtils.setFocusArea(parameters);
CameraConfigurationUtils.setMetering(parameters);
}
}
@@ -17,14 +17,14 @@ public class CameraSurface {
private SurfaceTexture surfaceTexture;
public CameraSurface(SurfaceHolder surfaceHolder) {
if(surfaceHolder == null) {
if (surfaceHolder == null) {
throw new IllegalArgumentException("surfaceHolder may not be null");
}
this.surfaceHolder = surfaceHolder;
}
public CameraSurface(SurfaceTexture surfaceTexture) {
if(surfaceTexture == null) {
if (surfaceTexture == null) {
throw new IllegalArgumentException("surfaceTexture may not be null");
}
this.surfaceTexture = surfaceTexture;
@@ -39,7 +39,7 @@ public class CameraSurface {
}
public void setPreview(Camera camera) throws IOException {
if(surfaceHolder != null) {
if (surfaceHolder != null) {
camera.setPreviewDisplay(surfaceHolder);
} else {
camera.setPreviewTexture(surfaceTexture);
@@ -27,7 +27,7 @@ public class CenterCropStrategy extends PreviewScalingStrategy {
*/
@Override
protected float getScore(Size size, Size desired) {
if(size.width <= 0 || size.height <= 0) {
if (size.width <= 0 || size.height <= 0) {
return 0f;
}
Size scaled = size.scaleCrop(desired);
@@ -36,7 +36,7 @@ public class CenterCropStrategy extends PreviewScalingStrategy {
// Treat downscaling as slightly better than upscaling
float scaleScore;
if(scaleRatio > 1.0f) {
if (scaleRatio > 1.0f) {
// Upscaling
scaleScore = (float)Math.pow(1.0f / scaleRatio, 1.1);
} else {
@@ -27,7 +27,7 @@ public class FitCenterStrategy extends PreviewScalingStrategy {
*/
@Override
protected float getScore(Size size, Size desired) {
if(size.width <= 0 || size.height <= 0) {
if (size.width <= 0 || size.height <= 0) {
return 0f;
}
Size scaled = size.scaleFit(desired);
@@ -36,7 +36,7 @@ public class FitCenterStrategy extends PreviewScalingStrategy {
// Treat downscaling as slightly better than upscaling
float scaleScore;
if(scaleRatio > 1.0f) {
if (scaleRatio > 1.0f) {
// Upscaling
scaleScore = (float)Math.pow(1.0f / scaleRatio, 1.1);
} else {
@@ -12,7 +12,7 @@ public class FitXYStrategy extends PreviewScalingStrategy {
private static float absRatio(float ratio) {
if(ratio < 1.0f) {
if (ratio < 1.0f) {
return 1.0f / ratio;
} else {
return ratio;
@@ -33,7 +33,7 @@ public class FitXYStrategy extends PreviewScalingStrategy {
*/
@Override
protected float getScore(Size size, Size desired) {
if(size.width <= 0 || size.height <= 0) {
if (size.width <= 0 || size.height <= 0) {
return 0f;
}
float scaleX = absRatio(size.width * 1.0f / desired.width);