Repository: MRYangY/YZxing
Branch: master
Commit: 00fe62b5ab69
Files: 65
Total size: 144.1 KB
Directory structure:
gitextract_56lrij_q/
├── .gitignore
├── .idea/
│ ├── caches/
│ │ └── build_file_checksums.ser
│ ├── codeStyles/
│ │ └── Project.xml
│ ├── inspectionProfiles/
│ │ └── Project_Default.xml
│ ├── misc.xml
│ ├── modules.xml
│ ├── runConfigurations.xml
│ └── vcs.xml
├── LICENSE
├── README.md
├── YZxing-lib/
│ ├── .gitignore
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src/
│ ├── androidTest/
│ │ └── java/
│ │ └── com/
│ │ └── example/
│ │ └── qrcode/
│ │ └── ExampleInstrumentedTest.java
│ ├── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── example/
│ │ │ └── qrcode/
│ │ │ ├── BarcodeActivity.java
│ │ │ ├── BeepManager.java
│ │ │ ├── Constant.java
│ │ │ ├── ScannerActivity.java
│ │ │ ├── ShowResultActivity.java
│ │ │ ├── callback/
│ │ │ │ └── PreviewCallback.java
│ │ │ ├── camera/
│ │ │ │ ├── AutoFocusManager.java
│ │ │ │ ├── CameraConfigurationManager.java
│ │ │ │ ├── CameraFacing.java
│ │ │ │ ├── CameraManager.java
│ │ │ │ ├── OpenCamera.java
│ │ │ │ └── OpenCameraInterface.java
│ │ │ ├── decode/
│ │ │ │ ├── DecodeHandler.java
│ │ │ │ ├── DecodeThread.java
│ │ │ │ ├── InactivityTimer.java
│ │ │ │ └── ScannerHandler.java
│ │ │ ├── utils/
│ │ │ │ ├── CameraConfigurationUtils.java
│ │ │ │ ├── CommonUtils.java
│ │ │ │ ├── DecodeUtils.java
│ │ │ │ └── UriUtils.java
│ │ │ └── view/
│ │ │ └── ScannerView.java
│ │ └── res/
│ │ ├── drawable/
│ │ │ └── progressbar_drawable.xml
│ │ ├── layout/
│ │ │ ├── layout_activity_barcode.xml
│ │ │ ├── layout_activity_scanner.xml
│ │ │ └── layout_activity_show_result.xml
│ │ ├── menu/
│ │ │ └── menu_scan.xml
│ │ ├── raw/
│ │ │ └── beep.ogg
│ │ └── values/
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test/
│ └── java/
│ └── com/
│ └── example/
│ └── qrcode/
│ └── ExampleUnitTest.java
├── app/
│ ├── .gitignore
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src/
│ ├── androidTest/
│ │ └── java/
│ │ └── com/
│ │ └── example/
│ │ └── yzxing/
│ │ └── ExampleInstrumentedTest.java
│ ├── main/
│ │ ├── AndroidManifest.xml
│ │ ├── java/
│ │ │ └── com/
│ │ │ └── example/
│ │ │ └── yzxing/
│ │ │ └── MainActivity.java
│ │ └── res/
│ │ ├── layout/
│ │ │ └── activity_main.xml
│ │ └── values/
│ │ ├── colors.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test/
│ └── java/
│ └── com/
│ └── example/
│ └── yzxing/
│ └── ExampleUnitTest.java
├── build.gradle
├── gradle/
│ └── wrapper/
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
# Built application files
*.apk
*.ap_
# Files for the ART/Dalvik VM
*.dex
# Java class files
*.class
# Generated files
bin/
gen/
out/
# Gradle files
.gradle/
build/
# Local configuration file (sdk path, etc)
local.properties
# Proguard folder generated by Eclipse
proguard/
# Log Files
*.log
# Android Studio Navigation editor temp files
.navigation/
# Android Studio captures folder
captures/
# Intellij
*.iml
.idea/workspace.xml
.idea/tasks.xml
.idea/gradle.xml
.idea/dictionaries
.idea/libraries
# Keystore files
*.jks
# External native build folder generated in Android Studio 2.2 and later
.externalNativeBuild
# Google Services (e.g. APIs or Firebase)
google-services.json
# Freeline
freeline.py
freeline/
freeline_project_description.json
================================================
FILE: .idea/codeStyles/Project.xml
================================================
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<Objective-C-extensions>
<file>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
</file>
<class>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
</class>
<extensions>
<pair source="cpp" header="h" fileNamingConvention="NONE" />
<pair source="c" header="h" fileNamingConvention="NONE" />
</extensions>
</Objective-C-extensions>
</code_scheme>
</component>
================================================
FILE: .idea/inspectionProfiles/Project_Default.xml
================================================
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="JavaDoc" enabled="true" level="WARNING" enabled_by_default="true">
<option name="TOP_LEVEL_CLASS_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="" />
</value>
</option>
<option name="INNER_CLASS_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="" />
</value>
</option>
<option name="METHOD_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="@return@param@throws or @exception" />
</value>
</option>
<option name="FIELD_OPTIONS">
<value>
<option name="ACCESS_JAVADOC_REQUIRED_FOR" value="none" />
<option name="REQUIRED_TAGS" value="" />
</value>
</option>
<option name="IGNORE_DEPRECATED" value="false" />
<option name="IGNORE_JAVADOC_PERIOD" value="true" />
<option name="IGNORE_DUPLICATED_THROWS" value="false" />
<option name="IGNORE_POINT_TO_ITSELF" value="false" />
<option name="myAdditionalJavadocTags" value="date" />
</inspection_tool>
</profile>
</component>
================================================
FILE: .idea/misc.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="NullableNotNullManager">
<option name="myDefaultNullable" value="android.support.annotation.Nullable" />
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
<option name="myNullables">
<value>
<list size="7">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
<item index="2" class="java.lang.String" itemvalue="javax.annotation.CheckForNull" />
<item index="3" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
<item index="4" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
<item index="5" class="java.lang.String" itemvalue="androidx.annotation.Nullable" />
<item index="6" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNullable" />
</list>
</value>
</option>
<option name="myNotNulls">
<value>
<list size="6">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
<item index="4" class="java.lang.String" itemvalue="androidx.annotation.NonNull" />
<item index="5" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNonNull" />
</list>
</value>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>
================================================
FILE: .idea/modules.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/YZxing.iml" filepath="$PROJECT_DIR$/YZxing.iml" />
<module fileurl="file://$PROJECT_DIR$/YZxing-lib/YZxing-lib.iml" filepath="$PROJECT_DIR$/YZxing-lib/YZxing-lib.iml" />
<module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
</modules>
</component>
</project>
================================================
FILE: .idea/runConfigurations.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
</set>
</option>
</component>
</project>
================================================
FILE: .idea/vcs.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.
================================================
FILE: README.md
================================================
# YZxing
一款仿微信扫一扫界面,基于zxing实现的扫码库。
### **实现效果** ###
 
### **使用方式** ###
~~首先通过在build.gradle文件中添加如下编译语句将YZxing-lib库添加到项目中。
compile 'com.yangy:YZxing-lib:1.1'~~
(或者在直接把本仓库里面的YZxing库下载下来,添加到项目中。)
然后在点击跳转到扫码界面的点击事件中,调用如下方法:
Intent intent = new Intent(this, ScannerActivity.class);
//这里可以用intent传递一些参数,比如扫码聚焦框尺寸大小,支持的扫码类型。
// //设置扫码框的宽
// intent.putExtra(Constant.EXTRA_SCANNER_FRAME_WIDTH, 400);
// //设置扫码框的高
// intent.putExtra(Constant.EXTRA_SCANNER_FRAME_HEIGHT, 400);
// //设置扫码框距顶部的位置
// intent.putExtra(Constant.EXTRA_SCANNER_FRAME_TOP_PADDING, 100);
// Bundle bundle = new Bundle();
// //设置支持的扫码类型
// bundle.putSerializable(Constant.EXTRA_SCAN_CODE_TYPE, mHashMap);
// intent.putExtras(bundle);
startActivityForResult(intent, RESULT_REQUEST_CODE);
这里可以使用intent传递一些配置参数。支持有设置扫码框的大小,及位置;设置支持的扫码类型。目前支持的自定义配置不多,后续有机会再扩充。 跳转的时候要有startActivityForResult来跳转,这样在扫码成功之后,返回的结果可以在onActivityResult方法中处理代码如下:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
switch (requestCode) {
case RESULT_REQUEST_CODE:
if (data == null) return;
String type = data.getStringExtra(Constant.EXTRA_RESULT_CODE_TYPE);
String content = data.getStringExtra(Constant.EXTRA_RESULT_CONTENT);
Toast.makeText(MainActivity.this,"codeType:" + type
+ "-----content:" + content,Toast.LENGTH_SHORT).show();
break;
default:
break;
}
}
super.onActivityResult(requestCode, resultCode, data);
}
----------------------------------------
## **YZxing版本更新说明** ##
目前最新版为v2.2!!
-------------
目前YZxing已经更新到了v2.1 ,更新内容有:
1.修改空指针导致的的闪退bug。
2.添加从相册获取二维码功能(用户可以选择是否使用该功能)。
首先通过在build.gradle文件中添加如下编译语句将YZxing-lib库添加到项目中。
compile 'com.yangy:YZxing-lib:2.1'
(或者在直接把本仓库里面的YZxing库下载下来,添加到项目中。)
使用方式与1.1版本一致,注意的是如需使用**从相册获取二维码功能**则需要在intent中添加是否启用scan_from_pic,默认是FALSE:
**// //设置是否启用从相册获取二维码。
// intent.putExtra(Constant.EXTRA_IS_ENABLE_SCAN_FROM_PIC,true);**
### **从照片获取二维码的效果如下:** ###

