My phone runs Android 4.0.4 and is in Media Transfer Protocol (MTP) mode. My app is attempting to overwrite the same text file on the phone’s SD card with progressing larger files, using successive calls of the following code:
File mDir = new File(Environment.getExternalStorageDirectory(), "Location");
File mFile = new File(mDir, "Location.txt");
PrintWriter mPW = new PrintWriter(mFile);
mPW.println(sData); // sData is a string of a few hundred characters
mPW.flush();
mPW.close();
During testing in USB debugging mode, I had the following problem. In Windows 7, I could open a file written with the latest data, but the Date modified’s time and Size corresponded to an earlier write of the file and I could only see as many characters as corresponded to that size. Effectively new data in an old file.
I scoured the Web but no one seems to have reported this sort of problem. I tried lots of fancier ways of writing the file, including using buffered classes and even deleting and recreating the file before re-writing it, all to no avail.
After re-booting the phone, the problem seems to have gone away, but I wonder if this rings a bell with anyone.
What is published via the MTP interface is what the MediaStore knows about the file. The MediaStore will eventually pick up your changes, faster if you use something like MediaScannerConnection to proactively tell it that the file has changed.
However, what MTP clients choose to do is up to them. In general, they seem to cache results, and I am not aware of whether MTP has any sort of "push" semantics to tell the MTP client "hey, something you asked for a bit ago has changed". Some might reload contents based upon a "reload" or "refresh" option in the MTP client UI. Others might assume the contents are unchanging, until such time as the device is unplugged and re-plugged in.
In general, I would not advocate your approach (continuously appending to the same file, with the user expecting to be able to see those changes in real time), simply due to the apparent limitations of MTP.
Related
Trying to capture a video and save it to sd card in Mp4/3gp formats using local socket. Being able to write bytes by bytes to sd card but the video file is not playable.I have gone through many examples :
https://github.com/fyhertz/spydroid-ipcamera
https://github.com/mconf/sipdroid
and many more. I have noticed people suggesting this might be a problem of file's header. I tried to skip those "mdat" data too from header:
private void skipHeader() throws IOException {
// Skip all atoms preceding mdat atom
byte[] buffer = new byte[3];
while (true) {
while (mReceiver.getInputStream().read() != 'm');
mReceiver.getInputStream().read(buffer,0,3);
if (buffer[0] == 'd' && buffer[1] == 'a' && buffer[2] == 't') break;
}
}
At last nothing worked for me.What extra do I need to do for making those video files playable using Local Socket
From your explanation, what you have in mind to implement is a screen recorder. Of course your intention is that the system will have it implemented as part of the technology that your software is offering.
In such case, the best approach is to improve what already exist, incorporating the code with new features or new performance and giving credit to the original source that you came across and included as part of your software - as expected. This is the beauty of Open Source, which allows code to be reused, distributed and improved.
At Github there are plenty of projects... as you know, some nice and others awesome. For your particular case, my suggestion is to use existing code that allows your streaming recording system to capture the video, writing it without any need to root the device, as final users would not be interested to void the warranty of a newly purchased device only to run your software.
It is also important to achieve a good speed that allows at least capturing 20 screen per second in Android for different screen sizes, providing clearly resolution and low CPU usage. All these characteristics would keep your solution stable and still looking rock solid.
I think the best approach you can take, that will save yourself time and lots of headaches, would be to incorporate the "sji-android-screen-capture" code as part of your project. If your target devices are Android 4.2~4.4, you are good to go as it supports these Android versions. More info and the source code itself, you find available at Github repository. Alternatively, you can also use Android ScreenCapture Sample to capture device screen in real time.
I'll try to sum this up briefly. I have an app that can synchronize its data with a USB flash drive connected via an OTG adapter. The problem is this: some files will end up in a folder called LOST.DIR in the root of the flash drive. They are all exactly 4KB large and have random, 3-number names with no file extension. I know they contain data from my app because if I open them in notepad, I can see the data that my app is outputting. This data, however, is sometimes mixed with random symbols. Based on my rudimentary knowledge of file systems, the consistent size of the files and random content makes me think these are blocks of memory marked bad by Android and moved to this folder.
There is one caveat: I am treating the flash drives as if they are hot-swappable, as they would be on a Windows device. I understand that it may not be valid to think of them as this. To get around this, I'm calling running the sync command via su after I finish reading and writing to and from the flash drive. My understanding is that this should sync the in-RAM buffer/cache with the physical flash drive, thereby making it safe to remove. This may be a faulty assumption.
So, my question is two-fold:
What is causing data to randomly disappear and be moved to LOST.DIR?
Is it safe to be treating flash drives as hot swappable? If not, is there a way to make them behave that way?
If my question is not clear enough or you need more information, I can clarify things for you. Thank you.
What comes to mind is that you are not the only one accessing the flash drive (media scanner, for instance), so sync will flush buffers but something could be ongoing, and sync exits anyway. I think you should also unmount it (and it will fail until it's really safe to remove).
all
When I try to read some media file from sd card after the first time I insert to the device, the read performance is much worse than the second time, does anybody have any idea about this phenomena, and how can I avoid this problem, I tried open and fopen, but the results are the same, I just want read performance is the same, no matter when I insert SD card, thanks
Using O_DIRECT (see open(2)) when opening the file will bypass the buffer cache. This is often not a good idea, but I would expect it to be more consistent from run to run.
Keep in mind that using O_DIRECT requires that the memory read into be SC_PAGESIZE aligned and read in blocks which are multiples of SC_PAGESIZE.
Are you saying it's worse for the first read than subsequent reads before you remove the device? If so, this is normal - it's due to buffering. Basically the system is using the system RAM to speed up the perceived speed of the device.
If you remove the card after unmounting it and then put it back and remount it I would expect the first read would again be slower, then subsequent reads would appear to be faster again.
So I'm creating a project on an Android Galaxy Tab 10.1 that uses its accelerometers and gyroscopes. One of the steps here is to collect alot of data and determine its accuracy and drift. To do this I need to move the device and allow the sensors to get their readings, and then take those readings and put them through some analysis.
My admittedly primitive way of doing this is to send each reading as an error to the log, copy the log from Eclipse, paste it in notepad, and format it, getting rid of other unwanted errors and timestamps. This method is not very good, and the log in Eclipse deletes the old log entries if the list gets too long, meaning I can only look at about 30 seconds of data.
I need much more time than this so I thought of a couple ways to fix the issue:
If I could somehow write the readings directly from the Android to a document on the computer im using, that would solve all my problems.
If i could write the readings to a file on the Android that could be saved and later transfered to the computer, that would also work
Writing a file to the internal SD card is quite easy and would probably solve your second point. You can access the file later via USB, which just mounts the internal SD card like an USB thumb drive.
For example, this question and answer gives you some starting points.
I am trying to display an image sent over a local network to my android device. An image is sent from a computer via tcp to my android device. The image is a png. The data sent over is a byte array stream of the png, which is packaged into a google protobuf message. On the android side, when receiving the data, it is read into a byte array, and the array is then given to BitmapFactory.decodeByteArray(). However, this returns null roughly 90% of the time. This only happens on a real device, but I can only test on the htc incredible at the moment. I've tried this on the android sdk emulator and i can get my image 100% of the time.
Other issues relating to BitmapFactory online has always been related to using file streams, where decoding isn't getting the entirety of the data, but I have yet to find any solutions for when the developer is sure the entirety of the data is received, and it only happens on a real device.
Is there some type of usage that I am unaware of for decodeByteArray()? The byte[] I am passing in is just the file itself.
Edit: Resolved thanks to a second insight from Brian Cooley.
I was just too quick to judge that the error may be in decodeByteArray(). If anyone ever runs into this problem do make sure that you make sure you have the data in its entirety. I made the false assumption that my byte stream was good. So first do a quick diff of the data you're sending and receiving, and make sure you're getting what you should.
One thing you might try is writing the raw bytes to a file on the SD card and looking at it on your computer, like was suggested for this question
This would reveal whether the problem is in the file or in your code. Since you are not seeing the problem in the emulator, my guess is that it is related to downloading the data over the phone.