尝试拍照/录制视频时应用程序崩溃

时间:2015-11-04 14:22:12

标签: java android

我刚刚遵循了这个指南:http://www.androidhive.info/2013/09/android-working-with-camera-api/

尝试为我的应用创建相机功能,但是当我点击拍照或录制视频(其中一个按钮)时,它会在我身上崩溃。我已经检查了代码,但我似乎无法找到错误。

CameraActivity.java:

package com.example.frederik.snapsule;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import android.widget.VideoView;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

public class CameraActivity extends AppCompatActivity {

    //Activity request codes
    private static final int CAMERA_CAPTURE_IMAGE_REQUEST_CODE = 100;
    private static final int CAMERA_CAPTURE_VIDEO_REQUEST_CODE = 200;
    public static final int MEDIA_TYPE_IMAGE = 1;
    public static final int MEDIA_TYPE_VIDEO = 2;

    //Storing of content
    private static final String IMAGE_DIRECTORY_NAME = "Hello Camera";

    private Uri fileUri; //Content url storing

    private ImageView imgPreview;
    private VideoView videoPreview;
    private Button btnCapturePicture, btnRecordVideo;

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

        imgPreview = (ImageView) findViewById(R.id.imgPreview);
        videoPreview = (VideoView) findViewById(R.id.videoPreview);
        btnCapturePicture = (Button) findViewById(R.id.btnCapturePicture);
        btnRecordVideo = (Button) findViewById(R.id.btnRecordVideo);

        btnCapturePicture.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                captureImage();
            }
        });

        btnRecordVideo.setOnClickListener(new View.OnClickListener() {

            public void onClick(View v) {
                recordVideo();
            }
        });
    }

    private void captureImage() {
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

        fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);

        intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);

        startActivityForResult(intent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);
    }

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        // if the result is capturing Image
        if (requestCode == CAMERA_CAPTURE_IMAGE_REQUEST_CODE) {
            // code to check capture image response
        } else if (requestCode == CAMERA_CAPTURE_VIDEO_REQUEST_CODE) {
            if (resultCode == RESULT_OK) {
                // video successfully recorded
                // preview the recorded video
                previewVideo();
            } else if (resultCode == RESULT_CANCELED) {
                // user cancelled recording
                Toast.makeText(getApplicationContext(),
                        "User cancelled video recording", Toast.LENGTH_SHORT)
                        .show();
            } else {
                // failed to record video
                Toast.makeText(getApplicationContext(),
                        "Sorry! Failed to record video", Toast.LENGTH_SHORT)
                        .show();
            }
        }
    }

    private void previewCapturedImage() {
        try {
            videoPreview.setVisibility(View.GONE);

            imgPreview.setVisibility(View.VISIBLE);

            BitmapFactory.Options options = new BitmapFactory.Options();

            options.inSampleSize = 8;

            final Bitmap bitmap = BitmapFactory.decodeFile(fileUri.getPath(),
                    options);

            imgPreview.setImageBitmap(bitmap);
        } catch (NullPointerException e) {
            e.printStackTrace();
        }
    }

    private void recordVideo() {
        Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);

        fileUri = getOutputMediaFileUri(MEDIA_TYPE_VIDEO);

        intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);

        intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);

        startActivityForResult(intent, CAMERA_CAPTURE_VIDEO_REQUEST_CODE);
    }

    private void previewVideo() {
        try {
            imgPreview.setVisibility(View.GONE);

            videoPreview.setVisibility(View.VISIBLE);
            videoPreview.setVideoPath(fileUri.getPath());

            videoPreview.start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);

        outState.putParcelable("file_uri", fileUri);
    }

    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);

        fileUri = savedInstanceState.getParcelable("file_uri");
    }

    public Uri getOutputMediaFileUri(int type) {
        return Uri.fromFile(getOutputMediaFile(type));
    }

    private static File getOutputMediaFile(int type) {
        File mediaStorageDir = new File(
                Environment
                        .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
                IMAGE_DIRECTORY_NAME);

        if (!mediaStorageDir.exists()) {
            if (!mediaStorageDir.mkdirs()) {
                Log.d(IMAGE_DIRECTORY_NAME, "Oops! Failed create " + IMAGE_DIRECTORY_NAME + " directory" );
                return null;
            }
        }

        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss",
                Locale.getDefault()).format(new Date());
        File mediaFile;
        if (type == MEDIA_TYPE_IMAGE) {
            mediaFile = new File(mediaStorageDir.getPath() + File.separator
            + "IMG_" + timeStamp + ".jpg");
        } else if (type == MEDIA_TYPE_VIDEO) {
            mediaFile = new File(mediaStorageDir.getPath() + File.separator
            + "VID_" + timeStamp + ".mp4");
        } else {
            return null;
        }

        return mediaFile;
    }
}

