diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2b75303 --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +*.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 diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..34dc27c --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000..79ee123 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file diff --git a/.idea/gradle.xml b/.idea/gradle.xml new file mode 100644 index 0000000..8e6b636 --- /dev/null +++ b/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..703e5d4 --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/runConfigurations.xml b/.idea/runConfigurations.xml new file mode 100644 index 0000000..7f68460 --- /dev/null +++ b/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/app/.gitignore b/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..47071a5 --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,64 @@ +apply plugin: 'com.android.application' + +apply plugin: 'kotlin-android' + +apply plugin: 'kotlin-android-extensions' + +android { + compileSdkVersion 28 + defaultConfig { + applicationId "team.clevel.documentscannerandroid" + minSdkVersion 19 + targetSdkVersion 28 + versionCode 1 + versionName "1.0" + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + multiDexEnabled true + } + buildTypes { + debug { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + release { + minifyEnabled true + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + + dexOptions { + jumboMode = true + javaMaxHeapSize "12g" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + splits { + abi { + enable true + reset() + include 'x86', 'x86_64', 'armeabi', 'armeabi-v7a', 'mips', 'mips64', 'arm64-v8a' + universalApk false + } + } +} + +dependencies { + implementation fileTree(include: ['*.jar'], dir: 'libs') + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" + implementation 'androidx.appcompat:appcompat:1.1.0-alpha02' + implementation 'androidx.core:core-ktx:1.1.0-alpha04' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test:runner:1.1.2-alpha01' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.2-alpha01' + implementation 'ru.superjob:kotlin-permissions:1.0.3' + implementation project(':documentscanner') +} diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro new file mode 100644 index 0000000..f1b4245 --- /dev/null +++ b/app/proguard-rules.pro @@ -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 diff --git a/app/src/androidTest/java/team/clevel/documentscannerandroid/ExampleInstrumentedTest.kt b/app/src/androidTest/java/team/clevel/documentscannerandroid/ExampleInstrumentedTest.kt new file mode 100644 index 0000000..c1588cf --- /dev/null +++ b/app/src/androidTest/java/team/clevel/documentscannerandroid/ExampleInstrumentedTest.kt @@ -0,0 +1,22 @@ +package team.clevel.documentscannerandroid + +import androidx.test.InstrumentationRegistry +import androidx.test.runner.AndroidJUnit4 +import org.junit.Assert.assertEquals +import org.junit.Test +import org.junit.runner.RunWith + +/** + * 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.getTargetContext() + assertEquals("team.clevel.documentscannerandroid", appContext.packageName) + } +} diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..16f9c8d --- /dev/null +++ b/app/src/main/AndroidManifest.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/java/team/clevel/documentscannerandroid/MainActivity.kt b/app/src/main/java/team/clevel/documentscannerandroid/MainActivity.kt new file mode 100644 index 0000000..f4f19f5 --- /dev/null +++ b/app/src/main/java/team/clevel/documentscannerandroid/MainActivity.kt @@ -0,0 +1,165 @@ +package team.clevel.documentscannerandroid + +import android.Manifest +import android.annotation.SuppressLint +import android.app.Activity +import android.content.Intent +import android.content.pm.PackageManager +import android.graphics.Bitmap +import android.graphics.BitmapFactory +import android.net.Uri +import android.os.Bundle +import android.os.Environment +import android.os.StrictMode +import android.provider.MediaStore +import android.util.Log +import android.view.View +import android.widget.Button +import android.widget.ImageView +import android.widget.Toast +import androidx.appcompat.app.AlertDialog +import androidx.appcompat.app.AppCompatActivity +import androidx.core.content.ContextCompat +import com.kotlinpermissions.KotlinPermissions +import team.clevel.documentscanner.ImageCropActivity +import team.clevel.documentscanner.helpers.ScannerConstants +import java.io.File +import java.io.IOException +import java.text.SimpleDateFormat +import java.util.* + +class MainActivity : AppCompatActivity() { + lateinit var btnPick : Button + lateinit var imgBitmap : ImageView + lateinit var mCurrentPhotoPath: String + + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { + super.onActivityResult(requestCode, resultCode, data) + if (requestCode == 1111 && resultCode == RESULT_OK && data != null) { + var selectedImage = data.data + var btimap: Bitmap? = null + try { + Log.e("IamgePath",""+data.data.path) + val inputStream = contentResolver.openInputStream(selectedImage) + btimap = BitmapFactory.decodeStream(inputStream) + ScannerConstants.selectedImageBitmap=btimap + startActivityForResult(Intent(MainActivity@this, ImageCropActivity::class.java),1234) + } catch (e: Exception) { + e.printStackTrace() + } + } + else if (requestCode==1231 && resultCode== Activity.RESULT_OK ) + { + ScannerConstants.selectedImageBitmap=MediaStore.Images.Media.getBitmap(this.contentResolver, Uri.parse(mCurrentPhotoPath)) + startActivityForResult(Intent(MainActivity@this, ImageCropActivity::class.java),1234) + } + else if (requestCode==1234 && resultCode== Activity.RESULT_OK ) + { + if (ScannerConstants.selectedImageBitmap!=null) + { + imgBitmap.setImageBitmap(ScannerConstants.selectedImageBitmap) + imgBitmap.visibility=View.VISIBLE + btnPick.visibility=View.GONE + } + else + Toast.makeText(MainActivity@this,"Not OK",Toast.LENGTH_LONG).show() + } + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_main) + btnPick=findViewById(R.id.btnPick) + imgBitmap=findViewById(R.id.imgBitmap) + askPermission() + } + + fun askPermission() + { + if ( + ContextCompat.checkSelfPermission( this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE ) != PackageManager.PERMISSION_GRANTED|| + ContextCompat.checkSelfPermission( this, android.Manifest.permission.READ_EXTERNAL_STORAGE ) != PackageManager.PERMISSION_GRANTED || + ContextCompat.checkSelfPermission( this, android.Manifest.permission.CAMERA ) != PackageManager.PERMISSION_GRANTED) + { + KotlinPermissions.with(this) + .permissions( + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.CAMERA) + .onAccepted { permissions -> + setView() + } + .onDenied { permissions -> + askPermission() + } + .onForeverDenied { permissions -> + Toast.makeText(MainActivity@this,"You have to grant permissions! Grant them from app settings please.", Toast.LENGTH_LONG).show() + finish() + } + .ask() + } + else + { + setView() + } + } + + fun setView() + { + btnPick.setOnClickListener(View.OnClickListener { + val builder = AlertDialog.Builder(this@MainActivity) + builder.setTitle("Carbon") + builder.setMessage("Görseli nereden seçmek istesiniz ?") + builder.setPositiveButton("Galeri"){dialog, which -> + dialog.dismiss() + val intent = Intent(Intent.ACTION_PICK) + intent.type = "image/*" + startActivityForResult(intent, 1111) + } + builder.setNegativeButton("Kamera"){dialog,which -> + dialog.dismiss() + val cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE) + if (cameraIntent.resolveActivity(packageManager) != null) { + var photoFile: File? = null + try { + photoFile = createImageFile() + } catch (ex: IOException) { + Log.i("Main", "IOException") + } + if (photoFile != null) { + val builder = StrictMode.VmPolicy.Builder(); + StrictMode.setVmPolicy(builder.build()); + cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile)) + startActivityForResult(cameraIntent, 1231) + } + } + } + builder.setNeutralButton("Cancel"){dialog,_ -> + dialog.dismiss() + } + val dialog: AlertDialog = builder.create() + dialog.show() + }) + } + + @SuppressLint("SimpleDateFormat") + @Throws(IOException::class) + private fun createImageFile(): File { + // Create an image file name + val timeStamp = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date()) + val imageFileName = "JPEG_" + timeStamp + "_" + val storageDir = Environment.getExternalStoragePublicDirectory( + Environment.DIRECTORY_PICTURES + ) + val image = File.createTempFile( + imageFileName, // prefix + ".jpg", // suffix + storageDir // directory + ) + + // Save a file: path for use with ACTION_VIEW intents + mCurrentPhotoPath = "file:" + image.absolutePath + return image + } + +} diff --git a/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..6348baa --- /dev/null +++ b/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + diff --git a/app/src/main/res/drawable/ic_launcher_background.xml b/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..a0ad202 --- /dev/null +++ b/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..2553574 --- /dev/null +++ b/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,23 @@ + + + +