Skip to content

Commit

Permalink
Merge branch 'release/0.1.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
G00fY2 committed Nov 27, 2020
2 parents 62084fc + 8015241 commit da5fed2
Show file tree
Hide file tree
Showing 165 changed files with 940 additions and 196 deletions.
26 changes: 18 additions & 8 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
root=true

[*.{kt,kts}]
# possible values: number (e.g. 2), "unset" (makes ktlint ignore indentation completely)
indent_size=2
# true (recommended) / false
# insert_final_newline=true
# possible values: number (e.g. 120) (package name, imports & comments are ignored), "off"
# it's automatically set to 100 on `ktlint --android ...` (per Android Kotlin Style Guide)
charset=utf-8
end_of_line=lf
insert_final_newline=false

max_line_length=120

indent_size=2
indent_style=space

# TODO remove .idea/codeStyles from vcs when https://youtrack.jetbrains.com/issue/KTIJ-165 is fixed
ij_kotlin_name_count_to_use_star_import=2147483647
ij_kotlin_name_count_to_use_star_import_for_members=2147483647

# ktlint
# Comma-separated list of rules to disable (Since 0.34.0)
# Note that rules in any ruleset other than the standard ruleset will need to be prefixed
# by the ruleset identifier.
# Note that rules in any ruleset other than the standard ruleset will need to be prefixed by the ruleset identifier.
# noinspection EditorConfigKeyCorrectness
disabled_rules=final-newline
# Defines the imports layout. There are predefined layouts like "ascii" or "idea", as well as a custom layout.
# noinspection EditorConfigKeyCorrectness
kotlin_imports_layout=idea
4 changes: 3 additions & 1 deletion .github/workflows/android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ name: Android CI
on:
push:
branches:
- develop
- master
pull_request:
branches:
- develop
- master

jobs:
Expand Down Expand Up @@ -33,4 +35,4 @@ jobs:
with:
java-version: 1.8
- name: Build debug sample app
run: ./gradlew :sample:assembleBundledMLDebug
run: ./gradlew :activity-sample:assembleBundledDebug :advanced-sample:assembleBundledDebug :fragment-sample:assembleBundledDebug
10 changes: 8 additions & 2 deletions .idea/codeStyles/Project.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
# Quickie [![Build Status](https://github.com/G00fY2/Quickie/workflows/Android%20CI/badge.svg)](https://github.com/G00fY2/Quickie/actions)
<p align="center">
<img width="345" height="120" src="https://raw.githubusercontent.com/G00fY2/Quickie/gh-pages/media/logo.png">
</p>

Android QR code scanner library - work in progress
**quickie** is an Quick Response (QR) Code scanning library for Android that is based on CameraX and ML Kit on-device barcode detection. It's written in Kotlin and allows easy integration by using the AndroidX Activity Result API. quickie features:
- Modern design, edge-to-edge scanning view with multilingual user hint
- Easy API for launching the QR scanner and receiving results
- Android Jetpack CameraX for communicating with the camera and showing the preview
- Firebase ML Kit on-device barcode recognition and decoding (no network connection required)

## License
The MIT License (MIT)
Expand Down
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask

