NativeCamera is a native Unity plugin that helps you take pictures/record videos with your device’s camera on Android and iOS. It has built-in support for runtime permissions, as well.
Can’t use the camera, it says “java.lang.ClassNotFoundException: com.yasirkula.unity.NativeCamera” in Logcat
If you are sure that your plugin is up-to-date, then enable Custom Proguard File option from Player Settings and add the following line to that file: -keep class com.yasirkula.unity.* { *; }
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class PicFromCamera : MonoBehaviour {
public Text textUIValue;
Vector3 currentPositon = new Vector3();
private int updateCount;
void Update()
{
updateCount++;
textUIValue.text = "Update Count: " + updateCount.ToString();
if( Input.GetMouseButtonDown( 0 ) )
{
textUIValue.text = "Registered MouseDown";
// Don't attempt to use the camera if it is already open
if( NativeCamera.IsCameraBusy() )
return;
if( Input.mousePosition.x < Screen.width / 2 )
{
// Take a picture with the camera
// If the captured image's width and/or height is greater than 512px, down-scale it
TakePicture( 512 );
}
else
{
// Record a video with the camera
RecordVideo();
}
}
if (Input.touchCount > 0) {
textUIValue.text = "TouchCount > 0";
if( NativeCamera.IsCameraBusy() )
return;
Touch touch = Input.GetTouch (0); // get first touch since touch count is greater than zero
currentPositon = Camera.main.ScreenToWorldPoint (new Vector3 (touch.position.x, touch.position.y, 10));
if (touch.phase == TouchPhase.Began) {
textUIValue.text = "Touch Began";
if(currentPositon.x < Screen.width / 2 )
{
// Take a picture with the camera
// If the captured image's width and/or height is greater than 512px, down-scale it
TakePicture( 512 );
}
else
{
// Record a video with the camera
RecordVideo();
}
}
if (touch.phase == TouchPhase.Ended || touch.phase == TouchPhase.Canceled) {
}
if (touch.phase == TouchPhase.Moved) {
textUIValue.text = "Registered Touch Began";
if(currentPositon.x < Screen.width / 2 )
{
// Take a picture with the camera
// If the captured image's width and/or height is greater than 512px, down-scale it
TakePicture( 512 );
}
else
{
// Record a video with the camera
RecordVideo();
}
}
}
}
private void TakePicture( int maxSize )
{
NativeCamera.Permission permission = NativeCamera.TakePicture( ( path ) =>
{
textUIValue.text = "Image path: " + path;
Debug.Log( "Image path: " + path );
if( path != null )
{
// Create a Texture2D from the captured image
Texture2D texture = NativeCamera.LoadImageAtPath( path, maxSize );
if( texture == null )
{
Debug.Log( "Couldn't load texture from " + path );
return;
}
// Assign texture to a temporary quad and destroy it after 5 seconds
GameObject quad = GameObject.CreatePrimitive( PrimitiveType.Quad );
quad.transform.position = Camera.main.transform.position + Camera.main.transform.forward * 2.5f;
quad.transform.forward = Camera.main.transform.forward;
quad.transform.localScale = new Vector3( 1f, texture.height / (float) texture.width, 1f );
Material material = quad.GetComponent<Renderer>().material;
if( !material.shader.isSupported ) // happens when Standard shader is not included in the build
material.shader = Shader.Find( "Legacy Shaders/Diffuse" );
material.mainTexture = texture;
Destroy( quad, 5f );
// If a procedural texture is not destroyed manually,
// it will only be freed after a scene change
Destroy( texture, 5f );
}
}, maxSize );
Debug.Log( "Permission result: " + permission );
}
private void RecordVideo()
{
NativeCamera.Permission permission = NativeCamera.RecordVideo( ( path ) =>
{
textUIValue.text = "Video path: " + path;
Debug.Log( "Video path: " + path );
if( path != null )
{
// Play the recorded video
Handheld.PlayFullScreenMovie( "file://" + path );
}
} );
Debug.Log( "Permission result: " + permission );
}
}
I see various debugs in editor correctly (can’t access camera of course which is understandable) but on mobile the update counter just stops and nothing else when I touch screen. I assume the camera is trying to be accessed? I get a dialog asking permission and of course I grant access when app starts up.
Using Samsung Galaxy S8, Unity 2017.1.0f3, mono 5.9.6
Sorry for the post length but I just wanted to be thorough.
Any ideas?
Your Gallery asset works perfectly on device so not sure why this would not?
The only fatal issue I could spot was this: android:name="com.furiogames.unity.NativeCameraContentProvider"
You shouldn’t change the value of android:name (leave it as com.yasirkula.unity.NativeCameraContentProvider) because it specifies the path of the content provider class. Please let me know if that works.
I did have it as your name originally and still no go. Decided to change to mine just to see and forgot to change it back. Just changed it back to yours and still no go.
Very strange it isn’t working. Does the project I sent work for you? If so then this may be an issue with my setup in some way.
The crucial part here is to move AndroidManifest.xml from Plugins/NativeCamera/Android to Plugins/Android. It is a must. Otherwise, Unity just ignores the manifest.
I also had to change </provider> to /> and tweak Update like this:
void Update()
{
updateCount++;
textUIValue.text = "Update Count: " + updateCount.ToString();
if( Input.GetMouseButtonDown( 0 ) )
{
textUIValue.text = "Registered MouseDown";
// Don't attempt to use the camera if it is already open
if( NativeCamera.IsCameraBusy() )
return;
if( Input.mousePosition.x < Screen.width / 2 )
{
// Take a picture with the camera
// If the captured image's width and/or height is greater than 512px, down-scale it
TakePicture( 512 );
}
else
{
// Record a video with the camera
RecordVideo();
}
}
if (Input.touchCount > 0) {
// Ray ray = Camera.main.ScreenPointToRay(Input.GetTouch(i).position);
textUIValue.text = "Registered TouchCount > 0";
}
}
Wow! Thank you for taking your time to help with this!
I updated to Unity 2018.1.0 made your changes, updated Android SDK (to get API level 25) and it mostly works now.
Having a small issue with if I take a photo it isn’t returning to displaying on plane. It stays at camera. If I take a second pic then it switches back to display on plane fine. It does this with vid also. I’ll play with it some more.
Thanks again!
UPDATE: Just switched take pic/vid from screen touch to buttons and now there is no issue.
Hi, how do you grab the camera’s pixels and save them to a texture like WebCamTexture but not directly to a file? I need to preview them like any camera app does.
Hi, First, thanks a lot for making this plugin freely available. It has been really really helpful.
I have been using this plugin successfully in iOS and android. As per our current requirement, we need as lowest resolution as possible for video recording.
We tested on various android devices and found the lowest is 640X480. Just wanted to know if there is any way we can manually specify the resolution to go below it.
Unfortunately not. AFAIK, resolution only depends on EXTRA_VIDEO_QUALITY on Android and UIImagePickerController.videoQuality on iOS, and they don’t accept custom resolutions. If you really need a lower resolution, you’ll probably have to use another plugin that renders the camera output directly inside Unity.
It does prompt for the needed permissions, but then Unity freezes after that.
By the way, huge fan. Thanks for all the assets you have released. Probably the best asset provider I know of, up there along with the usefulness of Catlike Coding. Keep being awesome.
After building your project to Android, can you check the contents of PROJECT_PATH/Temp/StagingArea/AndroidManifest.xml and verify that the provider exists? If it does exist, can I see it?
Hey, sorry for wasting your time! It was a pretty obvious error on my side, I had put the snippet into an ‘activity’ that was under ‘application’. Gotta hate the XML format… thanks for helping!
Is NativeCamera image smaller than an image captured via native camera app? What are their resolutions? Are there no quality settings in the camera overlay in NativeCamera?
To decrease the darkness, you should play with the exposure settings in the camera overlay. Please note that NativeCamera simply starts the native camera app and fetches the captured image from it, the rest is up to the camera app itself.