Android App Tutorial: Scanbot Document Scanner SDK – So integrieren Sie unsere Scan-Funktionen

11.11.2021

Erste Schritte

Voraussetzungen: 

Android Studio ist die am häufigsten verwendete IDE für die Entwicklung von Android-Anwendungen. Alternativ können Sie auch IntelliJ IDEA verwenden. In diesem Tutorial werden wir nur die Standardfunktionen des Android SDK verwenden – und das Scanbot SDK.

Erstellen Sie eine "Hello World"-App für Android

Erstellen Sie in Android Studio ein neues Projekt mit einer leeren Activity. Gehen Sie dazu auf File -> New -> New Project. Wählen Sie dann die Vorlage Empty Activity – wir brauchen keine komplexe Benutzeroberfläche oder besondere Funktionen. 

Geben Sie auf dem nächsten Bildschirm "io.example.myapplication" als Paketnamen ein und drücken Sie dann auf "Finish". 

Android Studio generiert nun ein einfaches Android-Projekt für Sie.

Hinweis: Stellen Sie sicher, dass die Option "Use legacy android.support.libraries" deaktiviert ist, damit Android Studio das Projekt unter Verwendung der neuen AndroidX-Bibliotheken generiert. 

Derzeit ist die minimale Version des Android SDK, die vom Scanbot SDK unterstützt wird, 5.0 (21 API Level). Wählen Sie hier einen höheren Wert, wenn Sie Benutzer mit veralteten Android-Versionen davon abhalten möchten, Ihre App zu installieren.

Testlauf

Schließen Sie zunächst ein mobiles Gerät über USB an (ADB-Debugging muss dazu aktiviert sein). Alternativ können Sie über den AVD-Manager in Android Studio auch ein emuliertes Gerät (Emulator) erstellen und verwenden. Wegen der Kamerafunktionalität wird jedoch ein echtes Gerät empfohlen.

Wählen Sie Ihr Gerät oder den Emulator in der Navigationsleiste aus und drücken Sie die Schaltfläche Run.

Sie sollten auf Ihrem Gerät nun eine leere App mit einem einfachen "Hello World!" laufen sehen.


Scanbot SDK Dependencies hinzufügen

Als Nächstes fügen wir unserem Projekt die Scanbot Scanner SDK für Android Dependency hinzu, die in Form von Gradle-Modulen vorliegt. Mit Gradle-Dependencies können Sie schnell Bibliotheken von Drittanbietern integrieren und aktualisieren. 

Diese Bibliotheken ermöglichen den Zugriff auf Hardware-APIs wie Kamera, Netzwerk oder Batteriestatus, aber auch auf Plattform-SDKs von Drittanbietern wie Firebase. Weitere Details zu Gradle-Dependencies finden Sie in der Android-Dokumentation unter "Build dependencies".

Lassen Sie uns jetzt die Scanbot SDK Module zu unserem Projekt hinzufügen. Gradle ermöglicht es Ihnen, externe Abhängigkeiten aus verschiedenen Repositories zu ziehen. Die Scanbot SDK Module stehen auf einem Nexus-Repository bereit. 

Zunächst müssen wir dieses also zur Liste der Repositories in der Datei settings.gradle des Projekts hinzufügen.

Fügen Sie das Scanbot-Repository unter den Repositories google und mavenCentral hinzu:


