android – 需要一个用MonoDroid和MVVMCross拍照的例子

前端之家收集整理的这篇文章主要介绍了android – 需要一个用MonoDroid和MVVMCross拍照的例子前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
任何人都可以指出我拍摄照片并使用MVVMCross存储它的例子吗?

我一直在寻找,但只发现了这个:

> Monodroid Take a picture with Camera(不实施MVVMCross)
> Video Recording(这是视频,我不能使它工作:S)
> The Oficialy Recipe Example(虽然有效,但未实施MVVMCross)

谢谢!!!

Resolved! Thanks!

To Future References: (Using Master Branch)

Credits to Stuart,I just changed the code to work with my reality

using CirrIoUs.MvvmCross.ExtensionMethods;
using CirrIoUs.MvvmCross.Interfaces.Platform.Tasks;
using CirrIoUs.MvvmCross.Interfaces.ServiceProvider;
using SIGEP.DummyService;
using SIGEP.Mobile.Core.Interfaces;


namespace SIGEP.Mobile.Core.Models
{
 public class PhotoService : IMvxServiceConsumer<IMvxPictureChooserTask>
{
    private const int MaxPixelDimension = 1024;
    private const int DefaultJpegQuality = 92;

    public void GetNewPhoto()
    {
        this.GetService<IMvxPictureChooserTask>().TakePicture(
            MaxPixelDimension,DefaultJpegQuality,HandlePhotoAvailable,() => { /* cancel is ignored */ });

    }

    public event EventHandler<PhotoStreamEventArgs> PhotoStreamAvailable;

    private void HandlePhotoAvailable(Stream pictureStream)
    {
        var handler = PhotoStreamAvailable;
        if (handler != null)
        {
            handler(this,new PhotoStreamEventArgs() { PictureStream = pictureStream,OnSucessGettingPhotoFileName = OnSucessGettingPhotoFileName });
        }
    }



    public static void TakePhoto(Action<string> successFileName,Action<Exception> error)
    {
        var service = new PhotoService();
        service.OnSucessGettingPhotoFileName = successFileName;
        service.OnError = error;
        service.GetNewPhoto();
        service.PhotoStreamAvailable += new EventHandler<PhotoStreamEventArgs>(service_PhotoStreamAvailable);
    }

    static void service_PhotoStreamAvailable(object sender,PhotoStreamEventArgs e)
    {
        //grava pra ficheiro!!!
        var directory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
        var filename = Path.Combine(directory,"photo.jpeg");
        string saveTo = filename;
        FileStream writeStream = new FileStream(saveTo,FileMode.Create,FileAccess.Write);
        ReadWriteStream(e.PictureStream,writeStream);

        e.OnSucessGettingPhotoFileName(filename);

    }
    private static void ReadWriteStream(Stream readStream,Stream writeStream)
    {
        int Length = 256;
        Byte[] buffer = new Byte[Length];
        int bytesRead = readStream.Read(buffer,Length);
        // write the required bytes
        while (bytesRead > 0)
        {
            writeStream.Write(buffer,bytesRead);
            bytesRead = readStream.Read(buffer,Length);
        }
        readStream.Close();
        writeStream.Close();
    }

    public Action<string> OnSucessGettingPhotoFileName { get; set; }
    public Action<Exception> OnError { get; set; }
}

[Serializable]
[ComVisible(true)]
public class PhotoStreamEventArgs : EventArgs
{
    public Stream PictureStream { get; set; }

    public Action<string> OnSucessGettingPhotoFileName { get; set; }
}
}

解决方法

我通常使用内置的IMvxPictureChooserTask实现一个服务(如果使用vNext,这是一个插件):
using CirrIoUs.MvvmCross.ExtensionMethods;
using CirrIoUs.MvvmCross.Interfaces.Platform.Tasks;
using CirrIoUs.MvvmCross.Interfaces.ServiceProvider;

public class PhotoService 
    : IMvxServiceConsumer<IMvxPictureChooserTask>,IPhotoService
{
    private const int MaxPixelDimension = 1024;
    private const int DefaultJpegQuality = 92;

    public void GetNewPhoto()
    {
        Trace.Info("Get a new photo started.");

        this.GetService<IMvxPictureChooserTask>().TakePicture(
            MaxPixelDimension,() => { /* cancel is ignored */ });
    }

    public event EventHandler<PhotoStreamEventArgs> PhotoStreamAvailable;

    private void HandlePhotoAvailable(Stream pictureStream)
    {
        Trace.Info("Picture available");
        var handler = PhotoStreamAvailable;
        if (handler != null)
        {
            handler(this,new PhotoStreamEventArgs() { PictureStream = pictureStream });
        }
    }
}

我通常在启动期间将此服务注册为单例,然后从viewmodel ICommand处理程序调用它.

一个使用这项服务的应用程序是Blooor样本 – 见BaseEditProductViewModel.cs – 这不是我有任何关系的样本,但我相信它带来了Picture take和ZXing – 两者都使用外部服务.

一个警告:在MonoDroid上,您可以看到一些奇怪/意外的Activity / viewmodel生命周期行为 – 基本上您可以看到拍摄照片的活动是在拍照期间从内存中卸载/擦除的.如果您的应用程序发生这种情况,那么您可能需要开始查看类似的问题:Saving Android Activity state using Save Instance State – 这不会在MvvmCross中自动处理(尚未).

我相信Blooor样本可能会遇到这个问题 – 但用户是否会在正常的应用程序中看到它是值得商榷的.

作为IMvxPictureChooserTask服务的替代方案,您还可以查看使用Xamarin.Mobile中的一些跨平台API – 请参阅MvvmCross vnext : monodroid use a VideoView inside a plugin获取可能的起始位置 – 或者仅限Android,您可以轻松实现自己的.

猜你在找的Android相关文章