第一次使用后相机无法连接

时间:2015-04-30 11:37:11

标签: android camera xamarin.android

我有我的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上进行了测试

2 个答案:

答案 0 :(得分:0)

预览是否包含参考?也许您需要在camera.SetPreviewDisplay(null)中致电SurfaceDestroyed(...)

答案 1 :(得分:0)

从SurfaceCreated()方法中删除camera.Lock()

相关问题