dependencyResolutionManagement {
   repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
   repositories {
       google()
       mavenCentral()
       maven { url 'https://nexus.scanbot.io/nexus/content/repositories/releases/' }
}

Wir müssen die Scanbot SDK Dependency zusätzlich auch zum app-Modul der Anwendung hinzufügen. Welche Gradle-Dependency genau erforderlich ist, hängt vom gewünschten Funktionsumfang ab. 

In diesem Tutorial werden wir nur die Dokumentenscanner-Funktion verwenden. Dafür benötigen wir das Dependency-Modul "io.scanbot:sdk-package-1". 
Öffnen Sie dazu die Datei build.gradle des app-Moduls.

Fügen Sie der Datei folgende Zeile hinzu: 


implementation "io.scanbot:sdk-package-1:1.87.1"

"1.87.1" ist die Version des Scanbot SDK für Android, die wir in diesem Tutorial verwenden. Die jeweils neueste Version finden Sie in unserem Changelog.

Das Scanbot SDK enthält eine Reihe von Ready-to-Use UI (RTU UI) Komponenten – Activities, die das Integrieren der Scanbot-Funktionen wesentlich vereinfachen. Um diese RTU UI-Komponenten zu verwenden, fügen Sie außerdem die folgende Gradle-Dependency hinzu:


implementation "io.scanbot:sdk-package-ui:1.87.1" 

Vergessen Sie nicht, Ihr Projekt jedes Mal zu synchronisieren, wenn Sie Dependencies hinzufügen 🙂 :

Um mehr über andere Funktionen des SDK und die Einrichtung der einzelnen Komponenten zu erfahren, lesen Sie bitte unsere Dokumentation.

Kamerazugriff und weitere Anpassungen

Als Nächstes fügen wir in der Datei app/src/main/AndroidManifest.xml die Berechtigung CAMERA hinzu und deklarieren, dass die App die Kamera verwendet:


<manifest ...>
  <uses-permission android:name="android.permission.CAMERA" />
  <uses-feature android:name="android.hardware.camera"/>
  ...
</manifest>

Da unsere App mit hochauflösenden Bildern arbeiten wird, empfehlen wir dringend, in der Datei AndroidManifest.xml dem Element <application> die Eigenschaft android:largeHeap="true" hinzuzufügen, insbesondere für Android-Versionen <= 7.x:


<application
 android:largeHeap="true"
  ...>

Die Verarbeitung hochauflösender Bilder benötigt viel Arbeitsspeicher. Mit dieser Änderung stellen Sie sicher, dass Ihrer Anwendung genügend Heap-Speicher zugewiesen wird, um OutOfMemoryError-Fehler zu vermeiden.

Zeit fürs Programmieren!

Schreiben wir nun etwas Kotlin-Code, um die SDK-Funktionen zu nutzen. 

Initialisierung des Scanbot SDK

Damit das Scanbot SDK einwandfrei funktioniert, muss es zuerst initialisiert werden. Dafür werden wir die Klasse ScanbotSDKInitializer verwenden. Am einfachsten ist es, sie unserer Application-Klasse hinzuzufügen, dem Haupteinstiegspunkt einer Android-Anwendung.

Dazu fügen wir als Erstes eine neue Klasse <codefont>ExampleApplication<codefont> hinzu (New -> Kotlin class) und implementieren sie wie folgt:


package io.example.myapplication

import android.app.Application
import io.scanbot.sdk.ScanbotSDKInitializer

class ExampleApplication : Application() {
   override fun onCreate() {
       super.onCreate()

       ScanbotSDKInitializer()
           .license(this, LICENSE_KEY) // Please add a valid trial license key here. See the notes below!
           .initialize(this)
   }
}

Nun deklarieren wir diese Klasse in AndroidManifest.xml:


<application
   android:largeHeap="true"
   android:name=".ExampleApplication"
   ..>
   


Erledigt! Jetzt wird das Scanbot SDK sofort initialisiert, wenn der Benutzer die App öffnet. 

Der nächste Schritt: Schnelles Hinzufügen einer Benutzeroberfläche, mit der wir tatsächlich etwas mit unserer neuen App scannen können.


Integrieren Sie die Dokumentenscanner-UI

Wie bereits erwähnt, bietet das Scanbot Scanner SDK für Android eine gebrauchsfertige UI-Komponente zum Scannen von Dokumenten. Für deren Integration reichen ein paar Zeilen Code. 

Dazu werden wir die Klasse DocumentScannerActivity verwenden und unsere gewünschte Konfiguration mittels der Klasse DocumentScannerConfiguration definieren.
Zunächst verpacken wir den Aufruf der SDK-Activity in eine einfache Funktion namens scanDocument() – wir werden sie später an eine Schaltfläche binden – und fügen sie zu unserer MainActivity-Klasse hinzu:


class MainActivity : AppCompatActivity() {
   ...

   private fun startDocument() {
       val configuration = DocumentScannerConfiguration()
       configuration.setTopBarBackgroundColor(Color.RED)
       // It is possible to customize the behavior and appearance of the SDK screen
       val docIntent = DocumentScannerActivity.newIntent(this, configuration)
       startActivityForResult(docIntent, DOCUMENT_SCANNER_ACTIVITY_REQUEST_CODE)
   }

   companion object {
       const val DOCUMENT_SCANNER_ACTIVITY_REQUEST_CODE = 100
   }
}

Mit DocumentScannerConfiguration können Sie Konfigurationsparameter übergeben, um Farben (z. B. um die Symbolleiste rot zu färben), Textressourcen und das Verhalten einiger Document Scanner-Funktionen anzupassen. Weitere Einzelheiten finden Sie in der API-Dokumentation.

Fügen wir nun eine Schaltfläche in das Layout unserer MainActivity ein. Der Einfachheit halber ersetzen wir auch das ConstraintLayout durch ein LinearLayout

Ändern Sie die src/main/res/layout/activity_main.xml dazu wie folgt:


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:orientation="vertical"
   tools:context=".MainActivity">

   <Button
       android:id="@+id/start_scanner_button"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_gravity="center"
       android:text="Start Scanner"
       app:layout_constraintBottom_toBottomOf="parent"
       app:layout_constraintLeft_toLeftOf="parent"
       app:layout_constraintRight_toRightOf="parent"
       app:layout_constraintTop_toTopOf="parent" />

</LinearLayout>

Als Nächstes binden wir unsere scanDocument()-Methode als onClickListener-Ereignis an die Schaltfläche, die wir gerade in der onCreate-Methode unserer MainActivity-Klasse erstellt haben:


override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        findViewById<Button>(R.id.start_scanner_button).setOnClickListener { 
            startDocument()
        }
    }
