AsyncPictureUpload.java 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609
  1. package com.fxy.common;
  2. import android.Manifest;
  3. import android.annotation.SuppressLint;
  4. import android.app.Activity;
  5. import android.content.Context;
  6. import android.content.Intent;
  7. import android.graphics.Color;
  8. import android.graphics.drawable.ColorDrawable;
  9. import android.net.ConnectivityManager;
  10. import android.net.NetworkInfo;
  11. import android.os.Handler;
  12. import android.os.Message;
  13. import android.support.v7.widget.GridLayoutManager;
  14. import android.support.v7.widget.RecyclerView;
  15. import android.view.Gravity;
  16. import android.view.View;
  17. import android.view.WindowManager;
  18. import android.widget.PopupWindow;
  19. import android.widget.TextView;
  20. import android.widget.Toast;
  21. import com.elvishew.xlog.XLog;
  22. import com.fxy.R;
  23. import com.fxy.adapter.GridImageAdapter;
  24. import com.fxy.baselibrary.bean.BaseEventBusBean;
  25. import com.fxy.baselibrary.util.DateUtil;
  26. import com.fxy.baselibrary.util.JsonUtil;
  27. import com.fxy.baselibrary.util.RxTimeTool;
  28. import com.fxy.bean.ActionBean;
  29. import com.fxy.constant.EventCode;
  30. import com.fxy.constant.SPCache;
  31. import com.fxy.net.MyDialogCallback;
  32. import com.fxy.realm.AsyncUploadRealm;
  33. import com.fxy.view.FullyGridLayoutManager;
  34. import com.google.gson.Gson;
  35. import com.luck.picture.lib.PictureSelector;
  36. import com.luck.picture.lib.config.PictureConfig;
  37. import com.luck.picture.lib.config.PictureMimeType;
  38. import com.luck.picture.lib.entity.LocalMedia;
  39. import com.luck.picture.lib.permissions.Permission;
  40. import com.luck.picture.lib.permissions.RxPermissions;
  41. import com.lzy.okgo.OkGo;
  42. import com.lzy.okgo.model.Response;
  43. import org.greenrobot.eventbus.EventBus;
  44. import org.json.JSONObject;
  45. import java.io.File;
  46. import java.util.ArrayList;
  47. import java.util.Calendar;
  48. import java.util.Date;
  49. import java.util.HashMap;
  50. import java.util.List;
  51. import java.util.UUID;
  52. import io.reactivex.functions.Consumer;
  53. import io.realm.Realm;
  54. import io.realm.RealmQuery;
  55. import io.realm.RealmResults;
  56. public class AsyncPictureUpload {
  57. private final Activity mActivity;
  58. private final Context mContext;
  59. private String uploadType = "";
  60. //文件上传类型
  61. protected String fileKey = "";
  62. //通知地址
  63. private String notifyUrl = "";
  64. //唯一标识
  65. private String uniqueTag = "";
  66. //通知地址
  67. private HashMap<String, Object> notifyParam = new HashMap<>();
  68. private HashMap<String, Object> limitOperate = new HashMap<>();
  69. protected Realm mRealm;
  70. private List<AsyncUploadRealm> awaitUploadList=new ArrayList<>();
  71. //
  72. private List<LocalMedia> selectList = new ArrayList<>();
  73. //上传图片路径
  74. private ArrayList<String> ossPhotoList =new ArrayList<>();
  75. private String mPrefix="tally";
  76. //是否停止上传
  77. private String resourceUrl = "";
  78. private String resourceType = "";
  79. private String resourcePrefix = "/fxy";
  80. private OssService ossService;
  81. private CosService cosService;
  82. private boolean allowUpload = true;
  83. //
  84. private boolean isAllRe =false;
  85. private boolean debug = false;
  86. public void setDebug(boolean debug) {
  87. this.debug = debug;
  88. }
  89. public AsyncPictureUpload(Activity activity){
  90. mActivity = activity;
  91. mContext = activity.getBaseContext();
  92. initData();
  93. }
  94. private void initData() {
  95. SPCache spCache = SPCache.getInstance(mContext);
  96. resourceUrl = spCache.getResourceHost()+"/";
  97. resourceType = spCache.getResourceType();
  98. resourcePrefix = spCache.getResourcePrefix();
  99. mRealm = Realm.getDefaultInstance();
  100. if (mActivity != null && mActivity.getClass()!=null){
  101. uploadType = mActivity.getClass().getSimpleName();
  102. }
  103. limitOperate = new HashMap<>();
  104. uniqueTag = this.fileKey+UUID.randomUUID().toString();
  105. }
  106. public void setUploadType(String fileKey) {
  107. this.fileKey = fileKey;
  108. }
  109. public void setNotifyParam( HashMap<String, Object> map){
  110. this.notifyParam = map;
  111. }
  112. //操作限制
  113. public void setLimitOperate(HashMap<String, Object> map){
  114. this.limitOperate = map;
  115. }
  116. public int getAwaitNum(){
  117. RealmResults<AsyncUploadRealm> realmResults = mRealm.where(AsyncUploadRealm.class)
  118. .equalTo("isDelete",0)
  119. .equalTo("pushStatus",0)
  120. .equalTo("uploadType",uploadType)
  121. .sort("pushStatus").findAll();
  122. realmResults.load();
  123. return realmResults.size();
  124. }
  125. public int getAwaitNum(String[] uploadTypeList){
  126. RealmResults<AsyncUploadRealm> realmResults = mRealm.where(AsyncUploadRealm.class)
  127. .equalTo("isDelete",0)
  128. .equalTo("pushStatus",0)
  129. .in("uploadType",uploadTypeList)
  130. .sort("pushStatus").findAll();
  131. realmResults.load();
  132. return realmResults.size();
  133. }
  134. /**
  135. * 获取所有待推送数据
  136. * @return
  137. */
  138. public int getAllAwaitNum(){
  139. if (isAllRe){
  140. Integer[] pushStatus = {0,1};
  141. RealmResults<AsyncUploadRealm> realmResults = mRealm.where(AsyncUploadRealm.class)
  142. .equalTo("isDelete",0)
  143. .in("pushStatus",pushStatus)
  144. .sort("pushStatus").findAll();
  145. realmResults.load();
  146. return realmResults.size();
  147. }else{
  148. RealmResults<AsyncUploadRealm> realmResults = mRealm.where(AsyncUploadRealm.class)
  149. .equalTo("isDelete",0)
  150. .equalTo("pushStatus",0)
  151. .sort("pushStatus").findAll();
  152. realmResults.load();
  153. return realmResults.size();
  154. }
  155. }
  156. /**
  157. * 返回错误数量
  158. * @return int
  159. */
  160. public int getFailNum(){
  161. Integer[] pushStatus = {1};
  162. RealmResults<AsyncUploadRealm> realmResults = mRealm.where(AsyncUploadRealm.class)
  163. .equalTo("isDelete",0)
  164. .in("pushStatus",pushStatus)
  165. .sort("pushStatus").findAll();
  166. realmResults.load();
  167. return realmResults.size();
  168. }
  169. @SuppressLint("HandlerLeak")
  170. private Handler uploadHandler = new Handler() {
  171. @Override
  172. public void handleMessage(Message msg) {
  173. HashMap<String,Object> hashMap = new HashMap<>();
  174. hashMap.put("fileKey",fileKey);
  175. try {
  176. //XLog.e(msg);
  177. int current = (Integer) msg.arg1;
  178. switch (msg.what){
  179. case 0:
  180. Toast.makeText(mActivity, "error", Toast.LENGTH_SHORT).show();
  181. break;
  182. case 1://失败
  183. if (awaitUploadList.size()>0){
  184. AsyncUploadRealm asyncUploadRealm = awaitUploadList.get(current);
  185. awaitUploadList.remove(current);
  186. resultUpload(asyncUploadRealm.getId(),0,"");
  187. String message = (String) msg.obj;
  188. if (!message.isEmpty() && mActivity!=null){
  189. Toast.makeText(mActivity, message, Toast.LENGTH_SHORT).show();
  190. }
  191. hashMap.put("error",(String) msg.obj);
  192. hashMap.put("result","error");
  193. hashMap.put("realmId",asyncUploadRealm.getId());
  194. }
  195. break;
  196. case 2://成功
  197. //表示数据存在
  198. if (awaitUploadList.size()>0){
  199. AsyncUploadRealm asyncUploadRealm = awaitUploadList.get(current);
  200. awaitUploadList.remove(current);
  201. resultUpload(asyncUploadRealm.getId(),1,(String) msg.obj);
  202. hashMap.put("result","success");
  203. hashMap.put("realmId",asyncUploadRealm.getId());
  204. }
  205. break;
  206. case 3:
  207. //设置进度条
  208. hashMap.put("result","process");
  209. hashMap.put("process",(int)msg.arg2);
  210. if (awaitUploadList.get(current)!=null){
  211. hashMap.put("realmId",awaitUploadList.get(current).getId());
  212. }
  213. EventBus.getDefault().post(new BaseEventBusBean<>(EventCode.file_upload_progress_lister,hashMap));
  214. return;
  215. case 4:
  216. //获取上传状态
  217. return;
  218. default:
  219. break;
  220. }
  221. } catch (Exception e) {
  222. XLog.e(e.getMessage());
  223. e.printStackTrace();
  224. // 通过接口对象传上传状态
  225. hashMap.put("error",e.getMessage());
  226. }
  227. EventBus.getDefault().post(new BaseEventBusBean<>(EventCode.file_upload_lister,hashMap));
  228. }
  229. };
  230. // 调用回调方法
  231. //uploadChangeListener.uploadResult(false);
  232. public void filedUpload(int num){
  233. // 例如 LocalMedia 里面返回三种path
  234. // 1.media.getPath(); 为原图path
  235. // 2.media.getCutPath();为裁剪后path,需判断media.isCut();是否为true
  236. // 3.media.getCompressPath();为压缩后path,需判断media.isCompressed();是否为true
  237. // 如果裁剪并压缩了,以取压缩路径为准,因为是先裁剪后压缩的
  238. LocalMedia localMedia = awaitUploadList.get(num).getLocalMedia();
  239. String urlPath =localMedia.getPath();
  240. if (urlPath.isEmpty()){
  241. setPushStatus(awaitUploadList.get(num).getId(),1,1);
  242. Message msg = new Message();
  243. msg.obj = "文件路径不为空";
  244. msg.what = 1;
  245. uploadHandler.sendMessage(msg);
  246. return;
  247. }
  248. if (localMedia.isCompressed() && localMedia.getCompressPath()!=null){
  249. if (new File(localMedia.getCompressPath()).exists()){
  250. urlPath = localMedia.getCompressPath();
  251. }
  252. }
  253. if (!new File(urlPath).exists()){
  254. XLog.d("文件不存在本地路径"+urlPath+",拍照时间:"+awaitUploadList.get(num).getCreateTime());
  255. setPushStatus(awaitUploadList.get(num).getId(),1,1);
  256. Message msg = new Message();
  257. msg.obj = "文件路径不存在";
  258. msg.what = 1;
  259. uploadHandler.sendMessage(msg);
  260. return;
  261. }
  262. String fileName = "";
  263. String path_prefix = "";
  264. String ossUrl = awaitUploadList.get(num).getOssUrl();
  265. fileKey = awaitUploadList.get(num).getNotifyKey();
  266. if (!ossUrl.isEmpty()){
  267. // 找到最后一个斜杠的位置
  268. int lastSlashIndex = ossUrl.lastIndexOf('/');
  269. // 如果找到了斜杠,则从斜杠之后的位置开始切割
  270. fileName = ossUrl.substring(lastSlashIndex + 1);
  271. path_prefix = ossUrl.substring(0,lastSlashIndex+ 1);
  272. }else{
  273. path_prefix = resourcePrefix+"/android/"+mPrefix+"/"+RxTimeTool.getYestoryDate("yyyyMMd")+"/";
  274. String fileSuffix = urlPath.lastIndexOf(".")>-1 ? urlPath.substring(urlPath.lastIndexOf(".")) : "";
  275. fileName = UUID.randomUUID().toString() + fileSuffix;
  276. }
  277. if (resourceType.equals("tencent")){
  278. if (cosService==null){
  279. cosService = new CosService(mActivity.getBaseContext(),path_prefix);
  280. }
  281. //new cosThread(urlPath, fileName , num).start();
  282. cosService.cosUpload(urlPath, fileName , num,uploadHandler,path_prefix);
  283. }else{
  284. if (ossService ==null){
  285. ossService = new OssService(mActivity,path_prefix);
  286. }
  287. ossService.ossUpload(urlPath, fileName , num,uploadHandler,path_prefix);
  288. //ossService.ossUpload(urlPath, fileName , num,uploadHandler);
  289. }
  290. // task.cancel(); // 可以取消任务
  291. // task.waitUntilFinished(); // 可以等待直到任务完成
  292. }
  293. //存储数据问题
  294. private void asyncUpload(){
  295. if (!getIsNetwork()){
  296. //无网络时在请求检查是否有网络
  297. return;
  298. }
  299. if (awaitUploadList==null || awaitUploadList.size()==0){
  300. Integer[] isFinish = {0,2};
  301. RealmResults<AsyncUploadRealm> realmResults = getBatchUploadRealm();
  302. awaitUploadList.addAll(realmResults);
  303. }
  304. if (awaitUploadList.size()>0){
  305. filedUpload(0);
  306. }
  307. }
  308. public static long getNextTimestamp(int day) {
  309. Calendar calendar = Calendar.getInstance();
  310. calendar.set(Calendar.HOUR_OF_DAY, 0);
  311. calendar.add(Calendar.DAY_OF_MONTH, day);
  312. calendar.set(Calendar.MINUTE, 0);
  313. calendar.set(Calendar.SECOND, 0);
  314. calendar.set(Calendar.MILLISECOND, 0);
  315. return calendar.getTimeInMillis();
  316. }
  317. //取消任务
  318. public void taskCancel(){
  319. }
  320. public void setStartUpload(){
  321. allowUpload = true;
  322. asyncUpload();
  323. }
  324. public void setIsAllRe(){
  325. isAllRe = true;
  326. }
  327. public void setStopUpload(){
  328. allowUpload = false;
  329. if(ossService !=null){
  330. ossService.taskCancel();
  331. }
  332. EventBus.getDefault().post(new UploadProgressEvent(0));
  333. }
  334. /**
  335. * 设置是否完成
  336. * @param realmId String
  337. * @param isFinish Integer
  338. */
  339. private void setIsFinish(String realmId,Integer isFinish){
  340. //更新值
  341. mRealm.beginTransaction();
  342. AsyncUploadRealm myObject = mRealm.where(AsyncUploadRealm.class).equalTo("id",realmId).findFirst();
  343. assert myObject != null;
  344. myObject.setIsFinish(isFinish);
  345. mRealm.commitTransaction();
  346. }
  347. private void setPushStatus(String realmId,Integer pushStatus,int isDelete){
  348. //更新值
  349. mRealm.beginTransaction();
  350. AsyncUploadRealm myObject = mRealm.where(AsyncUploadRealm.class).equalTo("id",realmId).findFirst();
  351. assert myObject != null;
  352. myObject.setPushStatus(pushStatus);
  353. myObject.setIsDelete(isDelete);
  354. mRealm.commitTransaction();
  355. }
  356. private RealmResults<AsyncUploadRealm> getBatchUploadRealm(){
  357. //更新值
  358. mRealm.beginTransaction();
  359. Integer[] isFinish = {0,1,2};
  360. RealmResults<AsyncUploadRealm> realmResults ;
  361. RealmQuery<AsyncUploadRealm> queryRealm = mRealm.where(AsyncUploadRealm.class)
  362. .in("isFinish",isFinish)
  363. .equalTo("isDelete",0);
  364. if (isAllRe){
  365. Integer[] pushStatus = {0,1};
  366. queryRealm.in("pushStatus",pushStatus)
  367. // .equalTo("notifyKey",fileKey)
  368. // .equalTo("uploadType",uploadType)
  369. ;
  370. isAllRe = false;
  371. }else{
  372. queryRealm.equalTo("pushStatus",0)
  373. // .equalTo("notifyKey",fileKey)
  374. // .equalTo("uploadType",uploadType)
  375. ;
  376. }
  377. realmResults = queryRealm.sort("createTime").findAll();
  378. // 遍历结果并修改
  379. for (AsyncUploadRealm item : realmResults) {
  380. item.setIsFinish(1);
  381. }
  382. realmResults.load();
  383. mRealm.commitTransaction();
  384. return realmResults;
  385. }
  386. /**
  387. * 上传结果
  388. * @param tmpRealmId String
  389. * @param status Integer
  390. * @param photoPath String
  391. */
  392. private void resultUpload(String tmpRealmId,Integer status,String photoPath){
  393. if (tmpRealmId!=null && !tmpRealmId.isEmpty()){
  394. //遍历删除
  395. if (awaitUploadList.size()>0){
  396. for (int i=0;i<awaitUploadList.size();i++){
  397. if (awaitUploadList.get(i).getId().equals(tmpRealmId)){
  398. awaitUploadList.remove(i);
  399. break;
  400. }
  401. }
  402. }
  403. //更新值
  404. mRealm.beginTransaction();
  405. AsyncUploadRealm myObject = mRealm.where(AsyncUploadRealm.class).equalTo("id",tmpRealmId).findFirst();
  406. assert myObject != null;
  407. int rePush = myObject.getRePush();
  408. int pushStatus = 2;
  409. if (status==0){
  410. pushStatus = rePush>4 ? 1 : 0;
  411. }
  412. if (myObject.getPushStatus()!=3){
  413. myObject.setPushStatus(pushStatus);
  414. }
  415. //已完成则不需要再更新
  416. if (myObject.getIsFinish() != 3){
  417. myObject.setIsFinish( status == 1 ? 3 : 2);
  418. }
  419. if (status == 1){
  420. myObject.setOssUrl(photoPath);
  421. }else{
  422. myObject.setRePush(myObject.getRePush()+1);
  423. }
  424. mRealm.commitTransaction();
  425. }
  426. //可以允许上传
  427. if (allowUpload){
  428. //上传完,继续执行
  429. asyncUpload();
  430. }
  431. }
  432. //异步通知结果
  433. private void asyncNotify(AsyncUploadRealm myObject){
  434. try {
  435. JSONObject jsonObject = new JSONObject(myObject.getNotifyParam());
  436. jsonObject.put(myObject.getNotifyKey(),myObject.getOssUrl());
  437. jsonObject.put("realm_id",myObject.getId());
  438. jsonObject.put("unique_tag",myObject.getUniqueTag());
  439. final String tmpRealmId1 = myObject.getId();
  440. OkGo.<String>post(myObject.getNotifyUrl()).upJson(jsonObject)
  441. .execute(new MyDialogCallback(mContext, true, false) {
  442. @Override
  443. public void onSuccess(Response<String> response) {
  444. super.onSuccess(response);
  445. try {
  446. ActionBean bean = JsonUtil.getObject(response.body(), ActionBean.class);
  447. if(bean.code == 1){
  448. setIsFinish(tmpRealmId1,3);
  449. }
  450. } catch (Exception e) {
  451. e.printStackTrace();
  452. XLog.e("回传图片地址错误",e.getMessage());
  453. setIsFinish(tmpRealmId1,2);
  454. }
  455. }
  456. });
  457. } catch (Exception e) {
  458. e.printStackTrace();
  459. XLog.e("异步通知"+e.getMessage());
  460. }
  461. }
  462. /**
  463. * 获取当前网络
  464. * @return Boolean
  465. */
  466. private Boolean getIsNetwork(){
  467. boolean isNetwork = false;
  468. try {
  469. if (mActivity==null){
  470. return isNetwork;
  471. }
  472. ConnectivityManager connectivityManager = (ConnectivityManager) mActivity.getSystemService(Context.CONNECTIVITY_SERVICE);
  473. if (connectivityManager == null) {
  474. //XLog.d( "无法获取ConnectivityManager实例");
  475. return isNetwork;
  476. }
  477. NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
  478. if (networkInfo != null) {
  479. //XLog.d( "当前网络状态:" + networkInfo.getState());
  480. isNetwork = true;
  481. } else {
  482. //XLog.d( "当前无网络连接");
  483. isNetwork = false;
  484. }
  485. } catch (Exception e) {
  486. e.printStackTrace();
  487. }
  488. return isNetwork;
  489. }
  490. //销毁
  491. public void removeHandler(){
  492. if (uploadHandler!=null){
  493. uploadHandler.removeCallbacksAndMessages(null);
  494. }
  495. }
  496. }