在 onActivityResult 中使用相机时出现问题

Posted

技术标签:

【中文标题】在 onActivityResult 中使用相机时出现问题【英文标题】:Trouble working with the camera in onActivityResult 【发布时间】:2018-06-06 22:37:38 【问题描述】:

我有两个选项“选择照片”和“拍照” - 我的选择照片功能可以正常工作,但在拍照时遇到问题。主要是保存后的图像显示在我的图像视图中。

定义了我的照片位置:

public class photoActivity extends Activity    
      private String photoPath;
      private ImageView imgView;
... 

我的摄像头监听器:

bPicFromCam.setOnClickListener(new View.OnClickListener() 
        public void onClick(View v) 

            String state = Environment.getExternalStorageState();

            if (Environment.MEDIA_MOUNTED.equals(state)) 

                long captureTime = System.currentTimeMillis();

                photoPath = Environment.getExternalStorageDirectory() + "/MYAPP" + captureTime + ".jpg";

                getPicFromCam(v);
            
            else

                Toast.makeText(getApplicationContext(),
                    "Sorry there is a problem accessing your SDCard, " +
                    "please select a picture from your gallery instead.", Toast.LENGTH_LONG).show();
            

        
    );

然后我的代码启动相机意图(注意photoPath是正确的):

    public void getPicFromCam(View view)

    System.out.println("photoPath: " + photoPath);
    //Outputs the CORRECT location!

    try

        Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
        File photo = new File(photoPath);
        intent.putExtra(MediaStore.EXTRA_OUTPUT,
                Uri.fromFile(photo));
        imageUri = Uri.fromFile(photo);
        startActivityForResult(Intent.createChooser(intent, "Capture Image"), CAPTURE_IMAGE);

     catch (Exception e) 
        Toast.makeText(getApplicationContext(),
                getString(R.string.exception_message),
                Toast.LENGTH_LONG).show();
        Log.e(e.getClass().getName(), e.getMessage(), e);
    

好吧,到目前为止一切都很好 - 拍摄照片并将图像保存到指定位置。

现在我正在尝试在我的图像视图中显示图像(然后可以在用户确认其良好后上传)。

我的 onActivityResult:

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

    switch (requestCode) 
    case PICK_IMAGE:
        if (resultCode == Activity.RESULT_OK) 
            //THIS WORKS
        
        break;

    case CAPTURE_IMAGE:         

        if (resultCode == RESULT_CANCELED) 
          Toast toast = Toast.makeText(this,"Canceled, no photo selected.", 1000);
          toast.show();
          return;
         

        if (requestCode == CAPTURE_IMAGE && resultCode == RESULT_OK)
         

            try 

                System.out.println("photoPath " + photoPath);
                //This is NULL!!!  And my problem, halp!

                BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();  
                bitmapOptions.inSampleSize = 6;  
                bitmap = BitmapFactory.decodeFile(photoPath, bitmapOptions);

                imgView.setImageBitmap(bitmap);


             catch (Exception e) 
                Toast.makeText(getApplicationContext(), "Internal error",
                        Toast.LENGTH_LONG).show();
                Log.e(e.getClass().getName(), e.getMessage(), e);

            

         

        break;
    default:
    

这就是我目前正在尝试的方式,但我也尝试在我的 onActivityResult 中使用以下内容:

bitmap = (Bitmap) data.getExtras().get("data");

但每次我尝试上述方法的变体时,我都会得到一个 NPE。

编辑:

    03-11 19:28:56.319: ERROR/java.lang.NullPointerException(16391): null
