Home / Tutorial / Android Camera Plugin for Unity: COMPLETE Tutorial

Android Camera Plugin for Unity: COMPLETE Tutorial

/
/
/
4893 Views

On a previous tutorial, we saw how to create a Native Android Plugin for Unity. However, this plugin had two shortcomings:

  • It’s impossible to include resources on a .jar file (AFAIK);
  • When extending the UnityPlayerActivity it can be harder to combine different plugins on the same project.
In this tutorial, we will try to address both these shortcomings by:
  • Exporting the plugin using a .aar file, which includes resource files;
  • Using a Fragment instead of extending the UnityPlayerActivity.
We will develop an Android Camera Plugin using a File Provider in order to comply with the new security restrictions introduced on Android Nougat (24).

ANDROID STUDIO PROJECT

CREATE THE ANDROID STUDIO PROJECT

  • Create a new Android Studio Project and choose the Application nameUnity Native Plugin – and your Company Domain addcomponent.com; IMAGE1
  • Choose the Minimum SDK version for your project. I suggest you leave the suggested version – API 14: Android 4.0 (IceCreamSandwich)IMAGE2
  • Select the “Basic Activity” as the default activity of the project; IMAGE3
  • Leave the suggested Activity detailsIMAGE4

ADD AN ANDROID LIBRARY MODULE

  • Create a New Module of type Library and give it a name – CameraIMAGE5 IMAGE6 IMAGE7
  • By default, you should be using the Android structure view. Change it to ProjectIMAGE8
  • Delete the test units of the Camera module; IMAGE9
  • Delete the tests and all dependencies of the build.gradle file of the Camera Module.

IMPORT UNITY CLASSES.JAR INTO ANDROID STUDIO

  • Copy the Unity classes.jar. You can find it at the following locations;
Windows
C:\Program Files\Unity\Editor\Data
Mac
/Applications/Unity in a sub-folder called PlaybackEngines/AndroidPlayer/Variations/mono or il2cpp/Development or Release/Classes/
  • Paste the file inside the libs directory on the project structure; IMAGE10 IMAGE11
  • Add the classes.jar dependency to the build.gradle file.
Unity already includes the classes.jar file, so we need to use provided instead of compile to prevent the file of being included on the .aar.

NATIVE CAMERA

IMPLEMENT THE CAMERA FRAGMENT

  • Add a method hasCamera() that returns whether a camera is available;
  • Add a method takePicture(String gameObject, String filename, String callback). Check this link for a deeper explanation;

ADD THE FILE PROVIDER

Android Nougat (24) introduced a big security change to file access which now requires a File Provider to securely access files associated with an app (read more here).

  • Add a File Provider to the AndroidManifest.xml of the Camera Module;
@xml/provider_paths will give you an error because we have not defined it yet.
  • Add an xml resource directory to the resources; IMAGE17 IMAGE18
  • Add a new xml file to the directory; IMAGE19 IMAGE20
  • Define which paths you want to access.
  • Delete the unnecessary resource files and clear the resource reference on the AndroidManifest.xmlIMAGE21

USE THE CAMERA WITH THE FILE PROVIDER

  • Get the file uri using the File Provider and start the camera activity;
  • Override the onActivityResult method and send the result to Unity.

UNITY PROJECT

CREATE THE UNITY PROJECT

This is a very simple scene with a Button to open the camera and an Image component to show the captured image.
  • Switch to the Android Platform on the project Build Settings and add the current scene; IMAGE24
  • Change the project Bundle Identifier and choose Build and Run. IMAGE25
This is just to make sure that you can compile an Android Project before continuing with the tutorial.

ADD THE ANDROID CAMERA C-SHARP COMPONENT

  • Create a new C-Sharp Script called AndroidCamera.cs to communicate with the Android plugin; IMAGE26
  • Add the following code to call the takePicture method on the Android Plugin and to receive the result on the TakePictureCallback method on Unity (Check our previous tutorial to understand more about how these methods work);
  • Add the AndroidCamera.cs component to the Controller GameObject. IMAGE27

