Browse Source

#22 android implementation complete

Ben Hsieh 8 years ago
parent
commit
cdee490ed1

+ 10
- 0
src/android/src/main/java/com/RNFetchBlob/RNFetchBlobFS.java View File

@@ -52,6 +52,15 @@ public class RNFetchBlobFS {
52 52
         this.emitter = ctx.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class);
53 53
     }
54 54
 
55
+    static String getExternalFilePath(ReactApplicationContext ctx, String taskId, RNFetchBlobConfig config) {
56
+        if(config.path != null)
57
+            return config.path;
58
+        else if(config.fileCache && config.appendExt != null)
59
+            return RNFetchBlobFS.getTmpPath(ctx, taskId) + "." + config.appendExt;
60
+        else
61
+            return RNFetchBlobFS.getTmpPath(ctx, taskId);
62
+    }
63
+
55 64
     /**
56 65
      * Write string with encoding to file
57 66
      * @param path Destination file path.
@@ -128,6 +137,7 @@ public class RNFetchBlobFS {
128 137
         AsyncTask<String, Integer, Integer> task = new AsyncTask<String, Integer, Integer>() {
129 138
             @Override
130 139
             protected Integer doInBackground(String... strings) {
140
+
131 141
                 try {
132 142
                     String path = strings[0];
133 143
                     String encoding = strings[1];

+ 39
- 8
src/android/src/main/java/com/RNFetchBlob/RNFetchBlobReq.java View File

@@ -1,7 +1,11 @@
1 1
 package com.RNFetchBlob;
2 2
 
3 3
 import android.app.DownloadManager;
4
+import android.content.BroadcastReceiver;
4 5
 import android.content.Context;
6
+import android.content.Intent;
7
+import android.content.IntentFilter;
8
+import android.database.Cursor;
5 9
 import android.net.Uri;
6 10
 
7 11
 import com.facebook.react.bridge.Callback;
@@ -15,11 +19,9 @@ import com.loopj.android.http.Base64;
15 19
 import com.loopj.android.http.MySSLSocketFactory;
16 20
 
17 21
 import java.io.File;
18
-import java.nio.charset.Charset;
19 22
 import java.security.KeyStore;
20 23
 
21 24
 import cz.msebera.android.httpclient.HttpEntity;
22
-import cz.msebera.android.httpclient.entity.AbstractHttpEntity;
23 25
 import cz.msebera.android.httpclient.entity.ByteArrayEntity;
24 26
 import cz.msebera.android.httpclient.entity.ContentType;
25 27
 import cz.msebera.android.httpclient.entity.FileEntity;
@@ -28,7 +30,7 @@ import cz.msebera.android.httpclient.entity.mime.MultipartEntityBuilder;
28 30
 /**
29 31
  * Created by wkh237 on 2016/6/21.
30 32
  */
