I have a tablet where I need to execute a service from a binary file which will continually receive data from a chip and store the various data files in the "/data/data/com.example.binary/received/" folder. I also have a FileObserver set up on that folder to perform an action on the files that are created and once the Close event is given by the FileObserver I an trying to delete the file. This is what I have an issue with. I can delete the files if it is in the "/data/data/com.example.binary/" folder but if its in the "/data/data/com.example.binary/received/" folder I cant delete it. Seems to be some android permission issue. Is there any way around this?.
So far I have tried and failed by
1) trying to execute the "rm /data/data/com.example.binary/received/file1.xy"
2) trying file.delete()
FYI - I have the Read and Write Permissions. And all file handles to the file are closed, that's when the file's Close event is fired by the FileObserver.
I can delete the files from ADB using the "rm file1.xy"
And the binary file is from our client and i cannot change the location where it creates the output files.xy . . it will always be in the received folder. So any suggestions?
PS: /data/data folder is the location where all the installed apps get stored in my tablet.
Related
I'm looking to delete file(s) at /data/user/0/com.android.providers.downloads/cache programmatically but do not seem to have access to it. I have signature level app permission and can do adb root and su in the shell but Runtime.getRuntime().exec(su) receives a Permission denied exception. When I try to do File file = new File(path) and check if it exists, it returns false. The permissions for the cache folder are drwxrwx--x.
How can I delete file(s) from the DownloadManager cache directory?
Update
The best way seems to be to use DownloadManager remove(downloadId) which removes it from the cache folder. It is not well documented that it does that though.
The best way seems to be DownloadManager remove(downloadId) when you have it available. It actually removes the file with a message Deleting /data/data/com.android.providers.downloads/cache/binary.apk via provider delete
If you want the list of downloadIds to remove the whole cache, the programmer might need to use DownloadManager Query and filter by status complete to get all of them to remove.
Suppose,
at timeA, the 1st process(P1) creates a file and begin writing to it, and after some time,
at timeB, the 2nd process tries to chmod the file permission. And, after some time,
at timeC, P1 finishes writing and closes the file.
The question is: at what time point can other process(say P3) observe that the file permission has been changed?
The file system is inside Android, which should be Linux file system.
I didn't find any document or specification addressing this concurrency issue.
In POSIX semantics which Linux tries to follow, the file access permissions are only checked when opening the file. After the process has an open file descriptor, the process can continue use those permissions the file descriptor was granted until the process closes the file descriptor.
It is also possible for a process to have an open file descriptor to a file that it didn't open, or never had permissions to open - the file descriptors can be inherited over fork and exec, and they can also be sent via Unix domain sockets.
Concurrency-wise there is only one thing: either the open happens before or after the chmod takes effect. If before, then the process writing into file can be completely oblivious that open happened.
it seems that MediaScanner wants to scan files that I told it not to. Now I wonder why.
My app downloads several media files from my server and shows them later with a playlist.
For that, the app gets the media files with the Android system's DownloadManager.
Using Request.setDestinationUri(), the download will be saved to a subdirectory of getExternalCacheDir() named "pending".
When the download is finished, the Android DownloadManager sends ACTION_DOWNLOAD_COMPLETE broadcast. My app's broadcast listener will then take that finished download and move it from the "pending" folder to a different folder named "media".
All this works as intended.
However, the system log is full of messages like these:
E/BitmapFactory(23779): Unable to decode stream: java.io.FileNotFoundException: /path/to/pending/image.jpg: open failed: ENOENT (No such file or directory)
E/JHEAD (23779): can't open '/path/to/pending/image.jpg'
E/StagefrightMetadataRetriever(25911): Unable to create data source for '/path/to/pending/video.mp4'.
E/MediaScannerJNI(23779): An error occurred while scanning file '/path/to/pending/video.mp4'.
So apparently, my app tells the DownloadManager to download an image / a video to the "pending" directory. It does as it's told and sends a "I completed the download" broadcast. My app receives the broadcast and moves the complete file to the "media" directory. Some moments later, the MediaScanner (or something else) tries to scan the completed file in the "pending" folder and barfs into the system log.
Now I'm wondering: Why is MediaScanner trying to read these files, anyway?
According to the Android API doc for setDestinationUri: "The downloaded file is not scanned by MediaScanner. But it can be made scannable by calling allowScanningByMediaScanner()." I don't call that method, so the downloaded file should not be scanned.
Next, I tried to put an empty .ignore in the app's cache directory and reminded the MediaScanner of the .ignore-file's existence through ACTION_MEDIA_SCANNER_SCAN_FILE, but the error messages remain.
To add to the mystique, the files do not show up in the system's gallery or video apps, so yes, the media scanner ignores them. But still: Why does it try to read them when it doesn't have to? Is it the MediaScanner at all or is it some other system service?
Next, I tried to put an empty .ignore in the app's cache directory and reminded the MediaScanner of the .ignore-file's existence through ACTION_MEDIA_SCANNER_SCAN_FILE, but the error messages remain.
The magic file to stop the Mediascanner is not ".ignore" but ".nomedia".
From MediaScanner.java:
File file = new File(path.substring(0, slashIndex) + ".nomedia");
if (file.exists()) {
// we have a .nomedia in one of the parent directories
return true;
}
And the reason why it did not appear in the system's gallery or video apps is maybe, because the scan crashed (as indicated in the log).
However, I have bad feelings about the media scanner too. For example, why doesn't it stop scanning in a more straight way. For example, in MediaScanner.java, instead of
public void scanDirectories(String[] directories, String volumeName) {
[...]
for (int i = 0; i < directories.length; i++) {
processDirectory(directories[i], mClient);
}
it could be
public void scanDirectories(String[] directories, String volumeName) {
[...]
for (int i = 0; i < directories.length; i++) {
if (! isNoMediaPath(directories[i]))
processDirectory(directories[i], mClient);
}
But instead, it goes forth and back between java code and cpp code again and again. What is the reason for that?
It really looks like the ".nomedia" won't give even half the effect some might expect. After further investigating in MediaScanner.java I would say, that this file does not stop the MediaScanner from scanning the whole tree at all. It still adds entries to MediaStore for each file, never mind of noMedia being set or not.
It just marks those entries in the MediaStore as "must not show up". On each file it does an "beginFile" and an "endFile". In the endFile it always does a mMediaInserter.insert, the one way or the other.
What bothers me so much about this is the fact, that it scans through all the files in e.g. a mounted stick, hereby taking the risk of trapping into a virus (specially designed for that scan process) and no .nomedia file can stop it from doing so.
I need to make a shared folder in android.
I want to be able to:
1) create a folder on the device(sdcard/SharedFolder). ;
2) create a folder on the server. ;
3) copy some files to that folder. ;
4) seamlessly synchronize those files with my Android(and vice-versa). ;
The idea is to make an ftp connection to the ftp server(local filzila server at first) and
compare my local files list to his remote files list(by means of comparing timestamps or any other way).
Then my application would decide which files are the most updated and will copy them(from device to server or from the server to the device).
So i have 3 issues which i wanted to talk about:
I.Currently i made my application be a Broadcast-Receiver which is being called by the Alarm-Manager repeatedly(with the inexact method) and run on its own process.
Upon receiving a broadcast i connect to the server and make the above.
currently the broadcast-receiver is set from some Activity(enable/disable buttons and thats it.)
What will happen to my Broadcast-Receiver after killing the Activity which set him? I understood that at some point the system will delete him from the Alarm-Manager too? How should i handle this? I want the program to run without the user handling it... hence after restart of the device and etc i don't want him to re-enable my program.
II. How would you suggest to handle the files compare between the folders? i would like to support copy, delete, edit on those files hence the most suitable version of a file should be on both the server and device after the sync.
i thought about making some manifest file in each folder and save in it data on the file like:
-who change it last and when
-how much readers does this file have(can it be done as a service of the phone? some event of opening a file or a folder?)
and etc.
III.
Any suggestions will be appreciated!
ADB provides a shell interface where you can issue commands shell commands. See http://developer.android.com/guide/developing/tools/adb.html#shellcommands
You can also use the sync command provided with ADB. Open a prompt and issue 'adb help' to see more.
I want to create an app which would monitor changes to data in a folder on SD card.
For example if a file is put in a folder, as soon as file is copied, my app would send this file to server and delete this file.
Is it possible to do this?
Thanks.
I think you can use android.os.FileObserver which is available since API Level 1.
Source: http://developer.android.com/reference/android/os/FileObserver.html
I looks like there is no system-wide "FileSystemMonitor" you could connect to.
So you have to write it yourself. You could for example receive the ACTION_TIME_TICK broadcast and check the filesystem for changes yourself every minute using the normal java File classes.