La capacité de partager des images de capture et de partage est l\'une des qualités qui ont propulsé les usages des smartphones au cours de la dernière décennie. Des franchises de plusieurs milliards de dollars, comme Instagram et Pinterest, sont ainsi nées. Cette capacité nous parle de nous-mêmes en tant qu\'êtres humains, nous aimons les histoires. Cependant, les histoires ne doivent pas simplement être mises en mots. Nous pouvons également utiliser des images et des séries d\'images appelées vidéos pour transmettre notre histoire.

Si vous êtes un développeur, vous devez intégrer la capacité de capture des images ou sélectionner des images capturées et les importer dans votre application. Ensuite, vous pouvez faire tous les types de choses intéressantes à ces images.

Heureusement pour nous android sdk fournit des classes et des API que nous pouvons utiliser pour fournir cette fonctionnalité de façon transparente dans notre application. Dans ce tutoriel, nous apprenons à capturer des images par caméra et à les afficher dans une vue imagevue. Sinon, nous verrons comment sélectionner des images dans la galerie et les rendre sur une image.

Exemple-Kotlin Android Capture From Camera ou Select from ImagePicker

Nous créons une application contenant une activité. Cette activité a une vue imagevue et deux boutons en dessous. Lorsque l\'utilisateur clique sur le premier bouton, nous allons lancer la caméra via l\'intention. Ensuite, nous pouvons capturer et l\'image et cette image sera affichée sur une image dans notre application. Le second bouton nous permet d\'ouvrir notre galerie de systèmes. A partir de la galerie, nous pouvons sélectionner une image et l\'avoir rendue sur notre image.

Tutoriel vidéo

Regardez le tutoriel vidéo pour plus de détails et de démonstration.

Etape 1: Créer notre projet

Ouvrez app android studio et créez un nouveau projet. Choisissez une activité vide, choisissez Kotlin comme langue de programmation. Assurez-vous que notre application supporte les artefacts androidx. Je vais utiliser l\'API Android Level 15 comme ma version minimale.

Voici mon niveau d\'application build.gradle:

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    testImplementation 'junit:junit:4.12'
    implementation 'androidx.appcompat:appcompat:1.0.2'
    implementation 'androidx.core:core-ktx:1.0.2'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
}

Vous pouvez voir qu\'il n\'y a pas de dépendance particulière à ajouter.

Etape 2: Présentations

Nous n\'aurons qu\'une seule mise en page:

(a). activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:gravity="center|top"
              android:layout_height="match_parent">
    <TextView
            android:id="@+id/headerTxt"
            android:text="Camera and ImagePicker Tutorial"
            android:background="@color/colorAccent"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="5dp"
            android:textAlignment="center"
            android:textStyle="bold"
            android:textAppearance="@style/TextAppearance.AppCompat.Large"
            android:textColor="@android:color/white" />
    <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="300dp"
            android:layout_marginTop="16dp"
            android:gravity="center"
            android:background="@android:color/darker_gray"
            android:orientation="vertical">

        <ImageView
                android:id="@+id/mImageView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_horizontal"
                android:contentDescription="Our Image"/>
    </LinearLayout>

    <LinearLayout
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
        <Button
                android:layout_weight="0.5"
                android:layout_width="0dp"
                android:layout_height="45dp"
                android:padding="5dp"
                android:text="Capture"
                android:layout_marginTop="10dp"
                android:textColor="@android:color/white"
                android:background="@drawable/button_shape"
                android:id="@+id/btnCapture"/>

        <Button
                android:layout_weight="0.5"
                android:layout_width="0dp"
                android:layout_height="45dp"
                android:padding="5dp"
                android:text="Choose"
                android:layout_marginTop="10dp"
                android:textColor="@android:color/white"
                android:background="@drawable/button_shape"
                android:id="@+id/btnChoose"/>
    </LinearLayout>

</LinearLayout>

Cet agencement contient les composants suivants:

  1. Présentation linéaire -Pour commander nos éléments linéairement, verticalement ou horizontalement.
  2. TextView-Pour afficher du texte
  3. ImageView-Pour afficher des images.
  4. Bouton-Pour nous permettre de choisir / sélectionner une image ou de la capturer à partir de la caméra.

Classes

Nous n\'avons qu\'une seule classe.

(a). MainActivity.kt

Star en ajoutant les importations:

import android.annotation.TargetApi
import android.app.Activity
import android.content.ContentUris
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.BitmapFactory
import android.net.Uri

import android.os.Build
import android.os.Bundle
import android.provider.DocumentsContract
import android.provider.MediaStore
import android.widget.Button
import android.widget.ImageView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.content.FileProvider
import java.io.File

Ensuite, faites étendre notre classe à AppCompatActivity:

class MainActivity : AppCompatActivity() {

Dans la classe, vous pouvez définir les zones de notre instance:

