Browse Source

Fix content URI loading issue #49

Ben Hsieh 7 years ago
parent
commit
1d92052cd2

+ 17
- 19
src/android/src/main/java/com/RNFetchBlob/RNFetchBlobBody.java View File

@@ -1,6 +1,8 @@
1 1
 package com.RNFetchBlob;
2 2
 
3
+import android.net.Uri;
3 4
 import android.util.Base64;
5
+import android.util.Log;
4 6
 
5 7
 import com.facebook.react.bridge.Arguments;
6 8
 import com.facebook.react.bridge.ReactApplicationContext;
@@ -12,6 +14,7 @@ import com.facebook.react.modules.core.DeviceEventManagerModule;
12 14
 
13 15
 import java.io.File;
14 16
 import java.io.FileInputStream;
17
+import java.io.FileNotFoundException;
15 18
 import java.io.IOException;
16 19
 import java.io.InputStream;
17 20
 import java.util.ArrayList;
@@ -88,7 +91,7 @@ public class RNFetchBlobBody extends RequestBody{
88 91
                                     InputStream in = ctx.getAssets().open(assetName);
89 92
                                     pipeStreamToSink(in, sink);
90 93
                                 } catch (IOException e) {
91
-
94
+                                    Log.e("RNFetchBlob", "Failed to create form data asset :" + orgPath + ", " + e.getLocalizedMessage() );
92 95
                                 }
93 96
                             }
94 97
                             // data from normal files
@@ -98,6 +101,9 @@ public class RNFetchBlobBody extends RequestBody{
98 101
                                     FileInputStream fs = new FileInputStream(file);
99 102
                                     pipeStreamToSink(fs, sink);
100 103
                                 }
104
+                                else {
105
+                                    Log.e("RNFetchBlob", "Failed to create form data from path :" + orgPath + "file not exists.");
106
+                                }
101 107
                             }
102 108
                         }
103 109
                         // base64 embedded file content
@@ -127,20 +133,6 @@ public class RNFetchBlobBody extends RequestBody{
127 133
                 break;
128 134
             case SingleFile:
129 135
                 pipeStreamToSink(requestStream, sink);
130
-//                byte [] chunk = new byte[10240];
131
-//                int read = requestStream.read(chunk, 0, 10240);
132
-//                sink.write(chunk, 0, read);
133
-//                bytesWritten += read;
134
-//                while(read > 0) {
135
-//                    read = requestStream.read(chunk, 0, 10240);
136
-//                    if(read > 0) {
137
-//                        sink.write(chunk, 0, read);
138
-//                        bytesWritten += read;
139
-//                        emitUploadProgress(bytesWritten, contentLength);
140
-//                    }
141
-//
142
-//                }
143
-//                requestStream.close();
144 136
                 break;
145 137
         }
146 138
         buffer.flush();
