2727
2828package com.aspose.barcode.cloud.demo_app
2929
30- import android.Manifest
3130import android.app.Activity
3231import android.content.Intent
33- import android.content.pm.PackageManager
3432import android.graphics.Bitmap
3533import android.graphics.BitmapFactory
34+ import android.net.Uri
3635import android.os.Bundle
3736import android.provider.MediaStore
3837import android.util.Size
@@ -42,47 +41,41 @@ import android.widget.ArrayAdapter
4241import android.widget.EditText
4342import android.widget.ImageView
4443import android.widget.Spinner
44+ import androidx.activity.result.PickVisualMediaRequest
45+ import androidx.activity.result.contract.ActivityResultContracts
4546import androidx.appcompat.app.AppCompatActivity
46- import androidx.core.content.ContextCompat
47+ import androidx.core.view.ViewCompat
48+ import androidx.core.view.WindowCompat
49+ import androidx.core.view.WindowInsetsCompat
4750import com.aspose.barcode.cloud.ApiClient
4851import com.aspose.barcode.cloud.ApiException
4952import com.aspose.barcode.cloud.api.GenerateApi
5053import com.aspose.barcode.cloud.api.ScanApi
5154import com.aspose.barcode.cloud.model.BarcodeImageFormat
52- import com.aspose.barcode.cloud.model.BarcodeResponseList
5355import com.aspose.barcode.cloud.model.EncodeBarcodeType
54- import com.aspose.barcode.cloud.model.EncodeDataType
5556import com.aspose.barcode.cloud.requests.GenerateRequestWrapper
5657import com.aspose.barcode.cloud.requests.ScanMultipartRequestWrapper
5758import com.google.android.material.snackbar.Snackbar
5859import java.io.File
5960import java.io.FileOutputStream
6061import kotlin.math.floor
6162
62-
6363class MainActivity : AppCompatActivity () {
6464 companion object {
65- const val PERMISSION_REQUEST_CALLBACK_CODE = 1
66- const val ACTION_GET_CONTENT_CALLBACK_CODE = 2
6765 const val ACTION_IMAGE_CAPTURE_CALLBACK_CODE = 3
6866
6967 private fun imageSize (width : Int , height : Int , maxSize : Int = 384): Size {
7068 val ratio = width.toFloat() / height
7169 if (ratio > 1 ) {
72- // width > height
73- // use width
7470 if (width < maxSize) {
75- // do not resize
7671 return Size (width, height)
7772 }
7873
7974 val newHeight = floor(maxSize / ratio).toInt()
8075 return Size (maxSize, newHeight)
8176 }
82- // width <= height
83- // use height
77+
8478 if (height < maxSize) {
85- // do not resize
8679 return Size (width, height)
8780 }
8881 val newWidth = floor(maxSize * ratio).toInt()
@@ -103,9 +96,19 @@ class MainActivity : AppCompatActivity() {
10396 private lateinit var generateApi: GenerateApi
10497 private val encodeTypes = EncodeBarcodeType .values().map { it.toString() }.sorted()
10598
99+ private val photoPickerLauncher =
100+ registerForActivityResult(ActivityResultContracts .PickVisualMedia ()) { uri ->
101+ if (uri == null ) {
102+ return @registerForActivityResult
103+ }
104+
105+ recognizeSelectedImage(uri)
106+ }
107+
106108 override fun onCreate (savedInstanceState : Bundle ? ) {
107109 super .onCreate(savedInstanceState)
108110 setContentView(R .layout.activity_main)
111+ configureEdgeToEdge()
109112
110113 val client = ApiClient (
111114 " Client Id from https://dashboard.aspose.cloud/applications" ,
@@ -124,6 +127,18 @@ class MainActivity : AppCompatActivity() {
124127 barcodeImgView = findViewById(R .id.imageView)
125128 }
126129
130+ private fun configureEdgeToEdge () {
131+ WindowCompat .setDecorFitsSystemWindows(window, false )
132+
133+ val rootLayout = findViewById<View >(R .id.rootLayout)
134+ ViewCompat .setOnApplyWindowInsetsListener(rootLayout) { view, windowInsets ->
135+ val insets = windowInsets.getInsets(WindowInsetsCompat .Type .systemBars())
136+ view.setPadding(insets.left, insets.top, insets.right, insets.bottom)
137+ windowInsets
138+ }
139+ ViewCompat .requestApplyInsets(rootLayout)
140+ }
141+
127142 private fun showErrorMessage (error : String ) {
128143 Snackbar .make(findViewById(android.R .id.content), error, Snackbar .LENGTH_LONG ).show()
129144 }
@@ -135,82 +150,39 @@ class MainActivity : AppCompatActivity() {
135150 barcodeTypeSpinner.setSelection(encodeTypes.indexOf(" QR" ))
136151 }
137152
138- private fun requestPermissionAndPickFile (context : Activity ) {
139- if (ContextCompat .checkSelfPermission(
140- context,
141- Manifest .permission.READ_EXTERNAL_STORAGE
142- ) == PackageManager .PERMISSION_GRANTED
143- ) {
144- pickFile()
145- } else {
146- requestPermissions(
147- arrayOf(Manifest .permission.READ_EXTERNAL_STORAGE ),
148- PERMISSION_REQUEST_CALLBACK_CODE
149- )
150- }
151- }
152-
153+ override fun onActivityResult (requestCode : Int , resultCode : Int , data : Intent ? ) {
154+ super .onActivityResult(requestCode, resultCode, data)
153155
154- override fun onRequestPermissionsResult (
155- requestCode : Int ,
156- permissions : Array <String >, grantResults : IntArray
157- ) {
158- super .onRequestPermissionsResult(requestCode, permissions, grantResults)
159- when (requestCode) {
160- PERMISSION_REQUEST_CALLBACK_CODE -> {
161- // If request is cancelled, the result arrays are empty.
162- if ((grantResults.isNotEmpty() &&
163- grantResults[0 ] == PackageManager .PERMISSION_GRANTED )
164- ) {
165- // Permission is granted. Continue the action or workflow
166- // in your app.
167- pickFile()
168- } else {
169- // Explain to the user that the feature is unavailable because
170- // the features requires a permission that the user has denied.
171- // At the same time, respect the user's decision. Don't link to
172- // system settings in an effort to convince the user to change
173- // their decision.
174- showErrorMessage(" Permission to read image denied" )
175- }
156+ if (requestCode == ACTION_IMAGE_CAPTURE_CALLBACK_CODE && resultCode == Activity .RESULT_OK ) {
157+ val bmpImage = data?.extras?.get(" data" ) as ? Bitmap
158+ if (bmpImage == null ) {
159+ showErrorMessage(" No photo captured" )
176160 return
177161 }
178-
179- // Add other 'when' lines to check for other
180- // permissions this app might request.
181- else -> {
182- // Ignore all other requests.
183- }
162+ recognizeBarcode(bmpImage)
184163 }
185164 }
186165
187-
188- override fun onActivityResult (requestCode : Int , resultCode : Int , data : Intent ? ) {
189- super .onActivityResult(requestCode, resultCode, data)
190-
191- when (requestCode) {
192- ACTION_GET_CONTENT_CALLBACK_CODE -> {
193- if (resultCode == Activity .RESULT_OK ) {
194- val bytes = contentResolver.openInputStream(data?.data!! )!! .readBytes()
195- val bmpImage = BitmapFactory .decodeByteArray(bytes, 0 , bytes.size)
196- recognizeBarcode(bmpImage)
197- }
166+ private fun recognizeSelectedImage (uri : Uri ) {
167+ try {
168+ val bytes = contentResolver.openInputStream(uri)?.use { it.readBytes() }
169+ if (bytes == null ) {
170+ showErrorMessage(" Unable to read selected image" )
171+ return
198172 }
199173
200- ACTION_IMAGE_CAPTURE_CALLBACK_CODE -> {
201- if (resultCode == RESULT_OK ) {
202- val bmpImage = data?.extras?.get(" data" ) as Bitmap
203- recognizeBarcode(bmpImage)
204- }
174+ val bmpImage = BitmapFactory .decodeByteArray(bytes, 0 , bytes.size)
175+ if (bmpImage == null ) {
176+ showErrorMessage(" Unable to decode selected image" )
177+ return
205178 }
206179
207- else -> {
208- showErrorMessage( " No file selected " )
209- }
180+ recognizeBarcode(bmpImage)
181+ } catch (e : Exception ) {
182+ showErrorMessage( " Unable to read selected image " )
210183 }
211184 }
212185
213-
214186 private fun recognizeBarcode (image : Bitmap ) {
215187 try {
216188 val smallerBmp = reduceBitmapSize(image)
@@ -224,7 +196,7 @@ class MainActivity : AppCompatActivity() {
224196 smallerBmp.compress(Bitmap .CompressFormat .PNG , 100 , output)
225197 }
226198
227- val apiRequest = ScanMultipartRequestWrapper (tmpFile);
199+ val apiRequest = ScanMultipartRequestWrapper (tmpFile)
228200
229201 Thread {
230202 try {
@@ -259,9 +231,8 @@ class MainActivity : AppCompatActivity() {
259231 }
260232 }
261233 }.start()
262-
263- } catch (e: java.lang.Exception ) {
264- showErrorMessage(e.message!! )
234+ } catch (e: Exception ) {
235+ showErrorMessage(e.message ? : " Unknown error" )
265236 }
266237 }
267238
@@ -276,25 +247,20 @@ class MainActivity : AppCompatActivity() {
276247 }
277248
278249 fun onBtnGenerateClick (@Suppress(" UNUSED_PARAMETER" ) view : View ) {
250+ val type = EncodeBarcodeType .fromValue(barcodeTypeSpinner.selectedItem.toString())
279251
280- val type: EncodeBarcodeType = EncodeBarcodeType .fromValue(barcodeTypeSpinner.selectedItem.toString())
281-
282- val genRequest = GenerateRequestWrapper (
283- type, barcodeTextEdit.text.toString());
284-
285- genRequest.imageFormat = BarcodeImageFormat .PNG ;
252+ val genRequest = GenerateRequestWrapper (type, barcodeTextEdit.text.toString())
253+ genRequest.imageFormat = BarcodeImageFormat .PNG
286254 genRequest.imageHeight = barcodeImgView.measuredHeight.toFloat()
287255 genRequest.imageWidth = barcodeImgView.measuredWidth.toFloat()
288256
289-
290257 Thread {
291258 try {
292- val generated: File ? = generateApi.generate(genRequest);
259+ val generated = generateApi.generate(genRequest)
293260 runOnUiThread {
294261 val bitmap = BitmapFactory .decodeFile(generated!! .absolutePath)
295262 barcodeImgView.setImageBitmap(bitmap)
296263 }
297-
298264 } catch (e: ApiException ) {
299265 runOnUiThread {
300266 var message = e.message + " : " + e.details
@@ -319,21 +285,8 @@ class MainActivity : AppCompatActivity() {
319285 }
320286
321287 fun onBtnSelectImageClick (@Suppress(" UNUSED_PARAMETER" ) view : View ) {
322- requestPermissionAndPickFile(this )
323- }
324-
325- private fun pickFile () {
326- val getContentIntent = Intent (Intent .ACTION_GET_CONTENT )
327- getContentIntent.type = " image/*"
328- getContentIntent.addCategory(Intent .CATEGORY_OPENABLE )
329- try {
330- startActivityForResult(
331- Intent .createChooser(getContentIntent, " Select an Image to Recognize" ),
332- ACTION_GET_CONTENT_CALLBACK_CODE
333- )
334- } catch (ex: java.lang.Exception ) {
335- showErrorMessage(" Unable to start file selector" )
336- }
337-
288+ photoPickerLauncher.launch(
289+ PickVisualMediaRequest (ActivityResultContracts .PickVisualMedia .ImageOnly )
290+ )
338291 }
339292}
0 commit comments