Камера "Bitmap imageBitmap = (Bitmap) extras.get (" data ");" выдает ошибку Nullpointer

Я слежу за обучающими программами разработчиков Android на камере здесь: https://developer.android.com/training/camera/photobasics#java

Однако я получаю ошибку в методе

onActivityResult:,java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.os.Bundle.get(java.lang.String)' on a null object reference

Эта строка дает ошибку:

Bitmap imageBitmap = (Bitmap) extras.get("data");

Как-то, когда я закомментировал эту строку, приложение работает:

takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);

Весь мой код находится здесь: https://github.com/europa9/EanScannerForAndroid

MainActivity.java

package one.askit.eanscanner;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.icu.text.SimpleDateFormat;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v4.content.FileProvider;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import java.io.File;
import java.io.IOException;
import java.util.Date;

public class MainActivity extends AppCompatActivity {
    static final int REQUEST_IMAGE_CAPTURE = 1;
    static final int REQUEST_TAKE_PHOTO = 1;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Permission
        checkPermissionExternalRead();
        checkPermissionExternalWrite();
        checkPermissionCamera();

        // Listeners
        listeners();

        FrameLayout frameLayoutCameraPreview = findViewById(R.id.frameLayoutCameraPreview);
        frameLayoutCameraPreview.setVisibility(View.GONE);

    }

    /*- Check permission Read ------------------------------------------------------------------- */
    // Pops up message to user for reading
    private void checkPermissionExternalRead(){
        int MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE = 1;
        if (checkSelfPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {

            // Should we show an explanation?
            if (shouldShowRequestPermissionRationale(
                    android.Manifest.permission.READ_EXTERNAL_STORAGE)) {
                // Explain to the user why we need to read the contacts
            }

            requestPermissions(new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE},
                    MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE);

            // MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE is an
            // app-defined int constant that should be quite unique

            return;
        }
    } // checkPermissionRead

    /*- Check permission Write ------------------------------------------------------------------ */
    // Pops up message to user for writing
    private void checkPermissionExternalWrite(){
        int MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE = 1;
        if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {

            // Should we show an explanation?
            if (shouldShowRequestPermissionRationale(
                    android.Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                // Explain to the user why we need to read the contacts
            }

            requestPermissions(new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE},
                    MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE);

            // MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE is an
            // app-defined int constant that should be quite unique

            return;
        }
    } // checkPermissionWrite

    /*- Check permission Camera ----------------------------------------------------------------- */
    public void checkPermissionCamera(){
        int MY_PERMISSIONS_REQUEST_CAMERA = 1;
        if (checkSelfPermission(Manifest.permission.CAMERA)
                != PackageManager.PERMISSION_GRANTED) {

            // Should we show an explanation?
            if (shouldShowRequestPermissionRationale(
                    Manifest.permission.CAMERA)) {
                // Explain to the user why we need to read the contacts
            }

            requestPermissions(new String[]{android.Manifest.permission.CAMERA},
                    MY_PERMISSIONS_REQUEST_CAMERA);

            // MY_PERMISSIONS_REQUEST_READ_EXTERNAL_STORAGE is an
            // app-defined int constant that should be quite unique

            return;
        }
    } // checkPermissionInternalRead


    public void listeners(){
        Button buttonScan = findViewById(R.id.buttonScan);
        buttonScan.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                buttonScanClicked();
            }
        });

    }
    public void buttonScanClicked(){
        // Scan text
        TextView TextViewScan = findViewById(R.id.TextViewScan);
        TextViewScan.setText("Now scanning");

        // Take picture
        dispatchTakePictureIntent();
    }

    private void dispatchTakePictureIntent() {
        Intent picIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE).addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);

        String file_path = Environment.getExternalStorageDirectory().toString() +
                "/" + this.getResources().getString(R.string.app_name);

        File dir = new File(file_path);
        if (!dir.exists())
            dir.mkdirs();
        // IMAGE_PATH = new File(dir, mContext.getResources().getString(R.string.app_name) + AppConstants.USER_ID + System.currentTimeMillis() + ".png");

        File IMAGE_PATH = new File(dir, this.getResources().getString(R.string.app_name) + System.currentTimeMillis() + ".png");

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            picIntent.putExtra(MediaStore.EXTRA_OUTPUT, FileProvider.getUriForFile(this, this.getPackageName() + ".fileprovider", IMAGE_PATH));
        }
        else {
            picIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(IMAGE_PATH));
        }

        startActivityForResult(picIntent, REQUEST_TAKE_PHOTO);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
            Bundle extras = data.getExtras();
            if (extras != null) {
                //Do your logic
                Bitmap imageBitmap = (Bitmap) extras.get("data");
                ImageView imageViewScanPreview = findViewById(R.id.imageViewScanPreview);
                imageViewScanPreview.setImageBitmap(imageBitmap);
            } else {
                //Do something else
                Toast.makeText(this, "Its null!", Toast.LENGTH_LONG).show();
            }

        }
    }

}

activity_main.xml

<?xml version = "1.0" encoding = "utf-8"?>
<LinearLayout
    xmlns:android = "http://schemas.android.com/apk/res/android"
    xmlns:app = "http://schemas.android.com/apk/res-auto"
    android:orientation = "vertical"
    android:layout_width = "match_parent"
    android:layout_height = "match_parent">

    <FrameLayout
        android:id = "@+id/frameLayoutCameraPreview"
        android:layout_width = "match_parent"
        android:layout_height = "match_parent"
        android:layout_weight = "1" />

    <ImageView
        android:id = "@+id/imageViewScanPreview"
        android:layout_width = "wrap_content"
        android:layout_height = "wrap_content"
        app:srcCompat = "?attr/colorAccent" />

    <TextView
        android:id = "@+id/TextViewScan"
        android:layout_width = "match_parent"
        android:layout_height = "wrap_content"
        android:text = "Doint nothing"></TextView>

    <Button
        android:id = "@+id/buttonScan"
        android:layout_width = "wrap_content"
        android:layout_height = "wrap_content"
        android:layout_gravity = "center"
        android:text = "Scan" />
</LinearLayout>

AndroidManifest.xml

<?xml version = "1.0" encoding = "utf-8"?>
<manifest xmlns:android = "http://schemas.android.com/apk/res/android"
    package = "one.askit.eanscanner">

    <uses-feature android:name = "android.hardware.camera" android:required = "true" />
    <uses-permission android:name = "android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name = "android.permission.WRITE_EXTERNAL_STORAGE" />



    <application
        android:allowBackup = "true"
        android:icon = "@mipmap/ic_launcher"
        android:label = "@string/app_name"
        android:roundIcon = "@mipmap/ic_launcher_round"
        android:supportsRtl = "true"
        android:theme = "@style/AppTheme">
        <activity android:name = ".MainActivity">
            <intent-filter>
                <action android:name = "android.intent.action.MAIN" />

                <category android:name = "android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <provider
            android:name = "android.support.v4.content.FileProvider"
            android:authorities = "${applicationId}.fileprovider"
            android:exported = "false"
            android:grantUriPermissions = "true">
            <meta-data
                android:name = "android.support.FILE_PROVIDER_PATHS"
                android:resource = "@xml/file_paths" />
        </provider>

    </application>

</manifest>

file_paths.xml

<?xml version = "1.0" encoding = "utf-8"?>
<paths xmlns:android = "http://schemas.android.com/apk/res/android">
    <external-path name = "images" path = "."/>
    <external-path name = "external_files" path = "."/>
</paths>

поскольку вы используете личную папку приложений для хранения изображений, вам необходимо использовать <files-path> вместо <external-path>

karan 02.01.2019 12:53
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
2
1 406
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Измените свой file provider, как показано ниже

    <provider
        android:name = "android.support.v4.content.FileProvider"
        android:authorities = "${applicationId}.fileprovider"
        android:exported = "false"
        android:grantUriPermissions = "true">
        <meta-data
            android:name = "android.support.FILE_PROVIDER_PATHS"
            android:resource = "@xml/file_paths" />
    </provider>

И ваш file_path.xml будет как ниже

<?xml version = "1.0" encoding = "utf-8"?>
<paths xmlns:android = "http://schemas.android.com/apk/res/android">
    <external-path name = "images" path = "."/>

    <external-path name = "external_files" path = "."/>

</paths>

