I am trying to create a folder that users can put stuff in and use in the app so I do this
File exportDir = new File(Environment.getExternalStorageDirectory()+"/BCAData");
if (!exportDir.exists()) {
exportDir.mkdirs();
}
File file = new File(exportDir, dbFile.getName());
file.createNewFile();
If I use a file explorer program like Astro File Manager I see the folder fine but when I plug the device into my PC the folder is not there to put stuff in.
is there something else that I have to do for it to be used on a PC?
At minimum, you need to get MediaStore to update its index, such as via scanFile() on MediaScannerConnection, as I outline in this blog post.
Depending on your PC's operating system (and possibly depending on the device), you may still not see changes while the device is plugged in. It appears that the PC does not necessarily "see" changes, even with the index updated, until you unplug and plug the device back in.
Related
I'm using Xamarin Forms for a photo capture app and using James' Media Plugin PCL to capture photo using the device camera.
I realize that, for every photo, it creates a file in
/storage/emulated/0/Android/data/com.myapp/files/Pictures
(and I can provide a subdirectory within Pictures folder and the name of the file). What I want to do is delete all these files the next time my app starts up.
Since I'm only focused on the Android version, I've set up a dependency service call to locally delete the file (which I thought was trivial) but for some reasons I simply can NOT find that file programmatically or through ADB shell.
When I plug my device in for USB file transfer on windows computer, I can see the photos I want to delete in
Computer\Moto G (4)\Internal shared storage\Android\data\com.myapp\files\Pictures
But I can't get to these files through code or shell. In code, I'm getting the path through
Forms.Context.GetExternalFilesDir(Android.OS.Environment.DirectoryPictures).AbsolutePath
which gives me the path
/storage/emulated/0/Android/data/com.myapp/files/Pictures
which I think is the path where my files SHOULD be. But it's come up blank. Whether I try System.IO or Java.IO, the directory comes up empty and file.delete() or System.IO.File.Delete(path) doesn't work for me.
tldr; What does
Computer\Moto G (4)\Internal shared storage\Android\data\com.myapp\files\Pictures
translate to in terms of actual physical path in Android OS which we can list from ADB Shell?
What I want to do is delete all these files the next time my app starts up.
Try using the following code, it works fine on my side :
public void DeleteFolder()
{
var path = Forms.Context.GetExternalFilesDir(Android.OS.Environment.DirectoryPictures).AbsolutePath;
Java.IO.File directory = new Java.IO.File(path);
if (directory.IsDirectory)
{
foreach (Java.IO.File child in directory.ListFiles())
{
deleteRecursive(child);
}
}
directory.Delete();
}
It was a false negative. I was looking at the files through Windows Explorer and for some reason, Windows kept showing me those files even after they were deleted. Obviously, the reason I couldn't se those files through ADB Shell or from within Android File Manager was because those files were never there.
Forms.Context.GetExternalFilesDir(Android.OS.Environment.DirectoryPictures).AbsolutePath
gives me
/storage/emulated/0/Android/data/com.myapp/files/Pictures
which is the same as
Computer\Moto G (4)\Internal shared storage\Android\data\com.myapp\files\Pictures
Both System.IO.File.Delete(path) and new Java.IO.File(dir, children[i]).Delete(); methods work fine. It's just that windows chooses to keep showing the empty "ghost" files.
This issue has apparently been raised before to no answer: Programatically deleted files still show up in Windows Explorer
Changes like renaming a file triggered by an app only appear to the USB-MTP interface after reboot of the Android device or after you registered the new file at the MediaScanner them like this (see Trigger mediascanner on specific path (folder), how to?):
file.renameTo(newFile);
MediaScannerConnection.scanFile(context,
new String[] { newFile.getAbsolutePath() }, null, null);
USB-MTP is used to access the storage of an android device via USB. E.g. with the Windows Explorer.
However, with the Sony XPERIA Tablet Z (SGP321) under Android 5.0.2 (Build 10.6.A.0.454) folders supplied in newFile will become a file with 4KB. I am no more able to access the folder structure using Windows Explorer anymore, nor can I copy the file to my computer. Even after reboot of the tablet! The same device with Android 4.4.4 does not show the behavior. It appears that only the USB-MTP view is broken. The file structure accessed by an android app still looks fine.
Question: Is this behavior a bug or did I implement it incorrectly? What would be the correct implementation?
What I've tried so far to fix the issue:
My current workaround is to avoid scanFile for directories.
I can convert files back into directories by renaming them with an android app without MediaScannerConnection#scanFile. After reboot, I can access the directory with Windows Explorer again.
Renaming files with Windows Explorer that actually are directories does not restore them. Even after Reboot.
This line as suggested in https://stackoverflow.com/a/21918085/433718
does not refresh USB-MTP view, but also does not convert directories
into files:
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
Uri.fromFile(newFile.getParentFile()));
Maybe related:
https://stackoverflow.com/a/27321544/433718
Using content resolver for all sorts of File operations like deleting a file in this answer: Android Deleting Files MediaScannerConnection
I ended up creating a dummy text file in each directory I wanted to make visible, and use scanFile on the file.
1) create directory, but don't "scan" directories
2) copy file to directory
3) run scanFile on the filePath
MediaScannerConnection.scanFile (_application, new String[] { filePath }, null, null);
My app polls a directory on the SDcard for the appearance of new files that where dropped there by the user from Windows file explorer over the USB connection. When a new file appears, my app processes it, and then deletes it, however the file still shows up in Windows file explorer. I know the file is gone because it no longer appears in the DDMS file explorer, and my poller doesn't get triggered again. Any insights into how Android interacts with Windows file explorer would be appreciated. I've tried playing around with MediaScannerConnectionClient, which helps with getting programatically created directories to appear, but does nothing to get files to disappear.
I'm running Android 3.2 on an Acer Iconia A500. My PC is running Windows XP. The files are .csv and .txt files. I'm using File.delete() to delete them.
Thanks.
This is an old issue, but the above answers were not really helpful to me, so I tried some other stuff and the following worked for me.
Just call the scanFile method of the MediaScannerConnection on the file to be deleted after you delete it:
File file = new File("...");
String absolutePathToFile = file.getAbsolutePath();
file.delete();
MediaScannerConnection.scanFile(context, new String[]{absolutePathToFile}, null, null);
I am guessing that the scanner scans the file location, does not find the file and updates the OS's file index or whatever takes care of making the files visible to the explorer.
Android, being a Linux-based OS, will delete a file only when the last file handle to it is closed. The file name may disappear earlier, though.
On Windows, having an open file handle means the file name still exists. So Windows simply doesn't expect the file to disappear like it does.
If the files are gone when you refresh, it may just be because Windows doesn't expect the directory to change out from underneath it, and so doesn't check for changes.
EDIT: After realizing I have to make things public so to speak this is what I attempted to create a folder I could see when plugging the tablet in from my pc and copying stuff over there:
File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) ;
File theFile = new File(path+"/Portfolio/");
//if(!theFile.exists())
theFile.mkdir();
I commented out the if theFile.exists() cause it was always returning true.
So now I have this folder that seems to work, no errors are thrown and the folder should be created in fact I am using
Adao File Manager on the device to browse to this location it is indeed there under /Pictures/Portfolio
but when I plug it into my windows machine, i see /Pictures but no folders underneath it, am i just losing it?
Okay so
I have these little DIR is make on my tablet from my application, to put client files into. I thought I could just connect the tablet up and copy files from my PC to these folder I
had made. The thing is when I plug my acer iconia in, while it shows up and I can browse some files it seems the folder I made in the app using File.mkdir(); is this path:
/sdcard/Android/data/my.softwares.package.name/files/Pictures/somefolders
while I can use a 3rd party file browser app to see this folder does exsist as far as I can tell from windows i can only browse as far as:
/sdcard/Android/data (if im even getting there not sure).... is this really the case or am I missing something? The code I use to create these folders is:
String p = Environment.DIRECTORY_PICTURES + "/" + s.getClient().getFirstName()+s.getClient().getLastName() + "/" + s.getPackage().getName() + (mSession.getSessionDate().getMonth()+1) + mSession.getSessionDate().getDate() + (mSession.getSessionDate().getYear()+1900);
File path = mContext.getExternalFilesDir(p);
if(!path.exists())
path.mkdir();
Seems no luck here when I plug my tablet into the pc, again only can go as far as Android/data
So this is for a portfolio like program, I want to create a folder on the device, users can copy pictures to from their pc, then the same app that created the folder can read this folder later on after the pictures have all been copied over, so what am I missing since my assumption of windows being able to read everything on the sdcard seems false?
You have created the pictures in the private data area of your app and therefore do not have access to it. That would be a security problem.
Save the data to a public location like the sdcard. Just read up on external storage.
http://developer.android.com/guide/topics/data/data-storage.html#filesExternal
Beginner android question. Ok, I've successfully written files. E.g.
// get the file name
String filename = getResources().getString(R.string.filename);
FileOutputStream toWriteTo;
try {
toWriteTo = openFileOutput(filename, MODE_WORLD_READABLE);
// get the string to write
String toWrite = getResources().getString(R.string.contentstowrite);
toWriteTo.write(toWrite.getBytes());
toWriteTo.close();
...
}
catch (Exception ex) {
Toast.makeText(HelloFilesAppActivity.this, "fail!", Toast.LENGTH_SHORT).show();
}
}});
And I've proved that it is there by reading it and displaying contents, even using getFilesDir() and displaying all of the files in the folder.
Everything I read says that the files are in /data/data//files/
But I cannot find them. (I'm on Windows XP). My install didn't use default locations because my C:\ is pretty full. I looked in C:\Documents and Settings\Mike\.android\avd and in the project folder and in the place I installed the SDK: D:\Program Files\Android\android-sdk-windows. So where is /data/data/ ?
I read that I can use ADB to push and pull files back and forth, but I'm using Eclipse ADT and I'd prefer to use something other than command line. The book I'm using seems to imply that you can use Eclipse but then proceeds to give the command-line commands.
I found info about the Project Explorer in the DDMS, but I don't see the files I have written.
I've been working under the assumption that I might want to create a text file using some other means in Windows that I would read with my App. So if the answer is "why do you want to do this?", that's what I'm after. Eventually a DB probably too (that's in the next chapter :-) ).
Do I have to use the ADB command line?
thanks
Mike
http://developer.android.com/guide/topics/data/data-storage.html
The method your using to get the directory you read/write to:
openFileOutput()
You can save files directly on the device's internal storage. By default, files saved to the internal storage are private to your application and other applications cannot access them (nor can the user). When the user uninstalls your application, these files are removed.
You'll want to save the files your working with to the SD card.
Try this:
getExternalStoragePublicDirectory Example
It's on your phone. Your phone has its own file system. If you are using an emulator, then it's on the emulated file system, which is completely separate from yours. Your only way to access the phone's (or emulator's) file system is via ADB (unless we're talking about the SD card, which however does NOT host /data/data).
Side note - if your phone is not rooted, you won't have access to a lot of stuff on /data/data. I suppose that you are using an emulator, which is "rooted" in the sense that you have full access to its filesystem.