31
-public class RNFetchBlobReq implements Runnable{
33
+public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
32 34
 
33 35
     final String filePathPrefix = "RNFetchBlob-file://";
34 36
     ReactApplicationContext ctx;
@@ -40,6 +42,7 @@ public class RNFetchBlobReq implements Runnable{
40 42
     ReadableMap headers;
41 43
     Callback callback;
42 44
     HttpEntity entity;
45
+    long downloadManagerId;
43 46
     AsyncHttpClient req;
44 47
     String type;
45 48
 
@@ -82,10 +85,13 @@ public class RNFetchBlobReq implements Runnable{
82 85
             if(options.addAndroidDownloads.getBoolean("useDownloadManager")) {
83 86
                 Uri uri = Uri.parse(url);
84 87
                 DownloadManager.Request req = new DownloadManager.Request(uri);
85
-                if(options.path != null) {
86
-                    Uri dest = null;
87
-                    dest = Uri.parse(options.path);
88
-                    req.setDestinationUri(dest);
88
+                req.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
89
+
90
+                if(options.addAndroidDownloads.hasKey("title")) {
91
+                    req.setTitle(options.addAndroidDownloads.getString("title"));
92
+                }
93
+                if(options.addAndroidDownloads.hasKey("description")) {
94
+                    req.setDescription(options.addAndroidDownloads.getString("description"));
89 95
                 }
90 96
                 // set headers
91 97
                 ReadableMapKeySetIterator it = headers.keySetIterator();
@@ -94,7 +100,8 @@ public class RNFetchBlobReq implements Runnable{
94 100
                     req.addRequestHeader(key, headers.getString(key));
95 101
                 }
96 102
                 DownloadManager dm = (DownloadManager) ctx.getSystemService(Context.DOWNLOAD_SERVICE);
97
-                dm.enqueue(req);
103
+                downloadManagerId = dm.enqueue(req);
104
+                ctx.registerReceiver(this, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
98 105
                 return;
99 106
             }
100 107
 
@@ -230,4 +237,28 @@ public class RNFetchBlobReq implements Runnable{
230 237
         }
231 238
 
232 239
     }
240
+
241
+    @Override
242
+    public void onReceive(Context context, Intent intent) {
243
+        String action = intent.getAction();
244
+        if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
245
+            long id = intent.getExtras().getLong(DownloadManager.EXTRA_DOWNLOAD_ID);
246
+            if(id == this.downloadManagerId) {
247
+                DownloadManager.Query query = new DownloadManager.Query();
248
+                query.setFilterById(downloadManagerId);
249
+                DownloadManager dm = (DownloadManager) ctx.getSystemService(Context.DOWNLOAD_SERVICE);
250
+                dm.query(query);
251
+                Cursor c = dm.query(query);
252
+                if (c.moveToFirst()) {
253
+                    String contentUri = c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
254
+                    Uri uri = Uri.parse(contentUri);
255
+                    Cursor cursor = ctx.getContentResolver().query(uri, new String[] { android.provider.MediaStore.Images.ImageColumns.DATA }, null, null, null);
256
+                    cursor.moveToFirst();
257
+                    String filePath = cursor.getString(0);
258
+                    cursor.close();
259
+                    this.callback.invoke(null, filePath);
260
+                }
261
+            }
262
+        }
263
+    }
233 264
 }

+ 3
- 2
src/index.js View File

@@ -28,6 +28,7 @@ const {
28 28
   mkdir,
29 29
   session,
30 30
   writeStream,
31
+  readFile,
31 32
   ls,
32 33
   isDir,
33 34
   mv,
@@ -124,7 +125,7 @@ function fetch(...args:any):Promise {
124 125
       else {
125 126
         let respType = 'base64'
126 127
         // response data is saved to storage
127
-        if(options.path || options.fileCache) {
128
+        if(options.path || options.fileCache || options.addAndroidDownloads) {
128 129
           respType = 'path'
129 130
           if(options.session)
130 131
             session(options.session).add(data)
@@ -247,7 +248,7 @@ class FetchBlobResponse {
247 248
     this.readFile = (encode: 'base64' | 'utf8' | 'ascii') => {
248 249
       if(this.type === 'path') {
249 250
         encode = encode || 'utf8'
250
-        return RNFetchBlob.fs.readFile(this.data, encode)
251
+        return readFile(this.data, encode)
251 252
       }
252 253
       else {
253 254
         console.warn('RNFetchblob', 'this response does not contains a readable file')

+ 6
- 1
src/scripts/prelink.js View File

@@ -6,11 +6,16 @@ fs.readFile(MANIFEST_PATH, function(err, data) {
6 6
   if(err)
7 7
     console.log('failed to locate AndroidManifest.xml file, you may have to add file access permission manually.');
8 8
   else {
9
-
9
+    // append fs permission
10 10
     data = String(data).replace(
11 11
       '<uses-permission android:name="android.permission.INTERNET" />',
12 12
       '<uses-permission android:name="android.permission.INTERNET" />\n    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> '
13 13
     )
14
+    // append DOWNLOAD_COMPLETE intent permission
15
+    data = String(data).replace(
16
+      '<category android:name="android.intent.category.LAUNCHER" />',
17
+      '<category android:name="android.intent.category.LAUNCHER" />\n     <action android:name="android.intent.action.DOWNLOAD_COMPLETE"/>'
18
+    )
14 19
     fs.writeFileSync(MANIFEST_PATH, data);
15 20
 
16 21
   }