无法在另一个活动中获取从自定义相机捕获的图像

时间:2013-12-06 04:33:21

标签: android camera nullpointerexception android-sdcard

我的应用程序中有一个自定义相机,用于捕捉图片,并将其保存在文件夹中的SD卡中。我能够捕获图像,但我需要在另一个活动中获取图像。我在onActivityResult事件中获得了失败传递结果和NullPointer异常。我知道图像正在保存,因为我可以看到图像的路径,但图像本身会在一段随机的时间后显示在文件夹中。我不确定这是否是NullPointerException的原因。我一直在尝试StackOverflow的各种解决方案,但没有解决问题。请尽快帮助我。

以下是我的代码片段: CustomCameraActivity.java文件:

public class CustomCameraActivity extends Activity {
private static final String TAG = "CameraActivity";
CameraPreview camPreview;
Button btn_take_pic, btn_use_pic;
Camera mCamera;
String fileName;
Activity act;
Context ctx;
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ctx = this;
    act = this;
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
    setContentView(R.layout.activity_custom_camera);

    camPreview = new CameraPreview(this,
            (SurfaceView) findViewById(R.id.surfaceView));
    camPreview.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT,
            LayoutParams.FILL_PARENT));
    ((FrameLayout) findViewById(R.id.preview)).addView(camPreview);
    camPreview.setKeepScreenOn(true);
    addListenerForButton();

}
private void addListenerForButton() {

    btn_take_pic = (Button) findViewById(R.id.btn_take_pic);
    btn_take_pic.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            Log.e(TAG, "Before taking picture");
            mCamera.stopPreview();
            mCamera.startPreview();
            mCamera.takePicture(null, null, jpegCallback);
            Log.e(TAG, "After taking picture");
            btn_take_pic.setText("Retake");
            // mCamera.startPreview();

        }
    });
btn_use_pic = (Button) findViewById(R.id.btn_usePhoto);
    btn_use_pic.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            File file = getOutputMediaFile();
            Log.e("use_pic buttn ", file.getPath());
            Intent intent = new Intent();
            intent.putExtra("output", file.getPath());
            finish();

        }
    });
}
...
PictureCallback jpegCallback = new PictureCallback() {

    @Override
    public void onPictureTaken(byte[] data, Camera camera) {
        Log.e(TAG, "Reached jpegcallback");
        File pictureFile = getOutputMediaFile();
        if (pictureFile == null) {
            Log.e("blah3", "picture file was null!");
            return;
        }
        try {
            FileOutputStream fos = new FileOutputStream(pictureFile);
            fos.write(data);
            fos.close();
        } catch (FileNotFoundException e) {
            Log.e(TAG, "picture file not found!");
        } catch (IOException e) {
            Log.e(TAG, e.getMessage());
        }
        Log.e(TAG, "hooray " + pictureFile.toURI().getRawPath());
    }

};
private static File getOutputMediaFile() {
    Log.e(TAG, "Get me the o/p file");
    File mediaStorageDir = new File(
            Environment
                    .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
            "PostcareApp");
    if (!mediaStorageDir.exists()) {
        if (!mediaStorageDir.mkdirs()) {
            Log.e("PostcareApp", "failed to create directory");
            return null;
        }
    }
    // Create a media file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
            .format(new Date());
    File mediaFile;
    mediaFile = new File(mediaStorageDir.getPath() + File.separator
            + "IMG_" + timeStamp + ".jpg");
    Log.e(TAG, "Before returning " + mediaFile.getAbsolutePath());

    return mediaFile;
}

需要图片的活动:

public class HowItWorksActivity extends Activity {

ImageButton btn_Account, btn_Photo, btn_Edit, btn_Flip, btn_Post;
RelativeLayout rl;
private static final int CAMERA_PIC_REQUEST = 2500;
private static final int SELECT_PICTURE = 1;
Bitmap postcard_image;
Uri uri_image;
...
private void takepicture() {
 Intent cameraIntent = new Intent(HowItWorksActivity.this,CustomCameraActivity.class);
 startActivityForResult(cameraIntent,CAMERA_PIC_REQUEST);
}

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

    Log.e("Howitworks..", "in activityresult");
    String imgfile = (String) getIntent().getExtras().get("output");
    Log.e("image ", imgfile);
if (requestCode == CAMERA_PIC_REQUEST && resultCode == RESULT_OK) {
postcard_image = BitmapFactory.decodeFile(imgfile);
        postcard_image = Bitmap.createScaledBitmap(postcard_image,
                metrics.widthPixels, 600, true);
        imgview.setImageBitmap(postcard_image);
 }
}

这是LogCat文件:

12-06 12:27:40.779: E/CameraActivity(16607): Get me the o/p file
12-06 12:27:40.779: E/CameraActivity(16607): Before returning /mnt/sdcard/Pictures/PostcareApp/IMG_20131206_122740.jpg
12-06 12:27:40.779: E/use_pic buttn(16607): /mnt/sdcard/Pictures/PostcareApp/IMG_20131206_122740.jpg
12-06 12:27:41.309: E/Howitworks..(16607): in activityresult
12-06 12:27:41.499: E/AndroidRuntime(16607): FATAL EXCEPTION: main
12-06 12:27:41.499: E/AndroidRuntime(16607): java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=2500, result=0, data=null} to activity {com.sample.postcare2/com.sample.postcare2.HowItWorksActivity}: java.lang.NullPointerException
12-06 12:27:41.499: E/AndroidRuntime(16607):    at android.app.ActivityThread.deliverResults(ActivityThread.java:3387)
12-06 12:27:41.499: E/AndroidRuntime(16607):    at android.app.ActivityThread.handleSendResult(ActivityThread.java:3437)
12-06 12:27:41.499: E/AndroidRuntime(16607):    at android.app.ActivityThread.access$1100(ActivityThread.java:139)
12-06 12:27:41.499: E/AndroidRuntime(16607):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1291)
12-06 12:27:41.499: E/AndroidRuntime(16607):    at android.os.Handler.dispatchMessage(Handler.java:99)
12-06 12:27:41.499: E/AndroidRuntime(16607):    at android.os.Looper.loop(Looper.java:154)
12-06 12:27:41.499: E/AndroidRuntime(16607):    at android.app.ActivityThread.main(ActivityThread.java:4944)
12-06 12:27:41.499: E/AndroidRuntime(16607):    at java.lang.reflect.Method.invokeNative(Native Method)
12-06 12:27:41.499: E/AndroidRuntime(16607):    at java.lang.reflect.Method.invoke(Method.java:511)
12-06 12:27:41.499: E/AndroidRuntime(16607):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
12-06 12:27:41.499: E/AndroidRuntime(16607):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
12-06 12:27:41.499: E/AndroidRuntime(16607):    at dalvik.system.NativeStart.main(Native Method)
12-06 12:27:41.499: E/AndroidRuntime(16607): Caused by: java.lang.NullPointerException
12-06 12:27:41.499: E/AndroidRuntime(16607):    at com.sample.postcare2.HowItWorksActivity.onActivityResult(HowItWorksActivity.java:217)
12-06 12:27:41.499: E/AndroidRuntime(16607):    at android.app.Activity.dispatchActivityResult(Activity.java:4740)
12-06 12:27:41.499: E/AndroidRuntime(16607):    at android.app.ActivityThread.deliverResults(ActivityThread.java:3383)
12-06 12:27:41.499: E/AndroidRuntime(16607):    ... 11 more

3 个答案:

答案 0 :(得分:0)

你必须为Uri使用静态,就像这样 private static Uri uri_image. 希望这能解决你的问题

答案 1 :(得分:0)

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
        if (resultCode == RESULT_OK) {
            // Image captured and saved to fileUri specified in the Intent
            Toast.makeText(this, "this is the uri for the iamge path:\n" +
                     data.getData(), Toast.LENGTH_LONG).show();
        } else if (resultCode == RESULT_CANCELED) {
            // User cancelled the image capture
        } else {
            // Image capture failed, advise user
        }
    }

