Skip to content

Commit aa04728

Browse files
authored
Release 26.3 (#138)
* Fix Java templates * Bump Java version to 26.3.2 * Bump SDK versions to 26.3 * Add Go Report Card badge to README template * Set PHP_CS_FIXER_IGNORE_ENV in PHP generator * Update Android templates for modern APIs Modernize templates: AGP 9.1.0, Java 17, SDK 36, Activity Result APIs, Photo Picker, edge-to-edge support. Remove deprecated onActivityResult/startActivityForResult, storage permissions, and Kotlin plugin (handled by AGP 9+). * Update Node.js package template for ESM exports Add ESM exports map, split build/prepare scripts, disable sourcemap and minify in tsup config, update dev dependency versions. * Split config.json into config-dotnet.json, config-node.json * Ignore example.com urls
1 parent 5df4ad7 commit aa04728

33 files changed

Lines changed: 226 additions & 227 deletions

codegen/Templates/android/apiException.mustache

Lines changed: 70 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,11 @@
22
{{>licenseInfo}}
33
package {{invokerPackage}}
44

5-
import android.Manifest
65
import android.app.Activity
76
import android.content.Intent
8-
import android.content.pm.PackageManager
97
import android.graphics.Bitmap
108
import android.graphics.BitmapFactory
9+
import android.net.Uri
1110
import android.os.Bundle
1211
import android.provider.MediaStore
1312
import android.util.Size
@@ -17,47 +16,41 @@ import android.widget.ArrayAdapter
1716
import android.widget.EditText
1817
import android.widget.ImageView
1918
import android.widget.Spinner
19+
import androidx.activity.result.PickVisualMediaRequest
20+
import androidx.activity.result.contract.ActivityResultContracts
2021
import androidx.appcompat.app.AppCompatActivity
21-
import androidx.core.content.ContextCompat
22+
import androidx.core.os.BundleCompat
23+
import androidx.core.view.ViewCompat
24+
import androidx.core.view.WindowCompat
25+
import androidx.core.view.WindowInsetsCompat
2226
import com.aspose.barcode.cloud.ApiClient
2327
import com.aspose.barcode.cloud.ApiException
2428
import com.aspose.barcode.cloud.api.GenerateApi
2529
import com.aspose.barcode.cloud.api.ScanApi
2630
import com.aspose.barcode.cloud.model.BarcodeImageFormat
27-
import com.aspose.barcode.cloud.model.BarcodeResponseList
2831
import com.aspose.barcode.cloud.model.EncodeBarcodeType
29-
import com.aspose.barcode.cloud.model.EncodeDataType
3032
import com.aspose.barcode.cloud.requests.GenerateRequestWrapper
3133
import com.aspose.barcode.cloud.requests.ScanMultipartRequestWrapper
3234
import com.google.android.material.snackbar.Snackbar
3335
import java.io.File
3436
import java.io.FileOutputStream
3537
import kotlin.math.floor
36-
38+
import androidx.core.graphics.scale
3739

3840
class MainActivity : AppCompatActivity() {
3941
companion object {
40-
const val PERMISSION_REQUEST_CALLBACK_CODE = 1
41-
const val ACTION_GET_CONTENT_CALLBACK_CODE = 2
42-
const val ACTION_IMAGE_CAPTURE_CALLBACK_CODE = 3
43-
4442
private fun imageSize(width: Int, height: Int, maxSize: Int = 384): Size {
4543
val ratio = width.toFloat() / height
4644
if (ratio > 1) {
47-
// width > height
48-
// use width
4945
if (width < maxSize) {
50-
// do not resize
5146
return Size(width, height)
5247
}
5348

5449
val newHeight = floor(maxSize / ratio).toInt()
5550
return Size(maxSize, newHeight)
5651
}
57-
// width <= height
58-
// use height
52+
5953
if (height < maxSize) {
60-
// do not resize
6154
return Size(width, height)
6255
}
6356
val newWidth = floor(maxSize * ratio).toInt()
@@ -66,7 +59,7 @@ class MainActivity : AppCompatActivity() {
6659

6760
private fun reduceBitmapSize(image: Bitmap): Bitmap {
6861
val newSize = imageSize(image.width, image.height)
69-
return Bitmap.createScaledBitmap(image, newSize.width, newSize.height, true)
62+
return image.scale(newSize.width, newSize.height)
7063
}
7164
}
7265

@@ -76,11 +69,35 @@ class MainActivity : AppCompatActivity() {
7669

7770
private lateinit var scanApi: ScanApi
7871
private lateinit var generateApi: GenerateApi
79-
private val encodeTypes = EncodeBarcodeType.values().map { it.toString() }.sorted()
72+
private val encodeTypes = EncodeBarcodeType.entries.map { it.toString() }.sorted()
73+
74+
private val cameraLauncher =
75+
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
76+
if (result.resultCode == Activity.RESULT_OK) {
77+
val bmpImage = result.data?.extras?.let {
78+
BundleCompat.getParcelable(it, "data", Bitmap::class.java)
79+
}
80+
if (bmpImage == null) {
81+
showErrorMessage("No photo captured")
82+
return@registerForActivityResult
83+
}
84+
recognizeBarcode(bmpImage)
85+
}
86+
}
87+
88+
private val photoPickerLauncher =
89+
registerForActivityResult(ActivityResultContracts.PickVisualMedia()) { uri ->
90+
if (uri == null) {
91+
return@registerForActivityResult
92+
}
93+
94+
recognizeSelectedImage(uri)
95+
}
8096

8197
override fun onCreate(savedInstanceState: Bundle?) {
8298
super.onCreate(savedInstanceState)
8399
setContentView(R.layout.activity_main)
100+
configureEdgeToEdge()
84101
85102
val client = ApiClient(
86103
"Client Id from https://dashboard.aspose.cloud/applications",
@@ -99,6 +116,18 @@ class MainActivity : AppCompatActivity() {
99116
barcodeImgView = findViewById(R.id.imageView)
100117
}
101118

119+
private fun configureEdgeToEdge() {
120+
WindowCompat.setDecorFitsSystemWindows(window, false)
121+
122+
val rootLayout = findViewById<View>(R.id.rootLayout)
123+
ViewCompat.setOnApplyWindowInsetsListener(rootLayout) { view, windowInsets ->
124+
val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
125+
view.setPadding(insets.left, insets.top, insets.right, insets.bottom)
126+
windowInsets
127+
}
128+
ViewCompat.requestApplyInsets(rootLayout)
129+
}
130+
102131
private fun showErrorMessage(error: String) {
103132
Snackbar.make(findViewById(android.R.id.content), error, Snackbar.LENGTH_LONG).show()
104133
}
@@ -110,82 +139,26 @@ class MainActivity : AppCompatActivity() {
110139
barcodeTypeSpinner.setSelection(encodeTypes.indexOf("QR"))
111140
}
112141

113-
private fun requestPermissionAndPickFile(context: Activity) {
114-
if (ContextCompat.checkSelfPermission(
115-
context,
116-
Manifest.permission.READ_EXTERNAL_STORAGE
117-
) == PackageManager.PERMISSION_GRANTED
118-
) {
119-
pickFile()
120-
} else {
121-
requestPermissions(
122-
arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE),
123-
PERMISSION_REQUEST_CALLBACK_CODE
124-
)
125-
}
126-
}
127-
128-
129-
override fun onRequestPermissionsResult(
130-
requestCode: Int,
131-
permissions: Array<String>, grantResults: IntArray
132-
) {
133-
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
134-
when (requestCode) {
135-
PERMISSION_REQUEST_CALLBACK_CODE -> {
136-
// If request is cancelled, the result arrays are empty.
137-
if ((grantResults.isNotEmpty() &&
138-
grantResults[0] == PackageManager.PERMISSION_GRANTED)
139-
) {
140-
// Permission is granted. Continue the action or workflow
141-
// in your app.
142-
pickFile()
143-
} else {
144-
// Explain to the user that the feature is unavailable because
145-
// the features requires a permission that the user has denied.
146-
// At the same time, respect the user's decision. Don't link to
147-
// system settings in an effort to convince the user to change
148-
// their decision.
149-
showErrorMessage("Permission to read image denied")
150-
}
142+
private fun recognizeSelectedImage(uri: Uri) {
143+
try {
144+
val bytes = contentResolver.openInputStream(uri)?.use { it.readBytes() }
145+
if (bytes == null) {
146+
showErrorMessage("Unable to read selected image")
151147
return
152148
}
153149

154-
// Add other 'when' lines to check for other
155-
// permissions this app might request.
156-
else -> {
157-
// Ignore all other requests.
158-
}
159-
}
160-
}
161-
162-
163-
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
164-
super.onActivityResult(requestCode, resultCode, data)
165-
166-
when (requestCode) {
167-
ACTION_GET_CONTENT_CALLBACK_CODE -> {
168-
if (resultCode == Activity.RESULT_OK) {
169-
val bytes = contentResolver.openInputStream(data?.data!!)!!.readBytes()
170-
val bmpImage = BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
171-
recognizeBarcode(bmpImage)
172-
}
173-
}
174-
175-
ACTION_IMAGE_CAPTURE_CALLBACK_CODE -> {
176-
if (resultCode == RESULT_OK) {
177-
val bmpImage = data?.extras?.get("data") as Bitmap
178-
recognizeBarcode(bmpImage)
179-
}
150+
val bmpImage = BitmapFactory.decodeByteArray(bytes, 0, bytes.size)
151+
if (bmpImage == null) {
152+
showErrorMessage("Unable to decode selected image")
153+
return
180154
}
181155

182-
else -> {
183-
showErrorMessage("No file selected")
184-
}
156+
recognizeBarcode(bmpImage)
157+
} catch (_: Exception) {
158+
showErrorMessage("Unable to read selected image")
185159
}
186160
}
187161

188-
189162
private fun recognizeBarcode(image: Bitmap) {
190163
try {
191164
val smallerBmp = reduceBitmapSize(image)
@@ -199,7 +172,7 @@ class MainActivity : AppCompatActivity() {
199172
smallerBmp.compress(Bitmap.CompressFormat.PNG, 100, output)
200173
}
201174

202-
val apiRequest = ScanMultipartRequestWrapper(tmpFile);
175+
val apiRequest = ScanMultipartRequestWrapper(tmpFile)
203176

204177
Thread {
205178
try {
@@ -234,9 +207,8 @@ class MainActivity : AppCompatActivity() {
234207
}
235208
}
236209
}.start()
237-
238-
} catch (e: java.lang.Exception) {
239-
showErrorMessage(e.message!!)
210+
} catch (e: Exception) {
211+
showErrorMessage(e.message ?: "Unknown error")
240212
}
241213
}
242214

@@ -251,25 +223,20 @@ class MainActivity : AppCompatActivity() {
251223
}
252224

253225
fun onBtnGenerateClick(@Suppress("UNUSED_PARAMETER") view: View) {
226+
val type = EncodeBarcodeType.fromValue(barcodeTypeSpinner.selectedItem.toString())
254227
255-
val type: EncodeBarcodeType = EncodeBarcodeType.fromValue(barcodeTypeSpinner.selectedItem.toString())
256-
257-
val genRequest = GenerateRequestWrapper(
258-
type, barcodeTextEdit.text.toString());
259-
260-
genRequest.imageFormat = BarcodeImageFormat.PNG;
228+
val genRequest = GenerateRequestWrapper(type, barcodeTextEdit.text.toString())
229+
genRequest.imageFormat = BarcodeImageFormat.PNG
261230
genRequest.imageHeight = barcodeImgView.measuredHeight.toFloat()
262231
genRequest.imageWidth = barcodeImgView.measuredWidth.toFloat()
263232
264-
265233
Thread {
266234
try {
267-
val generated: File? = generateApi.generate(genRequest);
235+
val generated = generateApi.generate(genRequest)
268236
runOnUiThread {
269237
val bitmap = BitmapFactory.decodeFile(generated!!.absolutePath)
270238
barcodeImgView.setImageBitmap(bitmap)
271239
}
272-
273240
} catch (e: ApiException) {
274241
runOnUiThread {
275242
var message = e.message + ": " + e.details
@@ -289,26 +256,13 @@ class MainActivity : AppCompatActivity() {
289256
fun onBtnTakePhotoClick(@Suppress("UNUSED_PARAMETER") view: View) {
290257
val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
291258
if (takePictureIntent.resolveActivity(packageManager) != null) {
292-
startActivityForResult(takePictureIntent, ACTION_IMAGE_CAPTURE_CALLBACK_CODE)
259+
cameraLauncher.launch(takePictureIntent)
293260
}
294261
}
295262

296263
fun onBtnSelectImageClick(@Suppress("UNUSED_PARAMETER") view: View) {
297-
requestPermissionAndPickFile(this)
298-
}
299-
300-
private fun pickFile() {
301-
val getContentIntent = Intent(Intent.ACTION_GET_CONTENT)
302-
getContentIntent.type = "image/*"
303-
getContentIntent.addCategory(Intent.CATEGORY_OPENABLE)
304-
try {
305-
startActivityForResult(
306-
Intent.createChooser(getContentIntent, "Select an Image to Recognize"),
307-
ACTION_GET_CONTENT_CALLBACK_CODE
308-
)
309-
} catch (ex: java.lang.Exception) {
310-
showErrorMessage("Unable to start file selector")
311-
}
312-
264+
photoPickerLauncher.launch(
265+
PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly)
266+
)
313267
}
314268
}
Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
// Top-level build file where you can add configuration options common to all sub-projects/modules.
22
plugins {
3-
id 'com.android.application' version '8.7.3' apply false
4-
id 'com.android.library' version '8.7.3' apply false
5-
id 'org.jetbrains.kotlin.android' version '2.1.0' apply false
3+
id 'com.android.application' version '9.1.0' apply false
4+
id 'com.android.library' version '9.1.0' apply false
65
}
7-
ext.kotlin_version = '2.1.0'

codegen/Templates/android/git_push.sh.mustache

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,4 @@ kotlin.code.style=official
2222
# resources declared in the library itself and none from the library's dependencies,
2323
# thereby reducing the size of the R class for that library
2424
android.nonTransitiveRClass=true
25-
android.defaults.buildfeatures.buildconfig=true
26-
android.nonFinalResIds=false
2725
org.gradle.configuration-cache=true

0 commit comments

Comments
 (0)