Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
KaushalVasava committed Mar 5, 2024
0 parents commit 2a12f27
Show file tree
Hide file tree
Showing 41 changed files with 1,114 additions and 0 deletions.
15 changes: 15 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
local.properties
1 change: 1 addition & 0 deletions app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
71 changes: 71 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
plugins {
alias(libs.plugins.androidApplication)
alias(libs.plugins.jetbrainsKotlinAndroid)
}

android {
namespace = "com.kaushalvasava.apps.documentscanner"
compileSdk = 34

defaultConfig {
applicationId = "com.kaushalvasava.apps.documentscanner"
minSdk = 24
targetSdk = 34
versionCode = 1
versionName = "1.0"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary = true
}
}

buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
buildFeatures {
compose = true
}
composeOptions {
kotlinCompilerExtensionVersion = "1.5.1"
}
packaging {
resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}"
}
}
}

dependencies {

implementation(libs.androidx.core.ktx)
implementation(libs.androidx.lifecycle.runtime.ktx)
implementation(libs.androidx.activity.compose)
implementation(platform(libs.androidx.compose.bom))
implementation(libs.androidx.ui)
implementation(libs.androidx.ui.graphics)
implementation(libs.androidx.ui.tooling.preview)
implementation(libs.androidx.material3)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
androidTestImplementation(platform(libs.androidx.compose.bom))
androidTestImplementation(libs.androidx.ui.test.junit4)
debugImplementation(libs.androidx.ui.tooling)
debugImplementation(libs.androidx.ui.test.manifest)

implementation(libs.play.services.mlkit.document.scanner)
}
21 changes: 21 additions & 0 deletions app/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.kaushalvasava.apps.documentscanner

import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4

import org.junit.Test
import org.junit.runner.RunWith

import org.junit.Assert.*

/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.kaushalvasava.app.documentscanner", appContext.packageName)
}
}
37 changes: 37 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.DocumentScanner"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true"
android:theme="@style/Theme.DocumentScanner">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths"/>
</provider>
</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.kaushalvasava.apps.documentscanner

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.ui.Modifier
import com.kaushalvasava.apps.documentscanner.ui.screen.HomeScreen
import com.kaushalvasava.apps.documentscanner.ui.theme.DocumentScannerTheme

class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
DocumentScannerTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
) {
HomeScreen()
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
package com.kaushalvasava.apps.documentscanner.ui.screen

import android.app.Activity
import android.content.Intent
import android.util.Log
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.IntentSenderRequest
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.Card
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExtendedFloatingActionButton
import androidx.compose.material3.Icon
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.remember
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.unit.dp
import androidx.core.content.FileProvider
import androidx.core.net.toFile
import com.google.mlkit.vision.documentscanner.GmsDocumentScannerOptions
import com.google.mlkit.vision.documentscanner.GmsDocumentScanning
import com.google.mlkit.vision.documentscanner.GmsDocumentScanningResult
import com.kaushalvasava.apps.documentscanner.MainActivity
import com.kaushalvasava.apps.documentscanner.R

typealias Pdf = GmsDocumentScanningResult.Pdf


@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun HomeScreen() {

val activity = LocalContext.current as MainActivity
val options = remember { getOptions() }
val docs = remember {
mutableStateListOf<Pdf>()
}
val scannerLauncher = rememberLauncherForActivityResult(
contract =
ActivityResultContracts.StartIntentSenderForResult()
) { result ->
if (result.resultCode == Activity.RESULT_OK) {
val scanningResult =
GmsDocumentScanningResult.fromActivityResultIntent(result.data)
scanningResult?.pdf?.let { pdf ->
docs.add(pdf)
}
}
}
val scanner = remember {
GmsDocumentScanning.getClient(options)
}
Scaffold(
topBar = {
TopAppBar(
title = { Text(stringResource(R.string.app_name)) },
colors = TopAppBarDefaults.mediumTopAppBarColors()
)
},
floatingActionButton = {
ExtendedFloatingActionButton(
onClick = {
scanner.getStartScanIntent(activity)
.addOnSuccessListener { intentSender ->
scannerLauncher.launch(
IntentSenderRequest.Builder(intentSender).build()
)
}
.addOnFailureListener {
Log.d("TAG", "HomeScreen: ${it.message}")
}
},
text = {
Text(text = stringResource(R.string.scan))
},
icon = {
Icon(
painterResource(id = R.drawable.ic_camera),
contentDescription = null,
)
}
)
},
content = {
Surface(modifier = Modifier.padding(it)) {
LazyColumn(
modifier = Modifier.fillMaxSize(),
contentPadding = PaddingValues(10.dp)
) {
items(items = docs) {
Card(modifier = Modifier
.fillMaxWidth()
.height(80.dp)
.padding(10.dp),
onClick = {
val pdfUri = it.uri
val pdfFileUri = FileProvider.getUriForFile(
activity,
activity.packageName + ".provider",
pdfUri.toFile()
)
val browserIntent = Intent(Intent.ACTION_VIEW, pdfFileUri)
browserIntent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
activity.startActivity(browserIntent)
}) {
Row(
modifier = Modifier
.fillMaxSize()
.padding(10.dp),
horizontalArrangement = Arrangement.spacedBy(10.dp),
verticalAlignment = Alignment.CenterVertically
) {
Image(
modifier = Modifier.fillMaxHeight(),
painter = painterResource(id = R.drawable.ic_pdf),
contentDescription = null,
)
Text(text = it.uri.lastPathSegment ?: "")
}
}
}
}
}
}
)
}


fun getOptions(): GmsDocumentScannerOptions {
return GmsDocumentScannerOptions.Builder()
.setGalleryImportAllowed(true)
.setResultFormats(GmsDocumentScannerOptions.RESULT_FORMAT_PDF)
.setScannerMode(GmsDocumentScannerOptions.SCANNER_MODE_FULL)
.build()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.kaushalvasava.apps.documentscanner.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

0 comments on commit 2a12f27

Please sign in to comment.