    //Our variables
    private var mImageView: ImageView? = null
    private var mUri: Uri? = null
    //Our widgets
    private lateinit var btnCapture: Button
    private lateinit var btnChoose : Button
    //Our constants
    private val OPERATION_CAPTURE_PHOTO = 1
    private val OPERATION_CHOOSE_PHOTO = 2

Dans ce qui précède, la vue imageview rendra notre image, l\'Uri est l\'uri de l\'image. BtnCapture Nous permettra de démarrer notre caméra pour capturer l\'image. BtnChoisir Nous permettra d\'ouvrir la galerie pour choisir l\'image.

Créez ensuite une méthode pour initialiser les widgets ci-dessus:

    private fun initializeWidgets() {
        btnCapture = findViewById(R.id.btnCapture)
        btnChoose = findViewById(R.id.btnChoose)
        mImageView = findViewById(R.id.mImageView)
    }

Ensuite, une méthode pour afficher notre message Toast:

    private fun show(message: String) {
        Toast.makeText(this,message,Toast.LENGTH_SHORT).show()
    }

Ensuite, nous allons créer une méthode pour capturer notre photo ou image:

    private fun capturePhoto(){
        val capturedImage = File(externalCacheDir, "My_Captured_Photo.jpg")
        if(capturedImage.exists()) {
            capturedImage.delete()
        }
        capturedImage.createNewFile()
        mUri = if(Build.VERSION.SDK_INT >= 24){
            FileProvider.getUriForFile(this, "info.camposha.kimagepicker.fileprovider",
             capturedImage)
        } else {
            Uri.fromFile(capturedImage)
        }

        val intent = Intent("android.media.action.IMAGE_CAPTURE")
        intent.putExtra(MediaStore.EXTRA_OUTPUT, mUri)
        startActivityForResult(intent, OPERATION_CAPTURE_PHOTO)
    }

Dans la méthode ci-dessus, vous pouvez voir que nous avons commencé par instancier un fichier que nous appelons capturedImage. Nous avons passé l\'emplacement ainsi que le nom du fichier.

Puis à l\'aide de la Existe () Nous avons vérifié si un fichier portant le nom de l\'image capturait existe. Si c\'est le cas, nous supprimons.

Ensuite, nous créons un nouveau fichier à l\'aide de la CreateNewFile () . Nous obtenons l\'Uri pour le fichier. Notez que si nous utilisons une version de génération sdk de l\'API Android version 24 et supérieure, nous utilisons le Fournisseur de fichiers Classe, appel de GetUriForFile () . Sinon, nous utilisons le bon vieux FromFile () De la classe Uri.

Ensuite, nous instancions notre intention et startActivityForResult.

Puis pour ouvrir notre galerie et filtrer les images:

    private fun openGallery(){
        val intent = Intent("android.intent.action.GET_CONTENT")
        intent.type = "image/*"
        startActivityForResult(intent, OPERATION_CHOOSE_PHOTO)
    }

Nous allons afficher notre image en tant que bitmap:

    private fun renderImage(imagePath: String?){
        if (imagePath != null) {
            val bitmap = BitmapFactory.decodeFile(imagePath)
            mImageView?.setImageBitmap(bitmap)
        }
        else {
            show("ImagePath is null")
        }
    }

Pour obtenir notre chemin d\'image, nous utiliserons cette méthode:

    private fun getImagePath(uri: Uri?, selection: String?): String {
        var path: String? = null
        val cursor = contentResolver.query(uri, null, selection, null, null )
        if (cursor != null){
            if (cursor.moveToFirst()) {
                path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA))
            }
            cursor.close()
        }
        return path!!
    }

Voici comment nous allons gérer notre image sur l\'API Android de niveau 19 et plus:

    @TargetApi(19)
    private fun handleImageOnKitkat(data: Intent?) {
        var imagePath: String? = null
        val uri = data!!.data
        //DocumentsContract defines the contract between a documents provider and the platform.
        if (DocumentsContract.isDocumentUri(this, uri)){
            val docId = DocumentsContract.getDocumentId(uri)
            if ("com.android.providers.media.documents" == uri.authority){
                val id = docId.split(":")[1]
                val selsetion = MediaStore.Images.Media._ID + "=" + id
                imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                 selsetion)
            }
            else if ("com.android.providers.downloads.documents" == uri.authority){
                val contentUri = ContentUris.withAppendedId(Uri.parse(
                    "content://downloads/public_downloads"), java.lang.Long.valueOf(docId))
                imagePath = getImagePath(contentUri, null)
            }
        }
        else if ("content".equals(uri.scheme, ignoreCase = true)){
            imagePath = getImagePath(uri, null)
        }
        else if ("file".equals(uri.scheme, ignoreCase = true)){
            imagePath = uri.path
        }
        renderImage(imagePath)
    }

Code COMPLET

Voici le code complet de MainActivity.kt:

package info.camposha.kimagepicker

import android.annotation.TargetApi
import android.app.Activity
import android.content.ContentUris
import android.content.Intent
import android.content.pm.PackageManager
import android.graphics.BitmapFactory
import android.net.Uri

import android.os.Build
import android.os.Bundle
import android.provider.DocumentsContract
import android.provider.MediaStore
import android.widget.Button
import android.widget.ImageView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.content.FileProvider
import java.io.File