Для захвата изображения используйте этот Intent

  Intent picIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE).addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);


        String file_path = Environment.getExternalStorageDirectory().toString() +
                "/" + mContext.getResources().getString(R.string.app_name);

        File dir = new File(file_path);
        if (!dir.exists())
            dir.mkdirs();
       // IMAGE_PATH = new File(dir, mContext.getResources().getString(R.string.app_name) + AppConstants.USER_ID + System.currentTimeMillis() + ".png");

        IMAGE_PATH = new File(dir, mContext.getResources().getString(R.string.app_name) + System.currentTimeMillis() + ".png");

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            picIntent.putExtra(MediaStore.EXTRA_OUTPUT, FileProvider.getUriForFile(mContext, mContext.getPackageName()+".fileprovider", IMAGE_PATH));
        }
        else {
            picIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(IMAGE_PATH));
        }

        ((Activity) mContext).startActivityForResult(picIntent, CAMERA_REQUEST);

А внутри onActivityREsult вам нужно изменить код следующим образом

@Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        int cropperType = 1;
        if (requestCode == REQUEST_IMAGE_CAPTURE) {

            switch (resultCode) {
                case Activity.RESULT_OK:

                     String imagePAth= Uri.fromFile(IMAGE_PATH);
                GlideApp.with(this).load(imagePAth).diskCacheStrategy(DiskCacheStrategy.ALL).skipMemoryCache(false).
                        placeholder(R.drawable.default_picture).error(R.drawable.default_picture).dontAnimate().into(YOUR_IMAGEVIEW);

                    break;
                case Activity.RESULT_CANCELED:

                    break;
            }
        }

    } 

И если вы хотите, чтобы Bitmap от onActivityResult, вам нужно сослаться на эту ссылку кликните сюда

"Связать extras = data.getExtras ();" все еще остается нулевым после съемки.

Europa 02.01.2019 12:40

Вы сменили поставщика, как я предлагал

Ravindra Kushwaha 02.01.2019 12:40

да. Я их обновил. Когда я закомментирую эту строку, приложение работает: «takePictureIntent.putExtra (MediaStore.EXTRA_OUTPUT, photoURI);»

Europa 02.01.2019 12:42

Подождите, я обновляю насвер

Ravindra Kushwaha 02.01.2019 12:42

Должен ли я использовать намерение как новый класс Java? Или это метод моей основной деятельности?

Europa 02.01.2019 12:47

В методе вы можете использовать это

Ravindra Kushwaha 02.01.2019 12:47

Почти, однако он дает новую ошибку: «2019-01-02 12: 53: 59.097 2315-2315 /? E / CAM_StateSavePic: исключение при сохранении результата в URI: Optional.of (content: //one.askit.eanscanner. fileprovider / images / EanScanner / EanSca‌ nner1546430035588.pn‌ g) java.io.FileNotFoundException: ошибка открытия: ENOENT (такого файла или каталога нет) »

Europa 02.01.2019 12:54

Я обновил код вашим ответом. Также я проверяю <uses-feature android: name = "android.hardware.camera" android: required = "true" /> <uses-permission android: name = "android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android: name = "android.permission.WRITE_EXTERNAL_STORAGE" />

Europa 02.01.2019 13:16

Вы также можете использовать <uses-permission android:name = "android.permission.CAMERA" android:required = "true" /> и <uses-feature android:name = "android.hardware.camera.autofocus" android:required = "false" /> <uses-feature android:name = "android.hardware.camera.flash" android:required = "false" />

Ravindra Kushwaha 02.01.2019 13:29

Я обновил код onActivityResult, пожалуйста, проверьте его один раз

Ravindra Kushwaha 02.01.2019 13:32

Спасибо. Внутри onActivityResult я добавил это, и теперь оно работает: if (IMAGE_PATH.exists ()) {Bitmap myBitmap = BitmapFactory.decodeFile (IMAGE_PATH.getAbsolutePath ()); ImageView imageViewScanPreview = (ImageView) findViewById (R.id.imageViewScanPreview); imageViewScanPreview.setImageBitmap (myBitmap); }

Europa 02.01.2019 13:52

Рад помочь тебе сделать @Europa .. Оставайся довольным кодированием

Ravindra Kushwaha 02.01.2019 14:06

Есть разные способы получить растровое изображение с камеры.

Вы пытаетесь получить растровое изображение из дополнительных материалов, которых нет. Поскольку вы передаете значение null в Bitmap, ошибка возникает в момент доступа к данным, а не в тот момент, когда вы пытаетесь работать с растровым изображением.

Если вы предоставляете выходной URI через takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);, большинство телефонов Android сохранят фотографию с этим URI, и вам необходимо получить доступ к растровому изображению через файл, который был там сохранен. Если вы удалите URI, фотография будет добавлена ​​в Intent, поэтому код работает, если вы удалите эту строку.

Другие вопросы по теме