Skip to content

Instantly share code, notes, and snippets.

@keijiro
Last active August 4, 2019 20:19
Show Gist options
  • Save keijiro/ee65e1d6edcb47912f34 to your computer and use it in GitHub Desktop.
Save keijiro/ee65e1d6edcb47912f34 to your computer and use it in GitHub Desktop.
using UnityEngine;
using System.Collections;
using System.IO;
using System.Runtime.InteropServices;
public class PhotoTaker : MonoBehaviour
{
// Screenshot file settings.
public string temporaryFileName = "temp.png";
public string androidStoragePath = "/mnt/sdcard/TestCameraApp";
public void StartShooting()
{
StartCoroutine(ShootingCoroutine());
}
// Main coroutine
IEnumerator ShootingCoroutine()
{
TakeTemporaryScreenshot();
PlayShutterSound();
yield return StartCoroutine(WaitCaptureCompletion());
#if UNITY_EDITOR
#elif UNITY_IOS
AddToAlbum(TemporaryScreenshotPath);
#elif UNITY_ANDROID
AddToAlbum(MoveToExternalStorage());
#endif
}
// Misc functions
string Timestamp {
get { return System.DateTime.Now.ToString("yyyy-MMdd-HHmm-ss"); }
}
string TemporaryScreenshotPath {
#if !UNITY_EDITOR && (UNITY_IOS || UNITY_ANDROID)
get { return Path.Combine(Application.persistentDataPath, temporaryFileName); }
#else
get { return temporaryFileName; }
#endif
}
bool CheckFileInUse(string filePath)
{
FileStream stream = null;
try {
stream = File.Open(filePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
} catch (IOException) {
return true;
} finally {
if (stream != null) stream.Close();
}
return false;
}
// Internal functions
void TakeTemporaryScreenshot()
{
if (File.Exists(TemporaryScreenshotPath)) File.Delete(TemporaryScreenshotPath);
Application.CaptureScreenshot(temporaryFileName);
}
void PlayShutterSound()
{
#if UNITY_EDITOR
#elif UNITY_IOS
PhotoTakerPlayShutterSound();
#elif UNITY_ANDROID
var mediaActionSound = new AndroidJavaObject("android.media.MediaActionSound");
mediaActionSound.Call("play", mediaActionSound.GetStatic<int>("SHUTTER_CLICK"));
#endif
}
IEnumerator WaitCaptureCompletion()
{
yield return new WaitForSeconds(0.1f);
while (!File.Exists(TemporaryScreenshotPath)) yield return null;
yield return new WaitForSeconds(0.1f);
while (CheckFileInUse(TemporaryScreenshotPath)) yield return null;
}
string MoveToExternalStorage()
{
if (!Directory.Exists(androidStoragePath))
Directory.CreateDirectory(androidStoragePath);
var destPath = Path.Combine(androidStoragePath, Timestamp + ".png");
File.Move(TemporaryScreenshotPath, destPath);
return destPath;
}
void AddToAlbum(string filePath)
{
#if UNITY_EDITOR
#elif UNITY_IOS
PhotoTakerMoveImageToAlbum(filePath);
#elif UNITY_ANDROID
// string action = Intent.ACTION_MEDIA_SCANNER_SCAN_FILE
AndroidJavaClass intentClass = new AndroidJavaClass("android.content.Intent");
string action = intentClass.GetStatic<string>("ACTION_MEDIA_SCANNER_SCAN_FILE");
// Intent intentObject = new Intent(action);
AndroidJavaObject intentObject = new AndroidJavaObject("android.content.Intent", action);
// Uri uriObject = Uri.parse("file:" + filePath);
AndroidJavaClass uriClass = new AndroidJavaClass("android.net.Uri");
AndroidJavaObject uriObject = uriClass.CallStatic<AndroidJavaObject>("parse","file:" + filePath);
// intentObject.setData(uriObject);
intentObject.Call<AndroidJavaObject>("setData", uriObject);
// this.sendBroadcast(intentObject);
AndroidJavaClass unity = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject currentActivity = unity.GetStatic<AndroidJavaObject>("currentActivity");
currentActivity.Call("sendBroadcast", intentObject);
#endif
}
#if UNITY_IOS
[DllImport("__Internal")] static extern void PhotoTakerPlayShutterSound();
[DllImport("__Internal")] static extern void PhotoTakerMoveImageToAlbum(string path);
#endif
}
@badjano
Copy link

badjano commented Nov 30, 2017

Not working in iOS:

"_PhotoTakerPlayShutterSound", referenced from:
_PictureController_PlayShutterSound_m1906002669 in Bulk_Assembly-CSharp_0.o
_PictureController_PhotoTakerPlayShutterSound_m1625647398 in Bulk_Assembly-CSharp_0.o
_U3CTakePictureRoutineU3Ec__Iterator0_MoveNext_m2050576911 in Bulk_Assembly-CSharp_0.o
(maybe you meant: _PictureController_PhotoTakerPlayShutterSound_m1625647398)
"_PhotoTakerMoveImageToAlbum", referenced from:
_PictureController_AddToAlbum_m2906851923 in Bulk_Assembly-CSharp_0.o
_PictureController_PhotoTakerMoveImageToAlbum_m3166195793 in Bulk_Assembly-CSharp_0.o
_U3CTakePictureRoutineU3Ec__Iterator0_MoveNext_m2050576911 in Bulk_Assembly-CSharp_0.o
(maybe you meant: _PictureController_PhotoTakerMoveImageToAlbum_m3166195793)
ld: symbol(s) not found for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment