Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .idea/deploymentTargetDropDown.xml

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

2 changes: 1 addition & 1 deletion .idea/kotlinc.xml

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

25 changes: 17 additions & 8 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -30,23 +30,32 @@ android {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
kotlinOptions {
jvmTarget = "17"
}
buildFeatures {
compose = true
viewBinding = true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.4.7"
}
kotlinOptions {
jvmTarget = "17"
}
}

dependencies {

implementation("androidx.core:core-ktx:1.10.1")
implementation("androidx.appcompat:appcompat:1.6.1")
implementation("com.google.android.material:material:1.9.0")
implementation("androidx.constraintlayout:constraintlayout:2.1.4")
implementation("androidx.navigation:navigation-fragment-ktx:2.7.1")
implementation("androidx.navigation:navigation-ui-ktx:2.7.1")
implementation("androidx.activity:activity-compose:1.7.2")
implementation("androidx.compose.ui:ui")
implementation("androidx.compose.ui:ui-graphics")
implementation("androidx.compose.ui:ui-tooling-preview")
implementation("androidx.compose.material3:material3:1.1.1")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.5")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
androidTestImplementation("androidx.compose.ui:ui-test-junit4")
debugImplementation("androidx.compose.ui:ui-tooling")
debugImplementation("androidx.compose.ui:ui-test-manifest")
implementation("com.google.zxing:core:3.4.1")
implementation("com.journeyapps:zxing-android-embedded:4.3.0")
}
13 changes: 10 additions & 3 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

<uses-permission android:name="android.permission.CAMERA" />

<uses-feature android:name="com.android.hardware.Camera.focus" />
<uses-feature
android:name="android.hardware.camera"
android:required="false" />

<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
Expand All @@ -10,13 +17,13 @@
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.XML_AND_JETPACKCOMPOSE_INTEROPERABILITY"

android:theme="@style/Theme.Xml_And_Jetpack_Interoperability"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true"
android:label="@string/app_name"
android:theme="@style/Theme.XML_AND_JETPACKCOMPOSE_INTEROPERABILITY">
android:theme="@style/Theme.Xml_And_Jetpack_Interoperability">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,32 +1,75 @@
package com.kaushalvasava.apps.xml_and_jetpackcompose_interoperability

import android.Manifest
import android.content.pm.PackageManager
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.navigation.NavController
import androidx.navigation.fragment.NavHostFragment
import androidx.navigation.ui.setupActionBarWithNavController
import com.kaushalvasava.apps.xml_and_jetpackcompose_interoperability.databinding.ActivityMainBinding
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.compose.ManagedActivityResultLauncher
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.compose.setContent
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.SideEffect
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.tooling.preview.Preview
import androidx.core.content.ContextCompat
import com.kaushalvasava.apps.xml_and_jetpackcompose_interoperability.ui.screen.ScanScreen
import com.kaushalvasava.apps.xml_and_jetpackcompose_interoperability.ui.theme.ComposeAppTheme

class MainActivity : AppCompatActivity() {
class MainActivity : ComponentActivity() {

private lateinit var binding: ActivityMainBinding
private lateinit var navController: NavController
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
RequestPermission()
ComposeAppTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
ScanScreen()
}
}
}
}
}

binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
@Composable
fun RequestPermission() {
val launcher: ManagedActivityResultLauncher<String, Boolean> =
rememberLauncherForActivityResult(
ActivityResultContracts.RequestPermission()
) { isGranted: Boolean ->
if (isGranted) {
// Permission Accepted: Do something
Log.d("TAG", "PERMISSION GRANTED")
// startService(intent)
// bindService(intent, connection, Context.BIND_AUTO_CREATE)
}
}

setSupportActionBar(binding.toolbar)
when (PackageManager.PERMISSION_GRANTED) {
ContextCompat.checkSelfPermission(
LocalContext.current,
android.Manifest.permission.CAMERA
) -> {
// Some works that require permission
Log.d("TAG", "Code requires permission")
}

val navHostFragment =
supportFragmentManager.findFragmentById(R.id.nav_host_fragment_content_main) as NavHostFragment
navController = navHostFragment.navController
setupActionBarWithNavController(navController)
else -> {
// Asking for permission
SideEffect {
launcher.launch(Manifest.permission.CAMERA)
}
}
}

override fun onSupportNavigateUp(): Boolean {
return navController.navigateUp()
|| super.onSupportNavigateUp()
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package com.kaushalvasava.apps.xml_and_jetpackcompose_interoperability.ui.screen

import android.app.Activity
import android.content.Context
import android.content.ContextWrapper
import android.view.View
import android.widget.Toast
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.width
import androidx.compose.material3.Button
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.viewinterop.AndroidView
import com.google.zxing.ResultPoint
import com.google.zxing.client.android.BeepManager
import com.journeyapps.barcodescanner.BarcodeCallback
import com.journeyapps.barcodescanner.BarcodeResult
import com.journeyapps.barcodescanner.camera.CameraSettings
import com.kaushalvasava.apps.xml_and_jetpackcompose_interoperability.R
import com.kaushalvasava.apps.xml_and_jetpackcompose_interoperability.databinding.BarcodeLayoutBinding
import com.kaushalvasava.apps.xml_and_jetpackcompose_interoperability.ui.theme.ComposeAppTheme

@Composable
fun ScanScreen() {
Column(
Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally
) {
val context = LocalContext.current
AndroidView(factory = {
View.inflate(it, R.layout.barcode_layout, null)
},
update = {
val beepManager = BeepManager(context.findActivity())
beepManager.isBeepEnabled = true
beepManager.isVibrateEnabled = true
val binding = BarcodeLayoutBinding.bind(it)
binding.barcodeView.resume()
val s = CameraSettings()
s.requestedCameraId = 0 // front/back/etc
binding.barcodeView.cameraSettings = s
binding.barcodeView.decodeSingle(object : BarcodeCallback {
override fun barcodeResult(result: BarcodeResult?) {
beepManager.playBeepSound()
Toast.makeText(context, "${result?.text}", Toast.LENGTH_SHORT).show()
try {
binding.barcodeView.pause()
} catch (e: Exception) {
Toast.makeText(context, "Invalid code", Toast.LENGTH_SHORT).show()
}
}

override fun possibleResultPoints(resultPoints: MutableList<ResultPoint>?) {
super.possibleResultPoints(resultPoints)
}
})
}
)
Spacer(modifier = Modifier.height(8.dp))
Text("OR")
Spacer(modifier = Modifier.height(8.dp))
Button(onClick = {
// no-op
}) {
Icon(
painter = painterResource(id = R.drawable.ic_image),
contentDescription = null,
)
Spacer(modifier = Modifier.width(8.dp))
Text(stringResource(R.string.select_code_from_device))
}
}
}

fun Context.findActivity(): Activity {
var context = this
while (context is ContextWrapper) {
if (context is Activity) return context
context = context.baseContext
}
throw IllegalStateException("no activity")
}

@Composable
@Preview
fun Preview() {
ComposeAppTheme {
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
ScanScreen()
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.kaushalvasava.apps.xml_and_jetpackcompose_interoperability.ui.theme

import androidx.compose.ui.graphics.Color

val Purple80 = Color(0xFFD0BCFF)
val PurpleGrey80 = Color(0xFFCCC2DC)
val Pink80 = Color(0xFFEFB8C8)

val Purple40 = Color(0xFF6650a4)
val PurpleGrey40 = Color(0xFF625b71)
val Pink40 = Color(0xFF7D5260)
Loading