IMPLEMENT THE UNITY CONTROLLER COMPONENT

  • Create a new Controller.cs component to link the UI to the AndroidCamera.cs component; IMAGE28
  • Add the following code to the Controller.cs (check the code comments for deeper explanation);
  • Add the Controller.cs to the Controller GameObject and assign the serialized references; IMAGE29
  • Set the TakePicture method of the Controller.cs as the OnCick Listener of the button; IMAGE30

EXPORT THE .AAR PLUGIN INTO UNITY

CHECK THIS POST FOR ALL THE GRADLE TASKS YOU MAY NEED

  • Add a Gradle Task on the build.gradle file to export the .aar file directly into the Unity Project;

This is an optional step that will save you some time. However you can skip it and manually copy/paste the .aar file from the camera/builds/outputs/aar/ directory.

  • Run the new Gradle Task and you should have the resulting .aar file on the Unity Project AssetsIMAGE31 IMAGE32

if the .aar is not inside the Unity Project, check the if you don’t have any errors and if the string  targetAssetFolder is correct. Probably the file is being copied to a different location.

If you try to run the project at this point you will get a lot of build errors. Check the final step to know what to do.


BUILDING THE PROJECT

ADD PLAY SERVICES RESOLVER

If you try to run the project you would get a runtime error when trying to access the camera because the Android Support Libraries wouldn’t be included in the project.

“This library is intended to be used by any Unity plugin that requires access to Google play-services or Android support libraries on Android. The goal is to minimize the risk of having multiple or conflicting versions of client libraries included in the Unity project.
With this library, a plugin declares the dependencies needed and these are resolved by using the play-services and support repositories that are part of the Android SDK. These repositories are used to store .aar files in a Maven (Gradle) compatible repository.”

  • Add a new component called NativePluginDependencies.cs to the PlayServicesResolver folder. In this file, you have to declare all the Android Library dependencies that your project and included plugins have. (read here for more detailed explanation).

FIXING BUILD ERRORS

  • Change the Unity Minimum API Level to the Android 4.0 (API level 14)IMAGE33

If you try to run the project you would get the following error because the Unity Project and the Library had different minimum sdk versions.

Error: [Temp/StagingArea/AndroidManifest-main.xml:12, /Users/tomazsaraiva/Documents/Work/addcomponent-com/repos/unity-native-plugins/project-unity/unity-native-plugin/Temp/StagingArea/android-libraries/native-camera/AndroidManifest.xml:3] Main manifest has but library uses minSdkVersion=’14’

  • Change the Android Build System to Gradle (New) and Enable Development Build (required by Gradle Build when not signing). IMAGE34

If you try to run the project you would get the following error because Unity is not replacing the android:authorities=“${applicationId}.provider” with the correct value. stderr[ AndroidManifest.xml:13: Tag attribute authorities has invalid character ‘$’.
If you encounter different errors please tell me so that I can post them here 🙂
When checking for build errors, open the Console Editor Window. Usually the message displayed on the console is truncated and it’s harder to understand the specific cause of the error.

Happy Coding

  • Facebook
  • Twitter
  • Google+
  • Linkedin
  • Pinterest
  • Reddit

7 Comments

  1. Please update this tutorial (if possible) for older versions of Unity.
    Those of us trapped in Version 5.4 find you tutorial a waste of a lot of time,
    as it take some time to get to the parts where you tutorial falls apart…

    Thanks for the effort though….

    • Sorry for the delay.
      I’m not sure if it works with the new build system.
      I think I’ve hardcoded the value because it was enough to solve my specific case.
      However, it’s not the ideal solution.
      I’ll get back to it.
      Thanks for your feedback.
      Really appreciated.

  2. I get an error CS0103: The name `Google’ does not exist in the current context in :
    Type playServicesSupport = Google.VersionHandler.FindClass(
    “Google.JarResolver”, “Google.JarResolver.PlayServicesSupport”);
    if (playServicesSupport == null) {
    return;
    }
    of NativePluginDependencies.cs file. How I can fix it

Leave a Comment

Your email address will not be published. Required fields are marked *