1

我有好几天试图让我的项目工作,但它没有,这个网站上有类似的问题和答案,但不能帮助我解决我的问题,这就是为什么我用下面的完整代码问这个问题。

我正在使用 Android 相机 API 创建一个相机项目,我想要的只是同时在表面上启动预览,但我一直收到运行时错误。

 04-10 22:52:28.690: D/com.Server.camerapreview.PreviewActivity(1194): SurfaceChanged: startPreview failed

我的活动 xml 是

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".PreviewActivity" >

    <SurfaceView
        android:id="@+id/surfaceView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true" />

</RelativeLayout>

我的安卓清单

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.Server.camerapreview"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />
    <uses-permission android:name="android.permission.CAMERA"/>
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.Server.camerapreview.PreviewActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

我的主要活动是:

  package com.Server.camerapreview;

//import android.graphics.PixelFormat;

import android.hardware.Camera;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.app.Activity;


public class PreviewActivity extends Activity implements SurfaceHolder.Callback{

    SurfaceView surfaceView;
    SurfaceHolder surfaceHolder;
    Camera camera = null;
    boolean inPreview = false;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.preview);
        surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
        surfaceHolder = surfaceView.getHolder();
        surfaceHolder.addCallback(this);


    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        camera = Camera.open();
        if(camera != null){
            try{
                camera.setPreviewDisplay(surfaceHolder);
            }catch(Exception x){
                Log.d(PreviewActivity.class.getName(), "Error in surface created: ["+x.getMessage()+"]");
            }
        }else Log.d(PreviewActivity.class.getName(), "Camera null");
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        if (surfaceHolder.getSurface() == null){
             Log.d(PreviewActivity.class.getName(), "SurfaceHolder is null");
              return;
            }


        if(camera != null && !inPreview){    
            Camera.Parameters parameters = camera.getParameters();
            Camera.Size size = getBestPreviewSize(width, height, parameters);

            if (size != null) {

                parameters.setPreviewSize(size.width, size.height);
                //parameters.setPictureFormat();
               // Log.d(PreviewActivity.class.getName(), "size: "+surfaceHolder;
                parameters.set("orientation", "portrait");
                camera.setParameters(parameters);
                try {
                    camera.setPreviewDisplay(surfaceHolder);
                    surfaceView.setVisibility(0);
                    camera.startPreview();

                    inPreview = true;
                } catch (Exception e) {
                    // TODO Auto-generated catch block
                    Log.d(PreviewActivity.class.getName(), "SurfaceChanged: "+e.getMessage());
                }
            }

        }else Log.d(PreviewActivity.class.getName(), "Camera null");

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        // TODO Auto-generated method stub
        if(inPreview){
            camera.stopPreview();
            camera.release();
            camera = null;
            inPreview = false;
        }
    }

    // Getting the best preview size
    private Camera.Size getBestPreviewSize(int width, int height, Camera.Parameters parameters) {
        Camera.Size result = null;

        for (Camera.Size size : parameters.getSupportedPreviewSizes()) {
            if (size.width <= width && size.height <= height) {
                if (result == null) {
                  result=size;
                }
                else {
                    int resultArea = result.width * result.height;
                    int newArea = size.width * size.height;

                    if (newArea > resultArea) {
                        result = size;
                    }
                }
            }
        }

        return(result);
    }


}
4

1 回答 1

1

这实际上不是一个解决方案,但我通过添加解决了这个问题

surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

并且我的应用程序可以工作,但是上面有一个叉号表示它已被弃用,因为我使用 API 级别 17 进行构建,有没有人知道另一种未被弃用且可以在此 API 级别中使用的替代方法?

于 2013-04-11T09:51:21.297 回答