最近我正在尝试在Xamarin制作Android应用程序,它将使用相机预览识别人物并测量摄影师与目标之间的距离。
要实现这一目标,我需要一个简单的相机预览,不需要捕捉任何图片,只需简单预览。
我能够打开相机并将其预览为全屏,但这不是我需要的。我的代码没有正确报告任何错误,应用程序部署和启动,但我的片段中的surfaceView是黑色的。 Logcat从Camera抛出一条消息,表明app传递了null surface。
我的MainActivity.cs:
using System;
using Android.App;
using Android.Graphics;
using Android.OS;
using Android.Views;
using Android.Widget;
namespace App1
{
[Activity(Label = "App1", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : Activity
{
bool color = false;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView (Resource.Layout.Main);
}
}
}
FirstFragment.cs - 它是带有surfaceView的片段(第二个片段只包含一个简单的textview,与案例无关):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Util;
using Android.Views;
using Android.Widget;
using Android.Hardware;
using Java.Lang;
namespace App1
{
public class FirstFragment : Fragment, ISurfaceHolderCallback
{
static Camera camera = null;
SurfaceView surfaceView;
ISurfaceHolder surfaceHolder;
private string tag = "FirstFragment";
public override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
start_camera();
// Create your fragment here
}
private void start_camera()
{
try
{
camera = Camera.Open();
}
catch (RuntimeException e)
{
Log.Error(tag, "init_camera: " + e);
return;
}
Camera.Parameters param;
param = camera.GetParameters();
//modify parameter
param.PreviewFrameRate = 20;
param.SetPreviewSize(176, 144);
camera.SetParameters(param);
try
{
//camera.SetPreviewDisplay(surfaceHolder);
//camera.StartPreview();
}
catch (Java.Lang.Exception e)
{
Log.Error(tag, "init_camera: " + e);
return;
}
}
public void SurfaceChanged(ISurfaceHolder arg0, Android.Graphics.Format arg1, int arg2, int arg3)
{
// TODO Auto-generated method stub
}
public void SurfaceCreated(ISurfaceHolder holder)
{
// TODO Auto-generated method stub
}
public void SurfaceDestroyed(ISurfaceHolder holder)
{
Log.Error(tag, "surfaceDestroyed() is called");
// Stop preview and release camera
if (holder.Surface != null)
{
camera.StopPreview();
//mCamera.release(); //should we release camera here?
//mCamera = null;
}
else
{
Log.Error(tag, "surfaceDestroyed(): preview surface does not exist");
}
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = inflater.Inflate(Resource.Layout.FirstFragment, container, false);
surfaceView = view.FindViewById<SurfaceView>(Resource.Id.surfaceView1);
surfaceHolder = surfaceView.Holder;
surfaceHolder.AddCallback(this);
camera.SetPreviewDisplay(surfaceHolder);
camera.StartPreview();
surfaceHolder.SetType(SurfaceType.PushBuffers);
return view;
}
}
}
这是布局:
主:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/linearLayout1">
<fragment
android:name="App1.FirstFragment"
android:layout_width="match_parent"
android:layout_height="279.5dp"
android:id="@+id/fragment1" />
<fragment
android:name="App1.SecondFragment"
android:layout_width="match_parent"
android:layout_height="125.0dp"
android:id="@+id/fragment2" />
</LinearLayout>
和FirstFragment:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minWidth="25px"
android:minHeight="25px">
<SurfaceView
android:layout_width="match_parent"
android:layout_height="200dp"
android:id="@+id/surfaceView1"
android:layout_marginTop="0.0dp" />
</LinearLayout>
我知道原因可能很简单,但我做了很多研究,如何修复它却没有成功。