Tuesday, 3 December 2019

Camera Application using Xamarin



Cross Platform Mobile application development


This blog explains how to use ‘Xamarin Forms’ to create your own camera application to capture photos and videos using your phone camera. This also explains how to implement functionality to select and display photos/videos from library.
We are using Xamarin forms to create cross platform app which allows to develop common functionality in one project and use that in android and iOS projects.


Step 1: Using ‘Xamarin.Forms’ project template to create common mobile application for Android and iOS

For Cross platform application select Xamarin.Forms project template

 After selecting Project template click Nextà Then provide project name & solution name and click Create àNow it shows popup to select template, Select Blank template






We have 3 projects in our solution,
   1.       Nk.CameraOperations – Project to design UI and add common functionality which will be shared by Android and iOS app.
   2.       Nk.CameraOperations.Android – Project for android application, contains resource and android application specific functionality. Uses above project ‘Nk.CameraOperations’ to render UI.
   3.       Nk.CameraOperations.iOS - Project for iOS application, contains resource and iOS application specific functionality. Uses above project ‘Nk.CameraOperations’ to render UI.


Step 2: Install package ‘Xam.Plugin.Media’ to handle media operations


Select ToolsàNuGet Package ManageràManage NuGet Packages for Solution…





Browse for ‘Xam.Plugin.Media’ and install for all projects.





Step 3: Add UI/buttons & event handlers for camera operations


Use MainPage.xaml inside ‘Nk.CameraOperations’ project to Design UI and add corresponding event handler code in code behind file MainPage.xaml.cs
<StackLayout>
        <!-- Place UI controls here -->
        <Image x:Name="image"
               WidthRequest="100"
               HeightRequest="500" />

        <StackLayout Orientation="Horizontal" Spacing="20" HorizontalOptions="Center">
            <ImageButton Source="Camera_Icon.png"
                     WidthRequest="30"
                     HeightRequest="30"
                    Clicked="takePhoto_Clicked"/>

            <ImageButton Source="PickPhoto.jpg"
                     WidthRequest="30"
                     HeightRequest="30"
                    Clicked="pickPhoto_Clicked"/>

            <ImageButton Source="Video_icon.png"
                     WidthRequest="30"
                     HeightRequest="30"
                    Clicked="takeVideo_Clicked"/>

            <ImageButton Source="Pick_Video.png"
                     WidthRequest="30"
                     HeightRequest="30"
                    Clicked="pickVideo_Clicked"/>
        </StackLayout>
</StackLayout>

Here Image control is used to show selected image from gallery.
Images used in image control source are stored in individual android and iOS projects(E.g. In android project images are stored in \ Resources\ drawable).
And ImageButtons are buttons used to perform different camera operations.
e.g. following event handler is for opening camera.
private async void takePhoto_Clicked(object sender, EventArgs e)
        {
            //This checks if camera is available on device and device supports taking photo
            if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
            {
                await DisplayAlert("No Camera", ":( No camera avaialble.", "OK");
                return;
            }

            //Opens camera for taking photo and once photo is captured returns captured image file
            var file = await CrossMedia.Current.TakePhotoAsync(new Plugin.Media.Abstractions.StoreCameraMediaOptions
            {
                PhotoSize = Plugin.Media.Abstractions.PhotoSize.Medium,
                SaveToAlbum = true,
                Directory = "Sample",
                Name = "test.jpg"
            });

            if (file == null)
                return;

            //await DisplayAlert("File Location", file.Path, "OK");
           
            //Shows captured image
            image.Source = ImageSource.FromStream(() =>
            {
                var stream = file.GetStream();
                file.Dispose();
                return stream;
            });
        }


Step 4: Initialize camera components in android project

Open ‘MainActivity.cs’ file inside android project (‘Nk.CameraOperations.Android’)
Make overriden oncreate method asynchronous by adding async keyword on method.
And add await on plugin initialize method to initialize all camera components as can be seen below
//Add async keyword
        protected override async void OnCreate(Bundle savedInstanceState)
        {
            TabLayoutResource = Resource.Layout.Tabbar;
            ToolbarResource = Resource.Layout.Toolbar;

            base.OnCreate(savedInstanceState);

            //call await to allow plugin to Initialize all camera components
            await CrossMedia.Current.Initialize();

            Xamarin.Essentials.Platform.Init(this, savedInstanceState);
            global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
            LoadApplication(new App());
        }


Step 5: Additional steps for Granting permissions

Perform following changes in android project (‘Nk.CameraOperations.Android’)
1.       Open ‘MainActivity.cs’ file inside android project (‘Nk.CameraOperations.Android’)
In overrirden OnRequestPermissionsResult method add below line to grant permission to plugin.
            Plugin.Permissions.PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults);
2.  Add the following to your AndroidManifest.xml(To find it open ‘android project (‘Nk.CameraOperations.Android’)’ and expand Properties) inside the <application> tags:
           
<provider android:name="android.support.v4.content.FileProvider"
                           android:authorities="${applicationId}.fileprovider"
                           android:exported="false"
                           android:grantUriPermissions="true">
        <meta-data android:name="android.support.FILE_PROVIDER_PATHS"
          android:resource="@xml/file_paths"></meta-data>
      </provider>

3.  Add a new folder called xml into your Resources folder and add a new XML file called `file_paths.xml`

Add the following code:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
  <external-files-path name="my_images" path="Pictures" />
  <external-files-path name="my_movies" path="Movies" />
</paths>













No comments:

Post a Comment