我有我的monodroid活动,它调用相机活动,当它完成这样的回叫时
void TakePicture(string index, bool before = false)
{
if (cameraFaulted)
return;
var intent = new Intent(this, typeof(CameraActivity));
intent.PutExtra("index", index);
StartActivityForResult(intent, before ? IMGBEFORE : IMGAFTER);
}
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
switch (requestCode)
{
case IMGBEFORE:
if (resultCode == Result.Ok)
{
string filename = data.GetStringExtra("filename");
string idx = data.GetStringExtra("index");
if (!string.IsNullOrEmpty(filename))
LoadImage(filename, imgBefore);
var work = new WorkProgress();
if (workToDo.FirstOrDefault(t => t.ContainsKey(idx)).TryGetValue(idx, out work))
work.imageBefore = filename;
}
else
cameraFaulted = true;
break;
case IMGAFTER:
if (resultCode == Result.Ok)
{
string filename = data.GetStringExtra("filename");
string idx = data.GetStringExtra("index");
if (!string.IsNullOrEmpty(filename))
LoadImage(filename, imgBefore);
var work = new WorkProgress();
if (workToDo.FirstOrDefault(t => t.ContainsKey(idx)).TryGetValue(idx, out work))
work.imageAfter = filename;
}
else
cameraFaulted = true;
break;
}
}
对于第一张图片,这很好用。当我尝试拍摄另一张照片时,我得到了以下的回归
Exception connecting to the camera: Fail to connect to camera service-- at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000b] in <filename unknown>:0
at Android.Runtime.JNIEnv.CallStaticObjectMethod (IntPtr jclass, IntPtr jmethod) [0x00063] in /Users/builder/data/lanes/monodroid-mavericks-monodroid-5.1-series/d23da369/source/monodroid/src/Mono.Android/src/Runtime/JNIEnv.g.cs:1284
at Android.Hardware.Camera.Open () [0x0002d] in /Users/builder/data/lanes/monodroid-mavericks-monodroid-5.1-series/d23da369/source/monodroid/src/Mono.Android/platforms/android-15/src/generated/Android.Hardware.Camera.cs:4796
at workflow.CameraActivity.OnCreate (Android.OS.Bundle bundle) [0x000ad] in /Users/Paul/Developer/new version/workflow/workflow/Camera.cs:46
--- End of managed exception stack trace ---
java.lang.RuntimeException: Fail to connect to camera service
at android.hardware.Camera.native_setup(Native Method)
at android.hardware.Camera.<init>(Camera.java:413)
at android.hardware.Camera.open(Camera.java:384)
at md5bc8404a1b249f250f39d69a02ba90430.CameraActivity.n_onCreate(Native Method)
at md5bc8404a1b249f250f39d69a02ba90430.CameraActivity.onCreate(CameraActivity.java:40)
at android.app.Activity.performCreate(Activity.java:5372)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1104)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2257)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2349)
at android.app.ActivityThread.access$700(ActivityThread.java:159)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1316)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:176)
at android.app.ActivityThread.main(ActivityThread.java:5419)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1046)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:862)
at dalvik.system.NativeStart.main(Native Method)
让相机使用该应用程序的唯一方法是重置手机,这不是一个很好的解决方案!
我的相机活动看起来像这样
namespace workflow
{
[Activity(ScreenOrientation = Android.Content.PM.ScreenOrientation.Portrait)]
public class CameraActivity : Activity, Android.Hardware.Camera.IAutoFocusCallback, Android.Hardware.Camera.IPictureCallback,
Android.Hardware.Camera.IPreviewCallback, Android.Hardware.Camera.IShutterCallback, ISurfaceHolderCallback
{
Android.Hardware.Camera camera;
readonly string PictureName = Guid.NewGuid().ToString();
int number;
Context context;
ISurfaceHolder holder;
string fullFilename = "", index;
bool isRunning;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
number = 0;
SetContentView(Resource.Layout.TakePicture);
isRunning = false;
var btnTakePicture = FindViewById<Button>(Resource.Id.btnTakePicture);
var btnReturn = FindViewById<Button>(Resource.Id.btnReturn);
var surface = FindViewById<SurfaceView>(Resource.Id.surfaceCameraView);
index = base.Intent.GetStringExtra("index");
holder = surface.Holder;
holder.AddCallback(this);
holder.SetType(SurfaceType.PushBuffers);
holder.SetFixedSize(300, 300);
context = surface.Context;
try
{
if (camera == null)
camera = Android.Hardware.Camera.Open();
else
camera.Reconnect();
}
catch (RuntimeException ex)
{
Toast.MakeText(context, string.Format("Exception connecting to the camera: {0}--{1}", ex.Message, ex.StackTrace), ToastLength.Long).Show();
System.Console.WriteLine("Exception connecting to the camera: {0}--{1}", ex.Message, ex.StackTrace);
btnTakePicture.Enabled = false;
}
btnTakePicture.Click += delegate
{
var p = camera.GetParameters();
p.PictureFormat = Android.Graphics.ImageFormatType.Jpeg;
camera.SetParameters(p);
camera.TakePicture(this, this, this);
};
btnReturn.Click += (object sender, EventArgs e) =>
{
var resultData = new Intent();
resultData.PutExtra("filename", fullFilename);
SetResult((!string.IsNullOrEmpty(fullFilename) ? Result.Ok : Result.Canceled), resultData);
resultData.PutExtra("index", index);
Finish();
};
}
public void OnAutoFocus(bool focused, Android.Hardware.Camera camera)
{
if (focused)
{
Toast.MakeText(context, "Focused", ToastLength.Short).Show();
}
}
public void OnShutter()
{
}
public void SurfaceCreated(ISurfaceHolder holder)
{
try
{
if (camera != null)
{
var p = camera.GetParameters();
p.PictureFormat = Android.Graphics.ImageFormatType.Jpeg;
p.AutoExposureLock = true;
p.JpegQuality = 100;
camera.SetParameters(p);
camera.AutoFocus(this);
camera.SetPreviewCallback(this);
camera.Lock();
camera.SetPreviewDisplay(holder);
camera.StartPreview();
isRunning = true;
}
else
{
var resultData = new Intent();
SetResult(Result.Canceled, resultData);
resultData.PutExtra("index", index);
FinishActivity(1);
}
}
catch (IOException)
{
RunOnUiThread(delegate
{
GeneralUtils.Alert(context, "Error", "No preview available");
});
}
}
public void SurfaceDestroyed(ISurfaceHolder holder)
{
if (camera != null)
{
camera.StopPreview();
camera.SetPreviewCallback(null);
camera.Unlock();
camera.Release();
camera.Dispose();
camera = null;
}
}
public void SurfaceChanged(ISurfaceHolder holder, Android.Graphics.Format fmt, int width, int height)
{
}
public void OnPreviewFrame(byte[] data, Android.Hardware.Camera camera)
{
}
public void OnPictureTaken(byte[] data, Android.Hardware.Camera camera)
{
FileOutputStream output = null;
if (data != null)
{
fullFilename = System.IO.Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.MyDocuments), index + ".jpg");
try
{
output = new FileOutputStream(fullFilename);
output.Write(data);
output.Close();
}
catch (FileNotFoundException)
{
RunOnUiThread(delegate
{
GeneralUtils.Alert(context, "Error", "Unable to transfer image");
});
return;
}
catch (IOException)
{
RunOnUiThread(delegate
{
GeneralUtils.Alert(context, "Error", "No images taken");
});
isRunning = true;
camera.StartPreview();
return;
}
catch (System.Exception e)
{
#if DEBUG
System.Console.WriteLine("Exception thrown - {0}", e.Message);
#endif
return;
}
var f = new File(fullFilename);
try
{
var exifInterface = new ExifInterface(f.CanonicalPath);
exifInterface.SetAttribute("UserComment", string.Format("JobID:{0}", Guid.NewGuid()));
exifInterface.SetAttribute(ExifInterface.TagDatetime, DateTime.Now.ToString());
//exifInterface.SetAttribute(ExifInterface.TagGpsLatitude, Camera.Singleton.Latitude.ToString());
//exifInterface.SetAttribute(ExifInterface.TagGpsLongitude, Camera.Singleton.Longitude.ToString());
exifInterface.SaveAttributes();
}
catch (IOException)
{
RunOnUiThread(delegate
{
GeneralUtils.Alert(context, "Error", "Unable to store EXIF information");
});
isRunning = true;
camera.StartPreview();
return;
}
}
RunOnUiThread(() => Toast.MakeText(context, "Picture taken", ToastLength.Short).Show());
isRunning = true;
camera.StartPreview();
return;
}
}
}
我故意使用活动而不是内置摄像头(它需要在相机应用程序附带但没有配备相机的设备上工作)。该代码虽然在三星S3上进行了测试
答案 0 :(得分:0)
预览是否包含参考?也许您需要在camera.SetPreviewDisplay(null)
中致电SurfaceDestroyed(...)
?
答案 1 :(得分:0)
从SurfaceCreated()方法中删除camera.Lock()