Android应用。尝试保存图片时崩溃

时间:2018-09-28 03:58:38

标签: java android xml android-studio

我正在尝试创建一个简单的应用程序,允许用户拍摄照片,将其显示在imageview上并保存到SD卡中的文件夹中。我遵循了在此处找到的指南“ https://developer.android.com/training/camera/photobasics”,尽管经过数小时的尝试后仍无法使它正常工作。

MainActivity.java

public class MainActivity extends AppCompatActivity {
    static final int REQUEST_IMAGE_CAPTURE = 1;
    private ImageView imageView;
    String mCurrentPhotoPath;
    static final int REQUEST_TAKE_PHOTO = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        this.imageView = (ImageView)this.findViewById(R.id.imageView1);
        Button photoButton = (Button) this.findViewById(R.id.button1);
        photoButton.setOnClickListener(new View.OnClickListener() {
            @RequiresApi(api = Build.VERSION_CODES.M)
            @Override
            public void onClick(View v) {
                dispatchTakePictureIntent();
            }
        });
    }

    private void dispatchTakePictureIntent() {
        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
            File photoFile = null;
            try {
                photoFile = createImageFile();
            } catch (IOException ex) {
                // Error occurred while creating the File
            }
            if (photoFile != null) {
                Uri photoURI = FileProvider.getUriForFile(this, "com.example.android.fileprovider", photoFile);
                // error line below
                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
                startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
            }
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
        //if (requestCode == REQUEST_TAKE_PHOTO && resultCode == RESULT_OK) {
            Bundle extras = data.getExtras();
            // crashes at line below
            Bitmap imageBitmap = (Bitmap) extras.get("data");
            imageView.setImageBitmap(imageBitmap);
        }
    }

    private File createImageFile() throws IOException {
        // Create an image file name
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String imageFileName = "JPEG_" + timeStamp + "_";
        File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        File image = File.createTempFile(
                imageFileName,  /* prefix */
                ".jpg",         /* suffix */
                storageDir      /* directory */
        );

        // Save a file: path for use with ACTION_VIEW intents
        mCurrentPhotoPath = image.getAbsolutePath();
        return image;
    }


}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.nick3.nickcamera">
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-feature android:name="android.hardware.camera"
        android:required="false" />
    <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="com.example.android.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths"></meta-data>
        </provider>
    </application>

</manifest>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="213dp"
        android:layout_height="0dp"
        android:layout_marginBottom="138dp"
        android:layout_marginTop="119dp"
        app:layout_constraintBottom_toTopOf="@+id/button1"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:srcCompat="@mipmap/ic_launcher" />

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="51dp"
        android:text="Snap"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/imageView1" />

</android.support.constraint.ConstraintLayout>

file_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="my_images" path="Android/data/com.example.nick3.nickcamera/files/Pictures" />
</paths>

它似乎在Bitmap imageBitmap = (Bitmap) extras.get("data");崩溃了,我注意到该应用程序。如果删除onActivityResult不会崩溃,它将成功在imageview上显示该图像,但不会保存。

这是日志:

