相机在Android设备上无法使用

时间:2011-11-17 09:58:52

标签: android android-emulator camera

我找到了一些使用相机的教程。模拟器上没有错误,但它在设备上崩溃了,为什么?我只是创建简单的代码来预览图片。

我正在测试的设备是HTC Wildfire Android 2.2

Mainclass

private Camera camera;  
private boolean isPreviewRunning = false;  
private SimpleDateFormat timeStampFormat = new SimpleDateFormat("yyyyMMddHHmmssSS");  

private SurfaceView surfaceView;  
private SurfaceHolder surfaceHolder;  

public void onCreate(Bundle icicle)  
{  
    super.onCreate(icicle);  
    Log.e(getClass().getSimpleName(), "onCreate");  
    getWindow().setFormat(PixelFormat.TRANSLUCENT);  
    setContentView(R.layout.main);  
    surfaceView = (SurfaceView)findViewById(R.id.surface);  
    surfaceHolder = surfaceView.getHolder();  
    surfaceHolder.addCallback(this);  
    surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);  
}  


@Override  
protected void onRestoreInstanceState(Bundle savedInstanceState)  
{  
    super.onRestoreInstanceState(savedInstanceState);  
}  

Camera.PictureCallback mPictureCallbackRaw = new Camera.PictureCallback() 
{  
    public void onPictureTaken(byte[] data, Camera c) 
    {  
         Log.e(getClass().getSimpleName(), "PICTURE CALLBACK RAW: " + data);  
         camera.startPreview();  
    }  
};  

Camera.PictureCallback mPictureCallbackJpeg= new Camera.PictureCallback() 
{  
    public void onPictureTaken(byte[] data, Camera c) 
    {  
         Log.e(getClass().getSimpleName(), "PICTURE CALLBACK JPEG: data.length = " + data);  
    }  
};  

Camera.ShutterCallback mShutterCallback = new Camera.ShutterCallback() 
{  
    public void onShutter() 
    {  
        Log.e(getClass().getSimpleName(), "SHUTTER CALLBACK");  
    }  
};  


public boolean onKeyDown(int keyCode, KeyEvent event)  
{  
    ImageCaptureCallback iccb = null;  
    if(keyCode == KeyEvent.KEYCODE_DPAD_CENTER) 
    {  
        try 
        {  
            String filename = timeStampFormat.format(new Date());  
            ContentValues values = new ContentValues();  
            values.put(Media.TITLE, filename);  
            values.put(Media.DESCRIPTION, "Image capture by camera");  
            Uri uri = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, values);  
            //String filename = timeStampFormat.format(new Date());  
            iccb = new ImageCaptureCallback( getContentResolver().openOutputStream(uri));  
        } 
        catch(Exception ex )
        {  
            ex.printStackTrace();  
            Log.e(getClass().getSimpleName(), ex.getMessage(), ex);  
        }  
    }  

    if (keyCode == KeyEvent.KEYCODE_BACK) 
    {  
        return super.onKeyDown(keyCode, event);  
    }  

    if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) 
    {  
        camera.takePicture(mShutterCallback, mPictureCallbackRaw, iccb);  
        return true;  
    }  

    return false;  
}  

protected void onResume()  
{  
    Log.e(getClass().getSimpleName(), "onResume");  
    super.onResume();  
}  

protected void onSaveInstanceState(Bundle outState)  
{  
    super.onSaveInstanceState(outState);  
}  

protected void onStop()  
{  
    Log.e(getClass().getSimpleName(), "onStop");  
    super.onStop();  
}  

public void surfaceCreated(SurfaceHolder holder)  
{  
    Log.e(getClass().getSimpleName(), "surfaceCreated");  
    camera = Camera.open();  
}  

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h)  
{  
    Log.e(getClass().getSimpleName(), "surfaceChanged");  
    if (isPreviewRunning) 
    {  
        camera.stopPreview();  
    }  

    Camera.Parameters p = camera.getParameters();  
    p.setPreviewSize(w, h);  
    camera.setParameters(p);  

    try 
    {
        camera.setPreviewDisplay(holder);
    } 

    catch (IOException e) 
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }  

    camera.startPreview();  
    isPreviewRunning = true;  
}  

public void surfaceDestroyed(SurfaceHolder holder)  
{  
    Log.e(getClass().getSimpleName(), "surfaceDestroyed");  
    camera.stopPreview();  
    isPreviewRunning = false;  
    camera.release();  
}  

}

ImageCaptureCallBack

private OutputStream filoutputStream;  

public ImageCaptureCallback(OutputStream filoutputStream) 
{  
    this.filoutputStream = filoutputStream;  
}  

@Override  
public void onPictureTaken(byte[] data, Camera camera) 
{  
    try 
    {  
        Log.v(getClass().getSimpleName(), "onPictureTaken=" + data + " length = " + data.length);  
        filoutputStream.write(data);  
        filoutputStream.flush();  
        filoutputStream.close();  
    } 
    catch(Exception ex) 
    {  
        ex.printStackTrace();  
    }  
}  

}

和清单

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.photo.test"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<application
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name" >
    <activity
        android:label="@string/app_name"
        android:name=".Main" >
        <intent-filter >
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

1 个答案:

答案 0 :(得分:5)

相机预览在不同设备上的工作方式非常不同。我们在mixare增强现实引擎中遇到了很多问题。

首先,最好使用兼容性类让代码在旧设备上运行。你可以在这里看到代码:

https://github.com/mixare/mixare/blob/master/src/org/mixare/Compatibility.java

然后,正如您在此处所见,您有责任在系统提供的预览列表中选择正确的一个: https://github.com/mixare/mixare/blob/master/src/org/mixare/MixView.java在第871行和正在进行中。

            List<Camera.Size> supportedSizes = null;
            //On older devices (<1.6) the following will fail
            //the camera will work nevertheless
            supportedSizes = Compatibility.getSupportedPreviewSizes(parameters);

            //preview form factor
            float ff = (float)w/h;
            Log.d("Mixare", "Screen res: w:"+ w + " h:" + h + " aspect ratio:" + ff);

            //holder for the best form factor and size
            float bff = 0;
            int bestw = 0;
            int besth = 0;
            Iterator<Camera.Size> itr = supportedSizes.iterator();

            //we look for the best preview size, it has to be the closest to the
            //screen form factor, and be less wide than the screen itself
            //the latter requirement is because the HTC Hero with update 2.1 will
            //report camera preview sizes larger than the screen, and it will fail
            //to initialize the camera
            //other devices could work with previews larger than the screen though
            while(itr.hasNext()) {
                Camera.Size element = itr.next();
                //current form factor
                float cff = (float)element.width/element.height;
                //check if the current element is a candidate to replace the best match so far
                //current form factor should be closer to the bff
                //preview width should be less than screen width
                //preview width should be more than current bestw
                //this combination will ensure that the highest resolution will win
                Log.d("Mixare", "Candidate camera element: w:"+ element.width + " h:" + element.height + " aspect ratio:" + cff);
                if ((ff-cff <= ff-bff) && (element.width <= w) && (element.width >= bestw)) {
                    bff=cff;
                    bestw = element.width;
                    besth = element.height;
                }
            } 
            Log.d("Mixare", "Chosen camera element: w:"+ bestw + " h:" + besth + " aspect ratio:" + bff);
            //Some Samsung phones will end up with bestw and besth = 0 because their minimum preview size is bigger then the screen size.
            //In this case, we use the default values: 480x320
            if ((bestw == 0) || (besth == 0)){
                Log.d("Mixare", "Using default camera parameters!");
                bestw = 480;
                besth = 320;
            }
            parameters.setPreviewSize(bestw, besth);

HTH 丹尼尔