How to Use Android Downloads Provider

本文介绍如何在Android应用中使用Download Provider进行文件下载。包括权限声明、下载任务的启动及监听下载进度的方法。同时展示了如何通过自定义接收器来处理下载完成通知。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

How to Use Android Downloads Provider
Posted on June 3, 2010 by deli

“Good programmers write solid code, while great programmers reuse the code of good programmers”
— W. Jason Gilmore, the author of “Beginning PHP and MySQL”

In Android Platform, it supports some ways to download files from URLs via HttpURLConnection or HttpClient, or DownloadProvider.When you write an android programm with Eclipse, try to import:

import android.provider.Downloads


The Eclipse gives a red error prompting and complains:

The import android.provider.Downloads cannot be resolved

Oops…

The download manager is not part of the public SDK, and there are no relational API description in Android developers Reference.Comment in sources frameworks/base/core/java/android/provider/Downloads.java, says: “For 1.0 the download manager can’t deal with abuse from untrusted apps, so this API is hidden.” Refer to the document description from: packages/providers/DownloadProvider/docs/index.html. we Know that Browser / Gmail / Market / Updater depend on the download manager. Yes, show some screenshots in the market:

use downloadprovider in android market

android market downloads shows in the statebar.

We maybe can’t compile with Eclipse, but we can write an Android.mk makefile, use mmm to do it.
===========================================
First, you want to compile all the android code, and then put your project to packages/apps/ , create Android.mk file in the root of your project, can refer to the Browser’s Android.mk, or others.
. build/envsetup.sh
mmm packages/apps/your_project
===========================================
DownloadProvider is very easy to use.First, declare permission in AndroidManifest.xml:

<uses-permission
android:name="android.permission.INTERNET"
>
</uses-permission>
<uses-permission
android:name="android.permission.ACCESS_DOWNLOAD_MANAGER"
>
</uses-permission>


And then just need to fill some field values:

ContentValues values = new ContentValues();
String url = "http://blog.lytsing.org/wp-content/uploads/2010/06/android_downloadprovider_market.jpg";
values.put(Downloads.URI, url);
values.put(Downloads.MIMETYPE, "image/jpeg");
values.put(Downloads.FILENAME_HINT, getFullFilename("android_downloadprovider_market.jpg"));
values.put(Downloads.TITLE, "screenshot");
values.put(Downloads.DESCRIPTION, "screenshot file for DownloadProvider Demo");
values.put(Downloads.VISIBILITY, Downloads.VISIBILITY_VISIBLE);
values.put(Downloads.NOTIFICATION_CLASS, "org.lytsting.android.downloads.DownloadReceiver");
values.put(Downloads.NOTIFICATION_PACKAGE, "org.lytsting.android.downloads");
getContentResolver().insert(Downloads.CONTENT_URI, values);


private String getFullFilename(String filename) {
return Environment.getExternalStorageDirectory().toString() + "/download/" + filename);
}


Notes

Downloads.FILENAME_HINT, for a demo, here, I put the file into SD Card, the download directory, without checking any exception.
Downloads.NOTIFICATION_CLASS, you want to write a DownloadReceiver class, which extends BroadcastReceiver, and handle the message Downloads.DOWNLOAD_COMPLETED_ACTION or Downloads.NOTIFICATION_CLICKED_ACTION. like this:

public class DownloadReceiver extends BroadcastReceiver {
static final String TAG = "DownloadReceiver";

@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, intent.getAction());
if (intent.getAction().equals(Downloads.NOTIFICATION_CLICKED_ACTION)) {
Intent activityIntent = new Intent(Intent.ACTION_VIEW);
activityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activityIntent.setClass(context, Downloads.class); // Downloads Activity
try {
context.startActivity(activityIntent);
} catch (ActivityNotFoundException ex) {
Log.d(TAG, "no activity for Downloads.NOTIFICATION_CLICKED_ACTION" + ex);
}
} else if (intent.getAction().equals(Downloads.DOWNLOAD_COMPLETED_ACTION)) {
// balabala
}
}
}


By here, we need to modify the AndroidManifest.xml, add:

<receiver
android:name=".DownloadReceiver"
android:permission="android.permission.SEND_DOWNLOAD_COMPLETED_INTENTS"
android:exported="true" >

<intent-filter>
<action
android:name="android.intent.action.DOWNLOAD_COMPLETED">
</action>
</intent-filter>
<intent-filter>
<action
android:name="android.intent.action.DOWNLOAD_NOTIFICATION_CLICKED">
</action>

<category
android:name="android.intent.category.DEFAULT">
</category>
<data
android:scheme="content">
</data>
</intent-filter>
</receiver>


Maybe, you don’t like show the the Download state in status bar, just change Downloads.VISIBILITY_VISIBLE to Downloads.VISIBILITY_HIDDEN

and even, maybe you would like to show the download progress in the Activity, little case.

Cursor c = getContentResolver().query(
Downloads.CONTENT_URI, new String[] {
Downloads._ID,
Downloads.CURRENT_BYTES,
Downloads.TOTAL_BYTES,
Downloads.STATUS },
" " + Downloads.MIMETYPE + " = 'image/jpeg'", null,
Downloads._ID);

if (c == null) {
return;
}

// Columns match projection in query above
final int idColumn = 0;
final int currentBytesColumn = 1;
final int totalBytesColumn = 2;
final int statusColumn = 3;

c.moveToFirst();
long totalBytes = c.getLong(totalBytesColumn);
long currentBytes = c.getLong(currentBytesColumn);

c.close();


Add a ProgressBar and a Handler to display and refresh the progress, I suppose you should know how to do. You also can write a class extends ContentObserver to observer the download status.

The last step, delete the history data:

getContentResolver().delete(Downloads.CONTENT_URI,
"(" + Downloads.TITLE + " = 'screenshot')", null);

This code snippet should be write into a function in really code.

Read the code packages/apps/Browser for a more complete example.
[color=cyan]
Update:Since Android 2.2, the Downloads’s api has changed, they put some variables input a sub class which named Impl, so you should check it in the source code.[/color]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值