Jetpack Compose: How to make a PDF Scanner 🔍🤳🖨

Kaan Enes KAPICI
3 min readAug 29, 2024

--

Selamlar arkadaşlar. Bildiğiniz üzere hepimiz çoğu zaman dosyalarla işlemler yapmamız gerekmiştir. Bunların başında dosyayı taratıp karşı tarafa gönderme durumu geliyor. Ama indirdiğimiz çoğu uygulama ise bunu tam istediğimiz gibi gerçekleştirmiyor. Bu yazımda ise sizlere basit bir şekilde kendi PDF Scanner app’inizi nasıl yapabilirsiniz onu göstereceğim. Hadi başlayalım 🎉

Konuya geçmeden önce bu yazıdaki anlatılan projenin tamamına şuradaki linkten ulaşabilirsiniz ➡️ https://github.com/kaaneneskpc/PdfScanner

Entegrasyon 🖥️

Bir Android app’in geliştirilmesinde olmazsa olmazı kütüphaneleri entegre etmek ile başlar. O yüzden app’imize başlamadan önce Pdf işlemlerini yapacağımız kütüphanemizi entegre etmemiz gerekiyor.

// Add the dependency to your build.gradle.kts file:

dependencies {
implementation("com.google.android.gms:play-services-mlkit-document-scanner:16.0.0-beta1")
}

Google, uygulamamıza kolayca bir belge tarayıcı özelliği eklemek için ML Kit belge tarayıcı API’sini kullanmamıza olanak sağlıyor. Bu şekilde istediğimiz işlemleri kolayca sağlıyoruz.

Eveet şimdi ise sırada proje içi konfigürasyonlarımızı yapmaya geldi.

PDF Scanner kullanıcı akışı (özel bir vizör ekranı ve önizleme ekranı içerir) SDK tarafından sağlanır. Bu ekran aşağıdaki özelleştirilebilir kontrolleri destekler:

  • fotoğraf galerisinden içe aktarma
  • taranan sayfa sayısı için bir sınır belirleme
  • tarayıcı modu (akıştaki özellik setlerini kontrol etmek için)

Taranan belgeleriniz için hem PDF hem de JPEG dosyalarını alabilirsiniz.

 val scanner = remember {
GmsDocumentScanning.getClient(
GmsDocumentScannerOptions.Builder()
.setGalleryImportAllowed(true) //Galeriden foto alınmasına izin verir
.setResultFormats(GmsDocumentScannerOptions.RESULT_FORMAT_PDF) //Çıktı formatı
.setScannerMode(GmsDocumentScannerOptions.SCANNER_MODE_FULL).build() //Tarama modunu belirlemek için(tamamını taratır)
.setPageLimit(1) //Sayfa limiti
)
}

Scanner konfigürasyonumuzu yaptık. Sırada ise scan işlemimiz scan işlemini gerçekleştirmek.

GmsDocumentScannerOptions’ını oluşturduktan sonra, bunun bir instancenı alıyoruz.Daha sonra AndroidX’te tanıtılan Activity Result API’lerini kullanarak tarayıcı etkinliğini başlatıyoruz. Belge taraması tamamlandığında, bir GmsDocumentScanningResult nesnesi taranan sayfa sayısına, setResultFormats aracılığıyla tanımlananlara göre JPEG formatındaki ve PDF’deki görüntülerin URI’lerine erişim sağlayacaktır.

val scanLauncher =
rememberLauncherForActivityResult(contract = ActivityResultContracts.StartIntentSenderForResult()) {
if (it.resultCode == Activity.RESULT_OK) {
val scanningResult = GmsDocumentScanningResult.fromActivityResultIntent(it.data)
scanningResult?.pdf?.let { pdf ->
Log.d("pdfName", pdf.uri.lastPathSegment.orEmpty())
val date = Date()
val fileName = SimpleDateFormat(
"dd-MMM-yyyy HH:mm:ss",
Locale.getDefault()
).format(date) + ".pdf"

val pdfItem = Pdf(
UUID.randomUUID().toString(),
fileName,
getFileSize(context, fileName),
date
)
pdfViewModel.insertPdf(pdfItem)
}
}
}

ExtendedFloatingActionButton(
onClick = {
scanner.getStartScanIntent(activity).addOnSuccessListener {
scanLauncher.launch(
IntentSenderRequest.Builder(it).build()
)
}.addOnFailureListener {
it.printStackTrace()
context.showToast(it.message.toString())
}
},
text = { Text("Scan Document") },
icon = {
Icon(
imageVector = Icons.Default.CameraEnhance,
contentDescription = "Icon"
)
}
)

Eveet gerekli işlemleri de yaptık artık kendi scan ettiğiniz dosyalar sisteminize otomatik olarak kayıt oluyor.Bunları görüntülemek istedğimiz zaman ise şu yapıyı kullanıyoruz.

val getFileUri = getFileUri(context, pdf.name.orEmpty())
val browserIntent = Intent(Intent.ACTION_VIEW, getFileUri)
browserIntent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
activity.startActivity(browserIntent)

Eğer ki paylaşmak ya da göndermek isterseniz ise şu yapıyı kurarak düzgün bir biçimde gönderim sağlayabilirsiniz.

   pdfViewModel.currentPdf?.let {
pdfViewModel.onHideRenameDialog()
val fileUri = getFileUri(context, it.name.orEmpty())
val shareIntent = Intent(Intent.ACTION_SEND)
shareIntent.type = "application/pdf"
shareIntent.clipData = ClipData.newRawUri("", fileUri)
shareIntent.putExtra(Intent.EXTRA_STREAM, fileUri)
shareIntent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
context.startActivity(
Intent.createChooser(
shareIntent,
"Share Pdf"
)
)

}

Yazının başında eklediğim örnek projeyi detaylı incelerseniz orada kullanımların hepsini tek tek nasıl uygulandığını daha iyi anlayabilirsiniz.

Ve hazırızz artık kendimize ait bir PDF Scanner App’imiz var 🎉🎉🎉

Sonuç olarak Google’ın API’nı kullanarak kolay bir şekilde kendi özelimizde istediğimiz formatta pdf taratıp, çıktı üretip, oluşan çıktıyı istediğimiz şekilde gönderim sağlayabiliyoruz.

Bir sonraki yazımda görüşmek üzere ✌️

Kaynakça:

--

--

Kaan Enes KAPICI

Hi everybody, I’m Kaan. Senior Application(Android) Engineer at @TurkTelekom/Innova - Ex @QnbFinansbank Love cats and dogs.🐶🐈. Writing whatever I want..