5

谁能指出我拍摄照片并使用它存储MVVMCross的示例?

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

谢谢!!!

解决!谢谢!
对未来的参考:(使用 Master 分支)
感谢 Stuart,我只是更改了代码以适应我的现实

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; }
}
}
4

1 回答 1

3

我通常使用内置实现服务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,
            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 });
        }
    }
}

我一般在启动时将此服务注册为单例,然后从 ViewModel ICommand 处理程序中调用它。


使用此服务的一个应用程序是Blooor示例 - 请参阅BaseEditProductViewModel.cs - 这不是我与之有任何关系的示例,但我相信它带来了拍照和 ZXing - 两者都使用外部服务。


一个警告:在 MonoDroid 上,您可以看到一些奇怪/意外的 Activity/ViewModel 生命周期行为 - 基本上您可以看到您从中拍照的 Activity 在拍照期间从内存中卸载/擦除。如果您的应用发生这种情况,那么您可能需要开始查看以下问题:使用 Save Instance State 保存 Android Activity 状态- 这在 MvvmCross 中不会自动处理(目前)。

我相信 Blooor 样本可能会遇到这个问题 - 但用户是否会在正常的应用程序使用中看到它是有争议的。


作为该IMvxPictureChooserTask服务的替代方案,您还可以查看使用 Xamarin.Mobile 中的一些跨平台 API - 请参阅MvvmCross vnext:monodroid 在插件中使用 VideoView 作为可能的起始位置 - 或者仅适用于 Android,您可以轻松实现你自己。

于 2012-11-20T15:11:19.710 回答