Get mime from url.
MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();
String mimeString = mimeTypeMap.getMimeTypeFromExtension(MimeTypeMap.getFileExtensionFromUrl(url));
public static boolean isDrmMimeType(Context context, String mimetype) {
boolean result = false;
if (context != null) {
try {
DrmManagerClient drmClient = new DrmManagerClient(context);
if (drmClient != null && mimetype != null && mimetype.length() > 0) {
result = drmClient.canHandle("", mimetype);
}
} catch (IllegalArgumentException e) {
Log.w(Constants.TAG,
"DrmManagerClient instance could not be created, context is Illegal.");
} catch (IllegalStateException e) {
Log.w(Constants.TAG, "DrmManagerClient didn't initialize properly.");
}
}
return result;
}
StorageManager检查存储空间
void verifySpaceBeforeWritingToFile(int destination, String path, long length)
throws StopRequestException {
// do this check only once for every 1MB of downloaded data
if (incrementBytesDownloadedSinceLastCheckOnSpace(length) <
FREQUENCY_OF_CHECKS_ON_SPACE_AVAILABILITY) {
return;
}
verifySpace(destination, path, length);
}
DownloadHandler防止重复下载
public synchronized void enqueueDownload(DownloadInfo info) {
// 等待队列中没有目标,尝试启动(等待队列和下载队列中有下载记录,do nothing)
if (!mDownloadsQueue.containsKey(info.mId)) {
if (Constants.LOGV) {
Log.i(TAG, "enqueued download. id: " + info.mId + ", uri: " + info.mUri);
}
mDownloadsQueue.put(info.mId, info);
startDownloadThreadLocked();
}
}
Test
/**
* Helper to create a large file of random data on the SD card.
*
* @param filename (optional) The name of the file to create on the SD card; pass in null to
* use a default temp filename.
* @param type The type of file to create
* @param subdirectory If not null, the subdirectory under the SD card where the file should go
* @return The File that was created
* @throws IOException if there was an error while creating the file.
*/
protected File createFileOnSD(String filename, long fileSize, DataType type,
String subdirectory) throws IOException {
// Build up the file path and name
String sdPath = Environment.getExternalStorageDirectory().getPath();
StringBuilder fullPath = new StringBuilder(sdPath);
if (subdirectory != null) {
fullPath.append(File.separatorChar).append(subdirectory);
}
File file = null;
if (filename == null) {
file = File.createTempFile("DMTEST_", null, new File(fullPath.toString()));
}
else {
fullPath.append(File.separatorChar).append(filename);
file = new File(fullPath.toString());
file.createNewFile();
}
// Fill the file with random data
DataOutputStream output = new DataOutputStream(new FileOutputStream(file));
final int CHUNK_SIZE = 1000000; // copy random data in 1000000-char chunks
long remaining = fileSize;
int nextChunkSize = CHUNK_SIZE;
byte[] randomData = null;
Random rng = new LoggingRng();
byte[] chunkSizeData = generateData(nextChunkSize, type, rng);
try {
while (remaining > 0) {
if (remaining < CHUNK_SIZE) {
nextChunkSize = (int)remaining;
remaining = 0;
randomData = generateData(nextChunkSize, type, rng);
}
else {
remaining -= CHUNK_SIZE;
randomData = chunkSizeData;
}
output.write(randomData);
Log.i(TAG, "while creating " + fileSize + " file, " +
"remaining bytes to be written: " + remaining);
}
} catch (IOException e) {
Log.e(LOG_TAG, "Error writing to file " + file.getAbsolutePath());
file.delete();
throw e;
} finally {
output.close();
}
return file;
}
/**
* Helper to wait for all downloads to finish, or else a timeout to occur
*
* @param query The query to pass to the download manager
* @param poll The poll time to wait between checks
* @param timeoutMillis The max amount of time (in ms) to wait for the download(s) to complete
*/
protected void doWaitForDownloadsOrTimeout(Query query, long poll, long timeoutMillis)
throws TimeoutException {
int currentWaitTime = 0;
while (true) {
query.setFilterByStatus(DownloadManager.STATUS_PENDING | DownloadManager.STATUS_PAUSED
| DownloadManager.STATUS_RUNNING);
Cursor cursor = mDownloadManager.query(query);
try {
if (cursor.getCount() == 0) {
Log.i(LOG_TAG, "All downloads should be done...");
break;
}
currentWaitTime = timeoutWait(currentWaitTime, poll, timeoutMillis,
"Timed out waiting for all downloads to finish");
} finally {
cursor.close();
}
}
}
/**
* Helper function to synchronously wait, or timeout if the maximum threshold has been exceeded.
*
* @param currentTotalWaitTime The total time waited so far
* @param poll The amount of time to wait
* @param maxTimeoutMillis The total wait time threshold; if we've waited more than this long,
* we timeout and fail
* @param timedOutMessage The message to display in the failure message if we timeout
* @return The new total amount of time we've waited so far
* @throws TimeoutException if timed out waiting for SD card to mount
*/
protected int timeoutWait(int currentTotalWaitTime, long poll, long maxTimeoutMillis,
String timedOutMessage) throws TimeoutException {
long now = SystemClock.elapsedRealtime();
long end = now + poll;
// if we get InterruptedException's, ignore them and just keep sleeping
while (now < end) {
try {
Thread.sleep(end - now);
} catch (InterruptedException e) {
// ignore interrupted exceptions
}
now = SystemClock.elapsedRealtime();
}
currentTotalWaitTime += poll;
if (currentTotalWaitTime > maxTimeoutMillis) {
throw new TimeoutException(timedOutMessage);
}
return currentTotalWaitTime;
}
/**
* Enables or disables WiFi.
*
* Note: Needs the following permissions:
* android.permission.ACCESS_WIFI_STATE
* android.permission.CHANGE_WIFI_STATE
* @param enable true if it should be enabled, false if it should be disabled
*/
protected void setWiFiStateOn(boolean enable) throws Exception {
Log.i(LOG_TAG, "Setting WiFi State to: " + enable);
WifiManager manager = (WifiManager)mContext.getSystemService(Context.WIFI_SERVICE);
manager.setWifiEnabled(enable);
String timeoutMessage = "Timed out waiting for Wifi to be "
+ (enable ? "enabled!" : "disabled!");
WiFiChangedReceiver receiver = new WiFiChangedReceiver(mContext);
mContext.registerReceiver(receiver, new IntentFilter(
ConnectivityManager.CONNECTIVITY_ACTION));
synchronized (receiver) {
long timeoutTime = SystemClock.elapsedRealtime() + DEFAULT_MAX_WAIT_TIME;
boolean timedOut = false;
while (receiver.getWiFiIsOn() != enable && !timedOut) {
try {
receiver.wait(DEFAULT_WAIT_POLL_TIME);
if (SystemClock.elapsedRealtime() > timeoutTime) {
timedOut = true;
}
}
catch (InterruptedException e) {
// ignore InterruptedExceptions
}
}
if (timedOut) {
fail(timeoutMessage);
}
}
assertEquals(enable, receiver.getWiFiIsOn());
}
public static class WiFiChangedReceiver extends BroadcastReceiver {
private Context mContext = null;
/**
* Constructor
*
* Sets the current state of WiFi.
*
* @param context The current app {@link Context}.
*/
public WiFiChangedReceiver(Context context) {
mContext = context;
}
/**
* {@inheritDoc}
*/
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equalsIgnoreCase(ConnectivityManager.CONNECTIVITY_ACTION)) {
Log.i(LOG_TAG, "ConnectivityManager state change: " + intent.getAction());
synchronized (this) {
this.notify();
}
}
}
/**
* Gets the current state of WiFi.
*
* @return Returns true if WiFi is on, false otherwise.
*/
public boolean getWiFiIsOn() {
ConnectivityManager connManager = (ConnectivityManager)mContext.getSystemService(
Context.CONNECTIVITY_SERVICE);
NetworkInfo info = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
Log.i(LOG_TAG, "WiFi Connection state is currently: " + info.isConnected());
return info.isConnected();
}
}
/**
* Helper to enables or disables airplane mode. If successful, it also broadcasts an intent
* indicating that the mode has changed.
*
* Note: Needs the following permission:
* android.permission.WRITE_SETTINGS
* @param enable true if airplane mode should be ON, false if it should be OFF
*/
protected void setAirplaneModeOn(boolean enable) throws Exception {
int state = enable ? 1 : 0;
// Change the system setting
Settings.System.putInt(mContext.getContentResolver(), Settings.System.AIRPLANE_MODE_ON,
state);
String timeoutMessage = "Timed out waiting for airplane mode to be " +
(enable ? "enabled!" : "disabled!");
// wait for airplane mode to change state
int currentWaitTime = 0;
while (Settings.System.getInt(mContext.getContentResolver(),
Settings.System.AIRPLANE_MODE_ON, -1) != state) {
timeoutWait(currentWaitTime, DEFAULT_WAIT_POLL_TIME, DEFAULT_MAX_WAIT_TIME,
timeoutMessage);
}
// Post the intent
Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
intent.putExtra("state", true);
mContext.sendBroadcast(intent);
}
////////////////////////////////////////////////////////////
ParcelFileDescriptor pfd = mDownloadManager.openDownloadedFile(requestId);
/**
* Helper to verify the size of a file.
*
* @param pfd The input file to compare the size of
* @param size The expected size of the file
*/
protected void verifyFileSize(ParcelFileDescriptor pfd, long size) {
assertEquals(pfd.getStatSize(), size);
}
/**
* Helper to verify the contents of a downloaded file versus a byte[].
*
* @param actual The file of whose contents to verify
* @param expected The data we expect to find in the aforementioned file
* @throws IOException if there was a problem reading from the file
*/
protected void verifyFileContents(ParcelFileDescriptor actual, byte[] expected)
throws IOException {
AutoCloseInputStream input = new ParcelFileDescriptor.AutoCloseInputStream(actual);
long fileSize = actual.getStatSize();
assertTrue(fileSize <= Integer.MAX_VALUE);
assertEquals(expected.length, fileSize);
byte[] actualData = new byte[expected.length];
assertEquals(input.read(actualData), fileSize);
compareByteArrays(actualData, expected);
}
/**
* Helper to compare 2 byte arrays.
*
* @param actual The array whose data we want to verify
* @param expected The array of data we expect to see
*/
protected void compareByteArrays(byte[] actual, byte[] expected) {
assertEquals(actual.length, expected.length);
int length = actual.length;
for (int i = 0; i < length; ++i) {
// assert has a bit of overhead, so only do the assert when the values are not the same
if (actual[i] != expected[i]) {
fail("Byte arrays are not equal.");
}
}
}