surfaceCreated() 从未被调用

发布于 2024-11-26 14:08:03 字数 3679 浏览 1 评论 0原文

我见过与我遇到的类似的问题,但我仍然找不到解决方案。我对 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>

I've seen similar problems to the one I'm having, but I still can't find a solution. I'm very new to Android development, so I'm having trouble tracking down my problem. Anyways, I'm trying to create a camera preview using a CameraSurfaceView class I created that extends SurfaceView and implements SurfaceHolder.Callback. No matter what I try in my StartCamera class, the surfaceCreated() method is never called, hence my camera never starts. Any help would be great, thanks!

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>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

情深如许 2024-12-03 14:08:03

我也遇到过同样的问题。对我来说,这是因为视图大小被设置为 0,因此从未创建表面。我通过设置特定大小来检查这一点,然后突然调用了回调。 (显然,如果视图布置在屏幕外,则同样成立)。

I have had the same problem. For me it was because the View size was being set to 0, and therefore the surface was never created. I checked this by setting a specific size, and all of a sudden the callbacks were called. (Same, apparently, holds if the View is laid out off-screen).

时光磨忆 2024-12-03 14:08:03

显然这是由于 FrameLayout 为空,因此没有创建任何类型的 SurfaceView。您可以尝试手动强制父 LinearLayout 设置高度和宽度,或者只是在 FrameLayout 内添加一个 imageView。由于 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>

Apparently this is due to FrameLayout being empty and thus not creating any kind of SurfaceView. You can try to force the parent LinearLayout setting height and width manually or simply adding an imageView inside the FrameLayout. Since FrameLayout may contain many widgets, but it only shows the last of them you can put a ImageView inside the FrameLayout showing a small image only for the SurfaceView to be created.

<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>
薔薇婲 2024-12-03 14:08:03

@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 中再次释放它。另外,在重写 onPause() 方法时,您需要调用 super.onPause()

@jvnane I tried your code, it works, with minor bug.

surfaceChanged is called without problem. In what way you think it doesn't work? Try adding debug message and see it in 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);
    }
}

Minor bug: Camera object is released in surfaceDestroyed so you don't need to release it again in the activity's onPause. Also, you need to call super.onPause() when overriding onPause() method.

茶色山野 2024-12-03 14:08:03

我在 CameraSurfaceView 方法 surfaceChanged 中遇到了这一行错误:

camera.setParameters(parameters);

我将其注释掉后,它就工作得很好。

I had errors from this line in the CameraSurfaceView method, surfaceChanged:

camera.setParameters(parameters);

It worked fine once I commented that out.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文