Die Fähigkeit, die Erfassung und gemeinsame Nutzung von Bildern zu teilen, ist eine der Eigenschaften, die die Smartphone-Nutzungen in den letzten zehn Jahren getrieben haben. So wurden Multi-Milliarden-Dollar-Tech-Franchises wie Instagram und Pinterest geboren. Diese Fähigkeit sagt uns über uns selbst als menschliche Wesen, wir lieben Geschichten. Geschichten müssen aber nicht nur in Worte gesetzt werden. Wir können auch Bilder und Serien von Bildern verwenden, die Videos genannt werden, um unsere Geschichte zu vermitteln.

Wenn Sie ein Entwickler sind, müssen Sie die Möglichkeit, Bilder zu erfassen, oder bereits erfasste Bilder auswählen und sie in Ihre Anwendung importieren. Dann können Sie alle Arten von interessanten Dingen zu diesen Bildern machen.

Glücklicherweise für uns android sdk bietet Klassen und APIs, die wir verwenden können, um diese Fähigkeit nahtlos in unsere Anwendung zu liefern. So lernen wir in diesem Tutorial, wie man Bilder per Kamera einfangen und in einer Imageansicht zeigt. Alternativ können wir sehen, wie Sie Bilder aus der Galerie auswählen und in einer Bildansicht wiedergeben.

Beispiel-Kotlin Android Capture From Camera oder Select von ImagePicker

Wir erstellen eine App, die eine Aktivität enthält. Diese Aktivität verfügt über eine Imageansicht und zwei Schaltflächen darunter. Wenn der Benutzer auf den ersten Button klickt, werden wir die Kamera über die Absicht initiieren. Dann können wir erfassen und abbilden, und dieses Bild wird in einer Imageansicht in unserer Anwendung wiedergegeben. Der zweite Button erlaubt uns, unsere Systemgalerie zu öffnen. Aus der Galerie können wir ein Bild auswählen und haben es in unserer Imageansicht wiedergegeben.

Video-Lernprogramm

Sehen Sie sich das Video-Tutorial für weitere Details und Demo an.

Schritt 1: Erstellen Sie unser Projekt

Öffnen Sie App android studio und erstellen Sie ein neues Projekt. Wählen Sie leere Aktivität, wählen Sie Kotlin als unsere Programmiersprache. Stellen Sie sicher, dass unsere App Androidx-Artefakte unterstützt. Ich werde Android API Level 15 als meine Mindestversion verwenden.

Hier ist meine App-Level 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'
}

Sie können sehen, dass es keine spezielle Abhängigkeit gibt, die hinzugefügt werden soll.

Schritt 2: Layouts

Wir werden nur ein einziges Layout haben:

(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>

Dieses Layout enthält die folgenden Komponenten:

  1. LinearLayout -Um unsere Elemente linear vertikal oder horizontal zu bestellen.
  2. TextView-Zum Darstellen von Text
  3. ImageView-Um Bilder zu machen.
  4. Button-Um uns zu erlauben, ein Bild zu wählen oder ein Bild von der Kamera zu erfassen.

Klassen

Wir haben nur eine Klasse.

(a). MainActivity.kt

Star durch Hinzufügen von Importen:

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

Dann machen Sie unsere Klasse erweitern die AppCompatActivity:

class MainActivity : AppCompatActivity() {

In der Klasse können Sie unsere Instanzfelder definieren:

    //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

In der obigen Abbildung wird die Bildansicht unser Bild wiedergeben, die Uri ist die Uri des Bildes. btnCapture Wir können unsere Kamera damit beginnen, das Bild zu erfassen. btnChoose erlaubt uns, die Galerie zu öffnen, um das Bild zu wählen.

Anschließend erstellen Sie eine Methode, um die oben genannten Widgets zu initialisieren:

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

Dann eine Methode, um unsere Toast-Nachricht zu zeigen:

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

Als nächstes werden wir eine Methode erstellen, um unser Foto oder Bild zu erfassen:

    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)
    }

In der obigen Methode können Sie sehen, wie wir mit der Instanziierung einer Datei, die wir capturedImage aufrufen, begonnen haben. Wir haben sowohl den Ort als auch den Dateinamen übergeben.

Dann verwenden Sie die exists() Methode, die überprüft wurde, wenn eine Datei mit dem Namen, wie das erfasste Bild vorhanden ist, vorhanden ist. Wenn ja, löschen wir.

Dann erstellen wir eine neue Datei mit dem createNewFile() Verfahren. Das wir die Uri für die Akte erhalten. Beachten Sie, dass, wenn wir mit einer Build-sdk-Version von Android API Version 24 und darüber verwenden, verwenden Sie die FileProvider Klasse unter Aufruf von getUriForFile() Verfahren. Sonst benutzen wir den guten alten fromFile() Methode der Uri-Klasse.

Dann instanziieren wir unsere Absicht und startActivityForResult.

Dann um unsere Galerie zu öffnen und Bilder zu filtern:

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

Wir werden unser Bild als Bitmap wiedergeben:

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

Um unseren Bildpfad zu erhalten, verwenden wir diese Methode:

    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!!
    }

Hier erfahren Sie, wie wir unser Image auf Android API Level 19 und höher behandeln:

    @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)
    }

FULL-Code

Hier ist der vollständige Code für 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

Ressourcen

Hier sind Downlaod-und Referenzressourcen:

Nein. Site Link
1. Github Durchsuchen
2. Github Herunterladen
3. YouTube Uhr

Wechseln Sie nun zum nächsten Lernprogramm.

Beste Grüße.

Categorized in:

Tagged in: