简体   繁体   English

faceview for camera在android lollipop os中不起作用

[英]surfaceview for camera is not working in android lollipop os

Today I had faced an issue in android surfaceview for camera customization . 今天我在android surfaceview for camera customization I tried the below code. 我尝试了下面的代码。

The Issue occurred when I captured the image, it stops the camera preview and doesn't return to the activity. 拍摄图像时出现问题,它会停止相机预览并且不会返回活动。

Following code will be implemented in the program. 以下代码将在程序中实现。 I took this code from an existing reference on stackoverflow 我从stackoverflow上的现有引用中获取此代码

  1. Supporting Class. 支持班级。

     public class AndroidCameraSurfaceview extends Activity implements SurfaceHolder.Callback { TextView testView; Camera camera; SurfaceView surfaceView; SurfaceHolder surfaceHolder; boolean preview; PictureCallback rawCallback; ShutterCallback shutterCallback; PictureCallback jpegCallback; int displayheight, displaywidth; Camera.PreviewCallback previewCallback; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.camerasurfaceview); getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); surfaceView = (SurfaceView) findViewById(R.id.surfaceView); surfaceHolder = surfaceView.getHolder(); surfaceHolder.addCallback(this); surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); jpegCallback = new PictureCallback() { public void onPictureTaken(byte[] data, Camera camera) { Bundle b = new Bundle(); b.putByteArray("Image", data); Intent intent = new Intent(); intent.putExtras(b); setResult(RESULT_OK, intent); finish(); // refreshCamera(); } }; } public void captureImage(View v) throws IOException { // take the picture camera.takePicture(null, null, jpegCallback); } public void refreshCamera() { if (surfaceHolder.getSurface() == null) { // preview surface does not exist return; } try { camera.stopPreview(); } catch (Exception e) { } try { camera.setDisplayOrientation(90); camera.setPreviewDisplay(surfaceHolder); camera.startPreview(); } catch (Exception e) { } } public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { if (preview) { camera.stopPreview(); } try{ Camera.Parameters parameters = camera.getParameters(); List<Size> sizes = parameters.getSupportedPreviewSizes(); Size optimalSize = getOptimalPreviewSize(sizes, width, height); parameters.setPreviewSize(optimalSize.width, optimalSize.height); camera.setParameters(parameters); try { camera.setDisplayOrientation(90); camera.setPreviewDisplay(holder); camera.startPreview(); preview = true; } catch (IOException e) { e.printStackTrace(); } }catch(Exception e){ System.out.println("Surface Exception---=>"+e); } } public void surfaceCreated(SurfaceHolder holder) { camera = Camera.open(); if (camera != null) { Camera.Parameters params = camera.getParameters(); camera.setDisplayOrientation(90); camera.setParameters(params); } } public void surfaceDestroyed(SurfaceHolder holder) { // stop preview and release camera camera.stopPreview(); camera.release(); camera = null; } private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) { final double ASPECT_TOLERANCE = 1; double targetRatio = (double) w / h; if (sizes == null) return null; Size optimalSize = null; double minDiff = Double.MAX_VALUE; int targetHeight = h; for (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 (Size size : sizes) { if (Math.abs(size.height - targetHeight) < minDiff) { optimalSize = size; minDiff = Math.abs(size.height - targetHeight); } } } return optimalSize; } } 

    2.Implemented in Activity 2.实施活动

    public void captureImage() { public void captureImage(){

      Intent intentDriver = new Intent(AddNewDevice_Activity.this, AndroidCameraSurfaceview.class); startActivityForResult(intentDriver, 0); // // Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); // // Uri fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE); // // intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // // // start the image capture Intent // startActivityForResult(intent, CAMERA_CAPTURE_IMAGE_REQUEST_CODE); // 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); } protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == 0) { System.out.println("Result Code: " + resultCode); if (resultCode == RESULT_OK && data != null) { Bundle bundle = data.getExtras(); byte[] test = bundle.getByteArray("Image"); Bitmap bpCamera = BitmapFactory.decodeByteArray(test, 0, test.length); Matrix matrix = new Matrix(); matrix.postRotate(90); bpCamera = Bitmap .createBitmap(bpCamera, 0, 0, bpCamera.getWidth(), bpCamera.getHeight(), matrix, true); imageView_camera.setImageBitmap(bpCamera); selectedImageStr = encodeTobase64(bpCamera); } } else { finish(); } } 

You shold split activity and surface view. 您将拆分活动和表面视图分开。

public class AndroidCameraActivity extends Activity {
    AndroidCameraSurfaceview surfaceView;
    ...
    @Override
    public void onCreate(Bundle savedInstanceState) {
        ...
        surfaceView = (AndroidCameraSurfaceview) findViewById(R.id.surfaceView);
    }
}

class AndroidCameraSurfaceview extends SurfaceView implements SurfaceHolder.Callback {
    public AndroidCameraSurfaceview(Context context, AttributeSet attrs) {
        super(context, attrs);
        getHolder().addCallback(this);
        ...
    }

    public void surfaceCreated(SurfaceHolder holder) {
        ...
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        ...
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
        ...
    }
}

Google had revised the camera API from in API version 21, henceforth we have to adopt new camera2 package and has to be adhered in cases where camera functionalities comes into picture. 谷歌已经从API版本21修改了相机API,因此我们必须采用新的camera2包,并且必须在相机功能出现的情况下加以遵守。 Here is the link to sample code published by google which uses surface view implementation and it works flawless in Android 5.0. 以下是google发布的示例代码的链接,该代码使用表面视图实现,并且在Android 5.0中完美无瑕。 I believe it solves a bit of mystery. 我相信它解决了一些神秘感。

https://github.com/googlesamples/android-Camera2Basic https://github.com/googlesamples/android-Camera2Basic

try this, I have made it from my self : 

package com.fragments;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.Date;
import java.text.SimpleDateFormat;

import com.jsonparsing.JsonMainActivity;
import com.jsonparsing.MailFragment;
import com.mobehc.R;
import com.sendmail.main;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.PictureCallback;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.net.Uri;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Environment;
import android.os.Handler;
import android.os.SystemClock;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

public class CamImageCapture2 extends Fragment implements
        MediaRecorder.OnInfoListener {

    private Camera myCamera;
    private MyCameraSurfaceView myCameraSurfaceView;
    private MediaRecorder mediaRecorder;
    Camera c = null;
    ImageView myButton, myButton1, backcam;
    SurfaceHolder surfaceHolder;
    boolean recording;
    private Button startButton;
    private Button pauseButton;

    private TextView timerValue;

    private long startTime = 0L;

    private Handler customHandler = new Handler();

    long timeInMilliseconds = 0L;
    long timeSwapBuff = 0L;
    long updatedTime = 0L;
    String path = Environment.getExternalStorageDirectory().toString()
            + "/00 MHC/VID.MP4";

    /** Called when the activity is first created. */
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.activity_captureimage, container,
                false);

        recording = false;

        getActivity().getWindow().addFlags(
                WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        timerValue = (TextView) v.findViewById(R.id.timer);
        // Get Camera for preview
        myCamera = getCameraInstance();
        if (myCamera == null) {
            Toast.makeText(getActivity(), "Fail to get Camera",
                    Toast.LENGTH_LONG).show();
        }

        myCameraSurfaceView = new MyCameraSurfaceView(getActivity(), myCamera);
        FrameLayout myCameraPreview = (FrameLayout) v
                .findViewById(R.id.videoview);
        myCameraPreview.addView(myCameraSurfaceView);

        myButton = (ImageView) v.findViewById(R.id.rec);
        myButton1 = (ImageView) v.findViewById(R.id.rec1);
        backcam = (ImageView) v.findViewById(R.id.backcamera);
        backcam.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {

                Intent ik = new Intent(getActivity(), Camrec2.class);
                startActivity(ik);
                // getActivity().finish();
                getActivity().getFragmentManager().popBackStack();
            }
        });
        myButton1.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                myCamera.takePicture(null, null, mPicture);
            }
        });

        myButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {

                File attachment1 = new File(Environment
                        .getExternalStorageDirectory(), "/00 MHC/image.jpg");
                if (attachment1.exists()) {
                    attachment1.delete();
                }

                if (recording) {
                    mediaRecorder.stop(); // stop the recording
                    releaseMediaRecorder(); // release the MediaRecorder object

                    // Exit after saved
                    getActivity().finish();
                } else {

                    // Release Camera before MediaRecorder start
                    releaseCamera();

                    if (!prepareMediaRecorder()) {
                        Toast.makeText(getActivity(),
                                "Fail in prepareMediaRecorder()!\n - Ended -",
                                Toast.LENGTH_LONG).show();
                        getActivity().finish();
                    }

                    mediaRecorder.start();
                    startTime = SystemClock.uptimeMillis();
                    customHandler.postDelayed(updateTimerThread, 0);

                    /*
                     * final TextView _tv = (TextView) findViewById(R.id.timer);
                     * _tv.setVisibility(View.VISIBLE); new
                     * CountDownTimer(60000, 1000) {
                     * 
                     * public void onTick(long millisUntilFinished) {
                     * _tv.setText(new SimpleDateFormat("00:ss") .format(new
                     * Date(millisUntilFinished))); }
                     * 
                     * public void onFinish() { _tv.setText("done!"); Intent ii
                     * = new Intent(Camrecord.this, Emailtry.class);
                     * startActivity(ii); finish(); } }.start();
                     */recording = true;
                    // myButton.setText("STOP");

                    Drawable myDrawable = getResources().getDrawable(
                            R.drawable.stp);
                    myButton.setImageDrawable(myDrawable);
                    backcam.setVisibility(View.INVISIBLE);

                }

            }
        });
        return v;
    }

    PictureCallback mPicture = new PictureCallback() {
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            File externalStorage = Environment.getExternalStorageDirectory();

            String sdcardPath = externalStorage.getAbsolutePath() + "/00 MHC/";
            File pictureFile = new File(sdcardPath + "/image" + ".jpg");

            try {
                FileOutputStream fos = new FileOutputStream(pictureFile);
                fos.write(data);
                fos.close();

                File attachment1 = new File(
                        Environment.getExternalStorageDirectory(),
                        "/00 MHC/VID.mp4");
                if (attachment1.exists()) {
                    attachment1.delete();
                }
                Toast.makeText(getActivity(), "Captured Successfully...",
                        Toast.LENGTH_LONG).show();
                Fragment fr = new main();
                android.support.v4.app.FragmentTransaction fragmentTransaction = getFragmentManager()
                        .beginTransaction();
                fragmentTransaction.replace(R.id.fragment_place, fr);
                fragmentTransaction.commit();
                // getActivity().finish();
            } catch (FileNotFoundException e) {

            } catch (IOException e) {
            }
        }
    };

    private Camera getCameraInstance() {
        // TODO Auto-generated method stub

        try {
            // c = Camera.open(); // attempt to get a Camera instance
            if (Camera.getNumberOfCameras() >= 2) {

                // backcam.setVisibility(View.VISIBLE);
                // if you want to open front facing camera use this line
                c = Camera.open(CameraInfo.CAMERA_FACING_FRONT);

                c = Camera.open(CameraInfo.CAMERA_FACING_BACK);

            } else {
                c = Camera.open(CameraInfo.CAMERA_FACING_BACK);
            }

            /*
             * c.setDisplayOrientation(90); c.setPreviewDisplay(surfaceHolder);
             * 
             * Camera.Parameters p = c.getParameters(); p.set("camera-id", 2);
             * c.setParameters(p);
             */
        } catch (Exception e) {
            // Camera is not available (in use or does not exist)
        }
        return c; // returns null if camera is unavailable
    }

    private boolean prepareMediaRecorder() {
        myCamera = getCameraInstance();
        myCamera.setDisplayOrientation(90);
        mediaRecorder = new MediaRecorder();

        myCamera.unlock();
        mediaRecorder.setCamera(myCamera);

        mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
        mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);

        mediaRecorder.setProfile(CamcorderProfile
                .get(CamcorderProfile.QUALITY_LOW));
        mediaRecorder.setOrientationHint(270);

        mediaRecorder.setOutputFile(path);
        mediaRecorder.setMaxDuration(60000); // Set max duration 60 sec.
        mediaRecorder.setOnInfoListener(this);
        mediaRecorder.setMaxFileSize(2500000); // Set max file size 5M

        // mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());
        mediaRecorder.setPreviewDisplay(myCameraSurfaceView.getHolder()
                .getSurface());

        try {
            mediaRecorder.prepare();
        } catch (IllegalStateException e) {
            releaseMediaRecorder();
            return false;
        } catch (IOException e) {
            releaseMediaRecorder();
            return false;
        }
        return true;

    }

    @Override
    public void onPause() {
        super.onPause();
        releaseMediaRecorder(); // if you are using MediaRecorder, release it
                                // first
        releaseCamera(); // release the camera immediately on pause event
    }

    private void releaseMediaRecorder() {
        if (mediaRecorder != null) {
            mediaRecorder.reset(); // clear recorder configuration
            mediaRecorder.release(); // release the recorder object
            mediaRecorder = null;
            myCamera.lock(); // lock camera for later use
        }
    }

    private void releaseCamera() {
        if (myCamera != null) {
            myCamera.release(); // release the camera for other applications
            myCamera = null;
        }
    }

    public class MyCameraSurfaceView extends SurfaceView implements
            SurfaceHolder.Callback {

        private SurfaceHolder mHolder;
        private Camera mCamera;

        public MyCameraSurfaceView(Context context, Camera camera) {
            super(context);
            mCamera = camera;

            // Install a SurfaceHolder.Callback so we get notified when the
            // underlying surface is created and destroyed.
            mHolder = getHolder();

            mHolder.addCallback(this);
            // deprecated setting, but required on Android versions prior to 3.0
            mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format,
                int weight, int height) {
            // If your preview can change or rotate, take care of those events
            // here.
            // Make sure to stop the preview before resizing or reformatting it.

            if (mHolder.getSurface() == null) {
                // preview surface does not exist
                return;
            }

            // stop preview before making changes
            try {

                mCamera.stopPreview();
            } catch (Exception e) {
                // ignore: tried to stop a non-existent preview
            }

            // make any resize, rotate or reformatting changes here

            // start preview with new settings
            try {

                mCamera.setPreviewDisplay(mHolder);
                mCamera.startPreview();

            } catch (Exception e) {
            }
        }

        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            // TODO Auto-generated method stub
            // The Surface has been created, now tell the camera where to draw
            // the preview.
            try {
                mCamera.setDisplayOrientation(90);
                mCamera.setPreviewDisplay(holder);
                mCamera.startPreview();
            } catch (IOException e) {
            }
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {

        }
    }

    private Runnable updateTimerThread = new Runnable() {

        public void run() {

            timeInMilliseconds = SystemClock.uptimeMillis() - startTime;

            updatedTime = timeSwapBuff + timeInMilliseconds;

            int secs = (int) (updatedTime / 1000);
            int mins = secs / 60;
            secs = secs % 60;
            int milliseconds = (int) (updatedTime % 1000);
            timerValue.setText("" + mins + ":" + String.format("%02d", secs)
                    + ":" + String.format("%03d", milliseconds));
            customHandler.postDelayed(this, 0);
        }

    };

    @Override
    public void onInfo(MediaRecorder mr, int what, int extra) {

        if (what == MediaRecorder.MEDIA_RECORDER_INFO_MAX_DURATION_REACHED) {
            Log.v("VIDEOCAPTURE", "Maximum Duration Reached");
            mediaRecorder.stop(); // stop the recording
            releaseMediaRecorder(); // release the MediaRecorder object

            // Exit after saved
            // getActivity().finish();
            getActivity().getFragmentManager().popBackStack();
        }
    }

}

I Tried the Camera API 2, but i don't have time fix the issue within the time line. 我尝试了Camera API 2,但我没有时间在时间​​线内解决问题。 This is the way I found the solutions for the issue using camera API 1. When the Multiple Views are Handle Single Activity. 这是我使用相机API找到解决问题的方法1.当多个视图处理单个活动时。 Please try this code in case of the Camera Handling. 如果是相机处理,请尝试使用此代码。

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == CAPTURE_IMAGE_CAPTURE_CODE) {
            if (resultCode == RESULT_OK) {
                Bitmap bp = (Bitmap) data.getExtras().get("data");
                Bitmap resized = Bitmap.createScaledBitmap(bp,
                        (int) (bp.getWidth() * 0.8),
                        (int) (bp.getHeight() * 0.8), true);

                imageView_camera.setImageBitmap(resized);

                SharedPreferences value_1_Details = getSharedPreferences(
                        "Value_1_Key", MODE_PRIVATE);
                Value_1_SelectedPosId = Integer.parseInt(value_1_Details.getString(
                        "Value_1_ID", ""));
                String value_1_Name = value_1_Details.getString("Value_1_Data", "");
                btn_popup_value_1_Name.setText(value_1_Name);

                SharedPreferences value_2_Details = getSharedPreferences(
                        "Value_2_Key", MODE_PRIVATE);
                value_2_SelectedPosId = Integer.parseInt(value_2_Details.getString(
                        "Value_2_ID", ""));
                String value_2_Name = value_2_Details.getString("Value_2_Data", "");
                btn_dropdown_value_2_Name.setText(value_2_Name);

                SharedPreferences value_3_Details = getSharedPreferences(
                        "Value_3_Key", MODE_PRIVATE);
                value_3_PosId = Integer.parseInt(value_3_Details
                        .getString("Value_3_ID", ""));
                String value_3_Name = value_3_Details.getString("Value_3_Data",
                        "");
                btn_dropdown_value_3_Name.setText(value_3_Name);


                rL_include_ViewDetails.setVisibility(View.GONE);
                rL_include_AddNew.setVisibility(View.VISIBLE);
                rL_include_View.setVisibility(View.GONE);

                selectedImageStr = encodeTobase64(resized);

            } else if (resultCode == RESULT_CANCELED) {
                Toast.makeText(this, "Cancelled", Toast.LENGTH_LONG).show();
            }
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM