Skip to content

Commit

Permalink
Merge branch 'release/0.3.1'
Browse files Browse the repository at this point in the history
  • Loading branch information
G00fY2 committed Dec 14, 2020
2 parents 5eaad4b + 49cf2f3 commit 45b999c
Show file tree
Hide file tree
Showing 10 changed files with 72 additions and 64 deletions.
18 changes: 10 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,27 +18,29 @@ 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.3.0")
implementation("com.g00fy2.quickie:quickie-bundled:0.3.1")

// unbundled:
implementation("com.g00fy2.quickie:quickie-unbundled:0.3.0")
implementation("com.g00fy2.quickie:quickie-unbundled:0.3.1")
```

## Quick Start
To use the QR scanner simply register the `ScanQRCode()` ActivityResultContract together with a callback during `initialization` or in the `onCreate()` lifecycle of your Activity/Fragment and call `launch(null)` anywhere to start it:
```kotlin
private val scanQrCode = registerForActivityResult(ScanQRCode()) { handleResult(it) }
val scanQrCode = registerForActivityResult(ScanQRCode(), ::handleResult)

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
...

binding.buttonQrScanner.setOnClickListener { scanQrCode.launch(null) }
binding.button.setOnClickListener { scanQrCode.launch(null) }
}

fun handleResult(result: QRResult) {
```
⚠️ **You can't register the ActivityResultContract inside of the OnClickListener. This will fail since the code get's executed after the onCreate lifecycle!**
⚠️ **You can't register the ActivityResultContract inside the OnClickListener lambda. This will fail since the code get's executed after the onCreate lifecycle!**

Check out the [samples](https://github.com/G00fY2/quickie/tree/master/sample) inside this repo or visit the [Activity Result API documentation](https://developer.android.com/training/basics/intents/result) for more information.
Check out the [samples](https://github.com/G00fY2/quickie/tree/develop/sample) inside this repo or visit the [Activity Result API documentation](https://developer.android.com/training/basics/intents/result) for more information.

#### Responses
The callback you add to the `registerForActivityResult` will receive an instance of the sealed `QRResult` class:
Expand Down
2 changes: 1 addition & 1 deletion quickie/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ dependencies {
}

group = "com.g00fy2.quickie"
version = "0.3.0"
version = "0.3.1"

tasks.register<Jar>("androidJavadocJar") {
archiveClassifier.set("javadoc")
Expand Down
15 changes: 11 additions & 4 deletions quickie/src/main/kotlin/com/g00fy2/quickie/QROverlayView.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import android.widget.FrameLayout
import androidx.annotation.Px
import androidx.appcompat.widget.AppCompatTextView
import androidx.core.content.ContextCompat
import com.g00fy2.quickie.databinding.QuickieTextviewBinding
import kotlin.math.min
import kotlin.math.roundToInt

Expand Down Expand Up @@ -52,8 +53,7 @@ internal class QROverlayView @JvmOverloads constructor(

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

override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) {
Expand Down Expand Up @@ -101,8 +101,15 @@ internal 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.getAccentColor(): Int {
return TypedValue().let {
if (context.theme.resolveAttribute(android.R.attr.colorAccent, it, true)) {
it.data
} else {
Color.WHITE
}
}
}

private fun View.updateTopMargin(@Px top: Int) {
val params = layoutParams as MarginLayoutParams
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,19 @@ import android.os.Parcelable
import kotlinx.parcelize.Parcelize

@Parcelize
internal object EmptyParcelable : Parcelable
internal class WifiParcelable(val encryptionType: Int, val password: String, val ssid: String) : Parcelable

@Parcelize
internal data class WifiParcelable(val encryptionType: Int, val password: String, val ssid: String) : Parcelable
internal class UrlBookmarkParcelable(val title: String, val url: String) : Parcelable

@Parcelize
internal data class UrlBookmarkParcelable(val title: String, val url: String) : Parcelable
internal class SmsParcelable(val message: String, val phoneNumber: String) : Parcelable

@Parcelize
internal data class SmsParcelable(val message: String, val phoneNumber: String) : Parcelable
internal class GeoPointParcelable(val lat: Double, val lng: Double) : Parcelable

@Parcelize
internal data class GeoPointParcelable(val lat: Double, val lng: Double) : Parcelable

@Parcelize
internal data class ContactInfoParcelable(
internal class ContactInfoParcelable(
val addressParcelables: List<AddressParcelable>,
val emailParcelables: List<EmailParcelable>,
val nameParcelable: PersonNameParcelable,
Expand All @@ -30,14 +27,14 @@ internal data class ContactInfoParcelable(
) : Parcelable

@Parcelize
internal data class EmailParcelable(val address: String, val body: String, val subject: String, val type: Int) :
internal class EmailParcelable(val address: String, val body: String, val subject: String, val type: Int) :
Parcelable

@Parcelize
internal data class PhoneParcelable(val number: String, val type: Int) : Parcelable
internal class PhoneParcelable(val number: String, val type: Int) : Parcelable

@Parcelize
internal data class PersonNameParcelable(
internal class PersonNameParcelable(
val first: String,
val formattedName: String,
val last: String,
Expand All @@ -48,7 +45,7 @@ internal data class PersonNameParcelable(
) : Parcelable

@Parcelize
internal data class CalendarEventParcelable(
internal class CalendarEventParcelable(
val description: String,
val end: CalendarDateTimeParcelable,
val location: String,
Expand All @@ -59,7 +56,7 @@ internal data class CalendarEventParcelable(
) : Parcelable

@Parcelize
internal data class CalendarDateTimeParcelable(
internal class CalendarDateTimeParcelable(
val day: Int,
val hours: Int,
val minutes: Int,
Expand All @@ -70,4 +67,4 @@ internal data class CalendarDateTimeParcelable(
) : Parcelable

@Parcelize
internal data class AddressParcelable(val addressLines: List<String>, val type: Int) : Parcelable
internal class AddressParcelable(val addressLines: List<String>, val type: Int) : Parcelable
35 changes: 21 additions & 14 deletions quickie/src/main/kotlin/com/g00fy2/quickie/content/QRContent.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,33 +8,40 @@ sealed class QRContent(val rawValue: String) {
/**
* Plain text or unknown content QR Code type.
*/
class Plain(rawValue: String) : QRContent(rawValue)
data class Plain(private val _rawValue: String) : QRContent(_rawValue)

/**
* Wi-Fi access point details from a 'WIFI:' or similar QR Code type.
*/
class Wifi(rawValue: String, val encryptionType: Int, val password: String, val ssid: String) : QRContent(rawValue)
data class Wifi(private val _rawValue: String, val encryptionType: Int, val password: String, val ssid: String) :
QRContent(_rawValue)

/**
* A URL or URL bookmark from a 'MEBKM:' or similar QR Code type.
*/
class Url(rawValue: String, val title: String, val url: String) : QRContent(rawValue)
data class Url(private val _rawValue: String, val title: String, val url: String) : QRContent(_rawValue)

/**
* An SMS message from an 'SMS:' or similar QR Code type.
*/
class Sms(rawValue: String, val message: String, val phoneNumber: String) : QRContent(rawValue)
data class Sms(private val _rawValue: String, val message: String, val phoneNumber: String) : QRContent(_rawValue)

/**
* GPS coordinates from a 'GEO:' or similar QR Code type.
*/
class GeoPoint(rawValue: String, val lat: Double, val lng: Double) : QRContent(rawValue)
data class GeoPoint(private val _rawValue: String, val lat: Double, val lng: Double) : QRContent(_rawValue)

/**
* An email message from a 'MAILTO:' or similar QR Code type.
*/
class Email(rawValue: String, val address: String, val body: String, val subject: String, val type: EmailType) :
QRContent(rawValue) {
data class Email(
private val _rawValue: String,
val address: String,
val body: String,
val subject: String,
val type: EmailType
) :
QRContent(_rawValue) {
enum class EmailType {
UNKNOWN, WORK, HOME
}
Expand All @@ -43,7 +50,7 @@ sealed class QRContent(val rawValue: String) {
/**
* A phone number from a 'TEL:' or similar QR Code type.
*/
class Phone(rawValue: String, val number: String, val type: PhoneType) : QRContent(rawValue) {
data class Phone(private val _rawValue: String, val number: String, val type: PhoneType) : QRContent(_rawValue) {
enum class PhoneType {
UNKNOWN, WORK, HOME, FAX, MOBILE
}
Expand All @@ -52,16 +59,16 @@ sealed class QRContent(val rawValue: String) {
/**
* A person's or organization's business card.
*/
class ContactInfo(
rawValue: String,
data class ContactInfo(
private val _rawValue: String,
val addresses: List<Address>,
val emails: List<Email>,
val name: PersonName,
val organization: String,
val phones: List<Phone>,
val title: String,
val urls: List<String>
) : QRContent(rawValue) {
) : QRContent(_rawValue) {

data class Address(val addressLines: List<String>, val type: AddressType) {
enum class AddressType {
Expand All @@ -83,16 +90,16 @@ sealed class QRContent(val rawValue: String) {
/**
* A calendar event extracted from a QR Code.
*/
class CalendarEvent(
rawValue: String,
data class CalendarEvent(
private val _rawValue: String,
val description: String,
val end: CalendarDateTime,
val location: String,
val organizer: String,
val start: CalendarDateTime,
val status: String,
val summary: String
) : QRContent(rawValue) {
) : QRContent(_rawValue) {

data class CalendarDateTime(
val day: Int,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import com.g00fy2.quickie.content.CalendarDateTimeParcelable
import com.g00fy2.quickie.content.CalendarEventParcelable
import com.g00fy2.quickie.content.ContactInfoParcelable
import com.g00fy2.quickie.content.EmailParcelable
import com.g00fy2.quickie.content.EmptyParcelable
import com.g00fy2.quickie.content.GeoPointParcelable
import com.g00fy2.quickie.content.PersonNameParcelable
import com.g00fy2.quickie.content.PhoneParcelable
Expand All @@ -15,7 +14,7 @@ import com.g00fy2.quickie.content.UrlBookmarkParcelable
import com.g00fy2.quickie.content.WifiParcelable
import com.google.mlkit.vision.barcode.Barcode

internal fun Barcode.toParcelableContentType(): Parcelable {
internal fun Barcode.toParcelableContentType(): Parcelable? {
return when (valueType) {
Barcode.TYPE_CONTACT_INFO -> {
ContactInfoParcelable(
Expand Down Expand Up @@ -58,7 +57,7 @@ internal fun Barcode.toParcelableContentType(): Parcelable {
summary = calendarEvent?.summary ?: ""
)
}
else -> EmptyParcelable // TYPE_TEXT, TYPE_ISBN, TYPE_PRODUCT, TYPE_DRIVER_LICENSE, TYPE_UNKNOWN
else -> null // TYPE_TEXT, TYPE_ISBN, TYPE_PRODUCT, TYPE_DRIVER_LICENSE, TYPE_UNKNOWN
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,12 @@ internal fun Intent?.toQuickieContentType(): QRContent {
if (this == null) return Plain("")

val rawValue = getStringExtra(QRScannerActivity.EXTRA_RESULT_VALUE) ?: ""
val resultContent = when (getIntExtra(QRScannerActivity.EXTRA_RESULT_TYPE, Barcode.TYPE_UNKNOWN)) {

return when (getIntExtra(QRScannerActivity.EXTRA_RESULT_TYPE, Barcode.TYPE_UNKNOWN)) {
Barcode.TYPE_CONTACT_INFO -> {
getParcelableExtra<ContactInfoParcelable>(QRScannerActivity.EXTRA_RESULT_PARCELABLE)?.run {
ContactInfo(
rawValue = rawValue,
_rawValue = rawValue,
addresses = addressParcelables.map { it.toAddress() },
emails = emailParcelables.map { it.toEmail(rawValue) },
name = nameParcelable.toPersonName(),
Expand All @@ -53,7 +54,7 @@ internal fun Intent?.toQuickieContentType(): QRContent {
Barcode.TYPE_EMAIL -> {
getParcelableExtra<EmailParcelable>(QRScannerActivity.EXTRA_RESULT_PARCELABLE)?.run {
Email(
rawValue = rawValue,
_rawValue = rawValue,
address = address,
body = body,
subject = subject,
Expand All @@ -63,33 +64,33 @@ internal fun Intent?.toQuickieContentType(): QRContent {
}
Barcode.TYPE_PHONE -> {
getParcelableExtra<PhoneParcelable>(QRScannerActivity.EXTRA_RESULT_PARCELABLE)?.run {
Phone(rawValue = rawValue, number = number, type = PhoneType.values().getOrElse(type) { PhoneType.UNKNOWN })
Phone(_rawValue = rawValue, number = number, type = PhoneType.values().getOrElse(type) { PhoneType.UNKNOWN })
}
}
Barcode.TYPE_SMS -> {
getParcelableExtra<SmsParcelable>(QRScannerActivity.EXTRA_RESULT_PARCELABLE)?.run {
Sms(rawValue = rawValue, message = message, phoneNumber = phoneNumber)
Sms(_rawValue = rawValue, message = message, phoneNumber = phoneNumber)
}
}
Barcode.TYPE_URL -> {
getParcelableExtra<UrlBookmarkParcelable>(QRScannerActivity.EXTRA_RESULT_PARCELABLE)?.run {
Url(rawValue = rawValue, title = title, url = url)
Url(_rawValue = rawValue, title = title, url = url)
}
}
Barcode.TYPE_WIFI -> {
getParcelableExtra<WifiParcelable>(QRScannerActivity.EXTRA_RESULT_PARCELABLE)?.run {
Wifi(rawValue = rawValue, encryptionType = encryptionType, password = password, ssid = ssid)
Wifi(_rawValue = rawValue, encryptionType = encryptionType, password = password, ssid = ssid)
}
}
Barcode.TYPE_GEO -> {
getParcelableExtra<GeoPointParcelable>(QRScannerActivity.EXTRA_RESULT_PARCELABLE)?.run {
GeoPoint(rawValue = rawValue, lat = lat, lng = lng)
GeoPoint(_rawValue = rawValue, lat = lat, lng = lng)
}
}
Barcode.TYPE_CALENDAR_EVENT -> {
getParcelableExtra<CalendarEventParcelable>(QRScannerActivity.EXTRA_RESULT_PARCELABLE)?.run {
CalendarEvent(
rawValue = rawValue,
_rawValue = rawValue,
description = description,
end = end.toCalendarEvent(),
location = location,
Expand All @@ -101,8 +102,7 @@ internal fun Intent?.toQuickieContentType(): QRContent {
}
}
else -> null
}
return resultContent ?: Plain(rawValue)
} ?: Plain(rawValue)
}

internal fun Intent?.getRootException(): Exception {
Expand All @@ -114,11 +114,11 @@ internal fun Intent?.getRootException(): Exception {
}

private fun PhoneParcelable.toPhone(rawValue: String) =
Phone(rawValue = rawValue, number = number, type = PhoneType.values().getOrElse(type) { PhoneType.UNKNOWN })
Phone(_rawValue = rawValue, number = number, type = PhoneType.values().getOrElse(type) { PhoneType.UNKNOWN })

private fun EmailParcelable.toEmail(rawValue: String) =
Email(
rawValue = rawValue,
_rawValue = rawValue,
address = address,
body = body,
subject = subject,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@ class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private var snackbar: Snackbar? = null

private val scanQrCode = registerForActivityResult(ScanQRCode()) {
showSnackbar(it)
}
private val scanQrCode = registerForActivityResult(ScanQRCode(), ::showSnackbar)

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ class MainActivity : AppCompatActivity() {
viewModel.scanQRCode()
}

viewModel.qrCodeState.observe(this) { showSnackbar(it) }
viewModel.qrCodeState.observe(this, ::showSnackbar)
}

private fun showSnackbar(result: QRResult) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,7 @@ class MainFragment : Fragment() {
private val binding get() = _binding!!
private var snackbar: Snackbar? = null

private val scanQrCode = registerForActivityResult(ScanQRCode()) {
showSnackbar(it)
}
private val scanQrCode = registerForActivityResult(ScanQRCode(), ::showSnackbar)

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
_binding = FragmentMainBinding.inflate(inflater, container, false)
Expand Down

0 comments on commit 45b999c

Please sign in to comment.