@@ -149,7 +141,9 @@ public class RNFetchBlobBody extends RequestBody{
149 141
     private void pipeStreamToSink(InputStream stream, BufferedSink sink) throws IOException {
150 142
         byte [] chunk = new byte[10240];
151 143
         int read = stream.read(chunk, 0, 10240);
152
-        sink.write(chunk, 0, read);
144
+        if(read > 0) {
145
+            sink.write(chunk, 0, read);
146
+        }
153 147
         bytesWritten += read;
154 148
         while(read > 0) {
155 149
             read = stream.read(chunk, 0, 10240);
@@ -174,6 +168,8 @@ public class RNFetchBlobBody extends RequestBody{
174 168
                 .emit(RNFetchBlobConst.EVENT_UPLOAD_PROGRESS, args);
175 169
     }
176 170
 
171
+
172
+
177 173
     /**
178 174
      * Compute a proximate content length for form data
179 175
      * @return
@@ -191,16 +187,18 @@ public class RNFetchBlobBody extends RequestBody{
191 187
                 if (data.startsWith(RNFetchBlobConst.FILE_PREFIX)) {
192 188
                     String orgPath = data.substring(RNFetchBlobConst.FILE_PREFIX.length());
193 189
                     orgPath = RNFetchBlobFS.normalizePath(orgPath);
194
-                    // path starts with content://
190
+                    // path starts with asset://
195 191
                     if (RNFetchBlobFS.isAsset(orgPath)) {
196 192
                         try {
197 193
                             String assetName = orgPath.replace(RNFetchBlobConst.FILE_PREFIX_BUNDLE_ASSET, "");
198
-                            long length = ctx.getAssets().openFd(assetName).getLength();
194
+                            long length = ctx.getAssets().open(assetName).available();
199 195
                             total += length;
200 196
                         } catch (IOException e) {
201 197
 
202 198
                         }
203
-                    } else {
199
+                    }
200
+                    // general files
201
+                    else {
204 202
                         File file = new File(RNFetchBlobFS.normalizePath(orgPath));
205 203
                         total += file.length();
206 204
                     }

+ 15
- 9
src/android/src/main/java/com/RNFetchBlob/RNFetchBlobFS.java View File

@@ -1,5 +1,7 @@
1 1
 package com.RNFetchBlob;
2 2
 
3
+import android.app.LoaderManager;
4
+import android.content.ContentResolver;
3 5
 import android.content.CursorLoader;
4 6
 import android.content.res.AssetFileDescriptor;
5 7
 import android.database.Cursor;
@@ -7,6 +9,7 @@ import android.media.MediaScannerConnection;
7 9
 import android.net.Uri;
8 10
 import android.os.AsyncTask;
9 11
 import android.os.Environment;
12
+import android.os.Looper;
10 13
 import android.provider.MediaStore;
11 14
 import android.util.Base64;
12 15
 
@@ -779,15 +782,18 @@ public class RNFetchBlobFS {
779 782
             return path;
780 783
         }
781 784
         else if (path.startsWith(RNFetchBlobConst.FILE_PREFIX_CONTENT)) {
782
-            String[] proj = { MediaStore.Images.Media.DATA };
783
-            Uri contentUri = Uri.parse(path);
784
-            CursorLoader loader = new CursorLoader(RNFetchBlob.RCTContext, contentUri, proj, null, null, null);
785
-            Cursor cursor = loader.loadInBackground();
786
-            int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
787
-            cursor.moveToFirst();
788
-            String result = cursor.getString(column_index);
789
-            cursor.close();
790
-            return result;
785
+            String filePath = null;
786
+            Uri uri = Uri.parse(path);
787
+            if (uri != null && "content".equals(uri.getScheme())) {
788
+                ContentResolver resolver = RNFetchBlob.RCTContext.getContentResolver();
789
+                Cursor cursor = resolver.query(uri, new String[] { MediaStore.Images.ImageColumns.DATA }, null, null, null);
790
+                cursor.moveToFirst();
791
+                filePath = cursor.getString(0);
792
+                cursor.close();
793
+            } else {
794
+                filePath = uri.getPath();
795
+            }
796
+            return filePath;
791 797
         }
792 798
         return path;
793 799
     }

+ 17
- 15
src/android/src/main/java/com/RNFetchBlob/RNFetchBlobReq.java View File

@@ -2,6 +2,7 @@ package com.RNFetchBlob;
2 2
 
3 3
 import android.app.DownloadManager;
4 4
 import android.content.BroadcastReceiver;
5
+import android.content.ContentResolver;
5 6
 import android.content.Context;
6 7
 import android.content.Intent;
7 8
 import android.content.IntentFilter;
@@ -116,9 +117,10 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
116 117
                     String key = it.nextKey();
117 118
                     req.addRequestHeader(key, headers.getString(key));
118 119
                 }
119
-                DownloadManager dm = (DownloadManager) ctx.getSystemService(Context.DOWNLOAD_SERVICE);
120
+                Context appCtx = RNFetchBlob.RCTContext.getApplicationContext();
121
+                DownloadManager dm = (DownloadManager) appCtx.getSystemService(Context.DOWNLOAD_SERVICE);
120 122
                 downloadManagerId = dm.enqueue(req);
121
-                ctx.registerReceiver(this, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
123
+                appCtx.registerReceiver(this, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
122 124
                 return;
123 125
             }
124 126
 
@@ -146,7 +148,7 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
146 148
 
147 149
         OkHttpClient.Builder client;
148 150
 
149
-//        try {
151
+        try {
150 152
             // use trusty SSL socket
151 153
             if (this.options.trusty) {
152 154
                 client = RNFetchBlobUtils.getUnsafeOkHttpClient();
@@ -173,7 +175,7 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
173 175
             // set request body
174 176
             switch (requestType) {
175 177
                 case SingleFile:
176
-                    InputStream dataStream= buildOctetBody(rawRequestBody);
178
+                    InputStream dataStream = buildOctetBody(rawRequestBody);
177 179
                     builder.method(method, new RNFetchBlobBody(
178 180
                             taskId,
179 181
                             RequestType.SingleFile,
@@ -200,7 +202,7 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
200 202
 
201 203
             final Request req = builder.build();
202 204
 
203
-//             create response handler
205
+//          create response handler
204 206
             client.addInterceptor(new Interceptor() {
205 207
                 @Override
206 208
                 public Response intercept(Chain chain) throws IOException {
@@ -262,10 +264,10 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
262 264
             });
263 265
 
264 266
 
265
-//        } catch (Exception error) {
266
-//            error.printStackTrace();
267
-//            callback.invoke("RNFetchBlob request error: " + error.getMessage() + error.getCause());
268
-//        }
267
+        } catch (Exception error) {
268
+            error.printStackTrace();
269
+            callback.invoke("RNFetchBlob request error: " + error.getMessage() + error.getCause());
270
+        }
269 271
     }
270 272
 
271 273
     /**
@@ -283,11 +285,10 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
283 285
                 }
284 286
                 break;
285 287
             case FileStorage:
286
-                // write chunk
287
-                try {
288
+                try{
288 289
                     resp.body().bytes();
289
-                } catch (IOException e) {
290
-                    e.printStackTrace();
290
+                } catch (Exception ignored) {
291
+
291 292
                 }
292 293
                 callback.invoke(null, this.destPath);
293 294
                 break;
@@ -364,17 +365,18 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
364 365
     public void onReceive(Context context, Intent intent) {
365 366
         String action = intent.getAction();
366 367
         if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
368
+            Context appCtx = RNFetchBlob.RCTContext.getApplicationContext();
367 369
             long id = intent.getExtras().getLong(DownloadManager.EXTRA_DOWNLOAD_ID);
368 370
             if (id == this.downloadManagerId) {
369 371
                 DownloadManager.Query query = new DownloadManager.Query();
370 372
                 query.setFilterById(downloadManagerId);
371
-                DownloadManager dm = (DownloadManager) ctx.getSystemService(Context.DOWNLOAD_SERVICE);
373
+                DownloadManager dm = (DownloadManager) appCtx.getSystemService(Context.DOWNLOAD_SERVICE);
372 374
                 dm.query(query);
373 375
                 Cursor c = dm.query(query);
374 376
                 if (c.moveToFirst()) {
375 377
                     String contentUri = c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
376 378
                     Uri uri = Uri.parse(contentUri);
377
-                    Cursor cursor = ctx.getContentResolver().query(uri, new String[]{android.provider.MediaStore.Images.ImageColumns.DATA}, null, null, null);
379
+                    Cursor cursor = appCtx.getContentResolver().query(uri, new String[]{android.provider.MediaStore.Images.ImageColumns.DATA}, null, null, null);
378 380
                     if (cursor != null) {
379 381
                         cursor.moveToFirst();
380 382
                         String filePath = cursor.getString(0);