Wednesday, April 17, 2019

Tutorial Membuat Aplikasi Tanda Tangan dengan Android Studio

Tutorial Membuat Aplikasi Tanda Tangan Digital dengan Android Studio
Aplikasi Tanda Tangan Digital dengan Android Studio
Halo sobat 48😁 kalau kemarin saya membagikan sebuah Tutorial Membuat Aplikasi Scan Barcode dan QR Code dengan Android Studio, kali ini saya akan membahas Tutorial Membuat Aplikasi Tanda Tangan dengan Android Studio. Mungkin dari kalian sudah ada beberapa yang tahu tutorial ini, namun bagi kalian yang belum tahu dan sangat butuh tutorial ini silahkan lanjut dibaca ya artikel ini😄

Jika kalian ingin SOURCE CODE Aplikasi Tanda Tangan ini, silahkan download di Github saya DISINI. Tetapi jika kalian ingin tahu cara mengaplikasikannya, silahkan tonton video tutorial yang sudah saya buatkan :

Oke langsung saja tanpa basa-basi lagi kita langsung ke langkah pertama :

1. Buat project baru di Android Studio dengan cara klik File ⇒ Project Baru. Ketika diminta untuk memilih Default Activity, pilih Empty Activity dan klik next. Untuk minSDK, disini saya set API 15 ya.

2. Buka build.gradle dan ubah menjadi seperti ini :


dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'androidx.appcompat:appcompat:1.2.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
    testImplementation 'junit:junit:4.13'
    androidTestImplementation 'androidx.test.ext:junit:1.1.2'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'

    implementation 'com.google.android.material:material:1.2.1'

    implementation 'com.github.gcacace:signature-pad:1.3.1'

}

3. Buka AndroidManifest.xml dan ubah menjadi seperti ini :


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.azhar.tandatangan">

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <application
        android:requestLegacyExternalStorage="true"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        tools:targetApi="q">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

4. Ubah isi MainActivity.java dan activity_main.xml menjadi seperti ini :


package com.azhar.tandatangan

import android.Manifest
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.net.Uri
import android.os.Bundle
import android.os.Environment
import android.util.Log
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import com.github.gcacace.signaturepad.views.SignaturePad
import kotlinx.android.synthetic.main.activity_main.*
import java.io.*

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        //set permission
        verifyStoragePermissions(this);

        //draw signature
        signaturePad.setOnSignedListener(object : SignaturePad.OnSignedListener {
            override fun onStartSigning() {
                //Toast.makeText(this@MainActivity, "Mulai menulis...", Toast.LENGTH_SHORT).show()
            }

            override fun onSigned() {
                btnSave.setEnabled(true)
                btnClear.setEnabled(true)
            }

            override fun onClear() {
                btnSave.setEnabled(false)
                btnClear.setEnabled(false)
            }
        })

        //clear signature
        btnClear.setOnClickListener {
            signaturePad.clear()
        }

        //save signature
        btnSave.setOnClickListener {
            val signatureBitmap = signaturePad.getSignatureBitmap()
            if (addJpgSignatureToGallery(signatureBitmap)) {
                Toast.makeText(this@MainActivity, "Tanda tangan disimpan ke dalam Galeri",
                        Toast.LENGTH_SHORT).show()
            } else {
                Toast.makeText(this@MainActivity, "Tidak dapat menyimpan Tanda Tangan",
                        Toast.LENGTH_SHORT).show()
            }
            if (addSvgSignatureToGallery(signaturePad.getSignatureSvg())) {
                Toast.makeText(this@MainActivity, "Tanda tangan SVG disimpan ke dalam Galeri",
                        Toast.LENGTH_SHORT).show()
            } else {
                Toast.makeText(this@MainActivity, "Tidak dapat menyimpan Tanda Tangan SVG",
                        Toast.LENGTH_SHORT).show()
            }
        }

    }

    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array, grantResults: IntArray) {
        if (requestCode == REQUEST_EXTERNAL_STORAGE) {
            if (grantResults.size <= 0 || grantResults[0] != PackageManager.PERMISSION_GRANTED) {
                Toast.makeText(this@MainActivity, "Tidak dapat menulis gambar ke Media Penyimpanan",
                        Toast.LENGTH_SHORT).show()
            }
        }
    }

    fun getAlbumStorageDir(albumName: String?): File {
        val file = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), albumName)
        if (!file.mkdirs()) {
            Log.e("SignaturePad", "Directory not created")
        }
        return file
    }

    //Image Signature
    @Throws(IOException::class)
    fun saveBitmapToJPG(bitmap: Bitmap, photo: File?) {
        val newBitmap = Bitmap.createBitmap(bitmap.width, bitmap.height, Bitmap.Config.ARGB_8888)
        val canvas = Canvas(newBitmap)
        canvas.drawColor(Color.WHITE)
        canvas.drawBitmap(bitmap, 0f, 0f, null)
        val stream: OutputStream = FileOutputStream(photo)
        newBitmap.compress(Bitmap.CompressFormat.JPEG, 80, stream)
        stream.close()
    }

    fun addJpgSignatureToGallery(signature: Bitmap): Boolean {
        var result = false
        try {
            val photo = File(getAlbumStorageDir("SignaturePad"), String.format("Signature_%d.jpg",
                    System.currentTimeMillis()))
            saveBitmapToJPG(signature, photo)
            scanMediaFile(photo)
            result = true
        } catch (e: IOException) {
            e.printStackTrace()
        }
        return result
    }

    private fun scanMediaFile(photo: File) {
        val mediaScanIntent = Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE)
        val contentUri = Uri.fromFile(photo)
        mediaScanIntent.data = contentUri
        this@MainActivity.sendBroadcast(mediaScanIntent)
    }

    //SVG Signature
    fun addSvgSignatureToGallery(signatureSvg: String?): Boolean {
        var result = false
        try {
            val svgFile = File(getAlbumStorageDir("SignaturePad"), String.format("Signature_%d.svg",
                    System.currentTimeMillis()))
            val stream: OutputStream = FileOutputStream(svgFile)
            val writer = OutputStreamWriter(stream)
            writer.write(signatureSvg)
            writer.close()
            stream.flush()
            stream.close()
            scanMediaFile(svgFile)
            result = true
        } catch (e: IOException) {
            e.printStackTrace()
        }
        return result
    }

    companion object {
        private const val REQUEST_EXTERNAL_STORAGE = 1
        private val PERMISSIONS_STORAGE = arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE)
        fun verifyStoragePermissions(activity: MainActivity?) {
            val permission = ActivityCompat.checkSelfPermission(activity!!, Manifest.permission.WRITE_EXTERNAL_STORAGE)
            if (permission != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(activity, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE)
            }
        }
    }

}




