Skip to content

Commit

Permalink
Merge branch 'release/0.5.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
G00fY2 committed Jan 13, 2021
2 parents b623b68 + 86cfd5a commit 8b7927e
Show file tree
Hide file tree
Showing 14 changed files with 97 additions and 54 deletions.
5 changes: 0 additions & 5 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,5 @@ 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.
# 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
29 changes: 15 additions & 14 deletions .github/workflows/android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,27 @@ on:
jobs:
ktlint:
name: Run ktlint
runs-on: ubuntu-latest
runs-on: ubuntu-20.04

steps:
- uses: actions/checkout@v2
- name: Setup java
uses: actions/setup-java@v1
with:
java-version: 11
- name: Run ktlintCheck
run: ./gradlew ktlintCheck

build:
name: Build debug app
runs-on: ubuntu-latest
build_bundled:
name: Build bundled debug apps
runs-on: ubuntu-20.04

steps:
- uses: actions/checkout@v2
- name: Setup java
uses: actions/setup-java@v1
with:
java-version: 11
- name: Build debug sample app
run: ./gradlew :activity-sample:assembleBundledDebug :advanced-sample:assembleBundledDebug :fragment-sample:assembleBundledDebug
- name: Build debug bundled sample app
run: ./gradlew :activity-sample:assembleBundledDebug :advanced-sample:assembleBundledDebug :fragment-sample:assembleBundledDebug

build_unbundled:
name: Build unbundled debug apps
runs-on: ubuntu-20.04

steps:
- uses: actions/checkout@v2
- name: Build debug unbundled sample app
run: ./gradlew :activity-sample:assembleUnbundledDebug :advanced-sample:assembleUnbundledDebug :fragment-sample:assembleUnbundledDebug
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ There are two different flavors available on `jcenter()`:
| V2 barcode model is used (possibly faster, more accurate) | currently V1 will be downloaded
```kotlin
// bundled:
implementation("com.g00fy2.quickie:quickie-bundled:0.4.0")
implementation("com.g00fy2.quickie:quickie-bundled:0.5.0")

// unbundled:
implementation("com.g00fy2.quickie:quickie-unbundled:0.4.0")
implementation("com.g00fy2.quickie:quickie-unbundled:0.5.0")
```

