File Uploader SDK
El File Uploader SDK facilita la carga de documentos e imágenes al sistema durante el proceso de KYC. Este componente maneja la transferencia de archivos desde la aplicación móvil o la interfaz web hacia el servidor de backend de manera rápida, segura y eficiente. Asegura que los archivos sean validados, codificados y almacenados correctamente para su posterior procesamiento. Este SDK también puede manejar diferentes formatos de archivo, como imágenes y videos, asegurando la versatilidad en la carga de documentos.
Objetivo
El objetivo es facilitar la integración de capacidades avanzadas de carga de archivos en aplicaciones Android, permitiendo la selección de imágenes y videos con opciones de personalización flexible y recuperación de URI para un uso sencillo en la aplicación.
Funcionalidades
El SDK proporciona funcionalidades para:
- Obtener una imagen del dispositivo Android y devolver su URI.
- Obtener un video del dispositivo Android y devolver su URI.
- Personalizar el tamaño máximo permitido para la carga de imágenes o videos.
- Personalizar los formatos deseados de imagen o video.
Empezando
Antes de integrar el SDK en tu proyecto, asegúrate de cumplir con los siguientes requisitos:
- Android Studio: Tener instalada la versión recomendada de Iguana de Android Studio.
- Gradle: Usar la versión recomendada de Gradle 8.4.
- Android Gradle Plugin: Tener la versión recomendada del plugin de Gradle 8.3.2.
- Compilación del SDK: Configurar la compilación con SDK 35.
- Compatibilidad de Source y Target: Utilizar las versiones recomendadas de source y target compatibility 18.
- minSdkVersion: Establecer la versión mínima del SDK en 26.
- targetSdkVersion: Configurar la versión del SDK objetivo en 33.
- Groovy DS: La configuración del build gradle, debe de estar en Groovy DSL.
Configuracion
1. Crear una aplicación
Al crear un proyecto debe de elegirse como No Activity y en la opción de build Configuration Language se debe de elegir: Groovy DSL (build,gradle)
2. Remplaza el contenido de build.gradle del proyecto por:
buildscript {
ext.kotlin_version = "1.9.22"
ext.hilt_version = '2.46'
repositories {
google()
mavenCentral()
maven {
url 'https://us-maven.pkg.dev/jaak-platform/jaak-android'
}
maven {
url 'https://jitpack.io'
}
}
dependencies {
classpath 'com.android.tools.build:gradle:8.3.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "com.google.dagger:hilt-android-gradle-plugin:$hilt_version"
classpath 'com.google.gms:google-services:4.4.2'
}
}
tasks.register('clean', Delete) {
delete rootProject.buildDir
}
3. Remplaza en el archivo settings.gradle el siguiente bloque de dependencyResolutionManagement:\
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
maven { url 'https://jitpack.io' }
maven {
url 'https://us-maven.pkg.dev/jaak-platform/jaak-android'
}
}
}
4. Remplaza la sección de plugins en el archivo build.gradle de app
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-kapt'
id 'dagger.hilt.android.plugin'
}
Remplaza la sección de dependencias en el archivo build.gradle de app
dependencies {
//Código previo
//..
//.
// Bibliotecas de Kotlin
implementation("org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version")
// Android Jetpack
implementation("androidx.core:core-ktx:1.15.0")
implementation("androidx.appcompat:appcompat:1.7.0")
implementation("androidx.fragment:fragment-ktx:1.8.5")
implementation("androidx.activity:activity-ktx:1.9.3")
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.7")
implementation("androidx.constraintlayout:constraintlayout:2.2.0")
implementation 'com.google.android.material:material:1.12.0'
// Inyección de Dependencias
implementation("com.google.dagger:hilt-android:$hilt_version")
kapt("com.google.dagger:hilt-android-compiler:$hilt_version")
// jaakdocumentdetector
implementation("com.jaak.fileuploadersdk:jaakfileuploader-sdk:1.1.1")
}
Agrega el siguiente bloque en Android en el archivo build.gradle de app
android {
//Código previo
//..
//.
buildFeatures{
viewBinding = true
}
}
5. Crea una clase kotlin que extienda de Application y agrega la anotación de HiltAndroidApp
import android.app.Application
import dagger.hilt.android.HiltAndroidApp
@HiltAndroidApp
class TestApp : Application()
6. Crea una clase kotlin con la anotación @AndroidEntryPoint, que extienda de AppCompatActivity() e implementa el listener FaceDetectorListener
Ejemplo de ActivityNota: Este ejemplo utiliza viewBinding por lo que se debe de crear un layout donde el nombre es como se armara la clase binding.
Ejemplo: layout: activity_main.xml --> El nombre del binding se llamaría ActivityMainBindingEjemplo 2: layout: main_activity.xml --> El nombre del binding se llamaría MainActivityBinding
class MainActivity : AppCompatActivity(), ImageVideoSelectionListener {
private lateinit var binding: MainActivityBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = MainActivityBinding.inflate(layoutInflater)
setContentView(binding.root)
}
// Method to return the image URI
override fun onImageSelected(uri: Uri) {
}
// Method to return the video URI
override fun onVideoSelected(uri: Uri) {
}
// Method to return an error in the URI process
override fun onErrorSelected(error: String) {
}
Crea una xml para utilizar los viewBinding
Nota: Al crear el xml se debe de agregar la línea:xmlns:tools="http://schemas.android.com/tools" y la línea: tools:context="nombre_clase_kotlin"
Ejemplo 1: tools:context="com.example.test.MainActivity"
Ejemplo 2: tools:context="com.example.test.ActivityMain"
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.example.test.MainActivity">
</androidx.constraintlayout.widget.ConstraintLayout>
7. Agrega los permisos al archivo AndroidManifest
<manifest...>
//Código previo
//..
//..
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
tools:replace="android:maxSdkVersion"
android:maxSdkVersion="28"/>
</manifest>
Agrega las siguientes líneas a application para agregar nuestra App previamente creada, además de unas excepciones
<application
//Código previo
//..
//..
android:name="com.example.test.TestApp"
tools:replace="android:theme,android:name">
Agrega la actividad principal que se creó previamente
<application ..>
//Código previo
//..
//..
<activity android:name="com.example.test.MainActivity"
android:exported="true"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
Crearemos un archivo en res/xml/file_paths.xml que contendrá la ruta donde queremos que almacene los videos:
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Ruta para acceder a archivos en el directorio de archivos externos privados de la aplicación -->
<external-path name="my_images" path="Pictures/" />
<external-path name="my_files" path="Android/data/nombre-de-tu-paquete/files/nombre-de-tu-root-name/" />
</paths>
Aqui está un ejemplo de su llenado:
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Ruta para acceder a archivos en el directorio de archivos externos privados de la aplicación -->
<external-path name="my_images" path="Pictures/" />
<external-path name="my_files" path="Android/data/com.example.test/files/Test/" />
</paths>
Agregaremos el file provider al Manifest:
Nota: en android:authorities debe de ir el nombre del paquete del proyecto:Ejemplo 1: android:authorities="com.example.jaakfacedetectorsdk" Ejemplo 2: android:authorities="com.example.test"
<application ..>
//Código previo
//..
//..
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.example.test"
android:exported="false"
android:grantUriPermissions="true"
tools:replace="android:authorities">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
</application>
8. Implementa la librería de face detector sdk:
private lateinit var fileUploaderSDK: FileUploaderSDK
Agregue su configuración::
private fun initSDKImageVideoDisk(){
fileUploaderSDK = FileUploaderSDK(this, this)
fileUploaderSDK.setImageSize(3) // Maximum size for images: 3 MB
fileUploaderSDK.setVideoSize(10) // Maximum size for videos: 10 MB
fileUploaderSDK.setFormatImage(arrayOf("image/*")) // Allowed formats for images
fileUploaderSDK.setFormatVideo(arrayOf("video/*")) // Allowed formats for videos
}
Ejecutar el SDK:
Nota: Si se quiere tener el menú de obtener video por cámara o por almacenamiento, se manda 0.Si se quiere solo obtener video por cámara se manda 2 y si solo por almacenamiento se manda 4
fileUploaderSDK.startImageVideo(typeProcess)
Ejemplo de Código
Ejemplo completo de código.
build.gradle Project
buildscript {
ext.kotlin_version = "1.9.22"
ext.hilt_version = '2.46'
repositories {
google()
mavenCentral()
maven {
url 'https://us-maven.pkg.dev/jaak-platform/jaak-android'
}
maven {
url 'https://jitpack.io'
}
}
dependencies {
classpath 'com.android.tools.build:gradle:8.3.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "com.google.dagger:hilt-android-gradle-plugin:$hilt_version"
classpath 'com.google.gms:google-services:4.4.2'
}
}
tasks.register('clean', Delete) {
delete rootProject.buildDir
}
settings.gradle
pluginManagement {
repositories {
google {
content {
includeGroupByRegex("com\\.android.*")
includeGroupByRegex("com\\.google.*")
includeGroupByRegex("androidx.*")
}
}
mavenCentral()
gradlePluginPortal()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
maven { url 'https://jitpack.io' }
maven {
url 'https://us-maven.pkg.dev/jaak-platform/jaak-android'
}
}
}
rootProject.name = "Test"
include ':app'
build.gradle App
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'kotlin-kapt'
id 'dagger.hilt.android.plugin'
}
android {
namespace 'com.example.test'
compileSdk 35
defaultConfig {
applicationId "com.example.test"
minSdk 26
targetSdk 35
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = '11'
}
buildFeatures{
viewBinding = true
}
}
dependencies {
// Bibliotecas de Kotlin
implementation("org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version")
// Android Jetpack
implementation("androidx.core:core-ktx:1.15.0")
implementation("androidx.appcompat:appcompat:1.7.0")
implementation("androidx.fragment:fragment-ktx:1.8.5")
implementation("androidx.activity:activity-ktx:1.9.3")
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:2.8.7")
implementation("androidx.constraintlayout:constraintlayout:2.2.0")
implementation 'com.google.android.material:material:1.12.0'
// Inyección de Dependencias
implementation("com.google.dagger:hilt-android:$hilt_version")
kapt("com.google.dagger:hilt-android-compiler:$hilt_version")
// jaakdocumentdetector
implementation("com.jaak.fileuploadersdk:jaakfileuploader-sdk:1.1.1")
}
res/xml/file_paths.xml
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Ruta para acceder a archivos en el directorio externo privado de archivos de la aplicación -->
<external-path name="my_images" path="Pictures/" />
<external-path name="my_files" path="Android/data/com.example.test/files/Test/" />
</paths>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
tools:replace="android:maxSdkVersion"
android:maxSdkVersion="28"/>
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Test"
tools:targetApi="31"
android:name="com.example.test.TestApp"
tools:replace="android:theme,android:name">
<activity android:name="com.example.test.MainActivity"
android:exported="true"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.example.test"
android:exported="false"
android:grantUriPermissions="true"
tools:replace="android:authorities">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
</application>
</manifest>
TestApp.kt
package com.example.test
import android.app.Application
import dagger.hilt.android.HiltAndroidApp
@HiltAndroidApp
class TestApp : Application()
res/layout/main_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.example.test.MainActivity">
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.kt
package com.example.test
import android.net.Uri
import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import com.example.test.databinding.MainActivityBinding
import com.jaak.jaakfacedetectorsdk.ui.adapter.FaceDetectorListener
import com.jaak.jaakfacedetectorsdk.ui.view.FaceDetectorSDK
import com.jaak.jaakfacedetectorsdk.utils.Utils
import dagger.hilt.android.AndroidEntryPoint
@AndroidEntryPoint
class MainActivity : AppCompatActivity(), ImageVideoSelectionListener {
private lateinit var binding: MainActivityBinding
private lateinit var fileUploaderSDK: FileUploaderSDK
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = MainActivityBinding.inflate(layoutInflater)
setContentView(binding.root)
initSDKImageVideoDisk()
fileUploaderSDK.startImageVideo(typeProcess)
}
private fun initSDKImageVideoDisk(){
fileUploaderSDK = FileUploaderSDK(this, this)
fileUploaderSDK.setImageSize(3) // Maximum size for images: 3 MB
fileUploaderSDK.setVideoSize(10) // Maximum size for videos: 10 MB
fileUploaderSDK.setFormatImage(arrayOf("image/*")) // Allowed formats for images
fileUploaderSDK.setFormatVideo(arrayOf("video/*")) // Allowed formats for videos
}
// Method to return the image URI
override fun onImageSelected(uri: Uri) {
}
// Method to return the video URI
override fun onVideoSelected(uri: Uri) {
}
// Method to return an error in the URI process
override fun onErrorSelected(error: String) {
}
}
Updated about 2 months ago