答案 2 :(得分:0)

我已经解决了这个问题。实际上我们需要以下java文件  1. OnPictureSavedListener(界面)  2.扩展Activity的CustomCameraActivity实现了OnPictureSavedListener  3.预览哪些扩展了SurfaceView  4.实现android.hardware.Camera.PictureCallback的PhotoHandler  5. PhotoHelper它包含创建目录的方法和获得最佳预览大小的方法等 和一个名为activity_custom_camera.xml的xml文件。 需要遵循以下条款

<uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
  1. 这是接口OnPictureSavedListener

    package ali.customcamera;

    public interface OnPictureSavedListener {
    
        public void onPictureSaved(String imagePath);
    }
    
  2. 2:这是CustomCameraActivity类

     package ali.customcamera;
    
    
        import android.app.Activity;
        import android.content.Intent;
        import android.os.Bundle;
        import android.view.View;
        import android.view.View.OnClickListener;
        import android.widget.Button;
    
        public class CustomCameraActivity extends Activity implements
                OnPictureSavedListener, Preview.Callback {
            private Preview mPreview;
            Button btnCapture;
    
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_custom_camera);
                mPreview = (Preview) findViewById(R.id.preview);
                btnCapture = (Button) findViewById(R.id.btnCapture);
                btnCapture.setOnClickListener(captureClick);
            }
    
            OnClickListener captureClick = new OnClickListener() {
    
    
    
                @Override
                public void onClick(View v) {
        //          Progresss.start(CustomCameraActivity.this);
                    PhotoHandler photoHandler = new PhotoHandler(
                            CustomCameraActivity.this, CustomCameraActivity.this, 0);
                    mPreview.takeScreenshot(photoHandler);
                    btnCapture.setClickable(false);
                }
            };
    
    // this is where we get the path of the image saved in sdcard
            @Override
            public void onPictureSaved(String imagePath) {
                // Progresss.stop();
                btnCapture.setClickable(true);
                if (imagePath != null && !imagePath.equals("")){
                    Intent i = getIntent();
                    i.putExtra("imagePath",imagePath );
                    setResult(2500, i);
                    finish();
                }
            }
    
            @Override
            public void cameraReady() {
                // TODO Auto-generated method stub
    
            }
    
            @Override
            public void cameraNotAvailable() {
                // TODO Auto-generated method stub
    
            }
    
        }
    

    3:这是预览课程

    package ali.customcamera;
    
    import java.io.IOException;
    import java.util.List;
    
    import android.app.Activity;
    import android.content.Context;
    import android.hardware.Camera;
    import android.hardware.Camera.Parameters;
    import android.util.AttributeSet;
    import android.view.Display;
    import android.view.Surface;
    import android.view.SurfaceHolder;
    import android.view.SurfaceView;
    import android.view.WindowManager;
    
    
    
    
    public class Preview extends SurfaceView implements SurfaceHolder.Callback {
        private SurfaceHolder mHolder;
        private Camera mCamera;
        private Callback mCallback;
        Activity mActivity;
        static boolean hasCamera = false;
        Context context;
        List<Camera.Size> previewSizes;
        Camera.Size previewSize;
        private PhotoHandler photoHandler;
        private int width;
        private int height;
        private boolean configured;
    
    
        public   Preview(Context context) {
            super(context);
            this.context = context;
            initHolder();
        }
    
        public   Preview(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
            this.context = context;
            initHolder();
        }
        public   Preview(Context context, AttributeSet attrs) {
            super(context, attrs);
            this.context = context;
            initHolder();
        }
        public void setCallback(Callback c) {
            mCallback = c;
            mActivity = (Activity) c;
        }
    
    
        public interface Callback {
            public void cameraReady();
            public void cameraNotAvailable();
        }
    
        @SuppressWarnings("deprecation")
        private void initHolder() {
            // Install a SurfaceHolder.Callback so we get notified when the
            // underlying surface is created and destroyed.
            mHolder = getHolder();
            mHolder.addCallback(this);
            mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        }
    
        public void takeScreenshot(PhotoHandler mPhotoHandler ) {
    
            try {
    
                this.photoHandler = mPhotoHandler;
                photoHandler.setCamDimensions(previewSize.width, previewSize.height);
                photoHandler.setSurfaceDimensions(width, height);
                mCamera.takePicture(null, null, null, mPhotoHandler);
    
            } catch (Exception e) {
    
                e.getCause();
            }
    
        }
    
        public void surfaceCreated(SurfaceHolder holder) {
    
            mHolder = holder;
            initCamera();
    
        }
    
        public void initCamera() {
            if (!hasCamera) {
                try {
                    mCamera = Camera.open();
                    hasCamera = true;
                } catch (RuntimeException e) {
                    hasCamera = false;
                    mCallback.cameraNotAvailable();
                    return;
                }
                try {
                    mCamera.setPreviewDisplay(mHolder);
                } catch (IOException exception) {
                    mCamera.release();
                    mCamera = null;
                    hasCamera = false;
                }
            }
        }
    
    
    
        public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    
            width = w;
            height = h;
    
            if(!configured){
                configureCamera();
            }
    
            try 
            {
                mCamera.startPreview();
    
            } catch (Exception e) {
    
            }
    
        }
    
        private void configureCamera(){
    
            Parameters parameters = mCamera.getParameters();
            previewSizes = parameters.getSupportedPreviewSizes();
    
            Display display = ((WindowManager)context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
            if(display.getRotation() == Surface.ROTATION_0)
            {
                previewSize = PhotoHelper.getOptimalPreviewSize(previewSizes, width, height, true);
    
                //parameters.setPreviewSize(previewSize.height, previewSize.width);//AQAG
                parameters.setPreviewSize(previewSize.width, previewSize.height);
                mCamera.setDisplayOrientation(90);
            }
    
            else if(display.getRotation() == Surface.ROTATION_90)
            {
                previewSize = PhotoHelper.getOptimalPreviewSize(previewSizes, width, height, false);
                parameters.setPreviewSize(previewSize.width, previewSize.height);   
                //parameters.setPreviewSize(previewSize.height, previewSize.width); 
    
            }
    
            else if(display.getRotation() == Surface.ROTATION_180)
            {
                previewSize = PhotoHelper.getOptimalPreviewSize(previewSizes, width, height, true);
                //parameters.setPreviewSize(previewSize.height, previewSize.width);   AQAG
                parameters.setPreviewSize(previewSize.width, previewSize.height);   
            }
    
            else if(display.getRotation() == Surface.ROTATION_270)
            {
                previewSize = PhotoHelper.getOptimalPreviewSize(previewSizes, width, height, false);
    
                parameters.setPreviewSize(previewSize.width, previewSize.height);
                mCamera.setDisplayOrientation(180);
            }
    
            mCamera.setParameters(parameters);
        }
    
    
    
        public void surfaceDestroyed(SurfaceHolder holder) {
    
            releaseCamera();
        }
    
        public void releaseCamera() {
            if (hasCamera) {
                mCamera.stopPreview();
                mCamera.release();
                mCamera = null;
                hasCamera = false;
            }
        }
    }
    

    4:这是PhotoHandler类

    package ali.customcamera;
    
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    import android.content.Context;
    import android.hardware.Camera;
    import android.hardware.Camera.PictureCallback;
    import android.util.Log;
    
    
    
    public class PhotoHandler implements PictureCallback {
    
        private final Context context;
    
        private OnPictureSavedListener picTakenListener;
        private int camWidth;
        private int camHeight;
        private int surfaceWidth;
        private int surfaceHeight;
        private int offset = 0;
    
    
    
        public PhotoHandler(Context context, OnPictureSavedListener listener, int offset/*, boolean isPortrait*/ ) {
            this.context = context;
    //      this.topImage = topOverlayImg;
            this.picTakenListener = listener;
    //      this.isPortrait = isPortrait;
            this.offset = offset;
    
        }
    
        public void setCamDimensions(int width, int height){
    
            camWidth = width;
            camHeight = height;
    
            /*dWidth= width;
            dHeight = height ;*/
        }
    
        public void setSurfaceDimensions(int width, int height){
    
            surfaceWidth = width;
            surfaceHeight = height;
    
    
        }
    
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
    
            File pictureFile = PhotoHelper.getOutputMediaFile(PhotoHelper.MEDIA_TYPE_IMAGE);
    
            if (pictureFile == null){
                return;
            }
    
            try {
    
                //Save camera image to file
                FileOutputStream fos = new FileOutputStream(pictureFile);
                int len1 = data.length;
                fos.write(data,0, len1);
                fos.close();
    
    
            } catch (FileNotFoundException e) {
                Log.d("Camera", "File not found: " + e.getMessage());
            } catch (IOException e) {
                Log.d("Camera", "Error accessing file: " + e.getMessage());
            }
            camera.startPreview();
    
            if(picTakenListener!=null){
                picTakenListener.onPictureSaved(pictureFile.getAbsolutePath());
            }
        }
    
    
    
    
    
    
    
    }
    

    5:这是PhotoHelper类

    package ali.customcamera;
    
    import java.io.File;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.List;
    
    import android.graphics.Bitmap;
    import android.graphics.Matrix;
    import android.hardware.Camera;
    import android.os.Environment;
    import android.util.Log;
    
    public class PhotoHelper {
    
        public static final int MEDIA_TYPE_IMAGE = 1;
        public static final int MEDIA_TYPE_VIDEO = 2;
    //  private static final  String dirName = "CustomCamera";
        public static File getOutputMediaFile(int type){
    
            // To be safe, you should check that the SDCard is mounted
            // using Environment.getExternalStorageState() before doing this.
    
            File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
                    Environment.DIRECTORY_DCIM/*DIRECTORY_PICTURES*/), "CustomCamera");
            // This location works best if you want the created images to be shared
            // between applications and persist after your app has been uninstalled.
    
            // Create the storage directory if it does not exist
            if (! mediaStorageDir.exists()){
                if (! mediaStorageDir.mkdirs()){
                    Log.d("MyCameraApp", "failed to create directory");
                    return null;
                }
            }
    
            // Create a media file name
            String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").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;
        }
    
        public static Bitmap rotateBitmap90(Bitmap bitMap ){
            Matrix mat = new Matrix();
            mat.postRotate(90);
    
            return Bitmap.createBitmap(bitMap, 0, 0, 
                    bitMap.getWidth(), bitMap.getHeight(), 
                    mat, true);
        }
    
    
        public static Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int w, int h, boolean isPortrait) {
            final double ASPECT_TOLERANCE = 0.1;
    
            double targetRatio;
    
            if(isPortrait){
                targetRatio=(double)h / w;
            }
            else{
                targetRatio=(double)w / h;
            }
    
            if (sizes == null) return null;
    
            Camera.Size optimalSize = null;
            double minDiff = Double.MAX_VALUE;
    
            int targetHeight = h;
    
            for (Camera.Size size : sizes) {
                double ratio = (double) size.width / size.height;
                if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
                if (Math.abs(size.height - targetHeight) < minDiff) {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - targetHeight);
                }
            }
    
            if (optimalSize == null) {
                minDiff = Double.MAX_VALUE;
                for (Camera.Size size : sizes) {
                    if (Math.abs(size.height - targetHeight) < minDiff) {
                        optimalSize = size;
                        minDiff = Math.abs(size.height - targetHeight);
                    }
                }
            }
            return optimalSize;
        }
    }
    

    最后,这是布局文件

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    
        <ali.customcamera.Preview
            android:id="@+id/preview"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    
        <Button
            android:id="@+id/btnCapture"
            style="?android:attr/buttonStyleSmall"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_alignParentTop="true"
            android:text="Capture" />
    
    </RelativeLayout>