Android: كيفية التقاط صورة باستخدام Kotlin

بالنسبة لمقالتي الأولى في هذا النظام الأساسي ، أود أن أوضح كيف يمكنك التقاط صورة في Android باستخدام تطبيق الكاميرا والحصول على الصورة الناتجة في تطبيقك. كل هذا باستخدام Kotlin كلغة برمجة.

نحتاج أولاً إلى إنشاء مشروع جديد في Android Studio. بالنسبة لهذا المثال ، أستخدم Android Studio 2.3.3.

بمجرد إنشاء المشروع الجديد ، نحتاج إلى تعيين المشروع حتى نتمكن من البدء في العمل مع Kotlin. يمكنك القيام بذلك عن طريق اتباع الدليل في موقع Kotlin:

يوجد عدد قليل من المكتبات التي أستخدمها في هذا المشروع من أجل تبسيط بعض الخطوات ، مثل عرض الربط وعرض الصور وطلبات الأذونات:

  • لعرض ملزم اعتدت Butterknife: http://jakewharton.github.io/butterknife/
  • لطلب إذن شملت دكستر: https://github.com/Karumi/Dexter
  • لعرض الصور التي استخدمتها فريسكو: http://frescolib.org/

الخطوة التالية هي تحديد الأذونات التي يتطلبها تطبيقنا في Android Manifest. في هذه الحالة ، سنحتاج إلى android.permission.WRITE_EXTERNAL_STORAGE.

<يستخدم - إذن android: name = "android.permission.WRITE_EXTERNAL_STORAGE" />

لنقم بإنشاء تخطيط لنشاطنا الرئيسي

<؟ xml version = "1.0" encoding = "utf-8"؟>



    

    

ستبدو الشاشة هكذا:

النشاط الرئيسي

في ملف MainActivity.kt ، سنقوم بتعيين مستمع نقرات على "زر العمل العائم" حتى نتمكن من تشغيل تطبيق الكاميرا عند قيام المستخدم بالنقر عليه.

تجاوز المتعة onCreate (تم حفظه في InstanceState: Bundle؟) {
    super.onCreate (savedInstanceState)
    setContentView (R.layout.activity_main)
    ButterKnife.bind (هذا)
    fabCapturePhoto؟ .setOnClickListener {validatePermissions ()}
}

تهتم طريقة validatePermission () بالتحقق وطلب أذونات الكتابة التي يتطلبها التطبيق. في حالة منح الإذن ، سيتم تشغيل تطبيق الكاميرا عبر نية:

متعة خاصة ValidatePermissions () {
    Dexter.withActivity (هذا)
         .withPermission (Manifest.permission.WRITE_EXTERNAL_STORAGE)
         .withListener (الكائن: PermissionListener {
                تجاوز المتعة onPermissionGranted (
                  استجابة: PermissionGrantedResponse؟) {
                    launchCamera ()
                }

                تخطي المرح علىإصدار RationaleShouldBeShown (
                   إذن: PermissionRequest؟ ،
                   الرمز المميز: PermissionToken؟) {
                      AlertDialog.Builder (هذا @ MainActivity)
                            .تعيين العنوان(
                       R.string.storage_permission_rationale_title)
                            .setMessage (
                       R.string.storage_permition_rationale_message)
                            .setNegativeButton (
                       android.R.string.cancel،
                                    {الحوار ، _ ->
                                    dialog.dismiss ()
                                    رمز؟ .cancelPermissionRequest ()
                                    })
                            .setPositiveButton (android.R.string.ok،
                                    {الحوار ، _ ->
                                  dialog.dismiss ()
                                  رمز؟ .continuePermissionRequest ()
                                    })
                            .setOnDismissListener ({
                                 الرمز المميز .cancelPermissionRequest ()})
                            .تبين()
                }

                تجاوز المتعة onPermissionDenied (
                    استجابة: PermissionDeniedResponse؟) {
                       Snackbar.make (mainContainer !!،
                         R.string.storage_permission_denied_message،
                         Snackbar.LENGTH_LONG)
                       .تبين()
                }
            })
            .التحقق من()
}

ستنشئ طريقة launchCamera () مسارًا سنعبره إلى نيتنا ومن ثم ندعو إلى تطبيق الكاميرا. أيضًا ، نحتاج إلى تخزين المسار الذي أنشأناه في متغير عضو لاستخدامه لاحقًا.

متعة إطلاق خاصةكاميرا () {
    القيم val = ContentValues ​​(1)
    values.put (MediaStore.Images.Media.MIME_TYPE، "image / jpg")
    val fileUri = contentResolver
            .insert (MediaStore.Images.Media.EXTERNAL_CONTENT_URI،
                    القيم)
    val intent = Intent (MediaStore.ACTION_IMAGE_CAPTURE)
    إذا (intent.resolveActivity (packageManager)! = خالية) {
        mCurrentPhotoPath = fileUri.toString ()
        intent.putExtra (MediaStore.EXTRA_OUTPUT، fileUri)
        intent.addFlags (Intent.FLAG_GRANT_READ_URI_PERMISSION
                أو Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
        startActivityForResult (نية ، TAKE_PHOTO_REQUEST)
    }
}

بمجرد التقاط الصورة ، نحتاج إلى تطبيق onActivityResult () حتى نتمكن من معالجة وعرض الصورة التي التقطناها للتو:

تجاوز متعة onActivityResult (requestCode: Int ، resultCode: Int ،
                              البيانات: النية؟) {
    if (resultCode == Activity.RESULT_OK
           && requestCode == TAKE_PHOTO_REQUEST) {
        processCapturedPhoto ()
    } آخر {
        super.onActivityResult (requestCode ، resultCode ، data)
    }
}

نظرًا لأن الصورة الأصلية كبيرة جدًا ، فقد تؤدي إلى "نفاد الذاكرة" عندما نحاول عرضها في تطبيقنا. يقدم Fresco طريقة بسيطة لتغيير حجم الصورة قبل عرضها.

عملية المرح الخاصة CapturedPhoto () {
    val cursor = contentResolver.query (Uri.parse (mCurrentPhotoPath)،
            مجموعة (1) {android.provider.MediaStore.Images.ImageColumns.DATA} ،
            لاغٍ ، لاغٍ ، لاغٍ)
    cursor.moveToFirst ()
    val photoPath = cursor.getString (0)
    cursor.close ()
    ملف فال = ملف (photoPath)
    val uri = Uri.fromFile (ملف)

    val height = resources.getDimensionPixelSize (R.dimen.photo_height)
    عرض val = resources.getDimensionPixelSize (R.dimen.photo_width)

    طلب فال = ImageRequestBuilder.newBuilderWithSource (uri)
            .setResizeOptions (ResizeOptions (العرض ، الارتفاع))
            . البناء ()
    وحدة تحكم val = Fresco.newDraweeControllerBuilder ()
            .setOldController (imgvPhoto؟ .controller)
            .setImageRequest (طلب)
            . البناء ()
    imgvPhoto؟ .controller = تحكم
}

هذا كل شيء ، الآن يمكننا التقاط الصور وعرضها داخل التطبيق لدينا بطريقة بسيطة للغاية.

يمكنك العثور على الكود المصدري للمشروع النموذجي هنا: https://github.com/bionicwan/capturephoto