03-11 19:28:56.319: ERROR/java.lang.NullPointerException(16391): java.lang.NullPointerException
03-11 19:28:56.319: ERROR/java.lang.NullPointerException(16391):     at com.myco.photoapp.SelectPhoto.onActivityResult(SelectPhoto.java:277)
03-11 19:28:56.319: ERROR/java.lang.NullPointerException(16391):     at android.app.Activity.dispatchActivityResult(Activity.java:3890)
03-11 19:28:56.319: ERROR/java.lang.NullPointerException(16391):     at android.app.ActivityThread.deliverResults(ActivityThread.java:3511)
03-11 19:28:56.319: ERROR/java.lang.NullPointerException(16391):     at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3115)
03-11 19:28:56.319: ERROR/java.lang.NullPointerException(16391):     at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3143)
03-11 19:28:56.319: ERROR/java.lang.NullPointerException(16391):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2684)
03-11 19:28:56.319: ERROR/java.lang.NullPointerException(16391):     at android.app.ActivityThread.access$2300(ActivityThread.java:125)
03-11 19:28:56.319: ERROR/java.lang.NullPointerException(16391):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
03-11 19:28:56.319: ERROR/java.lang.NullPointerException(16391):     at android.os.Handler.dispatchMessage(Handler.java:99)
03-11 19:28:56.319: ERROR/java.lang.NullPointerException(16391):     at android.os.Looper.loop(Looper.java:123)
03-11 19:28:56.319: ERROR/java.lang.NullPointerException(16391):     at android.app.ActivityThread.main(ActivityThread.java:4627)
03-11 19:28:56.319: ERROR/java.lang.NullPointerException(16391):     at java.lang.reflect.Method.invokeNative(Native Method)
03-11 19:28:56.319: ERROR/java.lang.NullPointerException(16391):     at java.lang.reflect.Method.invoke(Method.java:521)
03-11 19:28:56.319: ERROR/java.lang.NullPointerException(16391):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:858)
03-11 19:28:56.319: ERROR/java.lang.NullPointerException(16391):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
03-11 19:28:56.319: ERROR/java.lang.NullPointerException(16391):     at dalvik.system.NativeStart.main(Native Method)

NPE 出现在以下情况:

//below is line 277
String result = data.toURI();

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

                bitmapOptions.inSampleSize = 6;  
                bitmap = BitmapFactory.decodeFile(result, bitmapOptions);

【问题讨论】:

天哪,晚上 9 点快到了…… 嗨,bMon..我面临的问题和你一模一样。你能否更新你的答案..我真的很奇怪..如果你能看到我的post..你的答案真的会帮帮我..+1 你的问题 【参考方案1】:

当相机 Activity 关闭时,您的 Activity 可能正在被销毁并重新创建。也许尝试在 onSaveInstanceState 中将 photoPath 保存到 Bundle 中,然后在 onCreate 中将其取出(确保在这样做时检查 onCreate 中的空值)?

【讨论】:

嗨 jjb .. 我也面临同样的问题.. 你能否更新你的答案如何做到这一点.. +1 回答 问题是当另一个活动(在这种情况下是相机)启动时,活动可能会被破坏。您可以在 onSaveInstanceState 中保存信息,以恢复用户在您开始备份时所做的事情。 developer.android.com/reference/android/app/Activity.html 中的文档有很好的描述。【参考方案2】:

我无法使用数据。但我认为你需要改变如下

照片成为一般变量。

intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photo));

所以,你必须从这个文件夹中取出它:

Bitmap photo = Media.getBitmap(getContentResolver(), Uri.fromFile(photo) );

我按照您的代码进行更改。

【讨论】:

EXTRA_OUTPUT 和 get("data") 是互斥的,根据MediaStore.ACTION_IMAGE_CAPTURE 的官方文档:如果 EXTRA_OUTPUT 不存在,则将小尺寸图像作为 Bitmap 对象返回额外的字段【参考方案3】:

基本上,使用

intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photo));

效果很好

在放入 imageView 之前,请确保您压缩了图像,因为以这种方式保存时图像非常大。

int newWidth = bm.getWidth();
int newHeight = bm.getHeight();
while(newWidth > 300)
    newWidth = newWidth/2;
newHeight = newHeight/2;

mImagePlaceHolder.setImageBitmap(Bitmap.createScaledBitmap(bm, newWidth, newHeight, false));

【讨论】:

【参考方案4】:

我在这个问题上苦苦挣扎,并找到了另一个解决方案: 只需使用这样的代码:

Bitmap bitmap = data.getExtras().getParcelable("data");

你可以得到位图。

【讨论】:

以上是关于在 onActivityResult 中使用相机时出现问题的主要内容,如果未能解决你的问题,请参考以下文章

Android:使用相机意图时应用程序在 onActivityResult 上崩溃

使用相机意图时未调用 OnActivityResult()?

启动相机意图时未调用 onActivityResult?

在棒棒糖中通过相机拍摄照片后,在 onActivityResult() 方法中获取空意图

从图库或相机返回后不调用 onActivityResult

在 onActivityResult 中使用相机意图捕获的图片文件一段时间为空