示例#1
0
 private void VerifyOptions(StoreMediaOptions options)
 {
     if (options == null)
     {
         throw new ArgumentNullException(nameof(options));
     }
 }
示例#2
0
        private Intent CreateMediaIntent(int id, string type, string action, StoreMediaOptions options, bool tasked = true)
        {
            Intent pickerIntent = new Intent(this.context, typeof(MediaPickerActivity));

            pickerIntent.PutExtra(MediaPickerActivity.ExtraId, id);
            pickerIntent.PutExtra(MediaPickerActivity.ExtraType, type);
            pickerIntent.PutExtra(MediaPickerActivity.ExtraAction, action);
            pickerIntent.PutExtra(MediaPickerActivity.ExtraTasked, tasked);

            if (options != null)
            {
                pickerIntent.PutExtra(MediaPickerActivity.ExtraPath, options.Directory);
                pickerIntent.PutExtra(MediaStore.Images.ImageColumns.Title, options.Name);

                var vidOptions = (options as StoreVideoOptions);
                if (vidOptions != null)
                {
                    pickerIntent.PutExtra(MediaStore.ExtraDurationLimit, (int)vidOptions.DesiredLength.TotalSeconds);
                    pickerIntent.PutExtra(MediaStore.ExtraVideoQuality, (int)vidOptions.Quality);
                }
            }
            //pickerIntent.SetFlags(ActivityFlags.ClearTop);
            pickerIntent.SetFlags(ActivityFlags.NewTask);
            return(pickerIntent);
        }
示例#3
0
 private void VerifyCameraOptions(StoreMediaOptions options)
 {
     this.VerifyOptions(options);
     //if (!Enum.IsDefined(typeof(CameraFacingDirection), options.DefaultCamera))
     //{
     //    throw new ArgumentException("options.Camera is not a member of CameraDevice");
     //}
 }
示例#4
0
        /// <summary>
        ///     Take a photo async with specified options
        /// </summary>
        /// <param name="options">Camera Media Options</param>
        /// <returns>Media file of photo or null if canceled</returns>
        public Task <MediaFile> TakePhotoAsync(StoreMediaOptions options)
        {
            if (!this.IsCameraAvailable)
            {
                throw new NotSupportedException();
            }

            return(this.TakeMediaAsync("image/*", MediaStore.ActionImageCapture, options));
        }
示例#5
0
        // TODO GATH: Consider this way
        // http://developer.xamarin.com/recipes/android/other_ux/camera_intent/take_a_picture_and_save_using_camera_app/
        // http://stackoverflow.com/questions/21957599/xamarin-android-issue-reading-locally-stored-photo-from-camera-no-read-acces
        ////private void TakeAPicture(object sender, EventArgs eventArgs)
        ////{
        ////    Intent intent = new Intent(MediaStore.ActionImageCapture);
        ////    App._file = new File(App._dir, String.Format("myPhoto_{0}.jpg", Guid.NewGuid()));
        ////    intent.PutExtra(MediaStore.ExtraOutput, Uri.FromFile(App._file));
        ////    StartActivityForResult(intent, 0);
        ////}


        /// <inheritdoc />
        public async Task <MediaFile> TakePhotoAsync(StoreMediaOptions options)
        {
            if (!this.IsEnabled)
            {
                throw new NotSupportedException();
            }

            int id = this.GetRequestId();

            this.tracer.Debug("TakePhotoAsync with RequestId={0}", id);

            var ntcs = new TaskCompletionSource <MediaFile>(id);

            if (Interlocked.CompareExchange(ref this.completionSource, ntcs, null) != null)
            {
                throw new InvalidOperationException("Only one operation can be active at a time");
            }

            var cameraActivityIntent = this.CreateCameraIntent(options, id);

            this.context.StartActivity(cameraActivityIntent);

            EventHandler <MediaPickedEventArgs> handler = null;

            handler = (s, e) =>
            {
                this.tracer.Debug("EventHandler<MediaPickedEventArgs> fired");
                var tcs = Interlocked.Exchange(ref this.completionSource, null);

                Camera2BasicFragment.MediaPicked -= handler;

                if (e.RequestId != id)
                {
                    this.tracer.Warning("RequestId={0} does not match with {1}", id, e.RequestId);
                    return;
                }

                if (e.Error != null)
                {
                    tcs.SetResult(null);
                }
                else if (e.IsCanceled)
                {
                    this.tracer.Debug("EventHandler<MediaPickedEventArgs> IsCanceled");
                    tcs.SetResult(null);
                }
                else
                {
                    this.tracer.Debug("EventHandler<MediaPickedEventArgs> media returned: {0}", e.Media.Filename);
                    tcs.SetResult(e.Media);
                }
            };

            Camera2BasicFragment.MediaPicked += handler;

            return(await ntcs.Task);
        }
示例#6
0
        /// <summary>
        /// </summary>
        /// <param name="options"></param>
        /// <returns></returns>
        public Intent GetTakePhotoUI(StoreMediaOptions options)
        {
            if (!this.IsCameraAvailable)
            {
                throw new NotSupportedException();
            }

            int id = this.GetRequestId();

            return(this.CreateMediaIntent(id, "image/*", MediaStore.ActionImageCapture, options, tasked: false));
        }
示例#7
0
        internal MediaPickerDelegate(UIViewController viewController, UIImagePickerControllerSourceType sourceType, StoreMediaOptions options)
        {
            this.viewController = viewController;
            this.source         = sourceType;
            this.options        = options ?? new StoreMediaOptions();

            if (viewController != null)
            {
                UIDevice.CurrentDevice.BeginGeneratingDeviceOrientationNotifications();
                this.observer = NSNotificationCenter.DefaultCenter.AddObserver(UIDevice.OrientationDidChangeNotification, this.DidRotate);
            }
        }
示例#8
0
        private Intent CreateCameraIntent(StoreMediaOptions options, int id)
        {
            Intent pickerIntent = new Intent(this.context, typeof(CameraActivity));

            pickerIntent.PutExtra(Camera2BasicFragment.ExtraId, id);
            pickerIntent.PutExtra(Camera2BasicFragment.ExtraPath, options.Directory);
            pickerIntent.PutExtra(Camera2BasicFragment.ExtraFilename, options.Name);
            pickerIntent.PutExtra(Camera2BasicFragment.ExtraCameraFacingDirection, Camera2BasicFragment.ToLensFacingInteger(this.CameraFacingDirection));

            Tracer.Create(this).Debug("CreateCameraIntent: ExtraCameraFacingDirection={0}", Camera2BasicFragment.ToLensFacingInteger(this.CameraFacingDirection));

            pickerIntent.SetFlags(ActivityFlags.NewTask);
            return(pickerIntent);
        }
示例#9
0
        /// <inheritdoc />
        public Task <MediaFile> PickPhotoAsync(PickMediaOptions options = null)
        {
            options = options ?? new PickMediaOptions();

            this.CheckPhotoUsageDescription();

            // TODO Use inheritance here
            var cameraOptions = new StoreMediaOptions
            {
                PhotoSize = options.PhotoSize, CompressionQuality = options.CompressionQuality
            };

            return(this.GetMediaAsync(UIImagePickerControllerSourceType.PhotoLibrary, Constants.TypeImage, cameraOptions));
        }
示例#10
0
        /// <inheritdoc />
        public async Task <MediaFile> TakePhotoAsync(StoreMediaOptions options) // TODO GATH: link from WindowsStore assembly
        {
            if (!this.IsEnabled)
            {
                throw new NotSupportedException();
            }

            var capture = new CameraCaptureUI();
            ////capture.PhotoSettings.Format = CameraCaptureUIPhotoFormat.Jpeg;
            ////capture.PhotoSettings.MaxResolution = CameraCaptureUIMaxPhotoResolution.HighestAvailable;

            var result = await capture.CaptureFileAsync(this.deviceInformation.Id);

            if (result == null)
            {
                return(null);
            }


            StorageFolder rootFolder = ApplicationData.Current.LocalFolder;

            string targetFilePath = options.GetFilePath(rootFolder.Path);
            var    directoryPath  = Path.GetDirectoryName(targetFilePath);
            var    directoryName  = options.Directory;

            if (!string.IsNullOrWhiteSpace(directoryName))
            {
                var exists = await FolderExistsAsync(rootFolder, directoryPath);

                if (!exists)
                {
                    await rootFolder.CreateFolderAsync(directoryName, CreationCollisionOption.ReplaceExisting);
                }
            }

            rootFolder = await StorageFolder.GetFolderFromPathAsync(directoryPath);

            string targetFilename = Path.GetFileName(targetFilePath);

            var file = await result.CopyAsync(rootFolder, targetFilename, NameCollisionOption.ReplaceExisting).AsTask().ConfigureAwait(false);

            Stream stream = await file.OpenStreamForReadAsync().ConfigureAwait(false);

            return(new MediaFile(file.Path, () => stream));
        }