class MainActivity : AppCompatActivity() {
    //Our variables
    private var mImageView: ImageView? = null
    private var mUri: Uri? = null
    //Our widgets
    private lateinit var btnCapture: Button
    private lateinit var btnChoose : Button
    //Our constants
    private val OPERATION_CAPTURE_PHOTO = 1
    private val OPERATION_CHOOSE_PHOTO = 2

    private fun initializeWidgets() {
        btnCapture = findViewById(R.id.btnCapture)
        btnChoose = findViewById(R.id.btnChoose)
        mImageView = findViewById(R.id.mImageView)
    }

    private fun show(message: String) {
        Toast.makeText(this,message,Toast.LENGTH_SHORT).show()
    }
    private fun capturePhoto(){
        val capturedImage = File(externalCacheDir, "My_Captured_Photo.jpg")
        if(capturedImage.exists()) {
            capturedImage.delete()
        }
        capturedImage.createNewFile()
        mUri = if(Build.VERSION.SDK_INT >= 24){
            FileProvider.getUriForFile(this, "info.camposha.kimagepicker.fileprovider",
             capturedImage)
        } else {
            Uri.fromFile(capturedImage)
        }

        val intent = Intent("android.media.action.IMAGE_CAPTURE")
        intent.putExtra(MediaStore.EXTRA_OUTPUT, mUri)
        startActivityForResult(intent, OPERATION_CAPTURE_PHOTO)
    }
    private fun openGallery(){
        val intent = Intent("android.intent.action.GET_CONTENT")
        intent.type = "image/*"
        startActivityForResult(intent, OPERATION_CHOOSE_PHOTO)
    }
    private fun renderImage(imagePath: String?){
        if (imagePath != null) {
            val bitmap = BitmapFactory.decodeFile(imagePath)
            mImageView?.setImageBitmap(bitmap)
        }
        else {
            show("ImagePath is null")
        }
    }
    private fun getImagePath(uri: Uri?, selection: String?): String {
        var path: String? = null
        val cursor = contentResolver.query(uri, null, selection, null, null )
        if (cursor != null){
            if (cursor.moveToFirst()) {
                path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA))
            }
            cursor.close()
        }
        return path!!
    }
    @TargetApi(19)
    private fun handleImageOnKitkat(data: Intent?) {
        var imagePath: String? = null
        val uri = data!!.data
        //DocumentsContract defines the contract between a documents provider and the platform.
        if (DocumentsContract.isDocumentUri(this, uri)){
            val docId = DocumentsContract.getDocumentId(uri)
            if ("com.android.providers.media.documents" == uri.authority){
                val id = docId.split(":")[1]
                val selsetion = MediaStore.Images.Media._ID + "=" + id
                imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                 selsetion)
            }
            else if ("com.android.providers.downloads.documents" == uri.authority){
                val contentUri = ContentUris.withAppendedId(Uri.parse(
                    "content://downloads/public_downloads"), java.lang.Long.valueOf(docId))
                imagePath = getImagePath(contentUri, null)
            }
        }
        else if ("content".equals(uri.scheme, ignoreCase = true)){
            imagePath = getImagePath(uri, null)
        }
        else if ("file".equals(uri.scheme, ignoreCase = true)){
            imagePath = uri.path
        }
        renderImage(imagePath)
    }

    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>
    , grantedResults: IntArray) {
        super.onRequestPermissionsResult(requestCode, permissions, grantedResults)
        when(requestCode){
            1 ->
                if (grantedResults.isNotEmpty() && grantedResults.get(0) ==
                 PackageManager.PERMISSION_GRANTED){
                    openGallery()
                }else {
                    show("Unfortunately You are Denied Permission to Perform this Operataion.")
                }
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        when(requestCode){
            OPERATION_CAPTURE_PHOTO ->
                if (resultCode == Activity.RESULT_OK) {
                    val bitmap = BitmapFactory.decodeStream(
                        getContentResolver().openInputStream(mUri))
                    mImageView!!.setImageBitmap(bitmap)
                }
            OPERATION_CHOOSE_PHOTO ->
                if (resultCode == Activity.RESULT_OK) {
                    if (Build.VERSION.SDK_INT >= 19) {
                        handleImageOnKitkat(data)
                    }
                }
        }
    }

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

        initializeWidgets()

        btnCapture.setOnClickListener{capturePhoto()}
        btnChoose.setOnClickListener{
            //check permission at runtime
            val checkSelfPermission = ContextCompat.checkSelfPermission(this,
             android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
            if (checkSelfPermission != PackageManager.PERMISSION_GRANTED){
                //Requests permissions to be granted to this application at runtime
                ActivityCompat.requestPermissions(this,
                 arrayOf(android.Manifest.permission.WRITE_EXTERNAL_STORAGE), 1)
            }
            else{
                openGallery()
            }
        }
    }
}
//end

Ressources

Voici les ressources de référence:

Non. Site Lien
1. Github Parcourir
2. Github Télécharger
3. YouTube Suivre

Maintenant, passer au tutoriel suivant.

Meilleures saluperformances.

Catégorisé: