2015-12-14 133 views
1

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

该应用在Nexus 5个优良与Android 6.0。 但在三星Galaxy S4搭载Android 5.0.1应用程序崩溃,当我按“保存”这个问题:

了java.lang.RuntimeException:无法启动活动 ComponentInfo {com.jublikon.example/com.jublikon.example.ReviewMaschine.ReviewActivity}: 显示java.lang.NullPointerException:尝试上的空对象引用

调用虚拟方法 'INT java.lang.Integer.intValue()' 为什么在相机活动尝试启动另一个活动? 它应该只保存图像并完成()本身。

我的捕捉图像的方法看起来像这样:

文件:

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所用代码生成///storage/emulated/0/Pictures/ImageDokumentation/IMG_20151214_214131.jpg

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

应用崩溃,而不会在onActivityResult。

我真的不明白我做错了什么。该应用程序可以在物理Nexus设备上正常工作而不会出现任何问

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

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; 
    } 
} 

回答

2

我已经遇到了这个问题。 与os 5.0.1的三星Galaxy S4具有特定的问题,当相机流打开,屏幕方向多次更改,并且我们的活动正在重新创建时,这是根本原因。

尝试保存和恢复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); 
} 

你应该开始相机意图之前初始化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); 
} 

要当心,在片段从相机拍摄的图像,在这种情况下,你也应该保存并恢复imageUri的片段并添加活动:

fragment.setRetainInstance(true); 
+0

我已将您的建议添加到我的代码中。但它仍然给出同样的问题。也许我做错了,出于某种原因......为了展示我已经完成的工作,我已经将frament的代码添加到了我的上一篇文章中 – jublikon

+0

您是否添加了将imageUri恢复到onCreate的代码?看看我的例子onCreate()和你的onCreate,它是不同的@jublikon – northerngirl

+1

Rootcause:多次重新创建活动,你的imageUri为null。你需要保存在Bundle中。 您也可以在AndroidManifest.xml文件中为您的活动添加可选属性:android:configChanges =“orientation | screenSize” – northerngirl

0

这是您的activty?包和活动名称:

com.jublikon.example.ReviewMaschine.ReviewActivity

NPE从withing它正在添加

它看起来像这个装置的活动正在相机应用程序之前销毁已完成。您的活动可能会因各种原因而遭到破坏 - 即。相机应用程序只能在风景中使用,或者需要大量的内存并破坏您的活动。

现在,回国后 - onActivityResult之前,Android将调用的onCreate,并在onStart你的活动。所以这是你应该把断点放在你从哪里读空值对象的地方。

0

随着看看你的代码,好像活动被杀真正开始之前。

检查相机的Landscapemode工程或尝试运行的亚行日志,看看如果应用程序崩溃,因为大量内存使用或一些怪异的编码的东西。你可以做到这一点与

adb logcat -s com.jublikon.example.ReviewMaschine.ReviewActivity

之后 - 如果你发现了没有崩溃自己,张贴在这里,我会尽力帮助你! :) 并检查你的应用程序在哪里启动。

编辑: 尝试在Eclispe中使用断点并调试你的东西! :)

+0

我禁用了应用程序中的横向模式。关键是,相机开始工作。按下保存按钮后,拍摄照片后活动会崩溃。根据你的建议,我有一个问题:电话应该能够以完整的质量保存图像吗?沉重的内存使用来自哪里? – jublikon