未调用surfaceCreated(SurfaceHolder holder)

时间:2016-07-26 06:10:45

标签: android android-camera surfaceview

我已经看到很多关于错误的SurfaceView回调的问题,但没有一个有明确的解决方案。我有一个非常简单的布局文件,它有一个SurfaceView,一个TextView和一个不确定的进度指示器。根据我的日志,我的ScanActivity将自身注册为SurfaceView的布局回调,但只调用surfaceDestroyed(SurfaceHolder holder)。但是活动成功地预览了相机,这很奇怪,因为我将SurfaceView附加为surfaceCreated中的相机预览,以及" Surface创建。"在#34; Surface销毁时永远不会记录。"是

scan.xml

<?xml version="1.0" encoding="utf-8"?>

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <SurfaceView
        android:id="@+id/camera_preview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:background="@android:color/black"
    />

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="16dp"
        android:layout_gravity="bottom|center_horizontal">

        <TextView
            android:id="@+id/scan_instructions"
            android:layout_width="wrap_content"
            android:layout_height="fill_parent"
            android:textSize="16sp"
            android:gravity="center"
            android:visibility="visible"
            android:textColor="@android:color/primary_text_dark"
            android:text="@string/scan_instructions"
        />

        <ProgressBar
            android:id="@+id/progress"
            android:layout_width="32dp"
            android:layout_height="32dp"
            android:layout_margin="5dp"
            android:indeterminate="true"
        />

    </LinearLayout>

</FrameLayout>

ScanActivity.java

public class ScanActivity extends Activity implements SurfaceHolder.Callback {

    private Camera camera;
    private Scanner scanner;

    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.scan);

        scanner = new Scanner(20) {

            @Override
            public void onPostExecute(String result) {
                System.out.println("Read QR: " + result);
                onQRScanned(result);
            }

        };

    }

    /**
     * Registers this class as the callback for the image surface in the layout XML.
     */
    @Override
    public void onStart() {

        super.onStart();
        ((SurfaceView) findViewById(R.id.camera_preview)).getHolder().addCallback(this);

    }


    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        System.out.println("Surface created.");
        surfaceDestroyed(holder);

        try {

            // Open the camera.
            camera = Camera.open();
            camera.setPreviewDisplay(holder);
            camera.setPreviewCallback(scanner);
            System.out.println("Connected QR scan task.");

        } catch (NullPointerException e) {

            // Didn't find a camera to open.
            e.printStackTrace();
            surfaceDestroyed(holder);
            return;

        } catch (IOException e) {

            // Camera preview setup failed.
            e.printStackTrace();
            surfaceDestroyed(holder);
            return;

        } catch (RuntimeException e) {

            // The app was denied permission to camera services.
            e.printStackTrace();
            surfaceDestroyed(holder);
            return;

        }

        // Set auto-focus mode
        Parameters params = camera.getParameters();
        List<String> modes = params.getSupportedFocusModes();
        if (modes.contains(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE))
            params.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
        else if (modes.contains(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO))
            params.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
        else if (modes.contains(Parameters.FOCUS_MODE_AUTO)) {
            params.setFocusMode(Parameters.FOCUS_MODE_AUTO);
        }
        camera.setParameters(params);
    }

    /**
     * If the preview surface is altered for some reason, fixes it and refreshes the preview.
     */
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

        System.out.println("Surface changed.");

        if (camera == null)
            return;

        camera.setDisplayOrientation(90);
        camera.startPreview();

    }

    /**
     * When the activity is closed, release the camera.
     */
    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {

        System.out.println("Surface destroyed.");

        if (camera == null)
            return;

        camera.stopPreview();
        camera.setPreviewCallback(null);
        camera.release();
        camera = null;
        scanner.cancel(true);

    }

    /**
     * Called when a QR code is successfully read from the preview.
     * @param content The text encoded in the QR.
     */
    private void onQRScanned(String content) {

        if (content != null) {

            getIntent().putExtra("qr_content", content);
            setResult(RESULT_OK, getIntent());
            finish();

        } else {

            setResult(RESULT_CANCELED);
            finish();

        }

    }

}

1 个答案:

答案 0 :(得分:1)

我已尝试过您的代码,surfaceCreated()已按预期调用。你错误地检查了你的logcat。尝试使用Log.d("MainActivity", "Surface created.");代替System.out.println。还要学习how to use debugger