plugins {
id(Plugins.Android.application) version Versions.androidGradle apply false
kotlin(Plugins.Kotlin.android) version Versions.kotlin apply false
kotlin(Plugins.Kotlin.androidGradle) version Versions.kotlin apply false
id(Plugins.Misc.ktlint) version Versions.ktlintPlugin
id(Plugins.Misc.gradleVersions) version Versions.gradleVersions
}
Expand Down
5 changes: 4 additions & 1 deletion buildSrc/src/main/kotlin/Config.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
@Suppress("MemberVisibilityCanBePrivate")
object Config {
const val applicationId = "com.g00fy2.quickiesample"
const val activitySampleAppId = "com.g00fy2.quickieactivitysample"
const val fragmentSampleAppId = "com.g00fy2.quickiefragmentsample"
const val advancedSampleAppId = "com.g00fy2.quickieadvancedsample"

const val androidMinSdkVersion = 21
const val androidCompileSdkVersion = 30
Expand Down
2 changes: 2 additions & 0 deletions buildSrc/src/main/kotlin/Deps.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ object Deps {
const val camera = "androidx.camera:camera-camera2:${Versions.camera}"
const val cameraLifecycle = "androidx.camera:camera-lifecycle:${Versions.cameraLifecycle}"
const val cameraPreview = "androidx.camera:camera-view:${Versions.cameraPreview}"

const val navigation = "androidx.navigation:navigation-fragment-ktx:${Versions.navigation}"
}

object Mdc {
Expand Down
6 changes: 4 additions & 2 deletions buildSrc/src/main/kotlin/Plugins.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ object Plugins {
}

object Kotlin {
const val android = "android"
const val parcelize = "plugin.parcelize"
const val androidGradle = "android"
const val android = "kotlin-android"
const val parcelize = "kotlin-parcelize"
const val dokka = "org.jetbrains.dokka"
}

object Misc {
Expand Down
3 changes: 3 additions & 0 deletions buildSrc/src/main/kotlin/Versions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@ object Versions {
const val ktlintPlugin = "9.4.1"
const val ktlint = "0.39.0"
const val gradleVersions = "0.36.0"
const val dokka = "1.4.10.2"

const val activity = "1.2.0-beta01"
const val fragment = "1.3.0-beta01"
const val appcompat = "1.2.0"
const val core = "1.3.2"

const val navigation = "2.3.1"

const val camera = "1.0.0-beta12"
const val cameraLifecycle = "1.0.0-beta12"
const val cameraPreview = "1.0.0-alpha19"
Expand Down
10 changes: 5 additions & 5 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
# Allow usage of AndroidX instead of the old support libraries.
android.useAndroidX=true
# Set the build VMs heap size.
org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
# AndroidX package structure to make it clearer which packages are bundled with the
# Android operating system, and which are packaged with your app"s APK
android.useAndroidX=true
# Disable publishing SHA256 and SHA512 checksums.
systemProp.org.gradle.internal.publish.checksums.insecure=true
116 changes: 104 additions & 12 deletions quickie/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
plugins {
id(Plugins.Android.library)
kotlin(Plugins.Kotlin.android)
kotlin(Plugins.Kotlin.parcelize)
id(Plugins.Kotlin.android)
id(Plugins.Kotlin.parcelize)
id(Plugins.Kotlin.dokka) version Versions.dokka
`maven-publish`
}

android {
compileSdkVersion(Config.androidCompileSdkVersion)
defaultConfig {
minSdkVersion(Config.androidMinSdkVersion)
}
resourcePrefix = project.name
buildFeatures {
viewBinding = true
buildConfig = false
Expand All @@ -25,13 +28,13 @@ android {
kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8.toString()
}
flavorDimensions("bundleMode")
flavorDimensions("mlkit")
productFlavors {
create("bundledML") {
dimension("bundleMode")
create("bundled") {
dimension("mlkit")
}
create("unbundledML") {
dimension("bundleMode")
create("unbundled") {
dimension("mlkit")
}
}
}
Expand All @@ -41,13 +44,14 @@ repositories {
mavenCentral()
jcenter {
content {
includeModule("org.jetbrains.trove4j", "trove4j") // required by com.android.tools.lint:lint-gradle
includeGroupByRegex("org\\.jetbrains.*")
includeModule("com.soywiz.korlibs.korte", "korte-jvm")
}
}
}

val bundledMLImplementation by configurations
val unbundledMLImplementation by configurations
val bundledImplementation by configurations
val unbundledImplementation by configurations
dependencies {
implementation(Deps.AndroidX.activity)
implementation(Deps.AndroidX.fragment)
Expand All @@ -58,6 +62,94 @@ dependencies {
implementation(Deps.AndroidX.cameraLifecycle)
implementation(Deps.AndroidX.cameraPreview)

bundledMLImplementation(Deps.MLKit.barcodeScanning)
unbundledMLImplementation(Deps.MLKit.barcodeScanningGms)
bundledImplementation(Deps.MLKit.barcodeScanning)
unbundledImplementation(Deps.MLKit.barcodeScanningGms)
}

group = "com.g00fy2.quickie"
version = "0.1.0"

tasks.register<Jar>("androidJavadocJar") {
archiveClassifier.set("javadoc")
from("$buildDir/dokka/javadoc")
dependsOn("dokkaJavadoc")
}

tasks.register<Jar>("androidSourcesJar") {
archiveClassifier.set("sources")
from(android.sourceSets.getByName("main").java.srcDirs)
}

// JCenter does not support Gradle module metadata
tasks.withType<GenerateModuleMetadata> {
enabled = false
}

afterEvaluate {
publishing {
// publishBundledReleasePublicationToBintrayQuickieBundledRepository -Pbintray_user=name -Pbintray_key=key
publications {
create<MavenPublication>("bundledRelease") {
from(components["bundledRelease"])
val libraryName = "quickie-bundled"
artifactId = libraryName
artifact(tasks.named("androidJavadocJar"))
artifact(tasks.named("androidSourcesJar"))
configurePom(libraryName)
}
// publishUnbundledReleasePublicationToBintrayQuickieUnbundledRepository -Pbintray_user=name -Pbintray_key=key
create<MavenPublication>("unbundledRelease") {
from(components["unbundledRelease"])
val libraryName = "quickie-unbundled"
artifactId = libraryName
artifact(tasks.named("androidJavadocJar"))
artifact(tasks.named("androidSourcesJar"))
configurePom(libraryName)
}
}
repositories {
maven {
name = "bintrayQuickieBundled"
url = uri("https://api.bintray.com/maven/g00fy2/maven/quickie-bundled/;publish=1;")
credentials {
username = findProperty("bintray_user") as String?
password = findProperty("bintray_key") as String?
}
}
maven {
name = "bintrayQuickieUnbundled"
url = uri("https://api.bintray.com/maven/g00fy2/maven/quickie-unbundled/;publish=1;")
credentials {
username = findProperty("bintray_user") as String?
password = findProperty("bintray_key") as String?
}
}
}
}
}

fun MavenPublication.configurePom(libraryName: String) {
pom {
name.set(libraryName)
description.set("Android QR code scanner library")
url.set("https://github.com/G00fY2/Quickie")
licenses {
license {
name.set("MIT License")
url.set("https://opensource.org/licenses/MIT")
}
}
developers {
developer {
id.set("g00fy2")
name.set("Thomas Wirth")
email.set("[email protected]")
}
}
scm {
connection.set("https://github.com/G00fY2/Quickie.git")
developerConnection.set("https://github.com/G00fY2/Quickie.git")
url.set("https://github.com/G00fY2/Quickie")
}
}
}
3 changes: 2 additions & 1 deletion quickie/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

<activity
android:name=".QRScannerActivity"
android:theme="@style/Theme.Quickie"/>
android:screenOrientation="behind"
android:theme="@style/QuickieScannerActivity"/>
</application>
</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import com.google.mlkit.vision.barcode.BarcodeScanning
import com.google.mlkit.vision.common.InputImage

@ExperimentalGetImage
class QRCodeAnalyzer(val onSuccess: ((Barcode) -> Unit), val onFailure: ((Exception) -> Unit)) :
internal class QRCodeAnalyzer(val onSuccess: ((Barcode) -> Unit), val onFailure: ((Exception) -> Unit)) :
ImageAnalysis.Analyzer {

private var pendingTask: Task<List<Barcode>>? = null
Expand Down
21 changes: 13 additions & 8 deletions quickie/src/main/kotlin/com/g00fy2/quickie/QROverlayView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import android.content.Context
import android.graphics.Bitmap
import android.graphics.Bitmap.Config.ARGB_8888
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.PorterDuff.Mode.CLEAR
import android.graphics.PorterDuffXfermode
Expand All @@ -19,21 +20,22 @@ import androidx.core.content.ContextCompat
import kotlin.math.min
import kotlin.math.roundToInt

class QROverlayView @JvmOverloads constructor(
internal class QROverlayView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr) {

private val strokeColor = ContextCompat.getColor(context, R.color.qr_stroke_color)
private val highlightedStrokeColor = ContextCompat.getColor(context, R.color.qr_highlighted_stroke_color)
private val backgroundColor = ContextCompat.getColor(context, R.color.qr_background_color)
private val strokeColor = ContextCompat.getColor(context, R.color.quickie_stroke_color)
private val highlightedStrokeColor = getAccentColor()
private val backgroundColor = ContextCompat.getColor(context, R.color.quickie_background_color)
// alpha paint used for drawing the bitmap. So the final background alpha will be multiplied
private val alphaPaint = Paint().apply { alpha = Color.alpha(backgroundColor) }
private val strokePaint = Paint(Paint.ANTI_ALIAS_FLAG)
private val transparentPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
color = ContextCompat.getColor(context, android.R.color.transparent)
color = ContextCompat.getColor(context, R.color.quickie_transparent)
xfermode = PorterDuffXfermode(CLEAR)
}
private val backgroundPaint = Paint().apply { color = backgroundColor }
private val radius = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, OUT_RADIUS, resources.displayMetrics)
private val innerRadius =
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, OUT_RADIUS - STROKE_WIDTH, resources.displayMetrics)
Expand All @@ -50,7 +52,7 @@ class QROverlayView @JvmOverloads constructor(

init {
setWillNotDraw(false)
LayoutInflater.from(context).inflate(R.layout.qr_textview, this)
LayoutInflater.from(context).inflate(R.layout.quickie_textview, this)
titleTextView = findViewById(R.id.title_textview)
}

Expand All @@ -69,7 +71,7 @@ class QROverlayView @JvmOverloads constructor(
maskCanvas!!.drawColor(backgroundColor)
maskCanvas!!.drawRoundRect(outerFrame, radius, radius, strokePaint)
maskCanvas!!.drawRoundRect(innerFrame, innerRadius, innerRadius, transparentPaint)
canvas.drawBitmap(maskBitmap!!, 0f, 0f, backgroundPaint)
canvas.drawBitmap(maskBitmap!!, 0f, 0f, alphaPaint)
super.onDraw(canvas)
}

Expand Down Expand Up @@ -99,6 +101,9 @@ class QROverlayView @JvmOverloads constructor(
titleTextView.visibility = if (topInsetsToOuterFrame < titleTextView.height) View.INVISIBLE else View.VISIBLE
}

private fun View.getAccentColor() =
TypedValue().let { if (context.theme.resolveAttribute(R.attr.colorAccent, it, true)) it.data else Color.WHITE }

private fun View.updateTopMargin(@Px top: Int) {
val params = layoutParams as MarginLayoutParams
params.topMargin = top
Expand Down
Loading

0 comments on commit da5fed2

Please sign in to comment.