How to Use Android Downloads Provider
본문 http://blog.lytsing.org/archives/135.html
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:
We maybe can’t compile with Eclipse, but we can write an Android.mk makefile, use mmm to do it.
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.
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.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
m1 이클립스에 oracle cloud (오라클 클라우드)연결하기m1에는 oracle이 설치되지 않는다.... 큰맘먹고 지른 m1인데 oracle이 설치되지 않는다니... 하지만 이뻐서 용서가 된다. 이거 때문에 웹 개발 국비수업을 듣는 도중에 몇번 좌절하고 스트레스를 크게 받았...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.