简体   繁体   English

在屏幕的一部分上使用android.view.SurfaceView和相机

[英]Using android.view.SurfaceView with a camera on part of the screen

I trying to put together an Android app that will take a picture and process it in some way. 我试图整理一个Android应用程序,它将以某种方式拍照并处理它。 I'd like the layout to be similar to Google Goggles. 我希望布局与Google Goggles类似。 Meaning, camera preview on the top, and some controls on the bottom using portrait orientation. 含义,顶部的相机预览,以及使用纵向方向的底部的一些控件。

I've built a first version using code sample from here . 我已经使用此处的代码示例构建了第一个版本。 This works, but I want to add a button on the bottom. 这有效,但我想在底部添加一个按钮。

I've modified my main.xml to look as follows (based on comments from this post): 我修改了我的main.xml,看起来如下(基于这篇文章的评论):

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

      <android.view.SurfaceView android:id="@+id/preview"
                              android:layout_width="fill_parent"
                              android:layout_height="fill_parent"
                              android:layout_alignParentTop="true" />

    <Button android:id="@+id/snap" 
            android:layout_width="wrap_content" 
            android:layout_height="wrap_content" 
            android:text="Snap"
            android:layout_alignParentBottom="true" />

</RelativeLayout>

But when I run this code I get the following exception: 但是当我运行此代码时,我得到以下异常:

E/AndroidRuntime(  199): Uncaught handler: thread main exiting due to uncaught exception
E/AndroidRuntime(  199): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.beerometer/com.beerometer.ImageCapture}: android.view.InflateException: Binary XML file line #6: Error inflating class Android.view.SurfaceView
E/AndroidRuntime(  199):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2496)
E/AndroidRuntime(  199):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)
E/AndroidRuntime(  199):    at android.app.ActivityThread.access$2200(ActivityThread.java:119)
E/AndroidRuntime(  199):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863)
E/AndroidRuntime(  199):    at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime(  199):    at android.os.Looper.loop(Looper.java:123)
E/AndroidRuntime(  199):    at android.app.ActivityThread.main(ActivityThread.java:4363)
E/AndroidRuntime(  199):    at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(  199):    at java.lang.reflect.Method.invoke(Method.java:521)
E/AndroidRuntime(  199):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
E/AndroidRuntime(  199):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
E/AndroidRuntime(  199):    at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime(  199): Caused by: android.view.InflateException: Binary XML file line #6: Error inflating class Android.view.SurfaceView
E/AndroidRuntime(  199):    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:576)
E/AndroidRuntime(  199):    at android.view.LayoutInflater.rInflate(LayoutInflater.java:618)
E/AndroidRuntime(  199):    at android.view.LayoutInflater.inflate(LayoutInflater.java:407)
E/AndroidRuntime(  199):    at android.view.LayoutInflater.inflate(LayoutInflater.java:320)
E/AndroidRuntime(  199):    at android.view.LayoutInflater.inflate(LayoutInflater.java:276)
E/AndroidRuntime(  199):    at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:198)
E/AndroidRuntime(  199):    at android.app.Activity.setContentView(Activity.java:1622)
E/AndroidRuntime(  199):    at com.beerometer.ImageCapture.onCreate(ImageCapture.java:37)
E/AndroidRuntime(  199):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
E/AndroidRuntime(  199):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2459)
E/AndroidRuntime(  199):    ... 11 more
E/AndroidRuntime(  199): Caused by: java.lang.ClassNotFoundException: Android.view.SurfaceView in loader dalvik.system.PathClassLoader@44bfc7b0
E/AndroidRuntime(  199):    at dalvik.system.PathClassLoader.findClass(PathClassLoader.java:243)
E/AndroidRuntime(  199):    at java.lang.ClassLoader.loadClass(ClassLoader.java:573)
E/AndroidRuntime(  199):    at java.lang.ClassLoader.loadClass(ClassLoader.java:532)
E/AndroidRuntime(  199):    at android.view.LayoutInflater.createView(LayoutInflater.java:466)
E/AndroidRuntime(  199):    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:565)
E/AndroidRuntime(  199):    ... 20 more

When I replace the SurfaceView above with something else, eg a TextView, that it displays, but in landscape. 当我用其他东西替换上面的SurfaceView时,例如TextView,它会显示,但是在横向上。

How can I get a camera preview on part of the screen using portrait view? 如何使用纵向视图在屏幕的一部分上进行相机预览?

Thanks 谢谢

First, your layout probably won't give you what you want. 首先,您的布局可能无法满足您的需求。 Consider using a RelativeLayout , with the Button anchored to the bottom, and the SurfaceView anchored to the top of the screen and the top of the Button . 考虑使用RelativeLayoutButton固定在底部, SurfaceView锚定在屏幕顶部和Button的顶部。

Also, you have a duplicate xmlns:android="http://schemas.android.com/apk/res/android" on your SurfaceView that you don't need. 此外,您在SurfaceView上有一个重复的xmlns:android="http://schemas.android.com/apk/res/android" ,您不需要。 The one on your root element will suffice. 根元素上的那个就足够了。

In terms of your exception, there may be more detail in your stack trace that you are missing, explaining why startPreview() failed. 就您的异常而言,您的堆栈跟踪中可能有更多您缺少的细节,解释了为什么startPreview()失败。 Look for a "Caused by" or other line mid-way through the stack trace. 在堆栈跟踪的中间寻找“由...引起”或其他线路。 If you can't identify it, edit your question and paste in the entire stack trace (and ping me via a comment on this answer, since I won't know about the edit otherwise). 如果您无法识别它,请编辑您的问题并粘贴整个堆栈跟踪(并通过对此答案的评论来ping我,因为我不会知道编辑否则)。

You might also experiment with this book example as another Camera preview app, to see if there's something about how I approach the problem that works better for your circumstance. 您也可以尝试将此书示例作为另一个Camera预览应用程序,以查看是否有关于我如何处理更适合您的环境的问题。

If I am not missing something, you cannot just use SurfaceView as is. 如果我没有遗漏某些东西,你不能只是按原样使用SurfaceView。 You need a derived class of your own. 你需要一个自己的派生类。 I usually create this view programmatically, and give it the full screen. 我通常以编程方式创建此视图,并将其全屏显示。 But you can cover parts of it with other views, including buttons: 但您可以使用其他视图覆盖部分视图,包括按钮:

 setContentView(new CameraView());
 View mainscreen = getLayoutInflater().inflate(R.layout.mainscreen, null, false);
 ViewGroup.LayoutParams generalLayoutParam = new ViewGroup.LayoutParams(
                    ViewGroup.LayoutParams.FILL_PARENT,
                    ViewGroup.LayoutParams.FILL_PARENT);
 addContentView(mainscreen, generalLayoutParam);

Yes you can use a surfaceView. 是的,你可以使用surfaceView。 From the surfaceView you can get the SurfaceHolder which then can be used to set the camera's previewDisplay. 在surfaceView中,您可以获得SurfaceHolder,然后可以使用它来设置相机的previewDisplay。

        SurfaceView preview = (SurfaceView) findViewById(R.id.cameraPreview);
    SurfaceHolder previewHolder = preview.getHolder();
    previewHolder.addCallback(surfaceCallback);
    previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

You'll need to implement the SurfaceHolder.Callback method in order to update the preview size properly. 您需要实现SurfaceHolder.Callback方法才能正确更新预览大小。 In surfaceCreated set the previewDisplay of the camera. 在surfaceCreated中设置相机的previewDisplay。 On surfaceChanged update the previewSize for the camera. 在surfaceChanged上更新相机的previewSize。

camera.setPreviewDisplay(previewHolder);

In fact the example mentioned before is a very good reference! 事实上前面提到的例子是一个非常好的参考!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM