需要的例子拍照与MonoDroid和MVVMCross例子、MonoDroid、MVVMCross

由网友(欧no买噶)分享简介:任何人都可以点我的例子拍摄照片,并使用储存 MVVMCross 我一直在寻找,但只发现了这一点:Monodroid采取与相机图片(不实施MVVMCross) 视频录制(它的视频,我不能使它发挥作用:S) 的Oficialy配方实例(它的工作原理,但没有实现MVVMCross) 谢谢! 解决!谢谢!要备将来参考:(使...

任何人都可以点我的例子拍摄照片,并使用储存 MVVMCross

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

Monodroid采取与相机图片(不实施MVVMCross)

视频录制(它的视频,我不能使它发挥作用:S)

的Oficialy配方实例(它的工作原理,但没有实现MVVMCross)

谢谢!

  

解决!谢谢!   要备将来参考:(使用主科)   的积分斯图尔特,​​我只是改变了code与我的实际工作的

 使用Cirrious.MvvmCross.ExtensionMethods;
使用Cirrious.MvvmCross.Interfaces.Platform.Tasks;
使用Cirrious.MvvmCross.Interfaces.ServiceProvider;
使用SIGEP.DummyService;
使用SIGEP.Mobile.Core.Interfaces;


命名空间SIGEP.Mobile.Core.Models
{
 公共类照片服务:IMvxServiceConsumer< IMvxPictureChooserTask>
{
    私人const int的MaxPixelDimension = 1024;
    私人const int的DefaultJpegQuality = 92;

    公共无效GetNewPhoto()
    {
        this.GetService< IMvxPictureChooserTask>()TakePicture(。
            MaxPixelDimension,
            DefaultJpegQuality,
            HandlePhotoAvailable,
            ()=> {/ *取消被忽略* /});

    }

    公共事件的EventHandler< PhotoStreamEventArgs> PhotoStreamAvailable;

    私人无效HandlePhotoAvailable(流pictureStream)
    {
        VAR处理器= PhotoStreamAvailable;
        如果(处理!= NULL)
        {
            处理程序(这一点,新PhotoStreamEventArgs(){PictureStream = pictureStream,OnSucessGettingPhotoFileName = OnSucessGettingPhotoFileName});
        }
    }



    公共静态无效TakePhoto(动作<字符串> successFileName,动作<异常>错误)
    {
        VAR的服务=新的照片服务();
        service.OnSucessGettingPhotoFileName = successFileName;
        service.OnError =错误;
        service.GetNewPhoto();
        service.PhotoStreamAvailable + =新的EventHandler< PhotoStreamEventArgs>(service_PhotoStreamAvailable);
    }

    静态无效service_PhotoStreamAvailable(对象发件人,PhotoStreamEventArgs E)
    {
        // Grava酒店PRA ficheiro!
        var目录= Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
        变种文件名= Path.Combine(目录,photo.jpeg);
        字符串saveTo =文件名;
        的FileStream writeStream =新的FileStream(saveTo,FileMode.Create,FileAccess.Write);
        ReadWriteStream(e.PictureStream,writeStream);

        e.OnSucessGettingPhotoFileName(文件名);

    }
    私有静态无效ReadWriteStream(流readStream,流writeStream)
    {
        INT长度= 256;
        字节[]缓冲区=新的字节[长度];
        INT读取动作= readStream.Read(缓冲液,0,长度);
        //写所需的字节
        而(读取动作大于0)
        {
            writeStream.Write(缓冲液,0,读取动作);
            读取动作= readStream.Read(缓冲液,0,长度);
        }
        readStream.Close();
        writeStream.Close();
    }

    公益行动<字符串> OnSucessGettingPhotoFileName {获得;组; }
    公益行动<异常>的OnError {获得;组; }
}

[可序列化]
[标记有ComVisible特性(真)
公共类PhotoStreamEventArgs:EventArgs的
{
    公共流PictureStream {获得;组; }

    公益行动<字符串> OnSucessGettingPhotoFileName {获得;组; }
}
}
 
产品设计细节研究 戴着锁链跳舞

解决方案

我通常使用内置的 IMvxPictureChooserTask (这是一个插件,如果使用vNext实现服务):

 使用Cirrious.MvvmCross.ExtensionMethods;
使用Cirrious.MvvmCross.Interfaces.Platform.Tasks;
使用Cirrious.MvvmCross.Interfaces.ServiceProvider;

公共类照片服务
    :IMvxServiceConsumer< IMvxPictureChooserTask>
    ,IPhotoService
{
    私人const int的MaxPixelDimension = 1024;
    私人const int的DefaultJpegQuality = 92;

    公共无效GetNewPhoto()
    {
        Trace.Info(获取新的照片开始了。);

        this.GetService< IMvxPictureChooserTask>()TakePicture(。
            MaxPixelDimension,
            DefaultJpegQuality,
            HandlePhotoAvailable,
            ()=> {/ *取消被忽略* /});
    }

    公共事件的EventHandler< PhotoStreamEventArgs> PhotoStreamAvailable;

    私人无效HandlePhotoAvailable(流pictureStream)
    {
        Trace.Info(提供图片);
        VAR处理器= PhotoStreamAvailable;
        如果(处理!= NULL)
        {
            处理程序(这一点,新PhotoStreamEventArgs(){PictureStream = pictureStream});
        }
    }
}
 

我一般注册该服务在启动期间一个单,然后从一个ViewModel的ICommand处理程序调用它。

一个应用程序,它使用该服务的 Blooor 样本 - 见 BaseEditProductViewModel.cs - 这是不是一个样我有什么关系,但我相信它带来了两个拍照和ZXing - 两者都使用外部服务

一个警告:在MonoDroid,你可以看到一些奇怪的/出乎意料活动/视图模型的生命周期行为 - 基本上你可以看到,活动你从被卸载/照片在拍照从内存抹去。如果发生这种情况,您的应用程序,那么你可能需要开始寻找这样的问题:节能活动状态在Android的 - 这不是自动MvvmCross(还)办理

我相信Blooor样品可能受到这个问题 - 但用户是否会永远看到它在正常的应用程序使用的是值得商榷的。

作为替代 IMvxPictureChooserTask 服务,您也可以看看使用一些从Xamarin.Mobile跨平台API - 看MvvmCross vnext:monodroid使用VideoView插件里面一个可能的起点 - 或为Android只有你可以很容易地实现自己的

Can anyone point me to an example of take a Photo and store it using MVVMCross?

I have been searching but only have found this:

Monodroid Take a picture with Camera (Doesn't Implement MVVMCross)

Video Recording (It's Video and i can't make it work :S)

The Oficialy Recipe Example (It Works but does not implement MVVMCross)

Thanks!!!

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, 0, Length);
        // write the required bytes
        while (bytesRead > 0)
        {
            writeStream.Write(buffer, 0, bytesRead);
            bytesRead = readStream.Read(buffer, 0, 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; }
}
}

解决方案

I generally implement a service using the built-in IMvxPictureChooserTask (this is in a Plugin if using 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,
            DefaultJpegQuality,
            HandlePhotoAvailable,
            () => { /* 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 });
        }
    }
}

I generally register this service as a singleton during startup, and then call it from a ViewModel ICommand handler.

One app which uses this service is the Blooor sample - see BaseEditProductViewModel.cs - this isn't a sample I had anything to do with, but I believe it brings in both Picture taking and ZXing - both using external services.

One warning: On MonoDroid, you can see some strange/unexpected Activity/ViewModel lifecycle behaviour - basically you can see that the Activity you take the photo from is unloaded/wiped from memory during the photo taking. If this happens to your app then you'll probably need to start looking at questions like: Saving Activity state in Android - this isn't automatically handled in MvvmCross (yet).

I believe the Blooor sample might suffer from this issue - but whether a user would ever see it in normal app use is debatable.

As an alternative to the IMvxPictureChooserTask service, you can also look at using some of the cross-platform APIs from Xamarin.Mobile - see MvvmCross vnext : monodroid use a VideoView inside a plugin for a possible starting place - or for Android only you can easily implement your own.

阅读全文

相关推荐

最新文章