我的logcat:

11-04 15:18:42.487 23065-23065/com.example.frederik.snapsule E/AndroidRuntime: FATAL EXCEPTION: main
11-04 15:18:42.487 23065-23065/com.example.frederik.snapsule E/AndroidRuntime: Process: com.example.frederik.snapsule, PID: 23065
11-04 15:18:42.487 23065-23065/com.example.frederik.snapsule E/AndroidRuntime: java.lang.NullPointerException: file
11-04 15:18:42.487 23065-23065/com.example.frederik.snapsule E/AndroidRuntime:     at android.net.Uri.fromFile(Uri.java:452)
11-04 15:18:42.487 23065-23065/com.example.frederik.snapsule E/AndroidRuntime:     at com.example.frederik.snapsule.CameraActivity.getOutputMediaFileUri(CameraActivity.java:161)
11-04 15:18:42.487 23065-23065/com.example.frederik.snapsule E/AndroidRuntime:     at com.example.frederik.snapsule.CameraActivity.captureImage(CameraActivity.java:72)
11-04 15:18:42.487 23065-23065/com.example.frederik.snapsule E/AndroidRuntime:     at com.example.frederik.snapsule.CameraActivity.access$000(CameraActivity.java:26)
11-04 15:18:42.487 23065-23065/com.example.frederik.snapsule E/AndroidRuntime:     at com.example.frederik.snapsule.CameraActivity$1.onClick(CameraActivity.java:57)
11-04 15:18:42.487 23065-23065/com.example.frederik.snapsule E/AndroidRuntime:     at android.view.View.performClick(View.java:5198)
11-04 15:18:42.487 23065-23065/com.example.frederik.snapsule E/AndroidRuntime:     at android.view.View$PerformClick.run(View.java:21147)
11-04 15:18:42.487 23065-23065/com.example.frederik.snapsule E/AndroidRuntime:     at android.os.Handler.handleCallback(Handler.java:739)
11-04 15:18:42.487 23065-23065/com.example.frederik.snapsule E/AndroidRuntime:     at android.os.Handler.dispatchMessage(Handler.java:95)
11-04 15:18:42.487 23065-23065/com.example.frederik.snapsule E/AndroidRuntime:     at android.os.Looper.loop(Looper.java:148)
11-04 15:18:42.487 23065-23065/com.example.frederik.snapsule E/AndroidRuntime:     at android.app.ActivityThread.main(ActivityThread.java:5417)
11-04 15:18:42.487 23065-23065/com.example.frederik.snapsule E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Native Method)
11-04 15:18:42.487 23065-23065/com.example.frederik.snapsule E/AndroidRuntime:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
11-04 15:18:42.487 23065-23065/com.example.frederik.snapsule E/AndroidRuntime:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

我猜这是Uri的一个问题,但我不确定。

此外,预览未显示

2 个答案:

答案 0 :(得分:0)

你的方法

File getOutputMediaFile(int type)

它返回null,你有2个return null;语句。

在调用Uri.fromFile()

之前,您应该进行空检查

修改

只需更改此代码以消除崩溃,但它仍然会失败,您需要修复原始原因。

public Uri getOutputMediaFileUri(int type) {
    File f = getOutputMediaFile(type);
    if(f != null)
        return Uri.fromFile(f);
    else{
    //Show some error message
    return null;
    }
}

希望这有帮助。

答案 1 :(得分:0)

它是第161行的空指针异常。 显然,您将null交给Uri.fromFile()。 因此getOutputMediaFile(int type)会返回null

如果您看到"糟糕,可能就是这种情况!创建失败"在你的日志中。 如果type既不是MEDIA_TYPE_IMAGE也不是MEDIA_TYPE_VIDEO,可能就是这种情况。 如果new File(...)返回null,则可能是这种情况。

您是否尝试调试该方法?