aliyun-oss-react-native

AliyunUploadManager.java 17KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  1. package com.reactlibrary;
  2. import android.annotation.SuppressLint;
  3. import android.content.Context;
  4. import android.database.Cursor;
  5. import android.net.Uri;
  6. import android.provider.MediaStore;
  7. import android.util.Log;
  8. import com.alibaba.sdk.android.oss.ClientException;
  9. import com.alibaba.sdk.android.oss.OSS;
  10. import com.alibaba.sdk.android.oss.ServiceException;
  11. import com.alibaba.sdk.android.oss.callback.OSSCompletedCallback;
  12. import com.alibaba.sdk.android.oss.callback.OSSProgressCallback;
  13. import com.alibaba.sdk.android.oss.common.utils.IOUtils;
  14. import com.alibaba.sdk.android.oss.internal.OSSAsyncTask;
  15. import com.alibaba.sdk.android.oss.model.AbortMultipartUploadRequest;
  16. import com.alibaba.sdk.android.oss.model.AppendObjectRequest;
  17. import com.alibaba.sdk.android.oss.model.AppendObjectResult;
  18. import com.alibaba.sdk.android.oss.model.CompleteMultipartUploadRequest;
  19. import com.alibaba.sdk.android.oss.model.CompleteMultipartUploadResult;
  20. import com.alibaba.sdk.android.oss.model.InitiateMultipartUploadRequest;
  21. import com.alibaba.sdk.android.oss.model.InitiateMultipartUploadResult;
  22. import com.alibaba.sdk.android.oss.model.ListPartsRequest;
  23. import com.alibaba.sdk.android.oss.model.ListPartsResult;
  24. import com.alibaba.sdk.android.oss.model.ObjectMetadata;
  25. import com.alibaba.sdk.android.oss.model.PartETag;
  26. import com.alibaba.sdk.android.oss.model.PutObjectRequest;
  27. import com.alibaba.sdk.android.oss.model.PutObjectResult;
  28. import com.alibaba.sdk.android.oss.model.ResumableUploadRequest;
  29. import com.alibaba.sdk.android.oss.model.ResumableUploadResult;
  30. import com.alibaba.sdk.android.oss.model.UploadPartRequest;
  31. import com.alibaba.sdk.android.oss.model.UploadPartResult;
  32. import com.facebook.react.bridge.Arguments;
  33. import com.facebook.react.bridge.Promise;
  34. import com.facebook.react.bridge.ReactContext;
  35. import com.facebook.react.bridge.ReactMethod;
  36. import com.facebook.react.bridge.ReadableMap;
  37. import com.facebook.react.bridge.WritableMap;
  38. import com.facebook.react.modules.core.DeviceEventManagerModule;
  39. import com.reactlibrary.utils.FileUtils;
  40. import java.io.File;
  41. import java.io.FileInputStream;
  42. import java.io.FileNotFoundException;
  43. import java.io.IOException;
  44. import java.io.InputStream;
  45. import java.util.ArrayList;
  46. import java.util.HashMap;
  47. import java.util.List;
  48. public class AliyunUploadManager {
  49. private OSS mOSS;
  50. /**
  51. * AliyunUploadManager contructor
  52. * @param oss
  53. */
  54. public AliyunUploadManager(OSS oss) {
  55. mOSS = oss;
  56. }
  57. /**
  58. * asyncUpload
  59. * @param context
  60. * @param bucketName
  61. * @param ossFile
  62. * @param sourceFile
  63. * @param options
  64. * @param promise
  65. */
  66. public void asyncUpload(final ReactContext context, String bucketName, String ossFile, String sourceFile, ReadableMap options, final Promise promise) {
  67. // Content to file:// start
  68. Uri selectedVideoUri = Uri.parse(sourceFile);
  69. // 1. content uri -> file path
  70. // 2. inputstream -> temp file path
  71. Cursor cursor = null;
  72. try {
  73. String[] proj = {MediaStore.Images.Media.DATA};
  74. cursor = context.getCurrentActivity().getContentResolver().query(selectedVideoUri, proj, null, null, null);
  75. if (cursor == null) sourceFile = selectedVideoUri.getPath();
  76. int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
  77. cursor.moveToFirst();
  78. sourceFile = cursor.getString(column_index);
  79. } catch (Exception e) {
  80. sourceFile = FileUtils.getFilePathFromURI(context.getCurrentActivity(), selectedVideoUri);
  81. } finally {
  82. if (cursor != null) {
  83. cursor.close();
  84. }
  85. }
  86. // init upload request
  87. PutObjectRequest put = new PutObjectRequest(bucketName, ossFile, sourceFile);
  88. ObjectMetadata metadata = new ObjectMetadata();
  89. metadata.setContentType("application/octet-stream");
  90. put.setMetadata(metadata);
  91. // set callback
  92. put.setProgressCallback(new OSSProgressCallback<PutObjectRequest>() {
  93. @Override
  94. public void onProgress(PutObjectRequest request, long currentSize, long totalSize) {
  95. Log.d("PutObject", "currentSize: " + currentSize + " totalSize: " + totalSize);
  96. String str_currentSize = Long.toString(currentSize);
  97. String str_totalSize = Long.toString(totalSize);
  98. WritableMap onProgressValueData = Arguments.createMap();
  99. onProgressValueData.putString("currentSize", str_currentSize);
  100. onProgressValueData.putString("totalSize", str_totalSize);
  101. context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
  102. .emit("uploadProgress", onProgressValueData);
  103. }
  104. });
  105. OSSAsyncTask task = mOSS.asyncPutObject(put, new OSSCompletedCallback<PutObjectRequest, PutObjectResult>() {
  106. @Override
  107. public void onSuccess(PutObjectRequest request, PutObjectResult result) {
  108. Log.d("PutObject", "UploadSuccess");
  109. Log.d("ETag", result.getETag());
  110. Log.d("RequestId", result.getRequestId());
  111. promise.resolve("UploadSuccess");
  112. }
  113. @Override
  114. public void onFailure(PutObjectRequest request, ClientException clientExcepion, ServiceException serviceException) {
  115. PromiseExceptionManager.resolvePromiseException(clientExcepion,serviceException,promise);
  116. }
  117. });
  118. Log.d("AliyunOSS", "OSS uploadObjectAsync ok!");
  119. }
  120. /**
  121. * asyncAppendObject
  122. * @param bucketName
  123. * @param objectKey
  124. * @param uploadFilePath
  125. * @param options
  126. * @param promise
  127. */
  128. public void asyncAppendObject(final ReactContext context,String bucketName,String objectKey,String uploadFilePath,ReadableMap options,final Promise promise) {
  129. // Content to file:// start
  130. Uri selectedVideoUri = Uri.parse(uploadFilePath);
  131. // 1. content uri -> file path
  132. // 2. inputstream -> temp file path
  133. Cursor cursor = null;
  134. try {
  135. String[] proj = {MediaStore.Images.Media.DATA};
  136. cursor = context.getCurrentActivity().getContentResolver().query(selectedVideoUri, proj, null, null, null);
  137. if (cursor == null) uploadFilePath = selectedVideoUri.getPath();
  138. int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
  139. cursor.moveToFirst();
  140. uploadFilePath = cursor.getString(column_index);
  141. } catch (Exception e) {
  142. uploadFilePath = FileUtils.getFilePathFromURI(context.getCurrentActivity(), selectedVideoUri);
  143. } finally {
  144. if (cursor != null) {
  145. cursor.close();
  146. }
  147. }
  148. AppendObjectRequest append = new AppendObjectRequest(bucketName, objectKey, uploadFilePath);
  149. ObjectMetadata metadata = new ObjectMetadata();
  150. metadata.setContentType("application/octet-stream");
  151. append.setMetadata(metadata);
  152. //set appendpostions
  153. int nextPositon = options.getInt("appendPostions");
  154. append.setPosition(nextPositon);
  155. append.setProgressCallback(new OSSProgressCallback<AppendObjectRequest>() {
  156. @Override
  157. public void onProgress(AppendObjectRequest request, long currentSize, long totalSize) {
  158. Log.d("AppendObject", "currentSize: " + currentSize + " totalSize: " + totalSize);
  159. // add event
  160. String str_currentSize = Long.toString(currentSize);
  161. String str_totalSize = Long.toString(totalSize);
  162. WritableMap onProgressValueData = Arguments.createMap();
  163. onProgressValueData.putString("currentSize", str_currentSize);
  164. onProgressValueData.putString("totalSize", str_totalSize);
  165. context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
  166. .emit("uploadProgress", onProgressValueData);
  167. }
  168. });
  169. OSSAsyncTask task = mOSS.asyncAppendObject(append, new OSSCompletedCallback<AppendObjectRequest, AppendObjectResult>() {
  170. @Override
  171. public void onSuccess(AppendObjectRequest request, AppendObjectResult result) {
  172. Log.d("AppendObject", "AppendSuccess");
  173. Log.d("NextPosition", "" + result.getNextPosition());
  174. WritableMap map = Arguments.createMap();
  175. map.putString("AppendObject","AppendSuccess");
  176. map.putDouble("NextPosition", result.getNextPosition());
  177. promise.resolve(map);
  178. }
  179. @Override
  180. public void onFailure(AppendObjectRequest request, ClientException clientExcepion, ServiceException serviceException) {
  181. PromiseExceptionManager.resolvePromiseException(clientExcepion,serviceException,promise);
  182. }
  183. });
  184. }
  185. /**
  186. * asyncResumableUpload
  187. *
  188. * @param bucketName
  189. * @param objectKey
  190. * @param uploadFilePath
  191. * @param options
  192. * @param promise
  193. */
  194. public void asyncResumableUpload(final ReactContext context, String bucketName, String objectKey, String uploadFilePath, ReadableMap options, final Promise promise) {
  195. ResumableUploadRequest request = new ResumableUploadRequest(bucketName, objectKey, uploadFilePath);
  196. request.setProgressCallback(new OSSProgressCallback<ResumableUploadRequest>() {
  197. @Override
  198. public void onProgress(ResumableUploadRequest request, long currentSize, long totalSize) {
  199. Log.d("resumableUpload", "currentSize: " + currentSize + " totalSize: " + totalSize);
  200. // add event
  201. String str_currentSize = Long.toString(currentSize);
  202. String str_totalSize = Long.toString(totalSize);
  203. WritableMap onProgressValueData = Arguments.createMap();
  204. onProgressValueData.putString("currentSize", str_currentSize);
  205. onProgressValueData.putString("totalSize", str_totalSize);
  206. context.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
  207. .emit("uploadProgress", onProgressValueData);
  208. }
  209. });
  210. OSSAsyncTask resumableTask = mOSS.asyncResumableUpload(request, new OSSCompletedCallback<ResumableUploadRequest, ResumableUploadResult>() {
  211. @Override
  212. public void onSuccess(ResumableUploadRequest request, ResumableUploadResult result) {
  213. promise.resolve("resumableUpload success");
  214. }
  215. @Override
  216. public void onFailure(ResumableUploadRequest request, ClientException clientExcepion, ServiceException serviceException) {
  217. PromiseExceptionManager.resolvePromiseException(clientExcepion, serviceException, promise);
  218. }
  219. });
  220. }
  221. /**
  222. * initMultipartUpload
  223. * @param bucketName
  224. * @param objectKey
  225. * @param promise
  226. */
  227. public void initMultipartUpload(String bucketName,String objectKey,final Promise promise) {
  228. String uploadId;
  229. InitiateMultipartUploadRequest init = new InitiateMultipartUploadRequest(bucketName, objectKey);
  230. InitiateMultipartUploadResult initResult = null;
  231. try {
  232. initResult = mOSS.initMultipartUpload(init);
  233. uploadId = initResult.getUploadId();
  234. promise.resolve(uploadId);
  235. } catch (ClientException e) {
  236. e.printStackTrace();
  237. promise.reject(e);
  238. } catch (ServiceException e) {
  239. e.printStackTrace();
  240. promise.reject(e);
  241. }
  242. }
  243. /**
  244. * multipartUpload
  245. * @param context
  246. * @param bucketName
  247. * @param objectKey
  248. * @param uploadId
  249. * @param filepath
  250. * @param options
  251. * @param promise
  252. */
  253. public void multipartUpload(final ReactContext context,String bucketName, String objectKey, String uploadId,String filepath, ReadableMap options,final Promise promise) {
  254. Uri selectedVideoUri = Uri.parse(filepath);
  255. // 1. content uri -> file path
  256. // 2. inputstream -> temp file path
  257. Cursor cursor = null;
  258. try {
  259. String[] proj = {MediaStore.Images.Media.DATA};
  260. cursor = context.getCurrentActivity().getContentResolver().query(selectedVideoUri, proj, null, null, null);
  261. if (cursor == null) filepath = selectedVideoUri.getPath();
  262. int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
  263. cursor.moveToFirst();
  264. filepath = cursor.getString(column_index);
  265. } catch (Exception e) {
  266. filepath = FileUtils.getFilePathFromURI(context.getCurrentActivity(), selectedVideoUri);
  267. } finally {
  268. if (cursor != null) {
  269. cursor.close();
  270. }
  271. }
  272. long partSize = options.getInt("partSize"); // 设置分片大小
  273. int currentIndex = 1; // 上传分片编号,从1开始
  274. File uploadFile = new File(filepath); // 需要分片上传的文件
  275. InputStream input = null;
  276. try {
  277. input = new FileInputStream(uploadFile);
  278. } catch (FileNotFoundException e) {
  279. e.printStackTrace();
  280. }
  281. long fileLength = uploadFile.length();
  282. long uploadedLength = 0;
  283. List<PartETag> partETags = new ArrayList<PartETag>(); // 保存分片上传的结果
  284. while (uploadedLength < fileLength) {
  285. int partLength = (int)Math.min(partSize, fileLength - uploadedLength);
  286. byte[] partData = new byte[0]; // 按照分片大小读取文件的一段内容
  287. try {
  288. partData = IOUtils.readStreamAsBytesArray(input, partLength);
  289. } catch (IOException e) {
  290. e.printStackTrace();
  291. promise.reject(e);
  292. }
  293. UploadPartRequest uploadPart = new UploadPartRequest(bucketName, objectKey, uploadId, currentIndex);
  294. uploadPart.setPartContent(partData); // 设置分片内容
  295. UploadPartResult uploadPartResult = null;
  296. try {
  297. uploadPartResult = mOSS.uploadPart(uploadPart);
  298. } catch (ClientException e) {
  299. e.printStackTrace();
  300. promise.reject(e);
  301. } catch (ServiceException e) {
  302. e.printStackTrace();
  303. promise.reject(e);
  304. }
  305. partETags.add(new PartETag(currentIndex, uploadPartResult.getETag())); // 保存分片上传成功后的结果
  306. uploadedLength += partLength;
  307. currentIndex++;
  308. }
  309. CompleteMultipartUploadRequest complete = new CompleteMultipartUploadRequest(bucketName, objectKey,uploadId,partETags);
  310. CompleteMultipartUploadResult completeResult = null;
  311. try {
  312. completeResult = mOSS.completeMultipartUpload(complete);
  313. promise.resolve("mulitpartlaod success!");
  314. } catch (ClientException e) {
  315. e.printStackTrace();
  316. } catch (ServiceException e) {
  317. e.printStackTrace();
  318. }
  319. complete.setCallbackParam(new HashMap<String, String>() {
  320. {
  321. put("callbackUrl", "<server address>");
  322. put("callbackBody", "<test>");
  323. }
  324. });
  325. }
  326. /**
  327. * abortMultipartUpload
  328. * @param bucketName
  329. * @param objectKey
  330. * @param uploadId
  331. * @param promise
  332. */
  333. public void abortMultipartUpload(String bucketName,String objectKey,String uploadId,final Promise promise) {
  334. AbortMultipartUploadRequest abort = new AbortMultipartUploadRequest(bucketName, objectKey, uploadId);
  335. try {
  336. mOSS.abortMultipartUpload(abort);
  337. promise.resolve("abort multipart upload success!");
  338. } catch (ClientException e) {
  339. e.printStackTrace();
  340. promise.reject(e);
  341. } catch (ServiceException e) {
  342. e.printStackTrace();
  343. promise.reject(e);
  344. }
  345. }
  346. /**
  347. * listParts
  348. * @param bucketName
  349. * @param objectKey
  350. * @param uploadId
  351. * @param promise
  352. */
  353. public void listParts (String bucketName,String objectKey,String uploadId,final Promise promise) {
  354. ListPartsRequest listParts = new ListPartsRequest(bucketName, objectKey, uploadId);
  355. ListPartsResult result = null;
  356. try {
  357. result = mOSS.listParts(listParts);
  358. } catch (ClientException e) {
  359. e.printStackTrace();
  360. promise.reject(e);
  361. } catch (ServiceException e) {
  362. e.printStackTrace();
  363. promise.reject(e);
  364. }
  365. WritableMap listPartsData = Arguments.createMap();
  366. for (int i = 0; i < result.getParts().size(); i++) {
  367. Log.d("listParts", "partNum: " + result.getParts().get(i).getPartNumber());
  368. Log.d("listParts", "partEtag: " + result.getParts().get(i).getETag());
  369. Log.d("listParts", "lastModified: " + result.getParts().get(i).getLastModified());
  370. Log.d("listParts", "partSize: " + result.getParts().get(i).getSize());
  371. listPartsData.putInt("partNum" + i, result.getParts().get(i).getPartNumber());
  372. listPartsData.putString("partEtag"+i,result.getParts().get(i).getETag());
  373. // listPartsData.("lastModified" + i,result.getParts().get(i).getLastModified());
  374. listPartsData.putDouble("partSize"+i,result.getParts().get(i).getSize());
  375. }
  376. promise.resolve(listPartsData);
  377. }
  378. }