SoundRecorder.javaAPI DocAndroid 1.5 API30815Wed May 06 22:42:48 BST


public class RemainingTimeCalculator extends Object
Calculates remaining recording time based on available disk space and optionally a maximum recording file size. The reason why this is not trivial is that the file grows in blocks every few seconds or so, while we want a smooth countdown.

Fields Summary
public static final int
public static final int
public static final int
private int
private File
private File
private long
private int
private long
private long
private long
private long
Constructors Summary
public RemainingTimeCalculator()

        mSDCardDirectory = Environment.getExternalStorageDirectory();
Methods Summary
public intcurrentLowerLimit()
Indicates which limit we will hit (or have hit) first, by returning one of FILE_SIZE_LIMIT or DISK_SPACE_LIMIT or UNKNOWN_LIMIT. We need this to display the correct message to the user when we hit one of the limits.

        return mCurrentLowerLimit;
public booleandiskSpaceAvailable()
Is there any point of trying to start recording?

        StatFs fs = new StatFs(mSDCardDirectory.getAbsolutePath());
        // keep one free block
        return fs.getAvailableBlocks() > 1;
public voidreset()
Resets the interpolation.

        mCurrentLowerLimit = UNKNOWN_LIMIT;
        mBlocksChangedTime = -1;
        mFileSizeChangedTime = -1;
public voidsetBitRate(int bitRate)
Sets the bit rate used in the interpolation.

bitRate the bit rate to set in bits/sec.

        mBytesPerSecond = bitRate/8;
public voidsetFileSizeLimit( file, long maxBytes)
If called, the calculator will return the minimum of two estimates: how long until we run out of disk space and how long until the file reaches the specified size.

file the file to watch
maxBytes the limit

        mRecordingFile = file;
        mMaxBytes = maxBytes;
public longtimeRemaining()
Returns how long (in seconds) we can continue recording.

        // Calculate how long we can record based on free disk space
        StatFs fs = new StatFs(mSDCardDirectory.getAbsolutePath());
        long blocks = fs.getAvailableBlocks();
        long blockSize = fs.getBlockSize();
        long now = System.currentTimeMillis();
        if (mBlocksChangedTime == -1 || blocks != mLastBlocks) {
            mBlocksChangedTime = now;
            mLastBlocks = blocks;

        /* The calculation below always leaves one free block, since free space
           in the block we're currently writing to is not added. This
           last block might get nibbled when we close and flush the file, but 
           we won't run out of disk. */
        // at mBlocksChangedTime we had this much time
        long result = mLastBlocks*blockSize/mBytesPerSecond;
        // so now we have this much time
        result -= (now - mBlocksChangedTime)/1000;
        if (mRecordingFile == null) {
            mCurrentLowerLimit = DISK_SPACE_LIMIT;
            return result;
        // If we have a recording file set, we calculate a second estimate
        // based on how long it will take us to reach mMaxBytes.
        mRecordingFile = new File(mRecordingFile.getAbsolutePath());
        long fileSize = mRecordingFile.length();
        if (mFileSizeChangedTime == -1 || fileSize != mLastFileSize) {
            mFileSizeChangedTime = now;
            mLastFileSize = fileSize;

        long result2 = (mMaxBytes - fileSize)/mBytesPerSecond;
        result2 -= (now - mFileSizeChangedTime)/1000;
        result2 -= 1; // just for safety
        mCurrentLowerLimit = result < result2
        return Math.min(result, result2);