Android 默认相机崩溃

标签 android android-activity android-camera

我正在使用系统默认相机拍照并将图像保存到 SD 卡中。

该应用程序在装有 Android 6.0 的 Nexus 5 上运行良好。 但是在装有 Android 5.0.1 的三星 Galaxy S4 上,当我按“保存”时应用程序崩溃了:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.jublikon.example/com.jublikon.example.ReviewMaschine.ReviewActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'int java.lang.Integer.intValue()' on a null object reference

为什么相机 Activity 会尝试启动另一个 Activity? 它应该只保存图像和 finish() 本身。

我的捕获图像方法如下所示:

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

        fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);

        intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);

        // start the image capture Intent
        startActivityForResult(intent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);
    }

代码生成的fileUri:

file:///storage/emulated/0/Pictures/ImageDokumentation/IMG_20151214_214131.jpg

我注意到该应用程序将图像保存在本地 Samsung Galaxy S4 上,而不是保存在 SD 卡上。也许这是我犯的错误? 我意识到有时图片会被保存,有时不会。应用程序在每种情况下都会停止。

应用程序没有运行到 onActivityResult 就崩溃了。

我真的不明白我做错了什么。该应用程序可以在物理 Nexus 设备上正常运行。

编辑:因为这似乎是一个更复杂的问题,这里是 fragment 的缩短代码:

public class FragmentReview extends Fragment {

    // some initialization (...)

    private static final int CAMERA_CAPTURE_IMAGE_REQUEST_CODE = 100;
    public static final int MEDIA_TYPE_IMAGE = 1;

    private static final String IMAGE_DIRECTORY_NAME = "ImageDokumentation";

    private Uri fileUri; // file url to store image/video

    // Permission Strings
    private  static final String PERMISSION_HARDWARE_CAMERA = "android.permission.CAMERA";
    private  static final String PERMISSION_WRITE_EXTERNAL_STORAGE = "android.permission.WRITE_EXTERNAL_STORAGE";

    private static final String IMAGE_URI_BUNDLE = "fileUri";

    public FragmentReview() {

    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //Adding some data

        setRetainInstance(true);

    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putParcelable(IMAGE_URI_BUNDLE, fileUri);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        List<ReviewItem> currentData = mAdapter.getCurrentData();

        DatabaseHandler db = new DatabaseHandler(getActivity());
        Maschine updateMaschine = new Maschine();
        updateMaschine = db.getMaschineForKeyMaschineAndAnlage(getIdForSelectedAnlage(), getIdForSelectedMaschine());

        switch (item.getItemId()) {
            case R.id.action_save:

               //saving some data 

                return true;
            case R.id.action_photo:

                if (isDeviceSupportCamera()) {

                    boolean checkcamera = hasPermission(PERMISSION_HARDWARE_CAMERA);
                    boolean checkstorage = hasPermission(PERMISSION_WRITE_EXTERNAL_STORAGE);

                    if(hasPermission(PERMISSION_HARDWARE_CAMERA) == true && hasPermission(PERMISSION_WRITE_EXTERNAL_STORAGE)){

                        try {
                            captureImage();
                        } catch (Exception e) {
                            new MaterialDialog.Builder(getActivity())
                                    .title("Berechtigungen nicht aktiviert")
                                    .content("Bitte lassen Sie in den Einstellungen die notwendigen Berechtigungen zu")
                                    .positiveText("OK")
                                    .show();
                        }

                    } else {
                        new MaterialDialog.Builder(getActivity())
                                .title("Berechtigungen nicht aktiviert")
                                .content("Bitte lassen Sie in den Einstellungen die notwendigen Berechtigungen zu")
                                .positiveText("OK")
                                .show();
                    }

                } else {
                    new MaterialDialog.Builder(getActivity())
                            .title("Fehler")
                            .content("Kamera konnte nicht geöffnet werden")
                            .positiveText("OK")
                            .show();
                }

                return false;

            case R.id.action_gallery:

               // starting gallery activity

                return true;
            default:
                break;
        }
        return false;
    }

    private boolean isDeviceSupportCamera() {
        if (getActivity().getPackageManager().hasSystemFeature(
                PackageManager.FEATURE_CAMERA)) {
            // this device has a camera
            return true;
        } else {
            // no camera on this device
            return false;
        }

    }

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

        fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);

        intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);

        // start the image capture Intent
        startActivityForResult(intent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);
    }

    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) + File.separator + IMAGE_DIRECTORY_NAME);

        // Create the storage directory if it does not exist
        if (!mediaStorageDir.exists()) {
            mediaStorageDir.mkdirs();

            if (!mediaStorageDir.mkdirs()) {
                Log.d(IMAGE_DIRECTORY_NAME, "Fehler beim Erstellen der Datei: "
                        + IMAGE_DIRECTORY_NAME + " directory");
                return null;
            }
        }

        // Create a media file name
        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 {
            return null;
        }

        return mediaFile;
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {

        try{

            // if the result is capturing Image
            if (requestCode == CAMERA_CAPTURE_IMAGE_REQUEST_CODE) {
                if (resultCode == Activity.RESULT_OK) {


                    DatabaseHandler db = new DatabaseHandler(getActivity());


                    db.addImage(getIdForSelectedAnlage(), getIdForSelectedMaschine(), fileUri.toString());

                    Toast.makeText(getActivity(),
                            "Bild wurde gespeichert" + fileUri.toString(), Toast.LENGTH_SHORT)
                            .show();

                    //previewCapturedImage();
                } else if (resultCode == Activity.RESULT_CANCELED) {
                    // user cancelled Image capture
                /* Toast.makeText(getActivity(),
                        "User cancelled image capture", Toast.LENGTH_SHORT)
                        .show(); */
                } else {
                    // failed to capture image
                /* Toast.makeText(getActivity(),
                        "Sorry! Failed to capture image", Toast.LENGTH_SHORT)
                        .show(); */
                }
            }

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

            Toast.makeText(getActivity(),
                    "Datei konnte nicht in Datenbank gespeichert werden", Toast.LENGTH_SHORT)
                    .show();
        }


    }

    public boolean hasPermission(String permission)
    {
        try {
            PackageInfo info = getActivity().getPackageManager().getPackageInfo(getActivity().getPackageName(), PackageManager.GET_PERMISSIONS);
            if (info.requestedPermissions != null) {
                for (String p : info.requestedPermissions) {
                    if (p.equals(permission)) {
                        return true;
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
}

最佳答案

我遇到过这个问题。 带有 os 5.0.1 的 Samsung Galaxy S4 有特定问题,当相机流打开时,屏幕方向多次更改,我们的 Activity 正在重新创建,这是根本原因。

尝试保存和恢复imageUri:

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (savedInstanceState != null) {
        imageUri = savedInstanceState.getParcelable(IMAGE_URI_BUNDLE);
    }
}
@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putParcelable(IMAGE_URI_BUNDLE, imageUri);
}

你应该在启动相机 Intent 之前初始化 imageUri

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

    imageUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);

    intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri );

    // start the image capture Intent
    startActivityForResult(intent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE);
}

在 fragment 中从相机捕获图像时要小心,在这种情况下,您还应该在 fragment 中保存和恢复 imageUri 并添加到 Activity 中:

fragment.setRetainInstance(true);

关于Android 默认相机崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34276274/

相关文章:

android - 在sqlite数据库中添加新表

android - android eclipse 中的 float 操作按钮,点击后将导航到另一个 Activity

java - 套接字未在 Android 上关闭

android - Google 新登录,未调用 onActivityResult()

Android - 确保通过 Camera Intent 拍照时保留照片方向?

android - 带有 RTL 布局的 Edittext 中的 setError 无法正常工作

android - 没有 EditText 和检测按键的软键盘

android - ActionBarCompat 自定义样式

android - 在 Zxing 条码应用程序中出现相机错误

android - 超出最小未出列缓冲区计数