示例#11
0
        private Task <MediaFile> TakeMediaAsync(string type, string action, StoreMediaOptions options)
        {
            int id = this.GetRequestId();

            var ntcs = new TaskCompletionSource <MediaFile>(id);

            if (Interlocked.CompareExchange(ref this.completionSource, ntcs, null) != null)
            {
                throw new InvalidOperationException("Only one operation can be active at a time");
            }

            this.context.StartActivity(this.CreateMediaIntent(id, type, action, options));

            EventHandler <MediaPickedEventArgs> handler = null;

            handler = (s, e) =>
            {
                var tcs = Interlocked.Exchange(ref this.completionSource, null);

                MediaPickerActivity.MediaPicked -= handler;

                if (e.RequestId != id)
                {
                    return;
                }

                if (e.Error != null)
                {
                    tcs.SetResult(null);
                }
                else if (e.IsCanceled)
                {
                    tcs.SetResult(null);
                }
                else
                {
                    tcs.SetResult(e.Media);
                }
            };

            MediaPickerActivity.MediaPicked += handler;

            return(ntcs.Task);
        }
示例#12
0
        /// <summary>
        ///     Take a photo async with specified options
        /// </summary>
        /// <param name="options">Camera Media Options</param>
        /// <returns>Media file of photo or null if canceled</returns>
        public Task <MediaFile> TakePhotoAsync(StoreMediaOptions options)
        {
            if (!this.IsCameraAvailable)
            {
                throw new NotSupportedException();
            }

            options.VerifyOptions();

            var ntcs = new TaskCompletionSource <MediaFile>(options);

            if (Interlocked.CompareExchange(ref completionSource, ntcs, null) != null)
            {
                throw new InvalidOperationException("Only one operation can be active at a time");
            }

            this.cameraCapture.Show();

            return(ntcs.Task);
        }
        /// <inheritdoc />
        public async Task <MediaFile> TakePhotoAsync(StoreMediaOptions options)
        {
            if (!this.IsEnabled)
            {
                throw new NotSupportedException();
            }

            //var capture = new CameraCaptureUI(this.CameraFacingDirection);
            var capture = new ViewFinder(this.CameraFacingDirection);
            var result  = await capture.CaptureFileAsync();

            if (result == null)
            {
                return(null);
            }

            StorageFolder rootFolder = ApplicationData.Current.LocalFolder;

            string targetFilePath = options.GetFilePath(rootFolder.Path);
            var    directoryPath  = Path.GetDirectoryName(targetFilePath);
            var    directoryName  = options.Directory;

            if (!string.IsNullOrWhiteSpace(directoryName))
            {
                var exists = Directory.Exists(directoryPath);
                if (!exists)
                {
                    await rootFolder.CreateFolderAsync(directoryName, CreationCollisionOption.ReplaceExisting);
                }
            }

            rootFolder = await StorageFolder.GetFolderFromPathAsync(directoryPath);

            string targetFilename = Path.GetFileName(targetFilePath);

            var file = await result.CopyAsync(rootFolder, targetFilename, NameCollisionOption.ReplaceExisting).AsTask().ConfigureAwait(false);

            Stream stream = await file.OpenStreamForReadAsync().ConfigureAwait(false);

            return(new MediaFile(file.Path, () => stream));
        }
示例#14
0
        public async Task <MediaFile> TakePhotoAsync(StoreMediaOptions options)
        {
            if (!this.IsEnabled)
            {
                throw new NotSupportedException();
            }

            if (!await this.AuthorizeCameraUse())
            {
                throw new Exception("Not authorized to access the camera.");
            }

            CheckCameraUsageDescription();

            this.VerifyCameraOptions(options);

            return(await this.GetMediaAsync(
                       sourceType : UIImagePickerControllerSourceType.Camera,
                       mediaType : Constants.TypeImage,
                       cameraFacingDirection : this.CameraFacingDirection,
                       options : options));
        }