## Quick Start
Expand Down Expand Up @@ -67,11 +67,11 @@ The library is designed to behave and look as generic as possible. Currently it'
![Image](https://raw.githubusercontent.com/G00fY2/Quickie/gh-pages/media/quickie-device-demo.png)

## Release state
**quickie** relies on Google Jetpack libraries which are in pre-release state. CameraX has no stable release version yet and the Activity Result API is part of the latest AndroidX Activity and Fragment beta releases. Here is what Google says about this release state:
* Beta releases are functionally stable and have a feature-complete API surface.
* They are ready for production use but may contain bugs.
**quickie** relies on Google Jetpack libraries which are in pre-release state. CameraX has no stable release version yet and the Activity Result API is part of the latest AndroidX Activity and Fragment release candidates. Here is what Google says about this release state:
* A release candidate is a prospective stable release.
* It may contain critical last-minute fixes.

You should consider **quickie** to be in beta state too. I will raise the version to 1.0 once all dependent libraries hit stable.
You should consider **quickie** to be in pre-release state too. I will raise the version to 1.0 once all dependent libraries hit stable.

## Requirements
* AndroidX
Expand Down
6 changes: 3 additions & 3 deletions buildSrc/src/main/kotlin/Deps.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ object Deps {
const val appcompat = "androidx.appcompat:appcompat:${Versions.appcompat}"
const val core = "androidx.core:core:${Versions.core}"

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 camera = "androidx.camera:camera-camera2:${Versions.cameraX}"
const val cameraLifecycle = "androidx.camera:camera-lifecycle:${Versions.cameraX}"
const val cameraPreview = "androidx.camera:camera-view:${Versions.cameraView}"

const val navigation = "androidx.navigation:navigation-fragment-ktx:${Versions.navigation}"
}
Expand Down
5 changes: 2 additions & 3 deletions buildSrc/src/main/kotlin/Versions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@ object Versions {

const val navigation = "2.3.2"

const val camera = "1.0.0-rc01"
const val cameraLifecycle = "1.0.0-rc01"
const val cameraPreview = "1.0.0-alpha20"
const val cameraX = "1.0.0-rc01"
const val cameraView = "1.0.0-alpha20"

const val materialDesign = "1.2.1"

Expand Down
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
8 changes: 6 additions & 2 deletions quickie/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ android {
create("bundled").dimension("mlkit")
create("unbundled").dimension("mlkit")
}
sourceSets.getByName("main").java.srcDirs("src/main/kotlin")
sourceSets {
getByName("main").java.srcDirs("src/main/kotlin")
getByName("bundled").java.srcDirs("src/bundled/kotlin")
getByName("unbundled").java.srcDirs("src/unbundled/kotlin")
}
}

repositories {
Expand Down Expand Up @@ -50,7 +54,7 @@ dependencies {
}

group = "com.g00fy2.quickie"
version = "0.4.0"
version = "0.5.0"

tasks.register<Jar>("androidJavadocJar") {
archiveClassifier.set("javadoc")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.g00fy2.quickie.utils

import android.app.Activity

object PlayServicesValidator {

@Suppress("UNUSED_PARAMETER")
fun handleGooglePlayServicesError(activity: Activity, exception: Exception) = false // always false when bundled
}
7 changes: 1 addition & 6 deletions quickie/src/main/kotlin/com/g00fy2/quickie/QROverlayView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ internal class QROverlayView @JvmOverloads constructor(
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 {
Expand Down Expand Up @@ -103,11 +102,7 @@ internal class QROverlayView @JvmOverloads constructor(

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

Expand Down
29 changes: 19 additions & 10 deletions quickie/src/main/kotlin/com/g00fy2/quickie/QRScannerActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import androidx.core.content.ContextCompat
import androidx.core.view.ViewCompat
import com.g00fy2.quickie.databinding.QuickieScannerActivityBinding
import com.g00fy2.quickie.extensions.toParcelableContentType
import com.g00fy2.quickie.utils.PlayServicesValidator
import com.google.mlkit.vision.barcode.Barcode
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
Expand All @@ -32,10 +33,8 @@ internal class QRScannerActivity : ComponentActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val themedInflater = if (applicationInfo.theme != 0) {
layoutInflater.cloneInContext(ContextThemeWrapper(this, applicationInfo.theme))
} else {
layoutInflater
val themedInflater = applicationInfo.theme.let {
if (it != 0) layoutInflater.cloneInContext(ContextThemeWrapper(this, it)) else layoutInflater
}
binding = QuickieScannerActivityBinding.inflate(themedInflater)
setContentView(binding.root)
Expand Down Expand Up @@ -73,21 +72,32 @@ internal class QRScannerActivity : ComponentActivity() {
val imageAnalysis = ImageAnalysis.Builder()
.setTargetResolution(Size(1280, 720))
.build()
.apply { setAnalyzer(cameraExecutor, QRCodeAnalyzer({ onSuccess(it) }, { onFailure(it) })) }
.apply {
setAnalyzer(
cameraExecutor,
QRCodeAnalyzer(
{ onSuccess(it) },
{
clearAnalyzer()
onFailure(it)
}
)
)
}
val preview = Preview.Builder().build()

cameraProvider.unbindAll()
try {
cameraProvider.bindToLifecycle(this, cameraSelector, imageAnalysis, preview)
preview.setSurfaceProvider(binding.previewView.surfaceProvider)
binding.decorationView.visibility = View.VISIBLE
binding.overlayView.visibility = View.VISIBLE
} catch (e: Exception) {
onFailure(e)
}
}

private fun onSuccess(result: Barcode) {
binding.decorationView.isHighlighted = true
binding.overlayView.isHighlighted = true
setResult(
Activity.RESULT_OK,
Intent().apply {
Expand All @@ -101,11 +111,10 @@ internal class QRScannerActivity : ComponentActivity() {

private fun onFailure(exception: Exception) {
setResult(RESULT_ERROR, Intent().putExtra(EXTRA_RESULT_EXCEPTION, exception))
finish()
if (!PlayServicesValidator.handleGooglePlayServicesError(this, exception)) finish()
}

private fun setupEdgeToEdgeUI() {
// TODO migrate to androidx.core:core:1.5.0 once stable
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
window.setDecorFitsSystemWindows(false)
} else {
Expand All @@ -121,7 +130,7 @@ internal class QRScannerActivity : ComponentActivity() {
}
}
}
ViewCompat.setOnApplyWindowInsetsListener(binding.decorationView) { v, insets ->
ViewCompat.setOnApplyWindowInsetsListener(binding.overlayView) { v, insets ->
insets.systemWindowInsets.let {
v.setPadding(it.left, it.top, it.right, it.bottom)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,4 +111,4 @@ sealed class QRContent(val rawValue: String) {
val utc: Boolean
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ private fun EmailParcelable.toEmail(rawValue: String) =
address = address,
body = body,
subject = subject,
EmailType.values().getOrElse(type) { EmailType.UNKNOWN }
type = EmailType.values().getOrElse(type) { EmailType.UNKNOWN }
)

private fun AddressParcelable.toAddress() =
Expand All @@ -148,4 +148,4 @@ private fun CalendarDateTimeParcelable.toCalendarEvent() =
seconds = seconds,
year = year,
utc = utc
)
)
2 changes: 1 addition & 1 deletion quickie/src/main/res/layout/quickie_scanner_activity.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
/>

<com.g00fy2.quickie.QROverlayView
android:id="@+id/decoration_view"
android:id="@+id/overlay_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="invisible"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.g00fy2.quickie.utils

import android.app.Activity
import com.google.android.gms.common.ConnectionResult
import com.google.android.gms.common.GoogleApiAvailability
import com.google.mlkit.common.MlKitException

internal object PlayServicesValidator {

// version 20.12.14 (as suggested https://github.com/firebase/firebase-android-sdk/issues/407#issuecomment-632288258)
private const val MIN_SERVICES_VERSION = 201214 * 1000
private const val REQUEST_CODE = 9000

internal fun handleGooglePlayServicesError(activity: Activity, exception: Exception): Boolean {
if (exception is MlKitException && exception.errorCode == MlKitException.UNAVAILABLE) {
// check if Google Play services is available and its version is at least MIN_SERVICES_VERSION
val resultCode = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(activity, MIN_SERVICES_VERSION)

if (resultCode != ConnectionResult.SUCCESS &&
GoogleApiAvailability.getInstance().isUserResolvableError(resultCode)
) {
GoogleApiAvailability.getInstance().getErrorDialog(activity, resultCode, REQUEST_CODE)?.let {
it.setOnDismissListener { activity.finish() }
it.show()
return true
}
}
}
return false
}
}

0 comments on commit 8b7927e

Please sign in to comment.