I'm trying to write some code to take screenshot and save them in android default DCIM path, first part for take screenshot works but second part for move file to Path not work.
public class IS_Screenshot : MonoBehaviour
{
string ScreenShotFile;
void Start ()
{
ScreenShotFile = Application.persistentDataPath + "_Screenshot_" + System.DateTime.Now.ToString("_yyyy-MM-dd_HH-mm-ss") + ".png";
Debug.Log (ScreenShotFile);
}
public void Screen_Shot()
{
try
{
Application.CaptureScreenshot(ScreenShotFile);
string Path = "/mnt/sdcard/DCIM/" + "_Screenshot_" + System.DateTime.Now.ToString("_yyyy-MM-dd_HH-mm-ss_") + ".png";
Debug.Log (Path);
if(System.IO.File.Exists(ScreenShotFile))
{
System.IO.File.Move(ScreenShotFile, Path);
Debug.Log ("Screenshot file saved.");
}
else
{
Debug.Log ("Screenshot file not found.");
}
}
catch(Exception ex)
{
Debug.Log ("Screenshot capture failed. | " + ex);
}
}
}
Use Path.Combine to attach the filename to the persistentDataPath. It may well be that on Android the value of persistentDataPath does not end in a path seperator, which will result in an invalid path.
ScreenShotFile = Path.Combine(Application.persistentDataPath, "_Screenshot_" + System.DateTime.Now.ToString("_yyyy-MM-dd_HH-mm-ss") + ".png");
Related
I have the bit of code that searches the entire computer for a file and once found, should return that file. The problem is in the second function, the recursive one. Once the file is found, it should return, which it does, but for some reason, even after returning the value, it continues the recursive search.
I don't get it. I'd still consider myself new to programming so please explain in detail if you see what I'm doing wrong.
public string SearchDirectory(string dir, string fileName)
{
string foundDir = "";
bool fileFound = false;
// Gets all files from directory and creates list of matches to fileName
try
{
foreach (string match in Directory.GetFiles(dir, fileName))
{
// Returns the first found match as a path and breaks loop
Console.WriteLine("Checked path: " + dir + ".");
if (File.Exists(dir + #"\" + fileName))
{
Console.WriteLine("FOUND!!");
fileFound = true;
foundDir = dir;
break;
}
if (fileFound == true)
{
break;
}
}
}
catch
{
Console.WriteLine("Access to path: " + dir + " denied.");
}
// If fileName isn't found in directory, it searches each new directory
// The last directory it will check is the last one in the original directory
if (fileFound == false)
{
try
{
foreach (string newDirectory in Directory.GetDirectories(dir))
{
Console.WriteLine("Checked path: " + dir + ".");
SearchDirectory(newDirectory, fileName);
}
}
catch
{
Console.WriteLine("Access to path: " + dir + " denied.");
}
// fileName does not exist in starting directory
}
else
{
return foundDir;
}
return "";
}
Your recursive call is ignoring the returned value. You should instead check to see if it found something so you can stop searching more sub-directories.
foreach (string newDirectory in Directory.GetDirectories(dir))
{
Console.WriteLine("Checked path: " + dir + ".");
var result = SearchDirectory(newDirectory, fileName);
if(result != "") return result;
}
You could just do this instead:
public string SearchDirectory(string dir, string fileName)
{
return Directory
.EnumerateFiles(dir, fileName, SearchOption.AllDirectories)
.FirstOrDefault() ?? "";
}
I have a strange problem. I wrote a .net 2.0 console application running on Windows Server 2008 R2 that processes a file that's passed in via args When I run it by hand and pass in a file, I don't get an output. Nothing. No errors or exception of any kind. Event log is clear. I would expect that I get some output from the exe. I also have a Console.WriteLine in my catch statement. But again, no output whatsoever. Any ideas why?
using System;
using System.Collections.Generic;
//using System.Linq;
using System.Text;
using System.IO;
namespace RTDXCentralFileTransmit
{
class Program
{
static void Main(string[] args)
{
try
{
if (args.Length < 1)
{
Console.WriteLine("File name is required");
logit("File name is required");
return;
}
string filename = args[0];
Console.WriteLine("Now doing " + filename);
logit("Now doing " + filename);
if (!File.Exists(filename))
{
Console.WriteLine("File " + filename + " does not exists. Exiting.");
logit("File " + filename + " does not exists. Exiting.");
File.WriteAllText("Error.txt", "File " + filename + " does not exists. Exiting.");
return;
}
string fileplain = File.ReadAllText(filename);
string file64 = EncodeTo64(fileplain);
if (string.IsNullOrEmpty(file64))
{
Console.WriteLine("File " + filename + " is empty. Exiting");
logit("File " + filename + " is empty. Exiting");
File.WriteAllText("Error.txt", "File " + filename + " is empty. Exiting");
return;
}
FileInfo fi = new FileInfo(filename);
com.xxxxxxxxxxxxxxxxxx.api.Dispatch dis = new com.xxxxxxxxxxxxxxxx.api.Dispatch();
com.xxxxxxxxxxxx.api.FunnelResult fr = dis.Funnel(file64, fi.Name);
if (fr.Success)
{
Console.WriteLine("Success! " + fr.Result);
logit("Success! Response from the server: " + fr.Result);
File.WriteAllText("Success.txt", fr.Result);
return;
} else
{
Console.WriteLine("Failed!! " + fr.Result);
logit("Failed!! " + fr.Result);
File.WriteAllText("Error.txt", "Transmission Failed! " + fr.Result);
}
logit("Exiting for " + filename);
Environment.Exit(0);
} catch (Exception e)
{
Console.WriteLine("Error. " + e.ToString());
return;
}
}
static void logit (string s)
{
File.AppendAllText("FileTransmit.log",DateTime.Now.ToString() + ":" + s + Environment.NewLine);
}
static public string EncodeTo64(string toEncode)
{
byte[] toEncodeAsBytes
= System.Text.ASCIIEncoding.ASCII.GetBytes(toEncode);
string returnValue
= System.Convert.ToBase64String(toEncodeAsBytes);
return returnValue;
}
}
}
I found it. The issue was between the chair and the computer.
The project that I cloned, even though it had tons of Console.WriteLine, it was actually was being built as Windows Application. That explains why we have no output for the Console.WriteLine.
Since it was being build as windows application, the console doesn't wait for the program to finish. It returns right away - which totally threw me off seeing that many console.writelines. However, the program is still running and, with a large file, it takes a while to post it to the remote server. After waiting a minute or two all of 10 MB file was transmitted successfully as it was indicated in the logs.
I am getting an error when I run this newFile method:
class logFile
{
public static string logpath = #"D:\Program Files\CustomApps\DataFeed\";
public static void log(string log)
{
string timestamp = DateTime.Now.ToString("yyyy_MM_ddTHH_mm_ss");
Console.WriteLine(timestamp + log);
File.AppendAllText(logpath + #"log_file_current.txt", timestamp + log + Environment.NewLine);
}
public static void newFile()
{
if (File.Exists(logpath + #"log_file_current.txt") == true)
{
File.Move(logpath + #"log_file_current.txt"
, logpath + #"log_files\log_file_ORPHANED_" + DateTime.Now.ToString("yyyy_MM_ddTHH_mm_ss") + ".txt");
}
try
{
File.Create(logpath + #"log_file_current.txt");
logFile.log("logFile created.");
}
catch(System.NotSupportedException ex)
{
Console.WriteLine(ex.Message);
}
}
}
I get the following error:
If I comment the body of the "newFile" code out then it runs without error, but then I would need to manually archive. If I comment out the File.Move part it all runs fine so this is the culprit.
How can I release the file so that it can be moved?
You need to use File.Close after using File.Create, this is why you are getting an error saying the file is used by another process. Try adding this line to your code :
try
{
File.Create(logpath + #"log_file_current.txt").Close(); // Notice the .Close() here
logFile.log("logFile created.");
}
Source : Closing a file after File.Create
Try this one
public static void log(string log)
{
string timestamp = DateTime.Now.ToString("yyyy_MM_ddTHH_mm_ss") + ": ";
Console.WriteLine(timestamp + log);
using (StreamWriter sw = File.AppendText(logpath + #"log_file_current.txt"))
{
sw.WriteLine(timestamp + log);
}
}
I have tried all this links bellow:
Not getting image from Persistant path in Android using unity3d
https://developer.vuforia.com/forum/unity-3-extension-technical-discussion/capture-screen-problem-androidhelp
http://answers.unity3d.com/questions/731509/applicationcapturescreenshot-doesnt-save-anything.html
I need to set the path for saving the pictures with an application for Android and IOS with UNITY
http://answers.unity3d.com/questions/200173/android-how-to-refresh-the-gallery-.html#answer-893069
Every time i build an apk, install it on Android device, nothing happend.
Log doesn't exists, so i tryed all this links and then go to /DCIM/Camera/ to see if is it saved, no, nothing...
On iOS i did that, and work perfectly.
Here is some code where i stuck... or the things on Android wont work...
I don't know why no error appear or some file strange in folder
void saveImage()
{
#if UNITY_ANDROID
string theFileName = "Screenshot_" + System.DateTime.Now.ToString("MM_dd_yyyy") +"_"+ System.DateTime.Now.ToString("hh_mm_ss") +".png";
// Many different test, trying to discovery witch will work...
Application.CaptureScreenshot( Application.dataPath + "_" + theFileName );
Application.CaptureScreenshot( "../../../../DCIM/Camera/pathroot_" + theFileName );
Application.CaptureScreenshot( "/storage/emulated/0/DCIM/Camera/" + theFileName );
Application.CaptureScreenshot( "file:///storage/emulated/0/DCIM/Camera/" + theFileName );
StartCoroutine(TakeScreenshot()); // Different test
#endif
#if UNITY_IPHONE
// This work... so, does not need to be here...
#endif
}
This is the method that "Coroutine" calls ( copy from one of those links above ):
private IEnumerator TakeScreenshot()
{
yield return new WaitForEndOfFrame();
//INITIAL SETUP
string myFilename = "Screenshot_" + System.DateTime.Now.ToString("MM_dd_yyyy") +"_"+ System.DateTime.Now.ToString("hh_mm_ss") +".png";
string myDefaultLocation = Application.dataPath + "/" + myFilename;
//EXAMPLE OF DIRECTLY ACCESSING THE Camera FOLDER OF THE GALLERY
//string myFolderLocation = "/storage/emulated/0/DCIM/Camera/";
//EXAMPLE OF BACKING INTO THE Camera FOLDER OF THE GALLERY
//string myFolderLocation = Application.persistentDataPath + "/../../../../DCIM/Camera/";
//EXAMPLE OF DIRECTLY ACCESSING A CUSTOM FOLDER OF THE GALLERY
string myFolderLocation = "/storage/emulated/0/DCIM/Camera/";
string myScreenshotLocation = myFolderLocation + myFilename;
//ENSURE THAT FOLDER LOCATION EXISTS
if(!System.IO.Directory.Exists(myFolderLocation)){
System.IO.Directory.CreateDirectory(myFolderLocation);
}
//TAKE THE SCREENSHOT AND AUTOMATICALLY SAVE IT TO THE DEFAULT LOCATION.
Application.CaptureScreenshot(myFilename);
//MOVE THE SCREENSHOT WHERE WE WANT IT TO BE STORED
System.IO.File.Move(myDefaultLocation, myScreenshotLocation);
//REFRESHING THE ANDROID PHONE PHOTO GALLERY IS BEGUN
AndroidJavaClass classPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject objActivity = classPlayer.GetStatic<AndroidJavaObject>("currentActivity");
AndroidJavaClass classUri = new AndroidJavaClass("android.net.Uri");
AndroidJavaObject objIntent = new AndroidJavaObject("android.content.Intent", new object[2]{"android.intent.action.MEDIA_MOUNTED", classUri.CallStatic<AndroidJavaObject>("parse", "file://" + myScreenshotLocation)});
objActivity.Call ("sendBroadcast", objIntent);
//REFRESHING THE ANDROID PHONE PHOTO GALLERY IS COMPLETE
//AUTO LAUNCH/VIEW THE SCREENSHOT IN THE PHOTO GALLERY
Application.OpenURL(myScreenshotLocation);
//AFTERWARDS IF YOU MANUALLY GO TO YOUR PHOTO GALLERY,
//YOU WILL SEE THE FOLDER WE CREATED CALLED "myFolder"
}
Try This: (Tested & Works):
Application.CaptureScreenshot ("screenshot.png");
store screenshot at:
Application.persistentDataPath, "screenshot.png" i.e data/data/package_name/files
void captureScreenshot(string result){
if (result == "true") {
StartCoroutine(CaptureScreen());
}
}
void OnGUI(){
if (GUI.Button (new Rect (20, 70, 100, 45), "Click"))
captureScreenshot ("true");
}
public IEnumerator CaptureScreen()
{
// Wait for screen rendering to complete
yield return new WaitForEndOfFrame();
Application.CaptureScreenshot ("screenshot.png");
string Origin_Path = System.IO.Path.Combine (Application.persistentDataPath, "screenshot.png");
Debug.Log ("Origin_Path save is " + Origin_Path);
// This is the path of my folder.
string Path = "/mnt/sdcard/" + "screenshot.png";
Debug.Log ("Path save is " + Path);
if (System.IO.File.Exists (Origin_Path)) {
System.IO.File.Move (Origin_Path, Path);
Debug.Log ("Path_move save is " + Path);
}
jo.Call<bool> ("screenshotHandler", "screenshot.png");
}
If you want to store in gallery without Move again then you can use:
Application.CaptureScreenshot ("../../../../DCIM/screenshot.png");
If Error: System.IO.File.Exists (Origin_Path)
//returns FALSE even though file exists at Origin_Path.
Please try this:
public IEnumerator CaptureScreen()
{
Application.CaptureScreenshot ("../../../../DCIM/"+fileName);
Debug.Log ("Sanky: Screen Captured");
while (!File.Exists (filePath)) {
Debug.Log ("Sanky: File exist at location"+filePath);
yield return 0;
}
/////// do whatever you want
}
I am using chilkat library for zipping some files and moving them to a another path. This works fine most of the time, but some times there is a tmp file made in path where my exe resides. Now I checked suddenly after 3 months,this files has gone to take 2 GB of hard disk. Following is my code:
public static bool MoveShopTRRFiles() {
//string fullfilepath;
Zip zip = new Zip();
bool unlocked = zip.UnlockComponent("abc");
if (!unlocked) {
//MessageBox.Show(zip.LastErrorText);
//return;
return false;
}
if (Directory.Exists(_TRRPath)) {
foreach (string filename in Directory.GetFiles(_TRRPath, "*.trr")) {
if (!File.Exists(_ShopTRRPath + "\\" + GetShopName(filename) + ".zip")) {
zip.NewZip(_ShopTRRPath + "\\" + GetShopName(filename) + ".zip");
} else {
zip.OpenZip(_ShopTRRPath + "\\" + GetShopName(filename) + ".zip");
}
try {
if(zip.GetEntryByName (filename.Substring(filename.LastIndexOf('\\') + 4))==null ){
zip.AppendOneFileOrDir(filename);
}
zip.WriteZipAndClose();
File.Delete(filename);
} catch {
}
}
return true;
} else
return false;
}
FOr now,i am deleting the temp files if any from the application folder.So this solves the problem for now.