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-tp4669293p4669293.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

Reply via email to