<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/colorPrimary">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            android:text="Tanda Tangan Digital"
            android:textColor="@android:color/white"
            android:textSize="20sp" />

    </androidx.appcompat.widget.Toolbar>

    <LinearLayout
        android:id="@+id/linearMessage"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/toolbar"
        android:background="@color/colorPrimaryDark"
        android:orientation="horizontal">

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:padding="20dp"
            android:text="Sentuh dan gerakan jari Anda pada Area dibawah ini untuk membuat Tanda Tangan Digital."
            android:textColor="@android:color/white"
            android:textSize="16sp"
            android:textStyle="italic" />

    </LinearLayout>

    <RelativeLayout
        android:id="@+id/signatureContainer"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/linearButton"
        android:layout_below="@id/linearMessage">

        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:layout_above="@+id/signatureDescription"
            android:layout_marginBottom="8dp"
            android:background="@color/colorPrimary" />

        <TextView
            android:id="@+id/signatureDescription"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:layout_centerHorizontal="true"
            android:layout_marginBottom="16dp"
            android:text="*Saya Setuju dengan Syarat dan Ketentuan"
            android:textColor="@android:color/black" />

        <com.github.gcacace.signaturepad.views.SignaturePad
            android:id="@+id/signaturePad"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:penColor="@android:color/black" />

    </RelativeLayout>

    <LinearLayout
        android:id="@+id/linearButton"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:orientation="horizontal">

        <Button
            android:id="@+id/btnClear"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_margin="20dp"
            android:layout_weight="1"
            android:background="@drawable/button_background"
            android:drawableStart="@drawable/ic_delete"
            android:enabled="false"
            android:paddingStart="30dp"
            android:paddingEnd="30dp"
            android:text="Clear"
            android:textColor="@android:color/white" />

        <Button
            android:id="@+id/btnSave"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_margin="20dp"
            android:layout_weight="1"
            android:background="@drawable/button_background"
            android:drawableStart="@drawable/ic_save"
            android:enabled="false"
            android:paddingStart="30dp"
            android:paddingEnd="30dp"
            android:text="Save"
            android:textColor="@android:color/white" />

    </LinearLayout>

</RelativeLayout>

Kalau kalian mengikuti langkah-langkah diatas dengan baik, pasti aplikasi yang kalian buat akan berjalan sebagaimana mestinya. Namun jika mengalami Error, silahkan berikan komentar dan kita diskusikan bersama.

Demikian informasi yang saya bagikan untuk kalian. Jangan lupa bagikan artikel ini ke teman-teman kalian agar ikut membaca Tutorial Membuat Aplikasi Tanda Tangan dengan Android Studio ini. Subscribe juga blog Rivaldi 48 ini agar kalian mendapatkan notifikasi saat Admin update artikel terbaru. Follow Instagram Admin @azhardvls_. Semoga kalian lebih nyaman dan mudah dalam mengakses Blog Rivaldi 48 dimanapun kalian berada. Terima Kasih...

0 Comments

Post a Comment

Silahkan tinggalkan komentar jika Anda punya saran, kritik, atau pertanyaan seputar topik pembahasan. Gunakan bahasa yang bijak dan santun. Terima Kasih.