Compare commits
64 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d09b7c76c3 | |||
| 3a2db7ffc6 | |||
| 2a65a6c973 | |||
| 3c77f1d6c8 | |||
| b6c6421dd5 | |||
| 8173d4a8b2 | |||
| 8fdbbbef5e | |||
| 2324a5403e | |||
| c752130405 | |||
| 1c27c8fe2d | |||
| aa129af542 | |||
| 90b5db5fcd | |||
| 24d02945fe | |||
| 6ccf3a9d1a | |||
| 23f29e5a56 | |||
| 1a8d949325 | |||
| f1554b7478 | |||
| cc12c103e0 | |||
| a13ce2b161 | |||
| 0c97cf70cc | |||
| 9beeac7960 | |||
| cc34502f13 | |||
| 2221621de9 | |||
| 4d4c5a2c4e | |||
| 65d2716c71 | |||
| 7fd1ab8794 | |||
| 630e3cc0f8 | |||
| 40260272fc | |||
| f54615e43a | |||
| 1acc3a6f4f | |||
| 73093b9b4f | |||
| db85816b3d | |||
| 6a3d857019 | |||
| 6c8ea7e3fd | |||
| 35ee545f8b | |||
| 5d9e2c3756 | |||
| cce2a300ef | |||
| 13440ad875 | |||
| 5a2470f034 | |||
| 545672bb8f | |||
| 542dc66090 | |||
| ea414a236e | |||
| 1ba1ded540 | |||
| 4893bcc194 | |||
| 6498fad6a7 | |||
| f7f779d7ac | |||
| c555ffbe05 | |||
| e0d340952d | |||
| 9b924e6875 | |||
| 8df0cb554a | |||
| 09d992ddfa | |||
| 95cd4a3a4d | |||
| 7e5bbd2997 | |||
| 8d8cd7d445 | |||
| bd857c68eb | |||
| 0fdfbce9fb | |||
| eba457ee9e | |||
| 9319110de8 | |||
| ee4b181f23 | |||
| a4f751500c | |||
| 75b4aa57f5 | |||
| eb4cbd5095 | |||
| aa4fca5dae | |||
| d22b581cd3 |
@@ -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*"
|
||||
@@ -8,3 +8,6 @@ maven-repository
|
||||
local.properties
|
||||
mvn-clone
|
||||
*.keystore
|
||||
.project
|
||||
.settings
|
||||
.classpath
|
||||
|
||||
-31
@@ -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
|
||||
+20
@@ -1,3 +1,23 @@
|
||||
### 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.
|
||||
|
||||
@@ -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
@@ -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.2'
|
||||
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
@@ -1,3 +1,3 @@
|
||||
android.enableJetifier=true
|
||||
android.enableJetifier=false
|
||||
android.useAndroidX=true
|
||||
org.gradle.jvmargs=-Xmx1536M
|
||||
|
||||
Vendored
BIN
Binary file not shown.
+1
-2
@@ -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
|
||||
|
||||
@@ -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
@@ -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 +0,0 @@
|
||||
/build
|
||||
+23
-10
@@ -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 402
|
||||
versionName "4.0.2"
|
||||
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,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'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -63,14 +72,18 @@ dependencies {
|
||||
// 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
|
||||
|
||||
@@ -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.
|
||||
@@ -91,23 +146,20 @@ project.afterEvaluate {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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'
|
||||
repositories {
|
||||
maven {
|
||||
name = "sonatype"
|
||||
url = "https://oss.sonatype.org/service/local/staging/deploy/maven2/"
|
||||
credentials {
|
||||
username ossrhUsername
|
||||
password ossrhPassword
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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.
|
||||
|
||||
+5
-2
@@ -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 : "";
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -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() {
|
||||
|
||||
+2
-2
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
+3
-6
@@ -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();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
+1
-1
@@ -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;
|
||||
+8
-26
@@ -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));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
+7
-10
@@ -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);
|
||||
|
||||
+2
-2
@@ -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 {
|
||||
|
||||
+2
-2
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user