简体   繁体   中英

Android camera preview failure (only on API<14)

I am building an android app that uses inbuilt camera. I am building step by step so I first checked the camera preview. It works fine on my Jelly Bean phone But the same application when run on gingerbread phone fails with a failed to start preview error

Here are the details

The surface view is defined in xml layout and is of arbitrary size The jelly bean phone is galaxy s3 with screen in normal category The gingerbread device is galaxy Y with screen in small category

here is the log output

04-01 23:54:44.117: I/ApplicationPackageManager(15419): cscCountry is not German : INU
04-01 23:54:44.671: D/AndroidRuntime(15419): Shutting down VM
04-01 23:54:44.671: W/dalvikvm(15419): threadid=1: thread exiting with uncaught exception (group=0x40018578)
04-01 23:54:44.703: E/AndroidRuntime(15419): FATAL EXCEPTION: main
04-01 23:54:44.703: E/AndroidRuntime(15419): java.lang.RuntimeException: startPreview failed
04-01 23:54:44.703: E/AndroidRuntime(15419):    at android.hardware.Camera.startPreview(Native Method)
04-01 23:54:44.703: E/AndroidRuntime(15419):    at com.example.witalk.CameraHandle.surfaceCreated(CameraHandle.java:98)
04-01 23:54:44.703: E/AndroidRuntime(15419):    at android.view.SurfaceView.updateWindow(SurfaceView.java:552)
04-01 23:54:44.703: E/AndroidRuntime(15419):    at android.view.SurfaceView.dispatchDraw(SurfaceView.java:350)
04-01 23:54:44.703: E/AndroidRuntime(15419):    at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
04-01 23:54:44.703: E/AndroidRuntime(15419):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
04-01 23:54:44.703: E/AndroidRuntime(15419):    at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
04-01 23:54:44.703: E/AndroidRuntime(15419):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
04-01 23:54:44.703: E/AndroidRuntime(15419):    at android.view.View.draw(View.java:6883)
04-01 23:54:44.703: E/AndroidRuntime(15419):    at android.widget.FrameLayout.draw(FrameLayout.java:357)
04-01 23:54:44.703: E/AndroidRuntime(15419):    at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
04-01 23:54:44.703: E/AndroidRuntime(15419):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
04-01 23:54:44.703: E/AndroidRuntime(15419):    at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
04-01 23:54:44.703: E/AndroidRuntime(15419):    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
04-01 23:54:44.703: E/AndroidRuntime(15419):    at android.view.View.draw(View.java:6883)
04-01 23:54:44.703: E/AndroidRuntime(15419):    at android.widget.FrameLayout.draw(FrameLayout.java:357)
04-01 23:54:44.703: E/AndroidRuntime(15419):    at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1940)
04-01 23:54:44.703: E/AndroidRuntime(15419):    at android.view.ViewRoot.draw(ViewRoot.java:1527)
04-01 23:54:44.703: E/AndroidRuntime(15419):    at android.view.ViewRoot.performTraversals(ViewRoot.java:1264)
04-01 23:54:44.703: E/AndroidRuntime(15419):    at android.view.ViewRoot.handleMessage(ViewRoot.java:1865)
04-01 23:54:44.703: E/AndroidRuntime(15419):    at android.os.Handler.dispatchMessage(Handler.java:99)
04-01 23:54:44.703: E/AndroidRuntime(15419):    at android.os.Looper.loop(Looper.java:130)
04-01 23:54:44.703: E/AndroidRuntime(15419):    at android.app.ActivityThread.main(ActivityThread.java:3687)
04-01 23:54:44.703: E/AndroidRuntime(15419):    at java.lang.reflect.Method.invokeNative(Native Method)
04-01 23:54:44.703: E/AndroidRuntime(15419):    at java.lang.reflect.Method.invoke(Method.java:507)
04-01 23:54:44.703: E/AndroidRuntime(15419):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
04-01 23:54:44.703: E/AndroidRuntime(15419):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
04-01 23:54:44.703: E/AndroidRuntime(15419):    at dalvik.system.NativeStart.main(Native Method)

and here's the code

main activity.java

package com.example.witalk;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.SurfaceView;
import android.view.WindowManager;

public class MainActivity extends Activity {

    private CameraHandle cameraHandle;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        SurfaceView surface=(SurfaceView)findViewById(R.id.surfaceView1);

        cameraHandle=new CameraHandle(0);
        cameraHandle.initializeCamera(getWindowManager().getDefaultDisplay().getRotation());
        cameraHandle.setDisplaySurface(surface);
        cameraHandle.startPreview();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
    @Override
    protected void onDestroy() {
    cameraHandle.stop();
        super.onDestroy();
    }

}

Camera handle.java

package com.example.witalk;



import java.io.IOException;

import android.graphics.ImageFormat;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.PreviewCallback;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.WindowManager;

public class CameraHandle implements Callback, PreviewCallback  {

    private static Camera camera;
    private static SurfaceView surface;
    private static byte[] imageBuffer;
    private static byte[] imageData;
    private static int height,width;
    private static Parameters cameraSettings;
    private static boolean surfaceReady,cameraReady;
    long lastTime;

    public  CameraHandle(int id )
    {

        camera=Camera.open(id);

    }

    public  void initializeCamera(int rotation){
        cameraSettings=camera.getParameters();
        height=cameraSettings.getPreviewSize().height;
        width=cameraSettings.getPreviewSize().width;
        imageBuffer=new byte[(ImageFormat.getBitsPerPixel(cameraSettings.getPreviewFormat())*width*height)/8];
        camera.addCallbackBuffer(imageBuffer);
        if(rotation==Surface.ROTATION_0)
        camera.setDisplayOrientation(90);
        if(rotation==Surface.ROTATION_90)
            camera.setDisplayOrientation(0);

        if(rotation==Surface.ROTATION_270)
            camera.setDisplayOrientation(180);
    }

    public  void setDisplaySurface(SurfaceView surface){
        this.surface=surface;
        surface.getHolder().addCallback(this);
    }

    public  void startPreview(){
        if(surfaceReady){
            try {
                Log.d("CameraHandler", "camera from start Preview");
                camera.setPreviewDisplay(surface.getHolder());

                camera.setPreviewCallbackWithBuffer(this);
            } catch (IOException e) {}
        camera.startPreview();
        }
        else
            cameraReady=true;


    }

    public static byte[] getData(){
        return imageData;

    }


    public void stop(){
        if(camera!=null){
            camera.stopPreview();
        camera.release();}

    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {

    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {

        try {
        camera.setPreviewDisplay(holder);
        surfaceReady=true;
        if(cameraReady){
            camera.startPreview();
            camera.setPreviewCallbackWithBuffer(this);
            Log.d("CameraBuffer", "camera from surface");
            }
    } catch (IOException e) {
        Log.e("CameraHandler","Something went wrong cannot set preview");
        e.printStackTrace();}



    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onPreviewFrame(byte[] newData, Camera camera) {
        imageData=newData;
        camera.addCallbackBuffer(imageBuffer);

    }

}

For your surface Holder set type to SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS

ie

add this in your onCreate

SurfaceView surface=(SurfaceView)findViewById(R.id.surfaceView1);
SurfaceHolder holder=surface.getHolder();
 holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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