2011年12月28日 星期三

Android - Downloads.java和DownloadProvider的應用

想要讓自己的apk達到從網路下載東西(預設放到SD 卡的download底下)的功能,可以利用DownloadProvider。總共有3個主要步驟

(1)DownloadProvider必需是system權限才能執行的程式,所以我們必需讓自己的apk的USER是system。
(2)了解Download東西其實是透過改變data/data/com.android.providers.downloads/databases裡面的downloads.db裡面的downloads這一個table,來達成的。
(3)AndroidManifest.xml給予適當的權限。

接下來實作測試程式碼
public class Main extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
      
        ContentValues values = new ContentValues();
        String url = "http://lh4.ggpht.com/_cCOjVNtItLY/TLTC9OVLHeI/AAAAAAAAIOw/7PP-Ih9vOY4/s640/P1030438.JPG";
        values.put("uri", url);
        values.put("mimetype", "image/jpeg");
       
        ContentResolver mResolver = getContentResolver();
        mResolver.insert(Uri.parse("content://downloads/download"), values);  
    }
}

針對"content://downloads/download"所對應到的table寫入一筆準備download的資料,就會觸發系統下載的動作。其中必填欄位最少要對uri和mimetype給值。整個Android到底對應那些mimetype可以參考
frameworks/base/core/java/android/webkit/MimeTypeMap.java

而想知道table到底有那些欄位,可以利用adb shell進入後
# cd data/data/com.android.providers.downloads/databases
# sqlite3 downloads.db
SQLite version 3.6.22
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite>.headers on
sqlite> select * from downloads;
_id|uri|method|entity|no_integrity|hint|otaupdate|_data|mimetype|destination|no_system|visibility|control|status|numfailed|lastmod|notificationpackage|notificationclass|notificationextras|cookiedata|useragent|referer|total_bytes|current_bytes|etag|uid|otheruid|title|description|restriction|auth_header_name|auth_header_value|scanned
所有的欄位就出現了。這麼多欄位,有那些是比較重要的(比較需要填寫的),可以參考/packages/providers/DownloadProvider/Helpers.java


在AndroidManifest.xml中,需要給予的權限有
    <uses-permission android:name="android.permission.ACCESS_DOWNLOAD_MANAGER" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />


完成上述之後就等於完成了第2和第3項的條件。最後一項是要設定apk的USER是system。
這裡有兩個步驟
(1)在AndroidManifest.xml設定
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.test.testdownload"
      android:versionCode="1"
      android:versionName="1.0"
      android:sharedUserId="android.uid.system" >

(2)另外,這支程式要在source code底下利用mm的方式產生出來,所以在Android.mk中要加上
LOCAL_CERTIFICATE := platform

最後mm出來的apk放到手機上執行,就會發現程式download東西了。

沒有留言:

張貼留言