Compare commits

...

27 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
25 changed files with 846 additions and 373 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*"
-36
View File
@@ -1,36 +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-.+'
branches:
only:
- master
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
+14
View File
@@ -1,3 +1,17 @@
### 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).
+103 -63
View File
@@ -13,33 +13,33 @@ 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+, see [Older SDK versions](#older-sdk-versions).
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.x, 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 {
mavenCentral()
}
dependencies {
implementation 'com.journeyapps:zxing-android-embedded:4.2.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
}
```
## Older SDK versions
For Android SDK versions < 24, you can downgrade `zxing:core` to 3.3.0 or earlier for Android 14+ support:
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 {
@@ -47,23 +47,69 @@ repositories {
}
dependencies {
implementation('com.journeyapps:zxing-android-embedded:4.2.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
}
}
```
You'll also need this in your Android manifest:
dependencies {
implementation 'com.journeyapps:zxing-android-embedded:4.3.0'
```xml
<uses-sdk tools:overrideLibrary="com.google.zxing.client.android" />
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
}
```
No guarantees are made on support for older SDK versions - you'll have to test to make sure it's compatible.
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
@@ -75,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
@@ -132,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.
@@ -152,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
@@ -191,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.
@@ -216,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
+4 -16
View File
@@ -2,16 +2,10 @@ buildscript {
repositories {
google()
mavenCentral()
jcenter {
content {
// https://youtrack.jetbrains.com/issue/IDEA-261387
includeModule("org.jetbrains.trove4j", "trove4j")
}
}
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.3'
classpath 'com.android.tools.build:gradle:7.0.3'
}
}
@@ -20,17 +14,11 @@ subprojects {
google()
mavenLocal()
mavenCentral()
jcenter {
content {
// https://youtrack.jetbrains.com/issue/IDEA-261387
includeModule("org.jetbrains.trove4j", "trove4j")
}
}
}
version = '4.2.0'
version = '4.3.0'
group = 'com.journeyapps'
ext.androidTargetSdk = 28
ext.zxingCore = 'com.google.zxing:core:3.4.0'
ext.androidTargetSdk = 30
ext.zxingCore = 'com.google.zxing:core:3.4.1'
}
+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-6.0-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
+19 -5
View File
@@ -4,7 +4,8 @@ android {
compileSdkVersion project.androidTargetSdk
defaultConfig {
minSdkVersion 24
multiDexEnabled true
minSdkVersion 19
targetSdkVersion project.androidTargetSdk
versionCode 411
versionName "4.1.1"
@@ -50,10 +51,19 @@ 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'
}
}
@@ -62,14 +72,18 @@ dependencies {
// implementation 'com.journeyapps:zxing-android-embedded:<version>'
implementation project(':zxing-android-embedded')
implementation 'androidx.appcompat:appcompat:1.1.0'
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'
}
@@ -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,55 +124,22 @@ 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) {
Intent originalIntent = result.getOriginalIntent();
if (originalIntent == null) {
Log.d("MainActivity", "Cancelled scan");
Toast.makeText(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(this, "Cancelled due to missing camera permission", 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) {
@@ -168,29 +150,7 @@ public class MainActivity extends AppCompatActivity {
}
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);
}
}
@@ -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"
+7 -5
View File
@@ -33,10 +33,11 @@ if (secretPropsFile.exists()) {
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.13'
testImplementation "org.mockito:mockito-core:1.9.5"
testImplementation 'junit:junit:4.13.1'
testImplementation 'org.mockito:mockito-core:1.9.5'
}
android {
@@ -50,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.
@@ -69,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 {
@@ -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>
@@ -23,6 +23,7 @@ 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;
@@ -94,8 +95,13 @@ public final class BeepManager {
public MediaPlayer playBeepSound() {
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setAudioAttributes(new AudioAttributes.Builder().setContentType(
AudioAttributes.CONTENT_TYPE_MUSIC).build());
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();
@@ -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) {
@@ -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;
}
}
@@ -266,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);
@@ -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());
}
}
}
}
@@ -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;
@@ -74,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,
@@ -148,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);
@@ -280,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);
}
}