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
[email protected]
UNSUBSCRIBE INFORMATION:
http://lists.ximian.com/mailman/listinfo/monodroid