surfaceCreated () Никогда не вызывается - PullRequest
9 голосов
/ 28 июля 2011

Я видел проблемы, подобные той, что у меня есть, но я все еще не могу найти решение.Я очень плохо знаком с разработкой для Android, поэтому у меня проблемы с поиском решения моей проблемы.В любом случае, я пытаюсь создать предварительный просмотр камеры, используя созданный класс CameraSurfaceView, который расширяет SurfaceView и реализует SurfaceHolder.Callback.Независимо от того, что я пробую в своем классе StartCamera, метод surfaceCreated () никогда не вызывается, поэтому моя камера никогда не запускается.Любая помощь будет отличной, спасибо!

StartCamera.java

import net.peterd.zombierun.R;
import android.hardware.Camera;
import android.os.Bundle;
import android.widget.FrameLayout;

public class StartCamera extends BaseActivity {

    private Camera mCamera;
    private CameraSurfaceView mView;

    public void onCreate(Bundle state) {
        // TODO Auto-generated constructor stub
        super.onCreate(state);
        setContentView(R.layout.start_camera);
    }

    public void onResume() {
        super.onResume();

        mView = new CameraSurfaceView(this);
        FrameLayout preview = (FrameLayout) findViewById(R.id.cPreview);
        preview.addView(mView);
    }

    public void onPause() {
        mCamera.stopPreview();
        mCamera.release();
    }

}

CameraSurfaceView.java

import java.io.IOException;
import android.content.Context;
import android.hardware.Camera;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback
{
        private SurfaceHolder holder;
        private Camera camera;

        public CameraSurfaceView(Context context) 
        {
                super(context);

                //Initiate the Surface Holder properly
                this.holder = this.getHolder();
                this.holder.addCallback(this);
                this.holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        }

        @Override
        public void surfaceCreated(SurfaceHolder holder) 
        {
                try
                {
                        //Open the Camera in preview mode
                        this.camera = Camera.open();
                        this.camera.setPreviewDisplay(this.holder);
                }
                catch(IOException ioe)
                {
                        ioe.printStackTrace(System.out);
                }
        }

        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) 
        {
                // Now that the size is known, set up the camera parameters and begin
                // the preview.
                Camera.Parameters parameters = camera.getParameters();
                parameters.setPreviewSize(width, height);
                camera.setParameters(parameters);
                camera.startPreview();
        }

        @Override
        public void surfaceDestroyed(SurfaceHolder holder) 
        {
                // Surface will be destroyed when replaced with a new screen
                //Always make sure to release the Camera instance
                camera.stopPreview();
                camera.release();
                camera = null;
        }

        public Camera getCamera() {
            return camera;
        }
}

start_camera.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <FrameLayout android:id="@+id/cPreview"
        android:layout_weight="1" android:layout_width="fill_parent"
        android:layout_height="fill_parent">
    </FrameLayout>

</LinearLayout>

Ответы [ 4 ]

6 голосов
/ 06 сентября 2011

Очевидно, это связано с тем, что FrameLayout пуст и, следовательно, не создает никакого вида SurfaceView. Вы можете попытаться принудительно установить родительскую настройку высоты и ширины LinearLayout вручную или просто добавив imageView внутри FrameLayout. Поскольку FrameLayout может содержать много виджетов, но он показывает только последний из них, вы можете поместить ImageView внутри FrameLayout, показывая небольшое изображение только для создаваемого SurfaceView.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">

<FrameLayout android:id="@+id/cPreview"
    android:layout_weight="1" android:layout_width="fill_parent"
    android:layout_height="fill_parent">

<!-- Adding small dummy image -->
<ImageView android:layout_width="wrap_content"
    android:layout_height="wrap_content" 
    src="@drawable/small_picture">

</FrameLayout>

</LinearLayout>
5 голосов
/ 28 января 2015

У меня была такая же проблема. Для меня это было потому, что размер View был установлен на 0, и, следовательно, поверхность никогда не создавалась. Я проверил это, установив определенный размер, и внезапно были вызваны обратные вызовы. (То же самое, очевидно, имеет место, если представление размещено вне экрана).

2 голосов
/ 19 июня 2013

@ jvnane Я попробовал ваш код, он работает, с незначительной ошибкой.

surfaceChanged вызывается без проблем.Как вы думаете, это не работает?Попробуйте добавить сообщение отладки и посмотрите его в LogCat:

@Override
public void surfaceCreated(final SurfaceHolder holder)
{
    Log.i("Camera Test", "It works!");
    try
    {
        //Open the Camera in preview mode
        this.camera = Camera.open();
        this.camera.setPreviewDisplay(this.holder);
    }
    catch(final IOException ioe)
    {
        ioe.printStackTrace(System.out);
    }
}

Незначительная ошибка: Camera объект выпущен в surfaceDestroyed, поэтому вам не нужно снова выпускать его в onPause действия.Кроме того, вам нужно вызвать super.onPause() при переопределении onPause() метода.

0 голосов
/ 14 июня 2013

У меня были ошибки из этой строки в методе CameraSurfaceView, surfaceChanged:

camera.setParameters(parameters);

Все заработало, когда я это прокомментировал.

...