Exploring Ionic Capacitor Plugins: Access to Device Features

Athina Hadjichristodoulou
The Web Tub
Published in
6 min readJul 20, 2023
Source: https://capacitorjs.com/docs/img/v5/docs/capacitor-card.png (1)

Discovering The Potential

Capacitor simplifies the process of accessing device features through web applications by using plugins, which wrap common native operations such as camera access, geolocation, push notifications, etc. These plugins serve as intermediaries, bridging the gap between various platform-specific APIs and exposing a unified, cross-platform API to JavaScript.

The plugins make it possible for the developers to add extra functionality to their web apps without requiring expertise in programming languages for native applications. There is also the possibility for native and web developers to work together for a more stable and impactful project.

Source Plugins

The official team behind Capacitor currently maintains 27 core plugins that cover the APIs of the most commonly used software and hardware systems of a device. There is also a number of plugins that have been developed by the community and by a simple web search you can probably find what you need to build your application. Some Cordova plugins are also available in Capacitor apps, even though it is advised to update them to their Capacitor equivalent. At last, if the available plugins are not what you are searching for, you can always create your own. In this blog post, we will see how to utilize the already available plugins provided by the Ionic team.

Capacitor also offers a powerful suit of solutions for enterprise apps that can be integrated without any problems with any modern web technology and tool. Secure authentication is provided with Auth Connect. Encrypted sessions and used identity management through Identity Vault. The accessibility to high-performance, encrypted SQL data storage system is provided with Offline Storage.

Resources for Plugins:

The Camera Plugin

Now it’s time to see how we can actually use these plugins in our projects and make sure they work efficiently for both the web and native applications. We will use as an example the Camera plugin, one of the most commonly used functionalities of a mobile device.

Before using the plugin in your app make sure the following pre-conditions are met:

  • You have Xcode and Android Studio installed (Xcode is only available on MacBooks)
  • Capacitor is properly installed and initialized in your project
  • Both iOS and Android projects are created and synced with the web code

The first thing we need to do is install the plugin and sync the project.

npm install @capacitor/camera
npx cap sync

To enable our application to use a device’s camera, it is crucial to configure the necessary permissions within the native code’s files.

iOS

Open the project in Xcode by running this command inside the root directory.

npx cap open ios

Then select the App project, the App target and finally the Info tab.

In the table of keys introduce the following three keys and edit their value by providing an informative text message for the user:

  • Privacy - Camera Usage Description
  • Privacy - Photo Library Additions Usage Description
  • Privacy - Photo Library Usage Description

Android

For setting Android permissions you have to edit the AndroidManifest.xml file inside the Android project. Open Android Studio:

npx cap open android

Find the AndroidManifest.xml file and add the following permissions at the bottom of the file:

<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Also, make sure your app’s variables.gradle file includes the following variables. If not, include them manually.

  • androidxExifInterfaceVersion: version of androidx.exifinterface:exifinterface (default: 1.3.6)
  • androidxMaterialVersion: version of com.google.android.material:material (default: 1.8.0)

With permissions properly configured, there is one final step before using the Camera API: integrating PWA Elements, an essential component for the camera plugin to function.

Import PWA Elements:

npm install @ionic/pwa-elements

Then, depending on the framework you are working with, import the element loader at the correct time. For React, it should be the following:

import { defineCustomElements } from '@ionic/pwa-elements/loader';

ReactDOM.render(...);

// Call the element loader after the app has been rendered the first time
defineCustomElements(window);

Now, we are all set up to use the Camera API without any unexpected issues.

API

The camera API exposes six JavaScript functions that cover the basic functionalities of capturing images and selecting pictures. Let’s delve into the practical usage of some of them.

import { Camera, CameraResultType, CameraSource } from '@capacitor/camera';

async function takePicture() {
const image = await Camera.getPhoto({
quality: 90, //quality of the image to return as JPEG (0-100)
allowEditing: true, //whether the user can edit the picture they selected/took
resultType: CameraResultType.Uri, //type of the data to be returned
source: CameraSource.Prompt //source to get the photo from
});

var imageUrl = image.webPath;
// A piece of code that sets the source of an img element to the returned image...
setImage(imageUrl)
}

In the above function we are calling the getPhoto() function from the Camera API. This function prompts the user to either take a photo with the camera or pick an existing photo from an album. You can set how the data should be returned by defining the value of resultType. Currently, only Base64, Uri and DataUrl are supported. After we get the return image, we can set it as the src of an <img> element.

import { Camera } from '@capacitor/camera';

async function selectPictures() {
const galleryPhotos = await Camera.pickImages({
quality: 90, //quality of the image to return as JPEG (0-100)
limit: 10 //limit the number of images a user can select at a time
});

//A piece of code that uploads the pictures to a server...
uploadPhotos(galleryPhotos.photos)
}

In the above code we are utilizing the pickImages() function. This function allows the user to select multiple photos from a photo gallery within the limit option. You can access the array of selected images using the `galleryPhotos.photos` notation, allowing you to conveniently perform various actions such as uploading the pictures to a server, displaying them within the app, or any other desired functionality.

import { Camera } from '@capacitor/camera';
import { Capacitor } from '@capacitor/core';

async function requestPermissions() {
if (Capacitor.isNativePlatform()) {
const permissions = await Camera.requestPermissions()
if (permissions.camera == "denied" || permissions.photos == "denied") {
//A piece of code for displaying an error message to the user
showErrorDialog()
}
}
}

The above code is calling the requestPermissions() function in order to ask the user to grant access to the camera and photo albums if necessary. If any of the permissions are denied then you should let the user know that in order to use your application efficiently, the camera and photo album permissions should be granted.

Additionally, there are three more API functions that we haven’t covered here, but they are straightforward to use and should follow a similar pattern to the ones we have already explored. Take a look at the official documentation of the Camera plugin to discover more.

Conclusion

Capacitor plugins extend the normal functionality of an application by providing a simple to use API layer that is cross-platform. Web developers can access a variety of a device’s features with just JavaScript code and some trivia meddling with the native code’s files. There is a plethora of available plugins online created by the official team and contributors, so the probability to find what you need is high. Even though the word ‘plugins’ might sound advanced at first, don’t hesitate to incorporate them in your projects and elevate their usability.

If you have any questions about this blog post please leave them in the comments! :)

Resources:

  1. Ionic Team, Capacitor Plugins <https://capacitorjs.com/docs/plugins>

--

--