Are there namespaces in Android which "listen to the file system change notifications and raise events when a directory, or file in a directory, changes" that compatible with Unity?
Ex:
Does this quite nicely with events, see below.
Quick research leads me to believe Android.OS.FileObserver is the appropriate solution but can't quite seem to find any samples of its use with regards to Unity.
Reading in the Unity manual that one "can use Android plugins to call code created outside of Unity from their C# scripts, allowing them to access features like OS calls that would otherwise not be available to Unity".
Can we use a file watcher on Android Unity applications?
Note: Looking for FileObserver.jar files hasn't proved useful though we managed to find a FileObserver.java for Android 5.0.
Code
private void PrototypeFileWatcher_Created(object sender, FileSystemEventArgs e)
{
Debug.Log("FileWatcher created");
ReadFiles();
// prevent file access while it is still being written
while (IsFileLocked(e.FullPath))
{
}
UnityMainThreadDispatcher.Instance().Enqueue(() => GenerateMdls());
}
private void PrototypeFileWatcher_Changed(object sender, FileSystemEventArgs e)
{
Debug.Log("FileWatcher changed");
}
private void PrototypeFileWatcher_Deleted(object sender, FileSystemEventArgs e)
{
Debug.Log("FileWatcher deleted");
// prevent file access errors
while (IsFileLocked(e.FullPath))
{
}
if (e.ChangeType == WatcherChangeTypes.Deleted)
{
UnityMainThreadDispatcher.Instance().Enqueue(() => RemoveMdl(e.FullPath));
}
}
/* Credit for below:
* https://stackoverflow.com/questions/10982104/wait-until-file-is-completely-written
*/
const int ERROR_SHARING_VIOLATION = 32;
const int ERROR_LOCK_VIOLATION = 33;
private bool IsFileLocked(string file)
{
//check that problem is not in destination file
if (File.Exists(file) == true)
{
FileStream stream = null;
try
{
stream = File.Open(file, FileMode.Open, FileAccess.ReadWrite, FileShare.None);
}
catch (Exception ex2)
{
//_log.WriteLog(ex2, "Error in checking whether file is locked " + file);
int errorCode = System.Runtime.InteropServices.Marshal.GetHRForException(ex2) & ((1 << 16) - 1);
if ((ex2 is IOException) && (errorCode == ERROR_SHARING_VIOLATION || errorCode == ERROR_LOCK_VIOLATION))
{
return true;
}
}
finally
{
if (stream != null)
stream.Close();
}
}
return false;
}