Closed GoogleCodeExporter closed 9 years ago
Original comment by wbrune...@gmail.com
on 20 Dec 2010 at 8:18
The problem is caused by the HTC Incredible having two partitions on the
internal sdcard. HTC decided to use a new unpublished Uri
(content://media.phoneStorage/audio/media or
content://media.phoneStorage/video/media). The regular directories that the
rest of Android uses for media storage are not really there.
The first real issue occurs in the AudioWidget and the VideoWidget in the
method setBinaryData. if (!f.renameTo(newFile)) { fails because it is trying
to move and rename a file from two partitions across the same mnt point. The
docs for File.renameTo even say this will fail.
To fix this in our code we created a new method in the FileUtils class to copy
files and delete the original. We then replaced:
if (!f.renameTo(newFile)) {
with this code:
// new file to copy into
File newFile = new File(s);
if (!FileUtils.copyFileAndDelete(f, newFile)) {
Here is the code to do that:
/**
* Many high end phones are now partitioning the sdcard for storage the method
* File.renameTo(x) is failing because the partitions are on the same mnt point.
* This method is called to fix the issue.
*
* @param inFile this is the file to be copied and deleted
* @param outFile this is the final file in new loacation
*
* @return true if te file was copied and deleted oe false if it fails
*/
public static boolean copyFileAndDelete(File inFile, File outFile) {
Log.d(t, "-------------------------------------- starting copyFileAndDelete");
try {
// Get the size of the file
long length = inFile.length();
if (length > Integer.MAX_VALUE) {
Log.e(t, "File " + inFile.getName() + "is too large");
return false;
}
int fileLength = (int)length;
Log.d(t, "-------------------------------------- fileLength: " + fileLength);
// get the input stream to read from
InputStream is = null;
is = new FileInputStream(inFile);
// get the output steam to write to
OutputStream os = null;
os = new FileOutputStream(outFile);
// Read in the bytes
int offset = 0;
int read = 0;
byte[] dataBlock = new byte[fileLength];
try {
// read the file in
while (offset < fileLength) {
read = is.read(dataBlock, offset, fileLength);
Log.d(t, "-------------------------------------- read: " + read);
// are we at end of file
if (read == -1) {
offset = fileLength;
} else {
offset += read;
}
}
// write all data to the outFile
os.write(dataBlock, 0, fileLength);
} catch (IOException e) {
Log.e(t, "Cannot read " + inFile.getName());
e.printStackTrace();
return false;
}
// close the streams
try {
os.flush();
os.close();
} catch (Exception ignore) {}
try {
is.close();
} catch (Exception ignore) {}
// Ensure all the bytes have been read in
if (offset < length) {
Log.e(t, "Cannot copy " + inFile.getName());
return false;
}
// last thing to do is delete the infile
inFile.delete();
}
catch (Exception ignore) {
ignore.printStackTrace();
return false;
}
// how big is the output file
Log.d(t, "-------------------------------------- outFile size: " + outFile.length());
return true;
} // end copyFileAndDelete
Original comment by stevepot...@gmail.com
on 22 Dec 2010 at 2:32
The second problem you will run into with the HTC Incredible is in the method
getUriFromPath in both the AudioWidget and the Video Widget. Because HTC is
using unpublished Uri's you will have to trap for them with code like this:
// new Uri for HTC phonestorage
private Uri mPhoneStorageUri;
...
in method initialize
// create the uri
mPhoneStorageUri = Uri.parse("content://media/phoneStorage/audio/media");
now modify the method getUriFromPath
the current code looks like this:
Cursor c =
getContext().getContentResolver().query(mExternalUri, null, "_data='" + path + "'",
null, null);
c.moveToFirst();
// create uri from path
Log.d(t, "----------------------------- _id: " + c.getColumnIndex("_id"));
newPath += c.getInt(c.getColumnIndex("_id"));
Log.d(t, "----------------------------- newPath: " + newPath);
c.close();
the new code would look like this:
String newPath = mExternalUri + "/";
boolean tryInternal = false;
// try external first
try {
Cursor c =
getContext().getContentResolver().query(mExternalUri, null, "_data='" + path + "'",
null, null);
c.moveToFirst();
// create uri from path
Log.d(t, "----------------------------- _id: " + c.getColumnIndex("_id"));
newPath += c.getInt(c.getColumnIndex("_id"));
Log.d(t, "----------------------------- newPath: " + newPath);
c.close();
} catch (Exception ignore) {
tryInternal = true;
}
// try the phone storage
if (tryInternal) {
try {
Cursor c =
getContext().getContentResolver().query(mPhoneStorageUri, null, "_data='" + path + "'",
null, null);
c.moveToFirst();
// create uri from path
Log.d(t, "----------------------------- phone _id: " + c.getColumnIndex("_id"));
newPath = mPhoneStorageUri + "/" + c.getInt(c.getColumnIndex("_id"));
Log.d(t, "-----------------------------phone newPath: " + newPath);
c.close();
tryInternal = false;
} catch (Exception ignore) {
Log.d(t, "----------------------------- mPhoneStorageUri failed");
}
}
With these changes and the changes from the comment above your HTC will now
work and the code will continue to work on other phones.
Original comment by stevepot...@gmail.com
on 22 Dec 2010 at 2:39
The last thing you will need to change to add the mime type for amr to the
InstanceUploaderTask. The HTC Incredible records amr files for audio and the
InstanceUploaderTask does not know how to handle them.
add this code to the do in background method where // mime post are being
handled
else if (f.getName().endsWith(".amr")) {
fb = new FileBody(f, "audio/amr");
entity.addPart(f.getName(), fb);
Log.i(t, "added audio file " + f.getName());
}
now your audio files will be uploaded to the server
Original comment by stevepot...@gmail.com
on 22 Dec 2010 at 2:43
Original comment by wbrune...@gmail.com
on 22 Dec 2010 at 3:54
Thanks for the thorough explanation and code! I've rolled in the changes so
recording won't crash, but still need to add the .amr portion. Will do that in
the next couple days.
Original comment by carlhart...@gmail.com
on 7 Jun 2011 at 10:57
Original comment by wbrune...@gmail.com
on 7 Jun 2011 at 11:39
.amr has been added to 1.1.7.
Original comment by carlhart...@gmail.com
on 27 Sep 2011 at 6:01
Original issue reported on code.google.com by
bill.wa...@gmail.com
on 20 Dec 2010 at 2:29