Does anyone have any advice for this issue? Doesn't look liek anyone's looked at it!
Hi. I'm trying to implement an activity which previews the camera and allows a picture to be taken. However I get rather mixed results with each build. One time it will work fine, but I might make a change such as adding a comment and re-compile and I get an error when setting the ISurfaceHolderCallback, then I might take the comment out and re-compile and I get a page fault, then I can do something else and it works again! It seems that it's compile/build related because if I build and it happens to work it will always work; but if I build and it crashes then it will always crash. The below failed with the exception shown, then I took the '.' off the end of the comment, re-compiled and it then worked!!! Is there an issue here or am I failing to set something up properly? I'm running this on a Dell Streak 5. This is a snapshot from ADB of one of the errors: I/ActivityManager( 146): Starting activity: Intent { cmp=uk.co.reach.reachcloud/reachmobilecc.PictureActivity } I/CameraView( 2699): Adding Callback F/PrintK ( 2699): <2>Exception!!! each.reachcloud: unhandled page fault (11) at 0xed006d4e, code 0x005 I/MonoDroid( 2699): UNHANDLED EXCEPTION: System.NullReferenceException: Object reference not set to an instance of an object I/MonoDroid( 2699): at Android.Views.ISurfaceHolderCallbackAdapter.GetHandle (Android.Views.ISurfaceHolderCallback) <0x00038> I/MonoDroid( 2699): at Android.Views.ISurfaceHolderInvoker.AddCallback (Android.Views.ISurfaceHolderCallback) <0x000bf> I/MonoDroid( 2699): at ReachMobileCC.PictureActivity.OnResume () <0x00073> I/MonoDroid( 2699): at Android.App.Activity.n_OnResume (intptr,intptr) <0x00033> I/MonoDroid( 2699): at (wrapper dynamic-method) object.38c0d09b-61f8-491e-b367-fbed8a6fb14a (intptr,intptr) <0x0002b> E/mono ( 2699): E/mono ( 2699): Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object E/mono ( 2699): at Android.Views.ISurfaceHolderCallbackAdapter.GetHandle (ISurfaceHolderCallback instance) [0x00000] in <filename unknown>:0 E/mono ( 2699): at Android.Views.ISurfaceHolderInvoker.AddCallback (ISurfaceHolderCallback callback) [0x00000] in <filename unknown>:0 E/mono ( 2699): at ReachMobileCC.PictureActivity.OnResume () [0x00000] in <filename unknown>:0 E/mono ( 2699): at Android.App.Activity.n_OnResume (IntPtr jnienv, IntPtr native__this) [0x00000] in <filename unknown>:0 E/mono ( 2699): at (wrapper dynamic-method) object:38c0d09b-61f8-491e-b367-fbed8a6fb14a (intptr,intptr) I/ActivityManager( 146): Process uk.co.reach.reachcloud (pid 2699) has died. This is the activity class: using System; using System.Collections.Generic; using System.Linq; using System.Text; using Android.App; using Android.Content; using Android.Hardware; using Android.OS; using Android.Runtime; using Android.Views; using Android.Widget; using Android.Util; namespace ReachMobileCC { [Activity(Label = "@string/TakePicture", ConfigurationChanges = Android.Content.PM.ConfigChanges.Orientation | Android.Content.PM.ConfigChanges.Keyboard | Android.Content.PM.ConfigChanges.KeyboardHidden)] public class PictureActivity : Activity, ISurfaceHolderCallback, Camera.IPictureCallback { #region Fields private bool _previewing = false; private Camera _camera = null; #endregion public static byte[] JpegData { get; set; } #region Event Handlers protected override void OnCreate(Bundle bundle) { base.OnCreate(bundle); SetContentView(Resource.Layout.Picture); FindViewById<Button>(Resource.Id.TakePicture).Click += TakePictureClick; } protected override void OnResume() { base.OnResume(); var holder = FindViewById<SurfaceView>(Resource.Id.PicturePreview).Holder; Log.Info("CameraView", "Adding Callback"); holder.AddCallback(this); Log.Info("CameraView", "Added Callback"); holder.SetType(SurfaceType.PushBuffers); } public override bool OnKeyDown(Keycode keyCode, KeyEvent e) { if (keyCode == Keycode.Back && _previewing) { StopPreviewAndExit(false); return true; } if ((keyCode == Keycode.Camera || keyCode == Keycode.DpadCenter) && _previewing) { TakePictureClick(this, new EventArgs()); return true; } return base.OnKeyDown(keyCode, e); } void TakePictureClick(object sender, EventArgs e) { if (_camera != null) _camera.TakePicture(null, null, this); } #endregion #region ISurfaceHolderCallback Members public void SurfaceChanged(ISurfaceHolder holder, int format, int width, int height) { if (_camera != null) { if (_previewing) _camera.StopPreview(); var parameters = _camera.GetParameters(); var previewSize = GetNearestPreviewSize(parameters.SupportedPreviewSizes, width, height); parameters.SetPreviewSize(previewSize.Width, previewSize.Height); if (parameters.SupportedFocusModes.Contains(Camera.Parameters.FocusModeAuto)) parameters.FocusMode = Camera.Parameters.FocusModeAuto; else if (parameters.SupportedFocusModes.Contains(Camera.Parameters.FocusModeInfinity)) parameters.FocusMode = Camera.Parameters.FocusModeInfinity; parameters.SetRotation(90); // TODO: Match to window orientation. _camera.SetParameters(parameters); _camera.SetPreviewDisplay(holder); _camera.StartPreview(); _previewing = true; } } public void SurfaceCreated(ISurfaceHolder holder) { _camera = Android.Hardware.Camera.Open(); } public void SurfaceDestroyed(ISurfaceHolder holder) { StopPreview(); } #endregion #region IPictureCallback Members public void OnPictureTaken(byte[] data, Android.Hardware.Camera camera) { JpegData = data; StopPreviewAndExit(true); } #endregion #region Helper Methods private Camera.Size GetNearestPreviewSize(IList<Camera.Size> sizes, int width, int height) { Camera.Size nearestSize = sizes[0]; int diff = 99999; foreach (var size in sizes) { if (size.Width > width || size.Height > height) continue; var comp = (width - size.Width) + (height - size.Height); if (comp < diff) { comp = diff; nearestSize = size; } } return nearestSize; } public void StopPreview() { if (_camera != null) { _camera.StopPreview(); _camera.Release(); _camera = null; } } public void StopPreviewAndExit(bool ok) { StopPreview(); SetResult(ok ? Result.Ok : Result.Canceled, new Intent(this.ApplicationContext, typeof(PictureActivity))); Finish(); } #endregion } } This is the layout: <?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"> <Button android:id="@+id/TakePicture" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/TakePicture" android:layout_alignParentBottom="true" /> <SurfaceView android:id="@+id/PicturePreview" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_above="@id/TakePicture" /> </RelativeLayout> -- View this message in context: http://mono-for-android.1047100.n5.nabble.com/SurfaceHolder-AddCallback-random-errors-tp4669293p4678027.html Sent from the Mono for Android mailing list archive at Nabble.com. _______________________________________________ Monodroid mailing list Monodroid@lists.ximian.com UNSUBSCRIBE INFORMATION: http://lists.ximian.com/mailman/listinfo/monodroid