示例#15
0
        /// <inheritdoc />
        public async Task <MediaFile> TakePhotoAsync(StoreMediaOptions options)
        {
            if (!this.IsEnabled)
            {
                throw new NotSupportedException();
            }

            var capture = new CameraCaptureUI();

            capture.PhotoSettings.Format        = CameraCaptureUIPhotoFormat.Jpeg;
            capture.PhotoSettings.MaxResolution = CameraCaptureUIMaxPhotoResolution.HighestAvailable;

            var result = await capture.CaptureFileAsync(CameraCaptureUIMode.Photo);

            if (result == null)
            {
                return(null);
            }

            StorageFolder folder = ApplicationData.Current.LocalFolder;

            string path          = options.GetFilePath(folder.Path);
            var    directoryFull = Path.GetDirectoryName(path);
            var    newFolder     = directoryFull.Replace(folder.Path, string.Empty);

            if (!string.IsNullOrWhiteSpace(newFolder))
            {
                await folder.CreateFolderAsync(newFolder, CreationCollisionOption.OpenIfExists);
            }

            folder = await StorageFolder.GetFolderFromPathAsync(directoryFull);

            string filename = Path.GetFileName(path);

            var file = await result.CopyAsync(folder, filename, NameCollisionOption.GenerateUniqueName).AsTask();

            return(new MediaFile(file.Path, () => file.OpenStreamForReadAsync().Result));
        }
示例#16
0
        private Task <MediaFile> GetMediaAsync(UIImagePickerControllerSourceType sourceType, string mediaType, CameraFacingDirection cameraFacingDirection, StoreMediaOptions options = null)
        {
            var window = UIApplication.SharedApplication.KeyWindow;

            if (window == null)
            {
                throw new InvalidOperationException("There's no current active window");
            }

            var viewController = window.RootViewController;

            if (viewController == null)
            {
                window = UIApplication.SharedApplication.Windows.OrderByDescending(w => w.WindowLevel).FirstOrDefault(w => w.RootViewController != null);
                if (window == null)
                {
                    throw new InvalidOperationException("Could not find current view controller");
                }
                else
                {
                    viewController = window.RootViewController;
                }
            }

            while (viewController.PresentedViewController != null)
            {
                viewController = viewController.PresentedViewController;
            }

            MediaPickerDelegate ndelegate = new MediaPickerDelegate(viewController, sourceType, options);
            var od = Interlocked.CompareExchange(ref this.pickerDelegate, ndelegate, null);

            if (od != null)
            {
                throw new InvalidOperationException("Only one operation can be active at at time");
            }

            var picker = SetupController(ndelegate, sourceType, mediaType, cameraFacingDirection, options);

            if (UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Pad && sourceType == UIImagePickerControllerSourceType.PhotoLibrary)
            {
                ndelegate.Popover          = new UIPopoverController(picker);
                ndelegate.Popover.Delegate = new MediaPickerPopoverDelegate(ndelegate, picker);
                ndelegate.DisplayPopover();
            }
            else
            {
                viewController.PresentViewController(picker, true, null);
            }

            return(ndelegate.Task.ContinueWith(
                       t =>
            {
                if (this.popover != null)
                {
                    this.popover.Dispose();
                    this.popover = null;
                }

                Interlocked.Exchange(ref this.pickerDelegate, null);
                return t;
            }).Unwrap());
        }
示例#17
0
        private static MediaPickerController SetupController(MediaPickerDelegate mpDelegate, UIImagePickerControllerSourceType sourceType, string mediaType, CameraFacingDirection cameraFacingDirection, StoreMediaOptions options)
        {
            var picker = new MediaPickerController(mpDelegate);

            picker.MediaTypes = new[] { mediaType };
            picker.SourceType = sourceType;

            if (sourceType == UIImagePickerControllerSourceType.Camera)
            {
                picker.CameraDevice  = GetUICameraDevice(cameraFacingDirection);
                picker.AllowsEditing = options.AllowCropping;

                if (options.OverlayViewProvider != null)
                {
                    var overlay = options.OverlayViewProvider;
                    if (overlay is UIView)
                    {
                        picker.CameraOverlayView = overlay as UIView;
                    }
                }
                if (mediaType == Constants.TypeImage)
                {
                    picker.CameraCaptureMode = UIImagePickerControllerCameraCaptureMode.Photo;
                }
                else if (mediaType == Constants.TypeMovie)
                {
                    StoreVideoOptions voptions = (StoreVideoOptions)options;

                    picker.CameraCaptureMode    = UIImagePickerControllerCameraCaptureMode.Video;
                    picker.VideoQuality         = GetQuailty(voptions.Quality);
                    picker.VideoMaximumDuration = voptions.DesiredLength.TotalSeconds;
                }
            }

            return(picker);
        }