Kotlin Android Capture von Kamera oder Pick Image
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:
- LinearLayout -Um unsere Elemente linear vertikal oder horizontal zu bestellen.
- TextView-Zum Darstellen von Text
- ImageView-Um Bilder zu machen.
- 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:
| --- |
|---|
Wechseln Sie nun zum nächsten Lernprogramm.
Beste Grüße.