>

Starten wir nun die Anwendung, um uns die Benutzeroberfläche des Scanners anzusehen und zu versuchen, ein Dokument zu scannen. 

Beim ersten Scan-Durchlauf fragt die Anwendung um den dafür nötigen Zugriff auf die Kamera. Unsere RTU UI-Komponenten verwalten die Kameraberechtigung automatisch, sodass Sie sich darüber keine Gedanken machen müssen.

Juhu! Der Dokumentenscanner-Screen hat sich geöffnet und erkennt die Kontur des Dokuments. Wir können auch sehen, dass die Farbe der Symbolleiste jetzt rot ist. Dies haben wir in der Konfiguration eingestellt. 

Hinweis: Der Einfachheit halber haben wir die Multi-Page-Funktion des Dokumentenscanners nicht aktiviert (siehe Konfigurationsparameter setMultiPageEnabled, der standardmäßig false ist). Die Benutzeroberfläche des Scanners schließt sich daher nach einem einzelnen Scan automatisch. 

Als Nächstes werden wir das erste Page-Element aus dem Ergebnis-Array ziehen, um das automatisch zugeschnittene Dokumentenbild anzuzeigen.

Los geht's!

Verarbeiten und Anzeigen des gescannten Bildes

Nach dem Scannen gibt die DocumentScannerActivity ein Array von Page Objekten zurück. Diese Objekte enthalten alle Informationen über das gescannte Dokument. 

Wie in der Android-Entwicklung üblich, müssen wir die onActivityResult-Methode in der aufrufenden Activity überschreiben, um auf die Ergebnisse zuzugreifen. 

Zunächst stellen wir sicher, dass der Aufruf durch unsereDocumentScannerActivity erfolgt ist, indem wir <codefont>requestCode<codefont> und <codefont>resultCode<codefont> überprüfen. Um dann auf die Seiten selbst zuzugreifen, müssen wir den Schlüssel <codefont>SNAPPED_PAGE_EXTRA<codefont> verwenden. In diesem Beispiel sind wir, wie bereits erwähnt, nur am ersten Element des Arrays interessiert. Wir werden die Seite später in der processPagePreview-Methode verarbeiten.


class MainActivity : AppCompatActivity() {

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == DOCUMENT_SCANNER_ACTIVITY_REQUEST_CODE && resultCode == RESULT_OK) {
            val snappedPagesExtra = data?.getParcelableArrayExtra(DocumentScannerActivity.SNAPPED_PAGE_EXTRA)
            snappedPagesExtra?.get(0)?.let { page ->
                processPagePreview(page as Page)
            }
        }
    }

    private fun processPagePreview(page: Page) {
        // We will implement it later
    }
    


Um auf das im Page Objekt enthaltene Bild zuzugreifen, müssen wir die Klasse <codefont>PageFileStorage<codefont> verwenden. Eine Instanz davon kann durch den Aufruf von <codefont>createPageFileStorage()<codefont> in der Klasse <codefont>ScanbotSDK<codefont> erstellt werden. Der bequemste Ort dafür ist unsere onCreate-Methode, gespeichert wird sie dann als private Eigenschaft <codefont>pageFileStorage<codefont>.


class MainActivity : AppCompatActivity() {
class MainActivity : AppCompatActivity() {
    private lateinit var pageFileStorage: PageFileStorage

    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        pageFileStorage = ScanbotSDK(this).createPageFileStorage()
    }
    

Um eine Vorschau anzuzeigen, fügen wir unserem Layout ein ImageView-Widget hinzu. Das vollständige Layout unserer MainActivity sieht nun wie folgt aus:


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:app="http://schemas.android.com/apk/res-auto"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:orientation="vertical"
   tools:context=".MainActivity">

   <Button
       android:id="@+id/start_scanner_button"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:layout_gravity="center"
       android:text="Start Scanner"
       app:layout_constraintBottom_toBottomOf="parent"
       app:layout_constraintLeft_toLeftOf="parent"
       app:layout_constraintRight_toRightOf="parent"
       app:layout_constraintTop_toTopOf="parent" />

   <ImageView
       android:id="@+id/page_preview"
       android:layout_width="match_parent"
       android:layout_height="0dp"
       android:layout_weight="1" />
</LinearLayout>

Um das Bild tatsächlich anzuzeigen, müssen wir eine <codefont>processPagePreview<codefont>-Methode implementieren. Wir können das Bild über eine pageId dem pageFileStorage entnehmen. Alternativ könnten wir mit der Methode getImageURI per URI auf die Datei zugreifen. 

In realen Anwendungen gäbe es effizientere Möglichkeiten, Bilder aus dem internen Speicher zu laden (z. B. mittels Glide- oder Picasso-Bibliotheken). 


 private fun processPagePreview(page: Page) {
        val imageType = PageFileStorage.PageFileType.DOCUMENT
        val filteredPreviewImage = pageFileStorage.getImage(page.pageId, imageType)
        val previewWidget = findViewById<ImageView>(R.id.page_preview)
        previewWidget.setImageBitmap(filteredPreviewImage)
    }
    

Der Bildtyp <codefont>DOCUMENT<codefont> ist das zugeschnittene und perspektivisch korrigierte Bild (hochauflösend), während das <codefont>ORIGINAL<codefont> das unbearbeitete Bild (ebenfalls hochauflösend) beschreibt. Alle Bilder werden standardmäßig als JPG-Dateien gespeichert. 

Es ist auch möglich, auf Vorschaubilder (niedrige Auflösung) zuzugreifen, die als Thumbnails verwendet werden sollten und durch den Aufruf von <codefont>getPreviewImage<codefont> angezeigt werden können. Weitere Einzelheiten finden Sie in der API-Dokumentation.

Abschließend lassen wir unsere Anwendung noch einmal laufen – und nach erfolgreichem Scan erscheint die Vorschau des zugeschnittenen Bildes im ImageView. Herzlichen Glückwunsch!

Vollständige Beispielprojekte

Schauen Sie sich für einen reibungslosen Start das folgende Beispielprojekt auf GitHub an:

Dieses Projekt demonstriert die Integration aller API-Methoden des Scanbot SDK für Android, wie z.B. Cropping UI, Image Filtering, PDF- und TIFF-Rendering, Optical Character Recognition, Barcode- und QR-Code-Scanning, MRZ-Scanner (Machine Readable Zones) und EHIC-Scanning (European Health Insurance Card bzw. Gesundheitskarte). 

Wenn Sie mehr Kontrolle über das Design des Scanbildschirms oder mehr Flexibilität bei der Implementierung wünschen, können Sie unsere Classical Components verwenden. Ein Beispielprojekt für diese Komponenten finden Sie hier.

Und schließlich finden Sie die App, die wir in diesem Tutorial erstellt haben, hier.

Scanbot SDK (Testversion) Lizenzschlüssel

Hinweis: Ohne Lizenzschlüssel läuft das Scanbot SDK nur für eine Minute pro Sitzung! Nach Ablauf des Testzeitraums werden alle Funktionen des Scanbot Scanner SDK deaktiviert und  die Benutzeroberflächen beendet. 

Sie können eine uneingeschränkte, unverbindliche 30-Tage-Testlizenz kostenlos erhalten. Nutzen Sie dazu einfach das Testlizenz-Formular auf unserer Website.

Da der Scanbot SDK-Lizenzschlüssel an die Anwendungs-ID gebunden ist, müssen Sie den standardmäßig generierten App Identifier (io.example.myapplication) dieser Tutorial-App verwenden. Alternativ können Sie auch die ID Ihrer Anwendung verwenden, wenn Sie diese beim Beantragen Ihrer Testlizenz angeben. Bitte berücksichtigen Sie die Groß- und Kleinschreibung der Anwendungs-IDs!

Wo Sie die Anwendungs-ID finden

Die Anwendungs-ID wird in der Datei app/build.gradle als Eigenschaft applicationId definiert:


 android {
    defaultConfig {
        applicationId "io.example.myapplication"
        ...
    }
    ...
}

Viel Spaß beim Coden! 👩💻👨💻

Wenn Sie Hilfe benötigen, können Sie sich gerne an einen unserer Experten wenden. Wir freuen uns darauf, Ihnen weiterzuhelfen. 


Das Scanbot Fact Sheet: Alle Informationen auf einen Blick!

Scanbot verarbeitet und nutzt die angegebenen Informationen, um Sie bzgl. unserer Produkte zu kontaktieren und Ihnen den monatlichen Newsletter zuzusenden. Sie können diesen Service jederzeit deabonnieren. Hinweise zum Widerruf und zu der Verarbeitung Ihrer Daten finden Sie in unserer Datenschutzerklärung.

Bereit zum Ausprobieren?

Sprechen Sie mit einem unserer Lösungsexperten, um herauszufinden, wie wir Ihre Anforderungen an die mobile Datenerfassung lösen können, oder integrieren Sie das Scanbot SDK gleich in Ihre eigene mobile App oder Webseite.

Kontaktieren Sie uns
Jetzt testen

Entwickler, bereit loszulegen?

Das Hinzufügen der kostenlosen 30-Tage Testlizenz zu Ihrer App ist einfach. Laden Sie das Scanbot SDK jetzt herunter und entdecken Sie die Vorteile der mobilen Datenerfassung.