## **觉得还不错的就动动手指给个star吧(*^__^*)** ##
## **关于二维码功能的分析请移步至文章** ##
https://blog.csdn.net/qq_34902522/column/info/28769
================================================
FILE: YZxing-lib/.gitignore
================================================
/build
================================================
FILE: YZxing-lib/build.gradle
================================================
apply plugin: 'com.android.library'
apply plugin: 'com.jfrog.bintray'
apply plugin: 'com.github.dcendents.android-maven'
def siteUrl = 'https://github.com/MRYangY/YZxing' // 项目的主页
def gitUrl = 'https://github.com/MRYangY/YZxing.git' // Git仓库的url
Properties properties = new Properties()
properties.load(project.rootProject.file('local.properties').newDataInputStream())
version = "2.2" //发布版本号
group = "com.yangy" //最终引用形式,如compile 'com.yangy.lfilepicker:1.0.0',其中lfilepicker在后面配置
android {
compileSdkVersion 26
buildToolsVersion "25.0.3"
defaultConfig {
minSdkVersion 19
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:26.+'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
testCompile 'junit:junit:4.12'
compile 'com.google.zxing:core:3.3.0'
}
bintray {
user = properties.getProperty("bintray.user")
key = properties.getProperty("bintray.apikey")
pkg {
repo = 'YZXing'//自己创建的仓库名字
name = 'yzxing'//上传到JCenter的名字,最终引用的名字
websiteUrl = siteUrl
vcsUrl = gitUrl
licenses = ['Apache-2.0']//不能随便写,只能是仓库创建时选择的license type
userOrg = 'yangyulibrary' //自己创建的organization名称
publish = true // 是否是公开项目,公开别人可以引用
version {
name = '2.2'
desc = '基于zxing的扫码库,样式类似于微信扫一扫'//描述,自己定义
released = new Date()
vcsTag = 'v2.2'
attributes = ['gradle-plugin': 'com.use.less:com.use.less.gradle:gradle-useless-plugin']
}
}
configurations = ['archives']
}
install {
repositories.mavenInstaller {
// This generates POM.xml with proper parameters
pom {
project {
packaging 'aar'
// Add your description here
name 'yangy Android'
description 'yangy open library.'
url siteUrl
// Set your license
licenses {
license {
name 'Apache-2.0' //和之前自己定义的协议一致
url 'https://raw.githubusercontent.com/minggo620/Pluto-Android/master/LICENSE'
}
}
developers {
developer {
id 'mryangy423' //填写bintray或者github的用户名
name 'mryangy423' //姓名
email 'mryangy423@gmail.com'//邮箱
}
}
scm {
connection gitUrl
developerConnection gitUrl
url siteUrl
}
}
}
task sourcesJar(type: Jar) {
from android.sourceSets.main.java.srcDirs
classifier = 'sources'
}
task javadoc(type: Javadoc) {
failOnError false //必须添加以免出错
source = android.sourceSets.main.java.srcDirs
classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
}
task javadocJar(type: Jar, dependsOn: javadoc) {
classifier = 'javadoc'
from javadoc.destinationDir
}
artifacts {
archives javadocJar
archives sourcesJar
}
javadoc {
options{
//如果你的项目里面有中文注释的话,必须将格式设置为UTF-8,不然会出现乱码
encoding "UTF-8"
charSet 'UTF-8'
author true
version true
links "http://docs.oracle.com/javase/7/docs/api"
}
}
}
}
================================================
FILE: YZxing-lib/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /Users/yangyu/Library/Android/sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
================================================
FILE: YZxing-lib/src/androidTest/java/com/example/qrcode/ExampleInstrumentedTest.java
================================================
package com.example.qrcode;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumentation test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() throws Exception {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();
assertEquals("com.example.qrcode.test", appContext.getPackageName());
}
}
================================================
FILE: YZxing-lib/src/main/AndroidManifest.xml
================================================
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.qrcode">
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<application android:allowBackup="true"
android:label="@string/app_name"
android:supportsRtl="true"
>
<activity android:name=".ScannerActivity"
android:screenOrientation="portrait"
android:theme="@style/MyAppTheme"
/>
<activity android:name=".ShowResultActivity"
android:theme="@style/MyAppTheme"/>
<activity android:name=".BarcodeActivity"
android:theme="@style/MyAppTheme"/>
</application>
</manifest>
================================================
FILE: YZxing-lib/src/main/java/com/example/qrcode/BarcodeActivity.java
================================================
package com.example.qrcode;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Point;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.Toast;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.common.BitMatrix;
import java.util.EnumMap;
import java.util.Map;
/**
* Create by rain
* <p>
* DATE:18-10-26
* <p>
* Describe:
**/
public class BarcodeActivity extends Activity {
private static final String TAG = "BarcodeActivity";
private static final int WHITE = 0xFFFFFFFF;
private static final int BLACK = 0xFF000000;
private static final int CODE_TYPE_QR_CODE = 0x11;
private static final int CODE_TYPE_CODE_128 = 0x12;
private int mType = CODE_TYPE_QR_CODE;
private EditText mInputContentView;
private Button mEncodeView;
private ImageView mBarcodeImageView;
private RadioGroup mRgCodeType;
private RadioButton mRbQrCode;
private RadioButton mRb128Code;
private Bitmap bitmap;
private Handler mHandler = new Handler(Looper.getMainLooper());
private int smallerDimension;
private int barcodeImageWidth;
private int barcodeImageHeight;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_activity_barcode);
mInputContentView = findViewById(R.id.et_input_content);
mEncodeView = findViewById(R.id.bt_encode);
mEncodeView.setOnClickListener(mEncodeListener);
mBarcodeImageView = findViewById(R.id.barcode_image);
mRgCodeType = findViewById(R.id.rg_code_type);
mRbQrCode = findViewById(R.id.rb_qr_code);
mRb128Code = findViewById(R.id.rb_code_128);
mRgCodeType.setOnCheckedChangeListener(onCheckedChangeListener);
WindowManager manager = (WindowManager) getSystemService(WINDOW_SERVICE);
Display display = manager.getDefaultDisplay();
Point displaySize = new Point();
display.getSize(displaySize);
int width = displaySize.x;
int height = displaySize.y;
smallerDimension = width < height ? width : height;
smallerDimension = smallerDimension * 7 / 8;
barcodeImageWidth = smallerDimension;
barcodeImageHeight = smallerDimension;
Log.e(TAG, "onCreate: smallerDimension = " + smallerDimension);
}
private RadioGroup.OnCheckedChangeListener onCheckedChangeListener = new RadioGroup.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(RadioGroup group, int checkedId) {
barcodeImageWidth = smallerDimension;
if (checkedId == R.id.rb_qr_code) {
mType = CODE_TYPE_QR_CODE;
barcodeImageHeight = smallerDimension;
} else if (checkedId == R.id.rb_code_128) {
mType = CODE_TYPE_CODE_128;
barcodeImageHeight = smallerDimension / 2;
}
}
};
private View.OnClickListener mEncodeListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
String text = mInputContentView.getText().toString();
if (TextUtils.isEmpty(text)) {
Toast.makeText(BarcodeActivity.this, "请先输入条形码内容!!", Toast.LENGTH_SHORT).show();
return;
}
encode(text);
}
};
private void encode(String content) {
Log.e(TAG, "encode: content = " + content);
if (content == null) {
return;
}
Map<EncodeHintType, Object> hints = null;
String encoding = guessAppropriateEncoding(content);
if (encoding != null) {
hints = new EnumMap<>(EncodeHintType.class);
hints.put(EncodeHintType.CHARACTER_SET, encoding);
}
BitMatrix result;
try {
result = new MultiFormatWriter().encode(content, getWantedCodeType(mType)
, barcodeImageWidth, barcodeImageHeight, hints);
int width = result.getWidth();
int height = result.getHeight();
int[] pixels = new int[width * height];
for (int y = 0; y < height; y++) {
int offset = y * width;
for (int x = 0; x < width; x++) {
pixels[offset + x] = result.get(x, y) ? BLACK : WHITE;
}
}
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
mHandler.post(mUpdateImageRunnable);
} catch (Exception iae) {
// Unsupported format
Log.e(TAG, "encode: " + iae.getMessage());
}
}
private Runnable mUpdateImageRunnable = new Runnable() {
@Override
public void run() {
mBarcodeImageView.setImageBitmap(bitmap);
}
};
/**
* get apposite barcode type
*
* @param type
* @return
*/
private BarcodeFormat getWantedCodeType(int type) {
switch (type) {
case CODE_TYPE_QR_CODE:
return BarcodeFormat.QR_CODE;
case CODE_TYPE_CODE_128:
return BarcodeFormat.CODE_128;
default:
return BarcodeFormat.QR_CODE;
}
}
private static String guessAppropriateEncoding(CharSequence contents) {
// Very crude at the moment
for (int i = 0; i < contents.length(); i++) {
if (contents.charAt(i) > 0xFF) {
return "UTF-8";
}
}
return null;
}
}
================================================
FILE: YZxing-lib/src/main/java/com/example/qrcode/BeepManager.java
================================================
package com.example.qrcode;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.AssetFileDescriptor;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Vibrator;
import android.preference.PreferenceManager;
import android.util.Log;
import java.io.Closeable;
import java.io.IOException;
/**
* Created by yangyu on 17/10/19.
*/
public final class BeepManager implements MediaPlayer.OnErrorListener, Closeable {
private static final String TAG = BeepManager.class.getSimpleName();
private static final float BEEP_VOLUME = 0.10f;
private static final long VIBRATE_DURATION = 200L;
private final Activity activity;
private MediaPlayer mediaPlayer;
private boolean playBeep;
private boolean vibrate;
BeepManager(Activity activity) {
this.activity = activity;
this.mediaPlayer = null;
updatePrefs();
}
synchronized void updatePrefs() {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(activity);
playBeep = shouldBeep(prefs, activity);
vibrate = prefs.getBoolean(Constant.KEY_VIBRATE, false);
if (playBeep && mediaPlayer == null) {
// The volume on STREAM_SYSTEM is not adjustable, and users found it too loud,
// so we now play on the music stream.
activity.setVolumeControlStream(AudioManager.STREAM_MUSIC);
mediaPlayer = buildMediaPlayer(activity);
}
}
synchronized void playBeepSoundAndVibrate() {
if (playBeep && mediaPlayer != null) {
mediaPlayer.start();
}
if (vibrate) {
Vibrator vibrator = (Vibrator) activity.getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(VIBRATE_DURATION);
}
}
private static boolean shouldBeep(SharedPreferences prefs, Context activity) {
boolean shouldPlayBeep = prefs.getBoolean(Constant.KEY_PLAY_BEEP, true);
if (shouldPlayBeep) {
// See if sound settings overrides this
AudioManager audioService = (AudioManager) activity.getSystemService(Context.AUDIO_SERVICE);
if (audioService.getRingerMode() != AudioManager.RINGER_MODE_NORMAL) {
shouldPlayBeep = false;
}
}
return shouldPlayBeep;
}
private MediaPlayer buildMediaPlayer(Context activity) {
MediaPlayer mediaPlayer = new MediaPlayer();
try (AssetFileDescriptor file = activity.getResources().openRawResourceFd(R.raw.beep)) {
mediaPlayer.setDataSource(file.getFileDescriptor(), file.getStartOffset(), file.getLength());
mediaPlayer.setOnErrorListener(this);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setLooping(false);
mediaPlayer.setVolume(BEEP_VOLUME, BEEP_VOLUME);
mediaPlayer.prepare();
return mediaPlayer;
} catch (IOException ioe) {
Log.w(TAG, ioe);
mediaPlayer.release();
return null;
}
}
@Override
public synchronized boolean onError(MediaPlayer mp, int what, int extra) {
if (what == MediaPlayer.MEDIA_ERROR_SERVER_DIED) {
// we are finished, so put up an appropriate error toast if required and finish
activity.finish();
} else {
// possibly media player error, so release and recreate
close();
updatePrefs();
}
return true;
}
@Override
public synchronized void close() {
if (mediaPlayer != null) {
mediaPlayer.release();
mediaPlayer = null;
}
}
}
================================================
FILE: YZxing-lib/src/main/java/com/example/qrcode/Constant.java
================================================
package com.example.qrcode;
/**
* Created by yangyu on 17/10/29.
*/
public class Constant {
public static final int MESSAGE_SCANNER_DECODE = 0;
public static final int MESSAGE_SCANNER_DECODE_SUCCEEDED = 1;
public static final int MESSAGE_SCANNER_DECODE_FAIL = 2;
public static final int MESSAGE_SCANNER_QUIT = 3;
public static final String KEY_AUTO_FOCUS = "auto_focus";
public static final String KEY_DISABLE_CONTINUOUS_FOCUS = "continuous_focus";
public static final String KEY_VIBRATE = "beep_vibrate";
public static final String KEY_PLAY_BEEP = "beep_play";
public static final String EXTRA_SCANNER_FRAME_WIDTH = "scan_frame_width";
public static final String EXTRA_SCANNER_FRAME_HEIGHT = "scan_frame_height";
public static final String EXTRA_SCANNER_FRAME_TOP_PADDING = "scan_frame_top_padding";
public static final String EXTRA_SCAN_CODE_TYPE = "scan_code_type";
public static final String EXTRA_IS_ENABLE_SCAN_FROM_PIC = "is_enable_scan_from_pic";
public static final String EXTRA_RESULT_CODE_TYPE = "result_code_type";
public static final String EXTRA_RESULT_CONTENT = "result_content";
public static final String EXTRA_RESULT_TEXT_FROM_PIC = "text_from_pic";
}
================================================
FILE: YZxing-lib/src/main/java/com/example/qrcode/ScannerActivity.java
================================================
package com.example.qrcode;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import com.example.qrcode.camera.CameraManager;
import com.example.qrcode.decode.InactivityTimer;
import com.example.qrcode.decode.ScannerHandler;
import com.example.qrcode.utils.CommonUtils;
import com.example.qrcode.utils.DecodeUtils;
import com.example.qrcode.utils.UriUtils;
import com.example.qrcode.view.ScannerView;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.Result;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.Collection;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Set;
/**
* Created by yangyu on 17/10/18.
*/
public class ScannerActivity extends AppCompatActivity implements SurfaceHolder.Callback {
private static final String TAG = "ScannerActivity";
public static final String BARCODE_FORMAT = "support_barcode_format";
public final int PERMISSION_REQUEST_CODE_WRITE_EXTERNAL_STORAGE = 0X11;
public final int REQUEST_CODE_GET_PIC_URI = 0X12;
private final int MESSAGE_DECODE_FROM_BITMAP = 0;
private Toolbar mToolBar;
private ScannerView mScannerView;
private SurfaceView mSurfaceView;
private InactivityTimer mInactivityTimer;
private BeepManager beepManager;
private com.example.qrcode.camera.CameraManager cameraManager;
private ScannerHandler handler;
private Collection<BarcodeFormat> decodeFormats;
private int mScanFocusWidth;
private int mScanFocusHeight;
private int mScanFocusTopPadding;
private boolean isEnableScanFromPicture;
private boolean hasSurface;
private MyHandler mHandler;
private static class MyHandler extends Handler {
private WeakReference<ScannerActivity> activity;
MyHandler(ScannerActivity mainActivityWeakReference) {
activity = new WeakReference<ScannerActivity>(mainActivityWeakReference);
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
ScannerActivity activity = this.activity.get();
if (activity != null) {
if (msg.what == activity.MESSAGE_DECODE_FROM_BITMAP) {
Bitmap bm = (Bitmap) msg.obj;
DecodeUtils.DecodeAsyncTask decodeAsyncTask = new DecodeUtils.DecodeAsyncTask(activity);
decodeAsyncTask.execute(bm);
}
}
}
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_activity_scanner);
initView();
hasSurface = false;
Intent intent = getIntent();
if (intent != null) {
mScanFocusWidth = intent.getIntExtra(Constant.EXTRA_SCANNER_FRAME_WIDTH, -1);
mScanFocusHeight = intent.getIntExtra(Constant.EXTRA_SCANNER_FRAME_HEIGHT, -1);
mScanFocusTopPadding = intent.getIntExtra(Constant.EXTRA_SCANNER_FRAME_TOP_PADDING, -1);
isEnableScanFromPicture = intent.getBooleanExtra(Constant.EXTRA_IS_ENABLE_SCAN_FROM_PIC, false);
Bundle b = intent.getExtras();
if (b != null) {
HashMap<String, Set> formats = (HashMap<String, Set>) b.getSerializable(Constant.EXTRA_SCAN_CODE_TYPE);
if (formats != null) {
decodeFormats = formats.get(BARCODE_FORMAT);
} else {
decodeFormats = EnumSet.of(BarcodeFormat.QR_CODE
, BarcodeFormat.CODE_128);
}
} else {
decodeFormats = EnumSet.of(BarcodeFormat.QR_CODE
, BarcodeFormat.CODE_128);
}
}
Log.e(TAG, "onCreate:decodeFormats :" + decodeFormats.size() + "--" + decodeFormats.toString());
mInactivityTimer = new InactivityTimer(this);
beepManager = new BeepManager(this);
mHandler = new MyHandler(this);
}
@Override
protected void onResume() {
super.onResume();
cameraManager = new CameraManager(this);
cameraManager.setManualFramingRect(mScanFocusWidth, mScanFocusHeight, mScanFocusTopPadding);
mScannerView.setCameraManager(cameraManager);
SurfaceHolder holder = mSurfaceView.getHolder();
if (hasSurface) {
initCamera(holder);
} else {
holder.addCallback(this);
}
mInactivityTimer.onResume();
beepManager.updatePrefs();
}
@Override
protected void onPause() {
super.onPause();
if (handler != null) {
handler.quitSynchronously();
handler = null;
}
cameraManager.closeDriver();
mInactivityTimer.onPause();
beepManager.close();
}
@Override
protected void onDestroy() {
cameraManager.clearFramingRect();
mInactivityTimer.shutdown();
super.onDestroy();
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_VOLUME_DOWN:
//关闭灯光
cameraManager.setTorch(false);
return true;
case KeyEvent.KEYCODE_VOLUME_UP:
//开启闪光灯
cameraManager.setTorch(true);
return true;
}
return super.onKeyDown(keyCode, event);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
if (isEnableScanFromPicture) {
getMenuInflater().inflate(R.menu.menu_scan, menu);
return true;
} else {
return super.onCreateOptionsMenu(menu);
}
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int itemId = item.getItemId();
if (itemId == R.id.scan_from_picture) {
//先申请权限
int checked = ContextCompat.checkSelfPermission(ScannerActivity.this
, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (checked == PackageManager.PERMISSION_GRANTED) {
goPicture();
} else {
ActivityCompat.requestPermissions(ScannerActivity.this
, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE_WRITE_EXTERNAL_STORAGE);
}
} else if (itemId == R.id.encode_barcode) {
startActivity(new Intent(ScannerActivity.this, BarcodeActivity.class));
}
return true;
}
private void goPicture() {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, REQUEST_CODE_GET_PIC_URI);
}
private void initView() {
mToolBar = (Toolbar) findViewById(R.id.tool_bar);
mToolBar.setTitle("二维码/条形码");
mToolBar.setTitleTextColor(Color.WHITE);
setSupportActionBar(mToolBar);
mToolBar.setNavigationOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
mSurfaceView = (SurfaceView) findViewById(R.id.surface);
mScannerView = (ScannerView) findViewById(R.id.scan_view);
}
private void initCamera(SurfaceHolder surfaceHolder) {
if (surfaceHolder == null) {
throw new IllegalStateException("No SurfaceHolder provided");
}
if (cameraManager.isOpen()) {
Log.w(TAG, "initCamera() while already open -- late SurfaceView callback?");
return;
}
try {
cameraManager.openDriver(surfaceHolder);
if (handler == null) {
handler = new ScannerHandler(this, decodeFormats, "utf-8", cameraManager);
}
} catch (IOException ioe) {
Log.w(TAG, ioe);
} catch (RuntimeException e) {
Log.w(TAG, "Unexpected error initializing camera", e);
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
if (holder == null) {
Log.e(TAG, "*** WARNING *** surfaceCreated() gave us a null surface!");
}
if (!hasSurface) {
hasSurface = true;
initCamera(holder);
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
hasSurface = false;
}
//在这里处理扫码结果
public void handDecode(final Result result) {
mInactivityTimer.onActivity();
beepManager.playBeepSoundAndVibrate();
// AlertDialog.Builder mScannerDialogBuilder = new AlertDialog.Builder(this);
// mScannerDialogBuilder.setMessage("codeType:" + result.getBarcodeFormat() + "-----content:" + result.getText());
// mScannerDialogBuilder.setCancelable(false);
// mScannerDialogBuilder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
// @Override
// public void onClick(DialogInterface dialog, int which) {
// dialog.dismiss();
// ScannerActivity.this.finish();
// }
// });
// mScannerDialogBuilder.create().show();
Intent data = new Intent();
BarcodeFormat format = result.getBarcodeFormat();
String type = format.toString();
data.putExtra(Constant.EXTRA_RESULT_CODE_TYPE, type);
data.putExtra(Constant.EXTRA_RESULT_CONTENT, result.getText());
setResult(RESULT_OK, data);
finish();
}
public CameraManager getCameraManager() {
return cameraManager;
}
public Handler getHandler() {
return handler;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
switch (requestCode) {
case REQUEST_CODE_GET_PIC_URI:
Uri uri = data.getData();
String imagePath = UriUtils.getPicturePathFromUri(ScannerActivity.this, uri);
//对获取到的二维码照片进行压缩
Bitmap bitmap = CommonUtils.compressPicture(imagePath);
Message message = mHandler.obtainMessage(MESSAGE_DECODE_FROM_BITMAP, bitmap);
mHandler.sendMessage(message);
Log.e(TAG, "onActivityResult: uri:" + uri.toString());
break;
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PERMISSION_REQUEST_CODE_WRITE_EXTERNAL_STORAGE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
goPicture();
return;
}
}
}
}
================================================
FILE: YZxing-lib/src/main/java/com/example/qrcode/ShowResultActivity.java
================================================
package com.example.qrcode;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.util.Patterns;
import android.view.View;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.ProgressBar;
import android.widget.TextView;
/**
* Created by yangyu on 2017/11/28.
*/
public class ShowResultActivity extends AppCompatActivity {
private static final String TAG = "ShowResultActivity";
private WebView webView;
private TextView tv;
private ProgressBar pb;
private String resultText;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_activity_show_result);
webView = (WebView) findViewById(R.id.web_content);
tv = (TextView) findViewById(R.id.tv);
pb = (ProgressBar) findViewById(R.id.progress);
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setUseWideViewPort(true);
webSettings.setLoadWithOverviewMode(true);
webView.setWebChromeClient(webChromeClient);
webView.setWebViewClient(webViewClient);
Intent intent = getIntent();
if (intent != null) {
resultText = intent.getStringExtra(Constant.EXTRA_RESULT_TEXT_FROM_PIC);
if (Patterns.WEB_URL.matcher(resultText).matches()) {
//是一个web url
tv.setVisibility(View.GONE);
webView.setVisibility(View.VISIBLE);
webView.loadUrl(resultText);
} else {
//不是web url
tv.setVisibility(View.VISIBLE);
webView.setVisibility(View.GONE);
pb.setVisibility(View.GONE);
tv.setText(resultText);
}
}
}
private WebViewClient webViewClient = new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
}
};
private WebChromeClient webChromeClient = new WebChromeClient() {
@Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
if (newProgress == 100) {
pb.setVisibility(View.GONE);
} else {
pb.setVisibility(View.VISIBLE);
pb.setProgress(newProgress);
}
}
@Override
public void onReceivedTitle(WebView view, String title) {
super.onReceivedTitle(view, title);
Log.e(TAG, "onReceivedTitle: " + title);
}
};
}
================================================
FILE: YZxing-lib/src/main/java/com/example/qrcode/callback/PreviewCallback.java
================================================
package com.example.qrcode.callback;
import android.graphics.Point;
import android.hardware.Camera;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import com.example.qrcode.camera.CameraConfigurationManager;
/**
* Created by yangyu on 17/10/19.
*/
public class PreviewCallback implements Camera.PreviewCallback {
private static final String TAG = PreviewCallback.class.getSimpleName();
private final CameraConfigurationManager configManager;
private Handler previewHandler;
private int previewMessage;
public PreviewCallback(CameraConfigurationManager configManager) {
this.configManager = configManager;
}
public void setHandler(Handler previewHandler, int previewMessage) {
this.previewHandler = previewHandler;
this.previewMessage = previewMessage;
}
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
Point cameraResolution = configManager.getCameraResolution();
Handler thePreviewHandler = previewHandler;
if (cameraResolution != null && thePreviewHandler != null) {
Message message = thePreviewHandler.obtainMessage(previewMessage, cameraResolution.x,
cameraResolution.y, data);
message.sendToTarget();
previewHandler = null;
} else {
Log.d(TAG, "Got preview callback, but no handler or resolution available");
}
}
}
================================================
FILE: YZxing-lib/src/main/java/com/example/qrcode/camera/AutoFocusManager.java
================================================
package com.example.qrcode.camera;
import android.content.Context;
import android.content.SharedPreferences;
import android.hardware.Camera;
import android.os.AsyncTask;
import android.preference.PreferenceManager;
import android.util.Log;
import com.example.qrcode.Constant;
import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.RejectedExecutionException;
/**
* Created by yangyu on 17/10/19.
*/
final class AutoFocusManager implements Camera.AutoFocusCallback {
private static final String TAG = AutoFocusManager.class.getSimpleName();
private static final long AUTO_FOCUS_INTERVAL_MS = 2000L;
private static final Collection<String> FOCUS_MODES_CALLING_AF;
static {
FOCUS_MODES_CALLING_AF = new ArrayList<>(2);
FOCUS_MODES_CALLING_AF.add(Camera.Parameters.FOCUS_MODE_AUTO);
FOCUS_MODES_CALLING_AF.add(Camera.Parameters.FOCUS_MODE_MACRO);
}
private boolean stopped;
private boolean focusing;
private final boolean useAutoFocus;
private final Camera camera;
private AsyncTask<?, ?, ?> outstandingTask;
AutoFocusManager(Context context, Camera camera) {
this.camera = camera;
SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
String currentFocusMode = camera.getParameters().getFocusMode();
useAutoFocus =
sharedPrefs.getBoolean(Constant.KEY_AUTO_FOCUS, true) &&
FOCUS_MODES_CALLING_AF.contains(currentFocusMode);
Log.i(TAG, "Current focus mode '" + currentFocusMode + "'; use auto focus? " + useAutoFocus);
start();
}
@Override
public synchronized void onAutoFocus(boolean success, Camera theCamera) {
focusing = false;
autoFocusAgainLater();
}
private synchronized void autoFocusAgainLater() {
if (!stopped && outstandingTask == null) {
AutoFocusTask newTask = new AutoFocusTask();
try {
newTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
outstandingTask = newTask;
} catch (RejectedExecutionException ree) {
Log.w(TAG, "Could not request auto focus", ree);
}
}
}
synchronized void start() {
if (useAutoFocus) {
outstandingTask = null;
if (!stopped && !focusing) {
try {
camera.autoFocus(this);
focusing = true;
} catch (RuntimeException re) {
// Have heard RuntimeException reported in Android 4.0.x+; continue?
Log.w(TAG, "Unexpected exception while focusing", re);
// Try again later to keep cycle going
autoFocusAgainLater();
}
}
}
}
private synchronized void cancelOutstandingTask() {
if (outstandingTask != null) {
if (outstandingTask.getStatus() != AsyncTask.Status.FINISHED) {
outstandingTask.cancel(true);
}
outstandingTask = null;
}
}
synchronized void stop() {
stopped = true;
if (useAutoFocus) {
cancelOutstandingTask();
// Doesn't hurt to call this even if not focusing
try {
camera.cancelAutoFocus();
} catch (RuntimeException re) {
// Have heard RuntimeException reported in Android 4.0.x+; continue?
Log.w(TAG, "Unexpected exception while cancelling focusing", re);
}
}
}
private final class AutoFocusTask extends AsyncTask<Object, Object, Object> {
@Override
protected Object doInBackground(Object... voids) {
try {
Thread.sleep(AUTO_FOCUS_INTERVAL_MS);
} catch (InterruptedException e) {
// continue
}
start();
return null;
}
}
}
================================================
FILE: YZxing-lib/src/main/java/com/example/qrcode/camera/CameraConfigurationManager.java
================================================
package com.example.qrcode.camera;
/**
* Created by yangyu on 17/10/18.
*/
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Point;
import android.hardware.Camera;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.Display;
import android.view.WindowManager;
import com.example.qrcode.Constant;
import com.example.qrcode.utils.CameraConfigurationUtils;
/**
* A class which deals with reading, parsing, and setting the camera parameters which are used to
* configure the camera hardware.
*/
@SuppressWarnings("deprecation") // camera APIs
public final class CameraConfigurationManager {
private static final String TAG = "CameraConfiguration";
private final Context context;
private Point screenResolution;
private Point cameraResolution;
private Point bestPreviewSize;
CameraConfigurationManager(Context context) {
this.context = context;
}
/**
* Reads, one time, values from the camera that are needed by the app.
*/
void initFromCameraParameters(OpenCamera camera) {
Camera.Parameters parameters = camera.getCamera().getParameters();
WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = manager.getDefaultDisplay();
Point theScreenResolution = new Point();
display.getSize(theScreenResolution);
screenResolution = theScreenResolution;
Log.i(TAG, "Screen resolution in current orientation: " + screenResolution);
cameraResolution = CameraConfigurationUtils.findBestPreviewSizeValue(parameters, screenResolution);
Log.i(TAG, "Camera resolution: " + cameraResolution);
bestPreviewSize = CameraConfigurationUtils.findBestPreviewSizeValue(parameters, screenResolution);
Log.i(TAG, "Best available preview size: " + bestPreviewSize);
}
void setDesiredCameraParameters(OpenCamera camera, boolean safeMode) {
Camera theCamera = camera.getCamera();
Camera.Parameters parameters = theCamera.getParameters();
if (parameters == null) {
Log.w(TAG, "Device error: no camera parameters are available. Proceeding without configuration.");
return;
}
Log.i(TAG, "Initial camera parameters: " + parameters.flatten());
if (safeMode) {
Log.w(TAG, "In camera config safe mode -- most settings will not be honored");
}
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
CameraConfigurationUtils.setFocus(
parameters,
prefs.getBoolean(Constant.KEY_AUTO_FOCUS, true),
prefs.getBoolean(Constant.KEY_DISABLE_CONTINUOUS_FOCUS, true),
safeMode);
parameters.setPreviewSize(bestPreviewSize.x, bestPreviewSize.y);
theCamera.setParameters(parameters);
//设置屏幕方向为垂直方向
theCamera.setDisplayOrientation(90);
}
public Point getCameraResolution() {
return cameraResolution;
}
Point getScreenResolution() {
return screenResolution;
}
boolean getTorchState(Camera camera) {
if (camera != null) {
Camera.Parameters parameters = camera.getParameters();
if (parameters != null) {
String flashMode = parameters.getFlashMode();
return flashMode != null &&
(Camera.Parameters.FLASH_MODE_ON.equals(flashMode) ||
Camera.Parameters.FLASH_MODE_TORCH.equals(flashMode));
}
}
return false;
}
void setTorch(Camera camera, boolean newSetting) {
Camera.Parameters parameters = camera.getParameters();
doSetTorch(parameters, newSetting, false);
camera.setParameters(parameters);
}
private void doSetTorch(Camera.Parameters parameters, boolean newSetting, boolean safeMode) {
CameraConfigurationUtils.setTorch(parameters, newSetting);
}
}
================================================
FILE: YZxing-lib/src/main/java/com/example/qrcode/camera/CameraFacing.java
================================================
package com.example.qrcode.camera;
/**
* Created by yangyu on 17/10/18.
*/
enum CameraFacing {
BACK, // must be value 0!
FRONT, // must be value 1!
}
================================================
FILE: YZxing-lib/src/main/java/com/example/qrcode/camera/CameraManager.java
================================================
package com.example.qrcode.camera;
/**
* Created by yangyu on 17/10/18.
*/
import android.content.Context;
import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.Camera;
import android.os.Handler;
import android.util.Log;
import android.view.SurfaceHolder;
import com.example.qrcode.callback.PreviewCallback;
import com.google.zxing.PlanarYUVLuminanceSource;
import java.io.IOException;
/**
* This object wraps the Camera service object and expects to be the only one talking to it. The
* implementation encapsulates the steps needed to take preview-sized images, which are used for
* both preview and decoding.
*
* @author dswitkin@google.com (Daniel Switkin)
*/
@SuppressWarnings("deprecation") // camera APIs
public final class CameraManager {
private static final String TAG = CameraManager.class.getSimpleName();
private static final int MIN_FRAME_WIDTH = 240;
private static final int MIN_FRAME_HEIGHT = 240;
private static final int MAX_FRAME_WIDTH = 1200; // = 5/8 * 1920
private static final int MAX_FRAME_HEIGHT = 675; // = 5/8 * 1080
private static final int DEFAULT_TOP_PADDINF = 200;
private final Context context;
private final CameraConfigurationManager configManager;
private OpenCamera camera;
private AutoFocusManager autoFocusManager;
private Rect framingRect;
private boolean initialized;
private boolean previewing;
private int requestedCameraId = OpenCameraInterface.NO_REQUESTED_CAMERA;
private int requestedFramingRectWidth;
private int requestedFramingRectHeight;
private int requestedFramingRectTopPadding;
/**
* Preview frames are delivered here, which we pass on to the registered handler. Make sure to
* clear the handler so it will only receive one message.
*/
private final PreviewCallback previewCallback;
public CameraManager(Context context) {
this.context = context;
this.configManager = new CameraConfigurationManager(context);
previewCallback = new PreviewCallback(configManager);
}
/**
* Opens the camera driver and initializes the hardware parameters.
*
* @param holder The surface object which the camera will draw preview frames into.
* @throws IOException Indicates the camera driver failed to open.
*/
public synchronized void openDriver(SurfaceHolder holder) throws IOException {
OpenCamera theCamera = camera;
if (theCamera == null) {
theCamera = OpenCameraInterface.open(requestedCameraId);
if (theCamera == null) {
throw new IOException("Camera.open() failed to return object from driver");
}
camera = theCamera;
}
if (!initialized) {
initialized = true;
configManager.initFromCameraParameters(theCamera);
if (requestedFramingRectWidth > 0 && requestedFramingRectHeight > 0) {
setManualFramingRect(requestedFramingRectWidth, requestedFramingRectHeight
, requestedFramingRectTopPadding > 0 ? requestedFramingRectTopPadding : -1);
requestedFramingRectWidth = 0;
requestedFramingRectHeight = 0;
}
}
Camera cameraObject = theCamera.getCamera();
try {
configManager.setDesiredCameraParameters(theCamera, false);
} catch (RuntimeException re) {
}
cameraObject.setPreviewDisplay(holder);
}
public synchronized boolean isOpen() {
return camera != null;
}
/**
* Closes the camera driver if still in use.
*/
public synchronized void closeDriver() {
if (camera != null) {
camera.getCamera().release();
camera = null;
}
}
public synchronized void clearFramingRect(){
// Make sure to clear these each time we close the camera, so that any scanning rect
// requested by intent is forgotten.
framingRect = null;
}
/**
* Asks the camera hardware to begin drawing preview frames to the screen.
*/
public synchronized void startPreview() {
OpenCamera theCamera = camera;
if (theCamera != null && !previewing) {
theCamera.getCamera().startPreview();
previewing = true;
autoFocusManager = new AutoFocusManager(context, theCamera.getCamera());
}
}
/**
* Tells the camera to stop drawing preview frames.
*/
public synchronized void stopPreview() {
if (autoFocusManager != null) {
autoFocusManager.stop();
autoFocusManager = null;
}
if (camera != null && previewing) {
camera.getCamera().stopPreview();
previewCallback.setHandler(null, 0);
previewing = false;
}
}
/**
* @param newSetting if {@code true}, light should be turned on if currently off. And vice versa.
*/
public synchronized void setTorch(boolean newSetting) {
OpenCamera theCamera = camera;
if (theCamera != null && newSetting != configManager.getTorchState(theCamera.getCamera())) {
boolean wasAutoFocusManager = autoFocusManager != null;
if (wasAutoFocusManager) {
autoFocusManager.stop();
autoFocusManager = null;
}
configManager.setTorch(theCamera.getCamera(), newSetting);
if (wasAutoFocusManager) {
autoFocusManager = new AutoFocusManager(context, theCamera.getCamera());
autoFocusManager.start();
}
}
}
/**
* A single preview frame will be returned to the handler supplied. The data will arrive as byte[]
* in the message.obj field, with width and height encoded as message.arg1 and message.arg2,
* respectively.
*
* @param handler The handler to send the message to.
* @param message The what field of the message to be sent.
*/
public synchronized void requestPreviewFrame(Handler handler, int message) {
OpenCamera theCamera = camera;
if (theCamera != null && previewing) {
previewCallback.setHandler(handler, message);
theCamera.getCamera().setOneShotPreviewCallback(previewCallback);
}
}
/**
* Calculates the framing rect which the UI should draw to show the user where to place the
* barcode. This target helps with alignment as well as forces the user to hold the device
* far enough away to ensure the image will be in focus.
*
* @return The rectangle to draw on screen in window coordinates.
*/
public synchronized Rect getFramingRect() {
if (framingRect == null) {
if (camera == null) {
return null;
}
Point screenResolution = configManager.getScreenResolution();
if (screenResolution == null) {
// Called early, before init even finished
return null;
}
int width = findDesiredDimensionInRange(screenResolution.x, MIN_FRAME_WIDTH, MAX_FRAME_WIDTH);
int height = findDesiredDimensionInRange(screenResolution.y, MIN_FRAME_HEIGHT, MAX_FRAME_HEIGHT);
int leftOffset = (screenResolution.x - width) / 2;
int topOffset = DEFAULT_TOP_PADDINF;
framingRect = new Rect(leftOffset, topOffset, leftOffset + width, topOffset + height);
Log.d(TAG, "Calculated framing rect: " + framingRect);
}
return framingRect;
}
private static int findDesiredDimensionInRange(int resolution, int hardMin, int hardMax) {
int dim = 5 * resolution / 8; // Target 5/8 of each dimension
if (dim < hardMin) {
return hardMin;
}
if (dim > hardMax) {
return hardMax;
}
return dim;
}
// /**
// * Like {@link #getFramingRect} but coordinates are in terms of the preview frame,
// * not UI / screen.
// *
// * @return {@link Rect} expressing barcode scan area in terms of the preview size
// */
// public synchronized Rect getFramingRectInPreview() {
// if (framingRectInPreview == null) {
// Rect framingRect = getFramingRect();
// if (framingRect == null) {
// return null;
// }
// Rect rect = new Rect(framingRect);
// Point cameraResolution = configManager.getCameraResolution();
// Point screenResolution = configManager.getScreenResolution();
// if (cameraResolution == null || screenResolution == null) {
// // Called early, before init even finished
// return null;
// }
// rect.left = rect.left * cameraResolution.x / screenResolution.x;
// rect.right = rect.right * cameraResolution.x / screenResolution.x;
// rect.top = rect.top * cameraResolution.y / screenResolution.y;
// rect.bottom = rect.bottom * cameraResolution.y / screenResolution.y;
// framingRectInPreview = rect;
// }
// return framingRectInPreview;
// }
/**
* 设置camera ID
*
* @param cameraId camera ID of the camera to use. A negative value means "no preference".
*/
public synchronized void setManualCameraId(int cameraId) {
requestedCameraId = cameraId;
}
/**
* 设置扫码框的大小
*
* @param width The width in pixels to scan.
* @param height The height in pixels to scan.
*/
public synchronized void setManualFramingRect(int width, int height, int topPadding) {
if (initialized) {
Point screenResolution = configManager.getScreenResolution();
if (width > screenResolution.x) {
width = screenResolution.x;
}
if (height > screenResolution.y) {
height = screenResolution.y;
}
int leftOffset = (screenResolution.x - width) / 2;
int topOffset = topPadding < 0 ? DEFAULT_TOP_PADDINF : topPadding;
framingRect = new Rect(leftOffset, topOffset, leftOffset + width, topOffset + height);
} else {
requestedFramingRectWidth = width;
requestedFramingRectHeight = height;
requestedFramingRectTopPadding = topPadding;
}
}
/**
* A factory method to build the appropriate LuminanceSource object based on the format
* of the preview buffers, as described by Camera.Parameters.
*
* @param data A preview frame.
* @param width The width of the image.
* @param height The height of the image.
* @return A PlanarYUVLuminanceSource instance.
*/
public PlanarYUVLuminanceSource buildLuminanceSource(byte[] data, int width, int height) {
return new PlanarYUVLuminanceSource(data, width, height, 0, 0,
width, height, false);
}
}
================================================
FILE: YZxing-lib/src/main/java/com/example/qrcode/camera/OpenCamera.java
================================================
package com.example.qrcode.camera;
import android.hardware.Camera;
/**
* Created by yangyu on 17/10/18.
*/
public final class OpenCamera {
private final int index;
private final Camera camera;
private final CameraFacing facing;
private final int orientation;
public OpenCamera(int index, Camera camera, CameraFacing facing, int orientation) {
this.index = index;
this.camera = camera;
this.facing = facing;
this.orientation = orientation;
}
public Camera getCamera() {
return camera;
}
public CameraFacing getFacing() {
return facing;
}
public int getOrientation() {
return orientation;
}
@Override
public String toString() {
return "Camera #" + index + " : " + facing + ',' + orientation;
}
}
================================================
FILE: YZxing-lib/src/main/java/com/example/qrcode/camera/OpenCameraInterface.java
================================================
package com.example.qrcode.camera;
/**
* Created by yangyu on 17/10/18.
*/
import android.hardware.Camera;
import android.util.Log;
/**
* Abstraction over the {@link Camera} API that helps open them and return their metadata.
*/
@SuppressWarnings("deprecation") // camera APIs
public final class OpenCameraInterface {
private static final String TAG = OpenCameraInterface.class.getName();
/** For {@link #open(int)}, means no preference for which camera to open. */
public static final int NO_REQUESTED_CAMERA = -1;
private OpenCameraInterface() {
}
/**
* Opens the requested camera with {@link Camera#open(int)}, if one exists.
*
* @param cameraId camera ID of the camera to use. A negative value
* or {@link #NO_REQUESTED_CAMERA} means "no preference", in which case a rear-facing
* camera is returned if possible or else any camera
* @return handle to {@link OpenCamera} that was opened
*/
public static OpenCamera open(int cameraId) {
int numCameras = Camera.getNumberOfCameras();
if (numCameras == 0) {
Log.w(TAG, "No cameras!");
return null;
}
boolean explicitRequest = cameraId >= 0;
Camera.CameraInfo selectedCameraInfo = null;
int index;
if (explicitRequest) {
index = cameraId;
selectedCameraInfo = new Camera.CameraInfo();
Camera.getCameraInfo(index, selectedCameraInfo);
} else {
index = 0;
while (index < numCameras) {
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
Camera.getCameraInfo(index, cameraInfo);
CameraFacing reportedFacing = CameraFacing.values()[cameraInfo.facing];
if (reportedFacing == CameraFacing.BACK) {
selectedCameraInfo = cameraInfo;
break;
}
index++;
}
}
Camera camera;
if (index < numCameras) {
Log.i(TAG, "Opening camera #" + index);
camera = Camera.open(index);
} else {
if (explicitRequest) {
Log.w(TAG, "Requested camera does not exist: " + cameraId);
camera = null;
} else {
Log.i(TAG, "No camera facing " + CameraFacing.BACK + "; returning camera #0");
camera = Camera.open(0);
selectedCameraInfo = new Camera.CameraInfo();
Camera.getCameraInfo(0, selectedCameraInfo);
}
}
if (camera == null) {
return null;
}
return new OpenCamera(index,
camera,
CameraFacing.values()[selectedCameraInfo.facing],
selectedCameraInfo.orientation);
}
}
================================================
FILE: YZxing-lib/src/main/java/com/example/qrcode/decode/DecodeHandler.java
================================================
package com.example.qrcode.decode;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import com.example.qrcode.Constant;
import com.example.qrcode.ScannerActivity;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.PlanarYUVLuminanceSource;
import com.google.zxing.ReaderException;
import com.google.zxing.Result;
import com.google.zxing.common.HybridBinarizer;
import java.util.Arrays;
import java.util.Map;
/**
* Created by yangyu on 17/10/19.
*/
final class DecodeHandler extends Handler {
private static final String TAG = DecodeHandler.class.getSimpleName();
private final ScannerActivity activity;
private final MultiFormatReader multiFormatReader;
private boolean running = true;
private byte[] mRotatedData;
DecodeHandler(ScannerActivity activity, Map<DecodeHintType, Object> hints) {
multiFormatReader = new MultiFormatReader();
multiFormatReader.setHints(hints);
this.activity = activity;
}
@Override
public void handleMessage(Message message) {
if (message == null || !running) {
return;
}
if (message.what == Constant.MESSAGE_SCANNER_DECODE) {
decode((byte[]) message.obj, message.arg1, message.arg2);
} else if (message.what == Constant.MESSAGE_SCANNER_QUIT) {
running = false;
Looper.myLooper().quit();
}
}
/**
* Decode the data within the viewfinder rectangle, and time how long it took. For efficiency,
* reuse the same reader objects from one decode to the next.
*
* @param data The YUV preview frame.
* @param width The width of the preview frame.
* @param height The height of the preview frame.
*/
private void decode(byte[] data, int width, int height) {
//这里需要对扫码的数据进行宽高的调换,原来扫码的是横屏数据,需要转化成竖屏。
if (null == mRotatedData) {
mRotatedData = new byte[width * height];
} else {
if (mRotatedData.length < width * height) {
mRotatedData = new byte[width * height];
}
}
Arrays.fill(mRotatedData, (byte) 0);
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
if (x + y * width >= data.length) {
break;
}
mRotatedData[x * height + height - y - 1] = data[x + y * width];
}
}
int tmp = width;
width = height;
height = tmp;
long start = System.currentTimeMillis();
Result rawResult = null;
PlanarYUVLuminanceSource source = activity.getCameraManager().buildLuminanceSource(mRotatedData, width, height);
if (source != null) {
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
try {
rawResult = multiFormatReader.decodeWithState(bitmap);
} catch (ReaderException re) {
// continue
Log.e(TAG, "decode: re:" + re.getMessage());
} finally {
multiFormatReader.reset();
}
}
Handler handler = activity.getHandler();
if (rawResult != null) {
// Don't log the barcode contents for security.
long end = System.currentTimeMillis();
Log.d(TAG, "Found barcode in " + (end - start) + " ms");
if (handler != null) {
Message message = Message.obtain(handler, Constant.MESSAGE_SCANNER_DECODE_SUCCEEDED, rawResult);
Bundle bundle = new Bundle();
message.setData(bundle);
message.sendToTarget();
}
} else {
if (handler != null) {
Message message = Message.obtain(handler, Constant.MESSAGE_SCANNER_DECODE_FAIL);
message.sendToTarget();
}
}
}
}
================================================
FILE: YZxing-lib/src/main/java/com/example/qrcode/decode/DecodeThread.java
================================================
package com.example.qrcode.decode;
/**
* Created by yangyu on 17/10/18.
*/
import android.os.Handler;
import android.os.Looper;
import com.example.qrcode.ScannerActivity;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.DecodeHintType;
import java.util.Collection;
import java.util.EnumMap;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
/**
* This thread does all the heavy lifting of decoding the images.
*
* @author dswitkin@google.com (Daniel Switkin)
*/
final class DecodeThread extends Thread {
private final ScannerActivity activity;
private final Map<DecodeHintType, Object> hints;
private Handler handler;
private final CountDownLatch handlerInitLatch;
DecodeThread(ScannerActivity activity,
Collection<BarcodeFormat> decodeFormats,
String characterSet
) {
this.activity = activity;
handlerInitLatch = new CountDownLatch(1);
hints = new EnumMap<>(DecodeHintType.class);
hints.put(DecodeHintType.POSSIBLE_FORMATS, decodeFormats);
if (characterSet != null) {
hints.put(DecodeHintType.CHARACTER_SET, characterSet);
}
hints.put(DecodeHintType.TRY_HARDER, true);
}
Handler getHandler() {
try {
handlerInitLatch.await();
} catch (InterruptedException ie) {
}
return handler;
}
@Override
public void run() {
Looper.prepare();
handler = new DecodeHandler(activity, hints);
handlerInitLatch.countDown();
Looper.loop();
}
}
================================================
FILE: YZxing-lib/src/main/java/com/example/qrcode/decode/InactivityTimer.java
================================================
package com.example.qrcode.decode;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.AsyncTask;
import android.os.BatteryManager;
import android.util.Log;
import java.util.concurrent.RejectedExecutionException;
/**
* Created by yangyu on 17/10/30.
*/
public final class InactivityTimer {
private static final String TAG = InactivityTimer.class.getSimpleName();
private static final long INACTIVITY_DELAY_MS = 5 * 60 * 1000L;
private final Activity activity;
private final BroadcastReceiver powerStatusReceiver;
private boolean registered;
private AsyncTask<Object, Object, Object> inactivityTask;
public InactivityTimer(Activity activity) {
this.activity = activity;
powerStatusReceiver = new PowerStatusReceiver();
registered = false;
onActivity();
}
public synchronized void onActivity() {
cancel();
inactivityTask = new InactivityAsyncTask();
try {
inactivityTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} catch (RejectedExecutionException ree) {
Log.w(TAG, "Couldn't schedule inactivity task; ignoring");
}
}
public synchronized void onPause() {
cancel();
if (registered) {
activity.unregisterReceiver(powerStatusReceiver);
registered = false;
} else {
Log.w(TAG, "PowerStatusReceiver was never registered?");
}
}
public synchronized void onResume() {
if (registered) {
Log.w(TAG, "PowerStatusReceiver was already registered?");
} else {
activity.registerReceiver(powerStatusReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
registered = true;
}
onActivity();
}
private synchronized void cancel() {
AsyncTask<?, ?, ?> task = inactivityTask;
if (task != null) {
task.cancel(true);
inactivityTask = null;
}
}
public void shutdown() {
cancel();
}
private final class PowerStatusReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_BATTERY_CHANGED.equals(intent.getAction())) {
// 0 indicates that we're on battery
boolean onBatteryNow = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1) <= 0;
if (onBatteryNow) {
InactivityTimer.this.onActivity();
} else {
InactivityTimer.this.cancel();
}
}
}
}
private final class InactivityAsyncTask extends AsyncTask<Object, Object, Object> {
@Override
protected Object doInBackground(Object... objects) {
try {
Thread.sleep(INACTIVITY_DELAY_MS);
Log.i(TAG, "Finishing activity due to inactivity");
activity.finish();
} catch (InterruptedException e) {
// continue without killing
}
return null;
}
}
}
================================================
FILE: YZxing-lib/src/main/java/com/example/qrcode/decode/ScannerHandler.java
================================================
package com.example.qrcode.decode;
import android.os.Handler;
import android.os.Message;
import com.example.qrcode.Constant;
import com.example.qrcode.ScannerActivity;
import com.example.qrcode.camera.CameraManager;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.Result;
import java.util.Collection;
/**
* Created by yangyu on 17/10/18.
*/
/**
* This class handles all the messaging which comprises the state machine for capture.
*
* @author dswitkin@google.com (Daniel Switkin)
*/
public final class ScannerHandler extends Handler {
private static final String TAG = ScannerHandler.class.getSimpleName();
private final ScannerActivity activity;
private final DecodeThread decodeThread;
private State state;
private final CameraManager cameraManager;
private enum State {
PREVIEW,
SUCCESS,
DONE
}
public ScannerHandler(ScannerActivity activity,
Collection<BarcodeFormat> decodeFormats,
String characterSet,
CameraManager cameraManager) {
this.activity = activity;
decodeThread = new DecodeThread(activity, decodeFormats, characterSet);
decodeThread.start();
state = State.SUCCESS;
// Start ourselves capturing previews and decoding.
this.cameraManager = cameraManager;
cameraManager.startPreview();
restartPreviewAndDecode();
}
@Override
public void handleMessage(Message message) {
if (message == null) return;
switch (message.what) {
case Constant.MESSAGE_SCANNER_DECODE_SUCCEEDED:
Result r = (Result) message.obj;
activity.handDecode(r);
break;
case Constant.MESSAGE_SCANNER_DECODE_FAIL:
state = State.PREVIEW;
cameraManager.requestPreviewFrame(decodeThread.getHandler(), Constant.MESSAGE_SCANNER_DECODE);
break;
}
}
public void quitSynchronously() {
state = State.DONE;
cameraManager.stopPreview();
Message quit = Message.obtain(decodeThread.getHandler(), Constant.MESSAGE_SCANNER_QUIT);
quit.sendToTarget();
try {
// Wait at most half a second; should be enough time, and onPause() will timeout quickly
decodeThread.join(500L);
} catch (InterruptedException e) {
// continue
}
// Be absolutely sure we don't send any queued up messages
removeMessages(Constant.MESSAGE_SCANNER_DECODE_SUCCEEDED);
removeMessages(Constant.MESSAGE_SCANNER_DECODE_FAIL);
}
private void restartPreviewAndDecode() {
if (state == State.SUCCESS) {
state = State.PREVIEW;
cameraManager.requestPreviewFrame(decodeThread.getHandler(), Constant.MESSAGE_SCANNER_DECODE);
}
}
}
================================================
FILE: YZxing-lib/src/main/java/com/example/qrcode/utils/CameraConfigurationUtils.java
================================================
package com.example.qrcode.utils;
/**
* Created by yangyu on 17/10/18.
*/
import android.annotation.TargetApi;
import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.Camera;
import android.os.Build;
import android.util.Log;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Pattern;
/**
* Utility methods for configuring the Android camera.
*
* @author Sean Owen
*/
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
public final class CameraConfigurationUtils {
private static final String TAG = "CameraConfiguration";
private static final Pattern SEMICOLON = Pattern.compile(";");
private static final int MIN_PREVIEW_PIXELS = 480 * 320; // normal screen
private static final float MAX_EXPOSURE_COMPENSATION = 1.5f;
private static final float MIN_EXPOSURE_COMPENSATION = 0.0f;
private static final double MAX_ASPECT_DISTORTION = 0.15;
private static final int MIN_FPS = 10;
private static final int MAX_FPS = 20;
private static final int AREA_PER_1000 = 400;
private CameraConfigurationUtils() {
}
public static void setFocus(Camera.Parameters parameters,
boolean autoFocus,
boolean disableContinuous,
boolean safeMode) {
List<String> supportedFocusModes = parameters.getSupportedFocusModes();
String focusMode = null;
if (autoFocus) {
if (safeMode || disableContinuous) {
focusMode = findSettableValue("focus mode",
supportedFocusModes,
Camera.Parameters.FOCUS_MODE_AUTO);
} else {
focusMode = findSettableValue("focus mode",
supportedFocusModes,
Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE,
Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO,
Camera.Parameters.FOCUS_MODE_AUTO);
}
}
// Maybe selected auto-focus but not available, so fall through here:
if (!safeMode && focusMode == null) {
focusMode = findSettableValue("focus mode",
supportedFocusModes,
Camera.Parameters.FOCUS_MODE_MACRO,
Camera.Parameters.FOCUS_MODE_EDOF);
}
if (focusMode != null) {
if (focusMode.equals(parameters.getFocusMode())) {
Log.i(TAG, "Focus mode already set to " + focusMode);
} else {
parameters.setFocusMode(focusMode);
}
}
}
public static void setTorch(Camera.Parameters parameters, boolean on) {
List<String> supportedFlashModes = parameters.getSupportedFlashModes();
String flashMode;
if (on) {
flashMode = findSettableValue("flash mode",
supportedFlashModes,
Camera.Parameters.FLASH_MODE_TORCH,
Camera.Parameters.FLASH_MODE_ON);
} else {
flashMode = findSettableValue("flash mode",
supportedFlashModes,
Camera.Parameters.FLASH_MODE_OFF);
}
if (flashMode != null) {
if (flashMode.equals(parameters.getFlashMode())) {
Log.i(TAG, "Flash mode already set to " + flashMode);
} else {
Log.i(TAG, "Setting flash mode to " + flashMode);
parameters.setFlashMode(flashMode);
}
}
}
public static void setFocusArea(Camera.Parameters parameters) {
if (parameters.getMaxNumFocusAreas() > 0) {
Log.i(TAG, "Old focus areas: " + toString(parameters.getFocusAreas()));
List<Camera.Area> middleArea = buildMiddleArea(AREA_PER_1000);
Log.i(TAG, "Setting focus area to : " + toString(middleArea));
parameters.setFocusAreas(middleArea);
} else {
Log.i(TAG, "Device does not support focus areas");
}
}
public static void setMetering(Camera.Parameters parameters) {
if (parameters.getMaxNumMeteringAreas() > 0) {
Log.i(TAG, "Old metering areas: " + parameters.getMeteringAreas());
List<Camera.Area> middleArea = buildMiddleArea(AREA_PER_1000);
Log.i(TAG, "Setting metering area to : " + toString(middleArea));
parameters.setMeteringAreas(middleArea);
} else {
Log.i(TAG, "Device does not support metering areas");
}
}
private static List<Camera.Area> buildMiddleArea(int areaPer1000) {
return Collections.singletonList(
new Camera.Area(new Rect(-areaPer1000, -areaPer1000, areaPer1000, areaPer1000), 1));
}
public static void setVideoStabilization(Camera.Parameters parameters) {
if (parameters.isVideoStabilizationSupported()) {
if (parameters.getVideoStabilization()) {
Log.i(TAG, "Video stabilization already enabled");
} else {
Log.i(TAG, "Enabling video stabilization...");
parameters.setVideoStabilization(true);
}
} else {
Log.i(TAG, "This device does not support video stabilization");
}
}
public static void setBarcodeSceneMode(Camera.Parameters parameters) {
if (Camera.Parameters.SCENE_MODE_BARCODE.equals(parameters.getSceneMode())) {
Log.i(TAG, "Barcode scene mode already set");
return;
}
String sceneMode = findSettableValue("scene mode",
parameters.getSupportedSceneModes(),
Camera.Parameters.SCENE_MODE_BARCODE);
if (sceneMode != null) {
parameters.setSceneMode(sceneMode);
}
}
public static void setZoom(Camera.Parameters parameters, double targetZoomRatio) {
if (parameters.isZoomSupported()) {
Integer zoom = indexOfClosestZoom(parameters, targetZoomRatio);
if (zoom == null) {
return;
}
if (parameters.getZoom() == zoom) {
Log.i(TAG, "Zoom is already set to " + zoom);
} else {
Log.i(TAG, "Setting zoom to " + zoom);
parameters.setZoom(zoom);
}
} else {
Log.i(TAG, "Zoom is not supported");
}
}
private static Integer indexOfClosestZoom(Camera.Parameters parameters, double targetZoomRatio) {
List<Integer> ratios = parameters.getZoomRatios();
Log.i(TAG, "Zoom ratios: " + ratios);
int maxZoom = parameters.getMaxZoom();
if (ratios == null || ratios.isEmpty() || ratios.size() != maxZoom + 1) {
Log.w(TAG, "Invalid zoom ratios!");
return null;
}
double target100 = 100.0 * targetZoomRatio;
double smallestDiff = Double.POSITIVE_INFINITY;
int closestIndex = 0;
for (int i = 0; i < ratios.size(); i++) {
double diff = Math.abs(ratios.get(i) - target100);
if (diff < smallestDiff) {
smallestDiff = diff;
closestIndex = i;
}
}
Log.i(TAG, "Chose zoom ratio of " + (ratios.get(closestIndex) / 100.0));
return closestIndex;
}
public static void setInvertColor(Camera.Parameters parameters) {
if (Camera.Parameters.EFFECT_NEGATIVE.equals(parameters.getColorEffect())) {
Log.i(TAG, "Negative effect already set");
return;
}
String colorMode = findSettableValue("color effect",
parameters.getSupportedColorEffects(),
Camera.Parameters.EFFECT_NEGATIVE);
if (colorMode != null) {
parameters.setColorEffect(colorMode);
}
}
public static Point findBestPreviewSizeValue(Camera.Parameters parameters, Point screenResolution) {
List<Camera.Size> rawSupportedSizes = parameters.getSupportedPreviewSizes();
if (rawSupportedSizes == null) {
Log.w(TAG, "Device returned no supported preview sizes; using default");
Camera.Size defaultSize = parameters.getPreviewSize();
if (defaultSize == null) {
throw new IllegalStateException("Parameters contained no preview size!");
}
return new Point(defaultSize.width, defaultSize.height);
}
// Sort by size, descending
List<Camera.Size> supportedPreviewSizes = new ArrayList<>(rawSupportedSizes);
Collections.sort(supportedPreviewSizes, new Comparator<Camera.Size>() {
@Override
public int compare(Camera.Size a, Camera.Size b) {
int aPixels = a.height * a.width;
int bPixels = b.height * b.width;
if (bPixels < aPixels) {
return -1;
}
if (bPixels > aPixels) {
return 1;
}
return 0;
}
});
if (Log.isLoggable(TAG, Log.INFO)) {
StringBuilder previewSizesString = new StringBuilder();
for (Camera.Size supportedPreviewSize : supportedPreviewSizes) {
previewSizesString.append(supportedPreviewSize.width).append('x')
.append(supportedPreviewSize.height).append(' ');
}
Log.i(TAG, "Supported preview sizes: " + previewSizesString);
}
double screenAspectRatio = screenResolution.x / (double) screenResolution.y;
// Remove sizes that are unsuitable
Iterator<Camera.Size> it = supportedPreviewSizes.iterator();
while (it.hasNext()) {
Camera.Size supportedPreviewSize = it.next();
int realWidth = supportedPreviewSize.width;
int realHeight = supportedPreviewSize.height;
if (realWidth * realHeight < MIN_PREVIEW_PIXELS) {
it.remove();
continue;
}
boolean isCandidatePortrait = realWidth < realHeight;
int maybeFlippedWidth = isCandidatePortrait ? realHeight : realWidth;
int maybeFlippedHeight = isCandidatePortrait ? realWidth : realHeight;
double aspectRatio = maybeFlippedWidth / (double) maybeFlippedHeight;
double distortion = Math.abs(aspectRatio - screenAspectRatio);
if (distortion > MAX_ASPECT_DISTORTION) {
it.remove();
continue;
}
if (maybeFlippedWidth == screenResolution.x && maybeFlippedHeight == screenResolution.y) {
Point exactPoint = new Point(realWidth, realHeight);
Log.i(TAG, "Found preview size exactly matching screen size: " + exactPoint);
return exactPoint;
}
}
// If no exact match, use largest preview size. This was not a great idea on older devices because
// of the additional computation needed. We're likely to get here on newer Android 4+ devices, where
// the CPU is much more powerful.
if (!supportedPreviewSizes.isEmpty()) {
Camera.Size largestPreview = supportedPreviewSizes.get(0);
Point largestSize = new Point(largestPreview.width, largestPreview.height);
Log.i(TAG, "Using largest suitable preview size: " + largestSize);
return largestSize;
}
// If there is nothing at all suitable, return current preview size
Camera.Size defaultPreview = parameters.getPreviewSize();
if (defaultPreview == null) {
throw new IllegalStateException("Parameters contained no preview size!");
}
Point defaultSize = new Point(defaultPreview.width, defaultPreview.height);
Log.i(TAG, "No suitable preview sizes, using default: " + defaultSize);
return defaultSize;
}
private static String findSettableValue(String name,
Collection<String> supportedValues,
String... desiredValues) {
Log.i(TAG, "Requesting " + name + " value from among: " + Arrays.toString(desiredValues));
Log.i(TAG, "Supported " + name + " values: " + supportedValues);
if (supportedValues != null) {
for (String desiredValue : desiredValues) {
if (supportedValues.contains(desiredValue)) {
Log.i(TAG, "Can set " + name + " to: " + desiredValue);
return desiredValue;
}
}
}
Log.i(TAG, "No supported values match");
return null;
}
private static String toString(Collection<int[]> arrays) {
if (arrays == null || arrays.isEmpty()) {
return "[]";
}
StringBuilder buffer = new StringBuilder();
buffer.append('[');
Iterator<int[]> it = arrays.iterator();
while (it.hasNext()) {
buffer.append(Arrays.toString(it.next()));
if (it.hasNext()) {
buffer.append(", ");
}
}
buffer.append(']');
return buffer.toString();
}
private static String toString(Iterable<Camera.Area> areas) {
if (areas == null) {
return null;
}
StringBuilder result = new StringBuilder();
for (Camera.Area area : areas) {
result.append(area.rect).append(':').append(area.weight).append(' ');
}
return result.toString();
}
public static String collectStats(Camera.Parameters parameters) {
return collectStats(parameters.flatten());
}
public static String collectStats(CharSequence flattenedParams) {
StringBuilder result = new StringBuilder(1000);
result.append("BOARD=").append(Build.BOARD).append('\n');
result.append("BRAND=").append(Build.BRAND).append('\n');
result.append("CPU_ABI=").append(Build.CPU_ABI).append('\n');
result.append("DEVICE=").append(Build.DEVICE).append('\n');
result.append("DISPLAY=").append(Build.DISPLAY).append('\n');
result.append("FINGERPRINT=").append(Build.FINGERPRINT).append('\n');
result.append("HOST=").append(Build.HOST).append('\n');
result.append("ID=").append(Build.ID).append('\n');
result.append("MANUFACTURER=").append(Build.MANUFACTURER).append('\n');
result.append("MODEL=").append(Build.MODEL).append('\n');
result.append("PRODUCT=").append(Build.PRODUCT).append('\n');
result.append("TAGS=").append(Build.TAGS).append('\n');
result.append("TIME=").append(Build.TIME).append('\n');
result.append("TYPE=").append(Build.TYPE).append('\n');
result.append("USER=").append(Build.USER).append('\n');
result.append("VERSION.CODENAME=").append(Build.VERSION.CODENAME).append('\n');
result.append("VERSION.INCREMENTAL=").append(Build.VERSION.INCREMENTAL).append('\n');
result.append("VERSION.RELEASE=").append(Build.VERSION.RELEASE).append('\n');
result.append("VERSION.SDK_INT=").append(Build.VERSION.SDK_INT).append('\n');
if (flattenedParams != null) {
String[] params = SEMICOLON.split(flattenedParams);
Arrays.sort(params);
for (String param : params) {
result.append(param).append('\n');
}
}
return result.toString();
}
}
================================================
FILE: YZxing-lib/src/main/java/com/example/qrcode/utils/CommonUtils.java
================================================
package com.example.qrcode.utils;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
/**
* Created by yangyu on 2017/11/28.
*/
public class CommonUtils {
private static final String TAG = "CommonUtils";
public static Bitmap compressPicture(String imgPath) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(imgPath, options);
Log.e(TAG, "onActivityResult: 未压缩之前图片的宽:" + options.outWidth + "--未压缩之前图片的高:"
+ options.outHeight + "--未压缩之前图片大小:" + options.outWidth * options.outHeight * 4 / 1024 / 1024 + "M");
options.inSampleSize = calculateInSampleSize(options, 100, 100);
Log.e(TAG, "onActivityResult: inSampleSize:" + options.inSampleSize);
options.inJustDecodeBounds = false;
Bitmap afterCompressBm = BitmapFactory.decodeFile(imgPath, options);
// //默认的图片格式是Bitmap.Config.ARGB_8888
Log.e(TAG, "onActivityResult: 图片的宽:" + afterCompressBm.getWidth() + "--图片的高:"
+ afterCompressBm.getHeight() + "--图片大小:" + afterCompressBm.getWidth() * afterCompressBm.getHeight() * 4 / 1024 / 1024 + "M");
return afterCompressBm;
}
private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
while ((halfHeight / inSampleSize) >= reqHeight
&& (halfWidth / inSampleSize) >= reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
}
================================================
FILE: YZxing-lib/src/main/java/com/example/qrcode/utils/DecodeUtils.java
================================================
package com.example.qrcode.utils;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;
import com.example.qrcode.Constant;
import com.example.qrcode.ShowResultActivity;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.ChecksumException;
import com.google.zxing.DecodeHintType;
import com.google.zxing.FormatException;
import com.google.zxing.NotFoundException;
import com.google.zxing.RGBLuminanceSource;
import com.google.zxing.Result;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.QRCodeReader;
import java.lang.ref.WeakReference;
import java.util.EnumMap;
import java.util.Map;
/**
* Created by yangyu on 2017/11/27.
*/
public class DecodeUtils {
private static final String TAG = "DecodeUtils";
public static class DecodeAsyncTask extends AsyncTask<Bitmap, Integer, Result> {
private WeakReference<Context> mContext;
private Result result;
public DecodeAsyncTask(Context mContext) {
this.mContext = new WeakReference<Context>(mContext);
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Result doInBackground(Bitmap... bitmaps) {
result = decodeFromPicture(bitmaps[0]);
return result;
}
@Override
protected void onPostExecute(Result result) {
super.onPostExecute(result);
if (result != null) {
String text = result.getText();
if (!TextUtils.isEmpty(text)) {
Intent intent = new Intent(mContext.get(), ShowResultActivity.class);
intent.putExtra(Constant.EXTRA_RESULT_TEXT_FROM_PIC, text);
mContext.get().startActivity(intent);
if (mContext.get() instanceof Activity) ((Activity) mContext.get()).finish();
}
} else {
Toast.makeText(mContext.get(), "解码失败", Toast.LENGTH_SHORT).show();
}
}
}
private static Result decodeFromPicture(Bitmap bitmap) {
if (bitmap == null) return null;
int picWidth = bitmap.getWidth();
int picHeight = bitmap.getHeight();
int[] pix = new int[picWidth * picHeight];
Log.e(TAG, "decodeFromPicture:图片大小: " + bitmap.getByteCount() / 1024 / 1024 + "M");
bitmap.getPixels(pix, 0, picWidth, 0, 0, picWidth, picHeight);
//构造LuminanceSource对象
RGBLuminanceSource rgbLuminanceSource = new RGBLuminanceSource(picWidth
, picHeight, pix);
BinaryBitmap bb = new BinaryBitmap(new HybridBinarizer(rgbLuminanceSource));
//因为解析的条码类型是二维码,所以这边用QRCodeReader最合适。
QRCodeReader qrCodeReader = new QRCodeReader();
Map<DecodeHintType, Object> hints = new EnumMap<>(DecodeHintType.class);
hints.put(DecodeHintType.CHARACTER_SET, "utf-8");
hints.put(DecodeHintType.TRY_HARDER, true);
Result result = null;
try {
result = qrCodeReader.decode(bb, hints);
return result;
} catch (NotFoundException | ChecksumException | FormatException e) {
e.printStackTrace();
return null;
}
}
}
================================================
FILE: YZxing-lib/src/main/java/com/example/qrcode/utils/UriUtils.java
================================================
package com.example.qrcode.utils;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
/**
* Created by yangyu on 2017/11/27.
*/
public class UriUtils {
public static String getPicturePathFromUri(Context context, Uri uri) {
int sdkVersion = Build.VERSION.SDK_INT;
if (sdkVersion >= 19) {
return getPicturePathFromUriAboveApi19(context, uri);
} else {
return getPicturePathFromUriBelowAPI19(context, uri);
}
}
private static String getPicturePathFromUriBelowAPI19(Context context, Uri uri) {
return getDataColumn(context, uri, null, null);
}
private static String getPicturePathFromUriAboveApi19(Context context, Uri uri) {
String filePath = null;
if (DocumentsContract.isDocumentUri(context, uri)) {
// 如果是document类型的 uri, 则通过document id来进行处理
String documentId = DocumentsContract.getDocumentId(uri);
if (isMediaDocument(uri)) { // MediaProvider
// 使用':'分割
String id = documentId.split(":")[1];
String selection = MediaStore.Images.Media._ID + "=?";
String[] selectionArgs = {id};
filePath = getDataColumn(context, MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection, selectionArgs);
} else if (isDownloadsDocument(uri)) { // DownloadsProvider
Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(documentId));
filePath = getDataColumn(context, contentUri, null, null);
}
} else if ("content".equalsIgnoreCase(uri.getScheme())) {
// 如果是 content 类型的 Uri
filePath = getDataColumn(context, uri, null, null);
} else if ("file".equals(uri.getScheme())) {
// 如果是 file 类型的 Uri,直接获取图片对应的路径
filePath = uri.getPath();
}
return filePath;
}
private static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
String path = null;
String[] projection = new String[]{MediaStore.Images.Media.DATA};
Cursor cursor = null;
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
if (cursor != null && cursor.moveToFirst()) {
int columnIndex = cursor.getColumnIndexOrThrow(projection[0]);
path = cursor.getString(columnIndex);
}
} catch (Exception e) {
if (cursor != null) {
cursor.close();
}
}
return path;
}
private static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
private static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
}
================================================
FILE: YZxing-lib/src/main/java/com/example/qrcode/view/ScannerView.java
================================================
package com.example.qrcode.view;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.View;
import com.example.qrcode.R;
import com.example.qrcode.camera.CameraManager;
/**
* Created by yangyu on 17/10/30.
*/
public class ScannerView extends View {
private static final int[] SCANNER_ALPHA = {0, 64, 128, 192, 255, 192, 128, 64};
private static final long ANIMATION_DELAY = 90L;
private Paint mBgPaint;
private Paint mCornerPaint;
private Paint mFocusFramePaint;
private Paint mTipPaint;
private Paint mLaserPaint;
private CameraManager cameraManager;
private int mCornerLength;
private int mCornerThick;
private int mTipPaddingTop;
private int mFocusLineThick;
private int scannerAlpha;
public ScannerView(Context context) {
this(context, null);
}
public ScannerView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init();
}
/**
* 一些初始化操作
*/
private void init() {
mBgPaint = new Paint();
mCornerPaint = new Paint();
mFocusFramePaint = new Paint();
mTipPaint = new Paint();
mLaserPaint = new Paint();
mBgPaint.setColor(getResources().getColor(R.color.scan_view_bg));
mBgPaint.setAntiAlias(true);
mCornerPaint.setAntiAlias(true);
mCornerPaint.setColor(getResources().getColor(R.color.scan_frame_green_color));
mFocusFramePaint.setAntiAlias(true);
mFocusFramePaint.setColor(Color.WHITE);
mTipPaint.setAntiAlias(true);
mTipPaint.setTextSize(getResources().getDimensionPixelSize(R.dimen.scanner_view_tip_size));
mTipPaint.setColor(getResources().getColor(R.color.scan_view_tip_color));
mLaserPaint.setAntiAlias(true);
mLaserPaint.setColor(getResources().getColor(R.color.scan_line_color));
mCornerLength = getResources().getDimensionPixelSize(R.dimen.scanner_view_corner_width);
mCornerThick = getResources().getDimensionPixelSize(R.dimen.scanner_view_corner_thick);
mTipPaddingTop = getResources().getDimensionPixelSize(R.dimen.scanner_view_tip_top);
mFocusLineThick = getResources().getDimensionPixelSize(R.dimen.scanner_view_focus_line_thick);
scannerAlpha = 0;
}
public void setCameraManager(CameraManager cameraManager) {
this.cameraManager = cameraManager;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (cameraManager == null) return;
Rect mScannerRect = cameraManager.getFramingRect();
if (mScannerRect == null) return;
int width = canvas.getWidth();
int height = canvas.getHeight();
canvas.drawRect(0, 0, width, mScannerRect.top, mBgPaint);
canvas.drawRect(0, mScannerRect.top, mScannerRect.left, mScannerRect.bottom + 1, mBgPaint);
canvas.drawRect(mScannerRect.right + 1, mScannerRect.top, width, mScannerRect.bottom + 1, mBgPaint);
canvas.drawRect(0, mScannerRect.bottom + 1, width, height, mBgPaint);
drawCorner(canvas, mScannerRect);
drawFocusRect(canvas, mScannerRect);
drawTipText(canvas, getResources().getDisplayMetrics().widthPixels, mScannerRect.bottom + mTipPaddingTop);
drawLaser(canvas, mScannerRect);
//实现动画效果
postInvalidateDelayed(ANIMATION_DELAY, mScannerRect.left, mScannerRect.top, mScannerRect.right, mScannerRect.bottom);
}
/**
* 绘制矩形框的四个角
*
* @param canvas
* @param rect
*/
private void drawCorner(Canvas canvas, Rect rect) {
if (rect == null) return;
//绘制左上角
canvas.drawRect(rect.left, rect.top, rect.left + mCornerLength, rect.top + mCornerThick, mCornerPaint);
canvas.drawRect(rect.left, rect.top, rect.left + mCornerThick, rect.top + mCornerLength, mCornerPaint);
//绘制左下角
canvas.drawRect(rect.left, rect.bottom - mCornerThick, rect.left + mCornerLength, rect.bottom, mCornerPaint);
canvas.drawRect(rect.left, rect.bottom - mCornerLength, rect.left + mCornerThick, rect.bottom, mCornerPaint);
//绘制右上角
canvas.drawRect(rect.right - mCornerLength, rect.top, rect.right, rect.top + mCornerThick, mCornerPaint);
canvas.drawRect(rect.right - mCornerThick, rect.top, rect.right, rect.top + mCornerLength, mCornerPaint);
//绘制右下角
canvas.drawRect(rect.right - mCornerLength, rect.bottom - mCornerThick, rect.right, rect.bottom, mCornerPaint);
canvas.drawRect(rect.right - mCornerThick, rect.bottom - mCornerLength, rect.right, rect.bottom, mCornerPaint);
}
/**
* 绘制聚焦框
*/
private void drawFocusRect(Canvas canvas, Rect rect) {
canvas.drawRect(rect.left + mCornerLength, rect.top, rect.right - mCornerLength, rect.top + mFocusLineThick, mFocusFramePaint);
canvas.drawRect(rect.right - mFocusLineThick, rect.top + mCornerLength, rect.right, rect.bottom - mCornerLength, mFocusFramePaint);
canvas.drawRect(rect.left + mCornerLength, rect.bottom - mFocusLineThick, rect.right - mCornerLength, rect.bottom, mFocusFramePaint);
canvas.drawRect(rect.left, rect.top + mCornerLength, rect.left + mFocusLineThick, rect.bottom - mCornerLength, mFocusFramePaint);
}
//绘制提示语
private void drawTipText(Canvas canvas, int w, int h) {
String tip = getResources().getString(R.string.scanner_view_tip_text);
float l = (w - tip.length() * mTipPaint.getTextSize()) / 2;
canvas.drawText(tip, l, h, mTipPaint);
}
/**
* 绘制激光线
*/
private void drawLaser(Canvas canvas, Rect rect) {
mLaserPaint.setAlpha(SCANNER_ALPHA[scannerAlpha]);
scannerAlpha = (scannerAlpha + 1) % SCANNER_ALPHA.length;
int middle = rect.height() / 2 + rect.top;
canvas.drawRect(rect.left + 2, middle - 1, rect.right - 1, middle + 2, mLaserPaint);
}
}
================================================
FILE: YZxing-lib/src/main/res/drawable/progressbar_drawable.xml
================================================
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background">
<shape>
<corners android:radius="5dip" />
<gradient
android:startColor="#ff9d9e9d"
android:centerColor="#ff5a5d5a"
android:centerY="0.75"
android:endColor="#ff747674"
android:angle="270"
/>
</shape>
</item>
<!--<item android:id="@android:id/secondaryProgress">-->
<!--<clip>-->
<!--<shape>-->
<!--<corners android:radius="5dip" />-->
<!--<gradient-->
<!--android:startColor="#80ffd300"-->
<!--android:centerColor="#80ffb600"-->
<!--android:centerY="0.75"-->
<!--android:endColor="#a0ffcb00"-->
<!--android:angle="270"-->
<!--/>-->
<!--</shape>-->
<!--</clip>-->
<!--</item>-->
<item android:id="@android:id/progress">
<clip>
<shape>
<corners android:radius="5dip" />
<!--<gradient-->
<!--android:startColor="#ffffd300"-->
<!--android:centerColor="#ffffb600"-->
<!--android:centerY="0.75"-->
<!--android:endColor="#ffffcb00"-->
<!--android:angle="270"-->
<!--/>-->
<solid android:color="@color/scan_frame_green_color" />
</shape>
</clip>
</item>
</layer-list>
================================================
FILE: YZxing-lib/src/main/res/layout/layout_activity_barcode.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<EditText
android:id="@+id/et_input_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:hint="请输入条码的内容"
android:paddingTop="10dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
<RadioGroup
android:id="@+id/rg_code_type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingTop="10dp"
app:layout_constraintTop_toBottomOf="@id/et_input_content">
<RadioButton
android:id="@+id/rb_qr_code"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="QR_CODE" />
<RadioButton
android:id="@+id/rb_code_128"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="CODE_128" />
</RadioGroup>
<Button
android:id="@+id/bt_encode"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="5dp"
android:text="生成条码"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/rg_code_type" />
<ImageView
android:id="@+id/barcode_image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="18dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/bt_encode" />
</android.support.constraint.ConstraintLayout>
================================================
FILE: YZxing-lib/src/main/res/layout/layout_activity_scanner.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="@+id/tool_bar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:navigationIcon="@drawable/ic_arrow_back_white_24dp"
app:popupTheme="@style/ToolbarPopupTheme">
</android.support.v7.widget.Toolbar>
<SurfaceView
android:id="@+id/surface"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/tool_bar"
android:layout_centerInParent="true" />
<com.example.qrcode.view.ScannerView
android:id="@+id/scan_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/tool_bar"
android:layout_centerInParent="true" />
</RelativeLayout>
================================================
FILE: YZxing-lib/src/main/res/layout/layout_activity_show_result.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ProgressBar
android:id="@+id/progress"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="3dp"
android:progressDrawable="@drawable/progressbar_drawable"
/>
<WebView
android:id="@+id/web_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/progress">
</WebView>
<TextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textColor="#000"
android:textSize="22sp"
/>
</RelativeLayout>
================================================
FILE: YZxing-lib/src/main/res/menu/menu_scan.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/scan_from_picture"
android:title="从相册选取二维码"
app:showAsAction="never" />
<item
android:id="@+id/encode_barcode"
android:title="生成条形码"
app:showAsAction="never" />
</menu>
================================================
FILE: YZxing-lib/src/main/res/values/colors.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="scan_frame_green_color">#65E102</color>
<color name="scan_line_color">#98C360</color>
<color name="scan_view_bg">#64000000</color>
<color name="scan_view_tip_color">#AFAFAF</color>
</resources>
================================================
FILE: YZxing-lib/src/main/res/values/dimens.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="scanner_view_corner_width">14dp</dimen>
<dimen name="scanner_view_corner_thick">4dp</dimen>
<dimen name="scanner_view_focus_line_thick">1dp</dimen>
<dimen name="scanner_view_tip_top">28dp</dimen>
<dimen name="scanner_view_tip_size">14sp</dimen>
</resources>
================================================
FILE: YZxing-lib/src/main/res/values/strings.xml
================================================
<resources>
<string name="app_name">QrCode</string>
<string name="scanner_view_tip_text">将二维码/条形码放入框内,即可自动扫描</string>
</resources>
================================================
FILE: YZxing-lib/src/main/res/values/styles.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="MyAppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">#393A3F</item>
<item name="colorPrimaryDark">#303135</item>
</style>
<style name="ToolbarPopupTheme" parent="@style/ThemeOverlay.AppCompat.Dark">
<!--<item name="android:colorBackground">#000000</item>-->
<item name="actionOverflowMenuStyle">@style/OverflowMenuStyle</item> <!--新增一个item,用于控制menu-->
</style>
<style name="OverflowMenuStyle" parent="Widget.AppCompat.Light.PopupMenu.Overflow">
<item name="overlapAnchor">false</item> <!--把该属性改为false即可使menu位置位于toolbar之下-->
</style>
</resources>
================================================
FILE: YZxing-lib/src/test/java/com/example/qrcode/ExampleUnitTest.java
================================================
package com.example.qrcode;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() throws Exception {
assertEquals(4, 2 + 2);
}
}
================================================
FILE: app/.gitignore
================================================
/build
================================================
FILE: app/build.gradle
================================================
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
buildToolsVersion "25.0.3"
defaultConfig {
applicationId "com.example.yzxing"
minSdkVersion 19
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:26.+'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
testCompile 'junit:junit:4.12'
compile project(':YZxing-lib')
}
================================================
FILE: app/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /Users/yangyu/Library/Android/sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
================================================
FILE: app/src/androidTest/java/com/example/yzxing/ExampleInstrumentedTest.java
================================================
package com.example.yzxing;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumentation test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() throws Exception {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();
assertEquals("com.example.yzxing", appContext.getPackageName());
}
}
================================================
FILE: app/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.yzxing">
<uses-permission android:name="android.permission.CAMERA"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
================================================
FILE: app/src/main/java/com/example/yzxing/MainActivity.java
================================================
package com.example.yzxing;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.example.qrcode.Constant;
import com.example.qrcode.ScannerActivity;
public class MainActivity extends AppCompatActivity {
private final int REQUEST_PERMISION_CODE_CAMARE = 0;
private final int RESULT_REQUEST_CODE = 1;
private static final String TAG = "MainActivity";
// private HashMap<String, Set> mHashMap = new HashMap<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button mScanner = (Button) findViewById(R.id.scanner);
mScanner.setOnClickListener(mScannerListener);
// Set<BarcodeFormat> codeFormats = EnumSet.of(BarcodeFormat.QR_CODE
// , BarcodeFormat.CODE_128
// , BarcodeFormat.CODE_93 );
// mHashMap.put(ScannerActivity.BARCODE_FORMAT, codeFormats);
}
private View.OnClickListener mScannerListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
goScanner();
} else {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA}, REQUEST_PERMISION_CODE_CAMARE);
}
}
};
private void goScanner() {
Intent intent = new Intent(this, ScannerActivity.class);
//这里可以用intent传递一些参数,比如扫码聚焦框尺寸大小,支持的扫码类型。
// //设置扫码框的宽
// intent.putExtra(Constant.EXTRA_SCANNER_FRAME_WIDTH, 400);
// //设置扫码框的高
// intent.putExtra(Constant.EXTRA_SCANNER_FRAME_HEIGHT, 400);
// //设置扫码框距顶部的位置
// intent.putExtra(Constant.EXTRA_SCANNER_FRAME_TOP_PADDING, 100);
// //设置是否启用从相册获取二维码。
intent.putExtra(Constant.EXTRA_IS_ENABLE_SCAN_FROM_PIC,true);
// Bundle bundle = new Bundle();
// //设置支持的扫码类型
// bundle.putSerializable(Constant.EXTRA_SCAN_CODE_TYPE, mHashMap);
// intent.putExtras(bundle);
startActivityForResult(intent, RESULT_REQUEST_CODE);
}
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String permissions[], @NonNull int[] grantResults) {
switch (requestCode) {
case REQUEST_PERMISION_CODE_CAMARE: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
goScanner();
}
return;
}
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
switch (requestCode) {
case RESULT_REQUEST_CODE:
if (data == null) return;
String type = data.getStringExtra(Constant.EXTRA_RESULT_CODE_TYPE);
String content = data.getStringExtra(Constant.EXTRA_RESULT_CONTENT);
Toast.makeText(MainActivity.this, "codeType:" + type
+ "-----content:" + content, Toast.LENGTH_SHORT).show();
break;
default:
break;
}
}
super.onActivityResult(requestCode, resultCode, data);
}
}
================================================
FILE: app/src/main/res/layout/activity_main.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.yzxing.MainActivity">
<Button
android:id="@+id/scanner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="go scanner!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
================================================
FILE: app/src/main/res/values/colors.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
</resources>
================================================
FILE: app/src/main/res/values/strings.xml
================================================
<resources>
<string name="app_name">YZxing</string>
</resources>
================================================
FILE: app/src/main/res/values/styles.xml
================================================
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
</resources>
================================================
FILE: app/src/test/java/com/example/yzxing/ExampleUnitTest.java
================================================
package com.example.yzxing;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() throws Exception {
assertEquals(4, 2 + 2);
}
}
================================================
FILE: build.gradle
================================================
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5'
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
================================================
FILE: gradle/wrapper/gradle-wrapper.properties
================================================
#Wed Oct 18 15:21:49 CST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
================================================
FILE: gradle.properties
================================================
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
================================================
FILE: gradlew
================================================
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
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
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((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" ;;
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=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
================================================
FILE: gradlew.bat
================================================
@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
@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=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@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 Windowz 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
================================================
FILE: settings.gradle
================================================
include ':app', ':YZxing-lib'
gitextract_56lrij_q/ ├── .gitignore ├── .idea/ │ ├── caches/ │ │ └── build_file_checksums.ser │ ├── codeStyles/ │ │ └── Project.xml │ ├── inspectionProfiles/ │ │ └── Project_Default.xml │ ├── misc.xml │ ├── modules.xml │ ├── runConfigurations.xml │ └── vcs.xml ├── LICENSE ├── README.md ├── YZxing-lib/ │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src/ │ ├── androidTest/ │ │ └── java/ │ │ └── com/ │ │ └── example/ │ │ └── qrcode/ │ │ └── ExampleInstrumentedTest.java │ ├── main/ │ │ ├── AndroidManifest.xml │ │ ├── java/ │ │ │ └── com/ │ │ │ └── example/ │ │ │ └── qrcode/ │ │ │ ├── BarcodeActivity.java │ │ │ ├── BeepManager.java │ │ │ ├── Constant.java │ │ │ ├── ScannerActivity.java │ │ │ ├── ShowResultActivity.java │ │ │ ├── callback/ │ │ │ │ └── PreviewCallback.java │ │ │ ├── camera/ │ │ │ │ ├── AutoFocusManager.java │ │ │ │ ├── CameraConfigurationManager.java │ │ │ │ ├── CameraFacing.java │ │ │ │ ├── CameraManager.java │ │ │ │ ├── OpenCamera.java │ │ │ │ └── OpenCameraInterface.java │ │ │ ├── decode/ │ │ │ │ ├── DecodeHandler.java │ │ │ │ ├── DecodeThread.java │ │ │ │ ├── InactivityTimer.java │ │ │ │ └── ScannerHandler.java │ │ │ ├── utils/ │ │ │ │ ├── CameraConfigurationUtils.java │ │ │ │ ├── CommonUtils.java │ │ │ │ ├── DecodeUtils.java │ │ │ │ └── UriUtils.java │ │ │ └── view/ │ │ │ └── ScannerView.java │ │ └── res/ │ │ ├── drawable/ │ │ │ └── progressbar_drawable.xml │ │ ├── layout/ │ │ │ ├── layout_activity_barcode.xml │ │ │ ├── layout_activity_scanner.xml │ │ │ └── layout_activity_show_result.xml │ │ ├── menu/ │ │ │ └── menu_scan.xml │ │ ├── raw/ │ │ │ └── beep.ogg │ │ └── values/ │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test/ │ └── java/ │ └── com/ │ └── example/ │ └── qrcode/ │ └── ExampleUnitTest.java ├── app/ │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src/ │ ├── androidTest/ │ │ └── java/ │ │ └── com/ │ │ └── example/ │ │ └── yzxing/ │ │ └── ExampleInstrumentedTest.java │ ├── main/ │ │ ├── AndroidManifest.xml │ │ ├── java/ │ │ │ └── com/ │ │ │ └── example/ │ │ │ └── yzxing/ │ │ │ └── MainActivity.java │ │ └── res/ │ │ ├── layout/ │ │ │ └── activity_main.xml │ │ └── values/ │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test/ │ └── java/ │ └── com/ │ └── example/ │ └── yzxing/ │ └── ExampleUnitTest.java ├── build.gradle ├── gradle/ │ └── wrapper/ │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── gradlew ├── gradlew.bat └── settings.gradle
SYMBOL INDEX (177 symbols across 26 files)
FILE: YZxing-lib/src/androidTest/java/com/example/qrcode/ExampleInstrumentedTest.java
class ExampleInstrumentedTest (line 17) | @RunWith(AndroidJUnit4.class)
method useAppContext (line 19) | @Test
FILE: YZxing-lib/src/main/java/com/example/qrcode/BarcodeActivity.java
class BarcodeActivity (line 37) | public class BarcodeActivity extends Activity {
method onCreate (line 63) | @Override
method onCheckedChanged (line 90) | @Override
method onClick (line 104) | @Override
method encode (line 115) | private void encode(String content) {
method run (line 151) | @Override
method getWantedCodeType (line 163) | private BarcodeFormat getWantedCodeType(int type) {
method guessAppropriateEncoding (line 175) | private static String guessAppropriateEncoding(CharSequence contents) {
FILE: YZxing-lib/src/main/java/com/example/qrcode/BeepManager.java
class BeepManager (line 20) | public final class BeepManager implements MediaPlayer.OnErrorListener, C...
method BeepManager (line 32) | BeepManager(Activity activity) {
method updatePrefs (line 38) | synchronized void updatePrefs() {
method playBeepSoundAndVibrate (line 50) | synchronized void playBeepSoundAndVibrate() {
method shouldBeep (line 60) | private static boolean shouldBeep(SharedPreferences prefs, Context act...
method buildMediaPlayer (line 72) | private MediaPlayer buildMediaPlayer(Context activity) {
method onError (line 89) | @Override
method close (line 102) | @Override
FILE: YZxing-lib/src/main/java/com/example/qrcode/Constant.java
class Constant (line 7) | public class Constant {
FILE: YZxing-lib/src/main/java/com/example/qrcode/ScannerActivity.java
class ScannerActivity (line 48) | public class ScannerActivity extends AppCompatActivity implements Surfac...
class MyHandler (line 75) | private static class MyHandler extends Handler {
method MyHandler (line 78) | MyHandler(ScannerActivity mainActivityWeakReference) {
method handleMessage (line 82) | @Override
method onCreate (line 96) | @Override
method onResume (line 129) | @Override
method onPause (line 146) | @Override
method onDestroy (line 158) | @Override
method onKeyDown (line 165) | @Override
method onCreateOptionsMenu (line 180) | @Override
method onOptionsItemSelected (line 190) | @Override
method goPicture (line 209) | private void goPicture() {
method initView (line 215) | private void initView() {
method initCamera (line 231) | private void initCamera(SurfaceHolder surfaceHolder) {
method surfaceCreated (line 251) | @Override
method surfaceChanged (line 262) | @Override
method surfaceDestroyed (line 266) | @Override
method handDecode (line 272) | public void handDecode(final Result result) {
method getCameraManager (line 295) | public CameraManager getCameraManager() {
method getHandler (line 299) | public Handler getHandler() {
method onActivityResult (line 303) | @Override
method onRequestPermissionsResult (line 321) | @Override
FILE: YZxing-lib/src/main/java/com/example/qrcode/ShowResultActivity.java
class ShowResultActivity (line 22) | public class ShowResultActivity extends AppCompatActivity {
method onCreate (line 31) | @Override
method shouldOverrideUrlLoading (line 65) | @Override
method onPageStarted (line 71) | @Override
method onPageFinished (line 76) | @Override
method onProgressChanged (line 83) | @Override
method onReceivedTitle (line 94) | @Override
FILE: YZxing-lib/src/main/java/com/example/qrcode/callback/PreviewCallback.java
class PreviewCallback (line 15) | public class PreviewCallback implements Camera.PreviewCallback {
method PreviewCallback (line 23) | public PreviewCallback(CameraConfigurationManager configManager) {
method setHandler (line 27) | public void setHandler(Handler previewHandler, int previewMessage) {
method onPreviewFrame (line 32) | @Override
FILE: YZxing-lib/src/main/java/com/example/qrcode/camera/AutoFocusManager.java
class AutoFocusManager (line 20) | final class AutoFocusManager implements Camera.AutoFocusCallback {
method AutoFocusManager (line 39) | AutoFocusManager(Context context, Camera camera) {
method onAutoFocus (line 50) | @Override
method autoFocusAgainLater (line 56) | private synchronized void autoFocusAgainLater() {
method start (line 68) | synchronized void start() {
method cancelOutstandingTask (line 85) | private synchronized void cancelOutstandingTask() {
method stop (line 94) | synchronized void stop() {
class AutoFocusTask (line 108) | private final class AutoFocusTask extends AsyncTask<Object, Object, Ob...
method doInBackground (line 109) | @Override
FILE: YZxing-lib/src/main/java/com/example/qrcode/camera/CameraConfigurationManager.java
class CameraConfigurationManager (line 23) | @SuppressWarnings("deprecation") // camera APIs
method CameraConfigurationManager (line 33) | CameraConfigurationManager(Context context) {
method initFromCameraParameters (line 40) | void initFromCameraParameters(OpenCamera camera) {
method setDesiredCameraParameters (line 54) | void setDesiredCameraParameters(OpenCamera camera, boolean safeMode) {
method getCameraResolution (line 84) | public Point getCameraResolution() {
method getScreenResolution (line 88) | Point getScreenResolution() {
method getTorchState (line 92) | boolean getTorchState(Camera camera) {
method setTorch (line 105) | void setTorch(Camera camera, boolean newSetting) {
method doSetTorch (line 111) | private void doSetTorch(Camera.Parameters parameters, boolean newSetti...
FILE: YZxing-lib/src/main/java/com/example/qrcode/camera/CameraFacing.java
type CameraFacing (line 7) | enum CameraFacing {
FILE: YZxing-lib/src/main/java/com/example/qrcode/camera/CameraManager.java
class CameraManager (line 27) | @SuppressWarnings("deprecation") // camera APIs
method CameraManager (line 55) | public CameraManager(Context context) {
method openDriver (line 67) | public synchronized void openDriver(SurfaceHolder holder) throws IOExc...
method isOpen (line 97) | public synchronized boolean isOpen() {
method closeDriver (line 104) | public synchronized void closeDriver() {
method clearFramingRect (line 111) | public synchronized void clearFramingRect(){
method startPreview (line 120) | public synchronized void startPreview() {
method stopPreview (line 132) | public synchronized void stopPreview() {
method setTorch (line 147) | public synchronized void setTorch(boolean newSetting) {
method requestPreviewFrame (line 171) | public synchronized void requestPreviewFrame(Handler handler, int mess...
method getFramingRect (line 186) | public synchronized Rect getFramingRect() {
method findDesiredDimensionInRange (line 208) | private static int findDesiredDimensionInRange(int resolution, int har...
method setManualCameraId (line 253) | public synchronized void setManualCameraId(int cameraId) {
method setManualFramingRect (line 263) | public synchronized void setManualFramingRect(int width, int height, i...
method buildLuminanceSource (line 291) | public PlanarYUVLuminanceSource buildLuminanceSource(byte[] data, int ...
FILE: YZxing-lib/src/main/java/com/example/qrcode/camera/OpenCamera.java
class OpenCamera (line 9) | public final class OpenCamera {
method OpenCamera (line 16) | public OpenCamera(int index, Camera camera, CameraFacing facing, int o...
method getCamera (line 23) | public Camera getCamera() {
method getFacing (line 27) | public CameraFacing getFacing() {
method getOrientation (line 31) | public int getOrientation() {
method toString (line 35) | @Override
FILE: YZxing-lib/src/main/java/com/example/qrcode/camera/OpenCameraInterface.java
class OpenCameraInterface (line 13) | @SuppressWarnings("deprecation") // camera APIs
method OpenCameraInterface (line 21) | private OpenCameraInterface() {
method open (line 32) | public static OpenCamera open(int cameraId) {
FILE: YZxing-lib/src/main/java/com/example/qrcode/decode/DecodeHandler.java
class DecodeHandler (line 26) | final class DecodeHandler extends Handler {
method DecodeHandler (line 35) | DecodeHandler(ScannerActivity activity, Map<DecodeHintType, Object> hi...
method handleMessage (line 41) | @Override
method decode (line 64) | private void decode(byte[] data, int width, int height) {
FILE: YZxing-lib/src/main/java/com/example/qrcode/decode/DecodeThread.java
class DecodeThread (line 24) | final class DecodeThread extends Thread {
method DecodeThread (line 31) | DecodeThread(ScannerActivity activity,
method getHandler (line 45) | Handler getHandler() {
method run (line 54) | @Override
FILE: YZxing-lib/src/main/java/com/example/qrcode/decode/InactivityTimer.java
class InactivityTimer (line 18) | public final class InactivityTimer {
method InactivityTimer (line 28) | public InactivityTimer(Activity activity) {
method onActivity (line 35) | public synchronized void onActivity() {
method onPause (line 45) | public synchronized void onPause() {
method onResume (line 55) | public synchronized void onResume() {
method cancel (line 65) | private synchronized void cancel() {
method shutdown (line 73) | public void shutdown() {
class PowerStatusReceiver (line 77) | private final class PowerStatusReceiver extends BroadcastReceiver {
method onReceive (line 78) | @Override
class InactivityAsyncTask (line 92) | private final class InactivityAsyncTask extends AsyncTask<Object, Obje...
method doInBackground (line 93) | @Override
FILE: YZxing-lib/src/main/java/com/example/qrcode/decode/ScannerHandler.java
class ScannerHandler (line 23) | public final class ScannerHandler extends Handler {
type State (line 32) | private enum State {
method ScannerHandler (line 38) | public ScannerHandler(ScannerActivity activity,
method handleMessage (line 53) | @Override
method quitSynchronously (line 68) | public void quitSynchronously() {
method restartPreviewAndDecode (line 85) | private void restartPreviewAndDecode() {
FILE: YZxing-lib/src/main/java/com/example/qrcode/utils/CameraConfigurationUtils.java
class CameraConfigurationUtils (line 28) | @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
method CameraConfigurationUtils (line 43) | private CameraConfigurationUtils() {
method setFocus (line 46) | public static void setFocus(Camera.Parameters parameters,
method setTorch (line 81) | public static void setTorch(Camera.Parameters parameters, boolean on) {
method setFocusArea (line 105) | public static void setFocusArea(Camera.Parameters parameters) {
method setMetering (line 116) | public static void setMetering(Camera.Parameters parameters) {
method buildMiddleArea (line 127) | private static List<Camera.Area> buildMiddleArea(int areaPer1000) {
method setVideoStabilization (line 132) | public static void setVideoStabilization(Camera.Parameters parameters) {
method setBarcodeSceneMode (line 145) | public static void setBarcodeSceneMode(Camera.Parameters parameters) {
method setZoom (line 158) | public static void setZoom(Camera.Parameters parameters, double target...
method indexOfClosestZoom (line 175) | private static Integer indexOfClosestZoom(Camera.Parameters parameters...
method setInvertColor (line 197) | public static void setInvertColor(Camera.Parameters parameters) {
method findBestPreviewSizeValue (line 210) | public static Point findBestPreviewSizeValue(Camera.Parameters paramet...
method findSettableValue (line 298) | private static String findSettableValue(String name,
method toString (line 315) | private static String toString(Collection<int[]> arrays) {
method toString (line 332) | private static String toString(Iterable<Camera.Area> areas) {
method collectStats (line 343) | public static String collectStats(Camera.Parameters parameters) {
method collectStats (line 347) | public static String collectStats(CharSequence flattenedParams) {
FILE: YZxing-lib/src/main/java/com/example/qrcode/utils/CommonUtils.java
class CommonUtils (line 11) | public class CommonUtils {
method compressPicture (line 14) | public static Bitmap compressPicture(String imgPath) {
method calculateInSampleSize (line 31) | private static int calculateInSampleSize(BitmapFactory.Options options...
FILE: YZxing-lib/src/main/java/com/example/qrcode/utils/DecodeUtils.java
class DecodeUtils (line 32) | public class DecodeUtils {
class DecodeAsyncTask (line 35) | public static class DecodeAsyncTask extends AsyncTask<Bitmap, Integer,...
method DecodeAsyncTask (line 40) | public DecodeAsyncTask(Context mContext) {
method onPreExecute (line 44) | @Override
method doInBackground (line 49) | @Override
method onPostExecute (line 55) | @Override
method decodeFromPicture (line 74) | private static Result decodeFromPicture(Bitmap bitmap) {
FILE: YZxing-lib/src/main/java/com/example/qrcode/utils/UriUtils.java
class UriUtils (line 15) | public class UriUtils {
method getPicturePathFromUri (line 16) | public static String getPicturePathFromUri(Context context, Uri uri) {
method getPicturePathFromUriBelowAPI19 (line 25) | private static String getPicturePathFromUriBelowAPI19(Context context,...
method getPicturePathFromUriAboveApi19 (line 29) | private static String getPicturePathFromUriAboveApi19(Context context,...
method getDataColumn (line 55) | private static String getDataColumn(Context context, Uri uri, String s...
method isMediaDocument (line 74) | private static boolean isMediaDocument(Uri uri) {
method isDownloadsDocument (line 78) | private static boolean isDownloadsDocument(Uri uri) {
FILE: YZxing-lib/src/main/java/com/example/qrcode/view/ScannerView.java
class ScannerView (line 20) | public class ScannerView extends View {
method ScannerView (line 37) | public ScannerView(Context context) {
method ScannerView (line 41) | public ScannerView(Context context, @Nullable AttributeSet attrs) {
method init (line 49) | private void init() {
method setCameraManager (line 79) | public void setCameraManager(CameraManager cameraManager) {
method onDraw (line 83) | @Override
method drawCorner (line 110) | private void drawCorner(Canvas canvas, Rect rect) {
method drawFocusRect (line 132) | private void drawFocusRect(Canvas canvas, Rect rect) {
method drawTipText (line 140) | private void drawTipText(Canvas canvas, int w, int h) {
method drawLaser (line 149) | private void drawLaser(Canvas canvas, Rect rect) {
FILE: YZxing-lib/src/test/java/com/example/qrcode/ExampleUnitTest.java
class ExampleUnitTest (line 12) | public class ExampleUnitTest {
method addition_isCorrect (line 13) | @Test
FILE: app/src/androidTest/java/com/example/yzxing/ExampleInstrumentedTest.java
class ExampleInstrumentedTest (line 17) | @RunWith(AndroidJUnit4.class)
method useAppContext (line 19) | @Test
FILE: app/src/main/java/com/example/yzxing/MainActivity.java
class MainActivity (line 19) | public class MainActivity extends AppCompatActivity {
method onCreate (line 27) | @Override
method onClick (line 41) | @Override
method goScanner (line 51) | private void goScanner() {
method onRequestPermissionsResult (line 69) | @Override
method onActivityResult (line 84) | @Override
FILE: app/src/test/java/com/example/yzxing/ExampleUnitTest.java
class ExampleUnitTest (line 12) | public class ExampleUnitTest {
method addition_isCorrect (line 13) | @Test
Condensed preview — 65 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (160K chars).
[
{
"path": ".gitignore",
"chars": 760,
"preview": "# Built application files\n*.apk\n*.ap_\n\n# Files for the ART/Dalvik VM\n*.dex\n\n# Java class files\n*.class\n\n# Generated file"
},
{
"path": ".idea/codeStyles/Project.xml",
"chars": 1775,
"preview": "<component name=\"ProjectCodeStyleConfiguration\">\n <code_scheme name=\"Project\" version=\"173\">\n <Objective-C-extension"
},
{
"path": ".idea/inspectionProfiles/Project_Default.xml",
"chars": 1444,
"preview": "<component name=\"InspectionProjectProfileManager\">\n <profile version=\"1.0\">\n <option name=\"myName\" value=\"Project De"
},
{
"path": ".idea/misc.xml",
"chars": 2101,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"NullableNotNullManager\">\n <option nam"
},
{
"path": ".idea/modules.xml",
"chars": 474,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"ProjectModuleManager\">\n <modules>\n "
},
{
"path": ".idea/runConfigurations.xml",
"chars": 564,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"RunConfigurationProducerService\">\n <o"
},
{
"path": ".idea/vcs.xml",
"chars": 167,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n <component name=\"VcsDirectoryMappings\">\n <mapping dire"
},
{
"path": "LICENSE",
"chars": 11357,
"preview": " Apache License\n Version 2.0, January 2004\n "
},
{
"path": "README.md",
"chars": 3153,
"preview": "# YZxing\n一款仿微信扫一扫界面,基于zxing实现的扫码库。 \n### **实现效果** ### \n users:\n# Gradle settings configured through the IDE *will o"
},
{
"path": "gradlew",
"chars": 4971,
"preview": "#!/usr/bin/env bash\n\n##############################################################################\n##\n## Gradle start "
},
{
"path": "gradlew.bat",
"chars": 2404,
"preview": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@r"
},
{
"path": "settings.gradle",
"chars": 30,
"preview": "include ':app', ':YZxing-lib'\n"
}
]
// ... and 3 more files (download for full content)
About this extraction
This page contains the full source code of the MRYangY/YZxing GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 65 files (144.1 KB), approximately 34.9k tokens, and a symbol index with 177 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.