10-02 04:01:43.738 8977-8977/? I/ick3.nickcamer: Not late-enabling -Xcheck:jni (already on)
10-02 04:01:43.858 8977-8977/? W/ick3.nickcamer: Unexpected CPU variant for X86 using defaults: x86
10-02 04:01:44.421 8977-8977/com.example.nick3.nickcamera W/ick3.nickcamer: JIT profile information will not be recorded: profile file does not exits.
10-02 04:01:44.423 8977-8977/com.example.nick3.nickcamera I/chatty: uid=10090(com.example.nick3.nickcamera) identical 10 lines
10-02 04:01:44.423 8977-8977/com.example.nick3.nickcamera W/ick3.nickcamer: JIT profile information will not be recorded: profile file does not exits.
10-02 04:01:44.629 8977-8977/com.example.nick3.nickcamera I/InstantRun: starting instant run server: is main process
10-02 04:01:45.830 8977-8977/com.example.nick3.nickcamera W/ick3.nickcamer: Accessing hidden method Landroid/view/View;->computeFitSystemWindows(Landroid/graphics/Rect;Landroid/graphics/Rect;)Z (light greylist, reflection)
10-02 04:01:45.831 8977-8977/com.example.nick3.nickcamera W/ick3.nickcamer: Accessing hidden method Landroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V (light greylist, reflection)
10-02 04:01:46.113 8977-8977/com.example.nick3.nickcamera W/ick3.nickcamer: JNI critical lock held for 20.633ms on Thread[1,tid=8977,Runnable,Thread*=0xe975c000,peer=0x74760ee0,"main"]
10-02 04:01:46.114 8977-8977/com.example.nick3.nickcamera D/OpenGLRenderer: Skia GL Pipeline
10-02 04:01:46.874 8977-8997/com.example.nick3.nickcamera I/ConfigStore: android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasWideColorDisplay retrieved: 0
10-02 04:01:46.875 8977-8997/com.example.nick3.nickcamera I/ConfigStore: android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasHDRDisplay retrieved: 0
10-02 04:01:46.875 8977-8997/com.example.nick3.nickcamera I/OpenGLRenderer: Initialized EGL, version 1.4
10-02 04:01:46.875 8977-8997/com.example.nick3.nickcamera D/OpenGLRenderer: Swap behavior 1
10-02 04:01:46.928 8977-8997/com.example.nick3.nickcamera D/EGL_emulation: eglCreateContext: 0xe3985300: maj 3 min 0 rcv 3
10-02 04:01:46.967 8977-8997/com.example.nick3.nickcamera D/EGL_emulation: eglMakeCurrent: 0xe3985300: ver 3 0 (tinfo 0xe39832e0)
10-02 04:01:47.065 8977-8997/com.example.nick3.nickcamera D/EGL_emulation: eglMakeCurrent: 0xe3985300: ver 3 0 (tinfo 0xe39832e0)
10-02 04:01:47.794 8977-8997/com.example.nick3.nickcamera I/OpenGLRenderer: Davey! duration=1148ms; Flags=0, IntendedVsync=39220123941612, Vsync=39220523941596, OldestInputEvent=9223372036854775807, NewestInputEvent=0, HandleInputStart=39220533734500, AnimationStart=39220533799370, PerformTraversalsStart=39220534164340, DrawStart=39220536255260, SyncQueued=39220543543320, SyncStart=39220546417150, IssueDrawCommandsStart=39220551604020, SwapBuffers=39221121743290, FrameCompleted=39221275132280, DequeueBufferDuration=328000, QueueBufferDuration=1486000, 
10-02 04:01:47.873 8977-8977/com.example.nick3.nickcamera I/Choreographer: Skipped 46 frames!  The application may be doing too much work on its main thread.
10-02 04:01:47.994 8977-8997/com.example.nick3.nickcamera I/OpenGLRenderer: Davey! duration=902ms; Flags=0, IntendedVsync=39220572852382, Vsync=39221339519018, OldestInputEvent=9223372036854775807, NewestInputEvent=0, HandleInputStart=39221354746600, AnimationStart=39221354836100, PerformTraversalsStart=39221355236790, DrawStart=39221355536080, SyncQueued=39221355589860, SyncStart=39221355685110, IssueDrawCommandsStart=39221355740130, SwapBuffers=39221356778810, FrameCompleted=39221475373850, DequeueBufferDuration=1471000, QueueBufferDuration=3066000, 
10-02 04:01:52.924 8977-8997/com.example.nick3.nickcamera D/EGL_emulation: eglMakeCurrent: 0xe3985300: ver 3 0 (tinfo 0xe39832e0)
10-02 04:02:00.779 8977-8977/com.example.nick3.nickcamera D/AndroidRuntime: Shutting down VM
10-02 04:02:00.781 8977-8977/com.example.nick3.nickcamera E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.nick3.nickcamera, PID: 8977
    java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=1, result=-1, data=Intent {  }} to activity {com.example.nick3.nickcamera/com.example.nick3.nickcamera.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.os.Bundle.get(java.lang.String)' on a null object reference
        at android.app.ActivityThread.deliverResults(ActivityThread.java:4360)
        at android.app.ActivityThread.handleSendResult(ActivityThread.java:4402)
        at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:49)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:193)
        at android.app.ActivityThread.main(ActivityThread.java:6669)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858)
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.os.Bundle.get(java.lang.String)' on a null object reference
        at com.example.nick3.nickcamera.MainActivity.onActivityResult(MainActivity.java:70)
        at android.app.Activity.dispatchActivityResult(Activity.java:7454)
        at android.app.ActivityThread.deliverResults(ActivityThread.java:4353)
        at android.app.ActivityThread.handleSendResult(ActivityThread.java:4402) 
        at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:49) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1808) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loop(Looper.java:193) 
        at android.app.ActivityThread.main(ActivityThread.java:6669) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:858) 
10-02 04:02:01.004 8977-8977/com.example.nick3.nickcamera I/Process: Sending signal. PID: 8977 SIG: 9

2 个答案:

答案 0 :(得分:1)

在相机意图中通过EXTRA_OUTPUT时...您无法在onActivityResult中从意图中获取图像。您已根据相机意图在EXTRA_OUTPUT中传递了文件uri。因此,您只需访问已传递给EXTRA_OUTPUT的uri中的图片即可。

您可以使用Imageview.setImageUri(fileUri)来显示图像

答案 1 :(得分:0)

那是因为您正在设置输出路径:

takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);

执行此操作时,相机不会在extras.get("data")中返回照片位图。如果删除它,您会发现它不会崩溃。但是,当然,图像将无法保存。您可以做的就是获取该位图并将其保存到文件中。或者将图像从文件加载到imageView中,而不是试图从意图中获取它。