Android實(shí)現(xiàn)斷點(diǎn)續(xù)傳功能
本文實(shí)例為大家分享了Android實(shí)現(xiàn)斷點(diǎn)續(xù)傳的具體代碼,供大家參考,具體內(nèi)容如下
斷點(diǎn)續(xù)傳功能,在文件上傳中斷時(shí),下次上傳同一文件時(shí),能在上次的斷點(diǎn)處繼續(xù)上傳,可節(jié)省時(shí)間和流量
總結(jié)規(guī)劃步驟:
1.給大文件分片,每一個(gè)大文件發(fā)送前,相對(duì)應(yīng)的創(chuàng)建一個(gè)文件夾存放所有分片
2.上傳接口,每一個(gè)分片上傳完成就刪掉,直到所有分片上傳完成,再刪掉存放分片的文件夾,服務(wù)器把分片合成完整的文件。
先看分片功能,傳入的3個(gè)參數(shù)分別為源文件地址,分片大小,存放分片的文件夾地址。返回的是分片個(gè)數(shù)。
/** ? ? ?* ? ? ?* @param sourceFilePath ? ?源文件地址 ? ? ?* @param partFileLength ? ?分割文件的每一個(gè)片段大小標(biāo)準(zhǔn) ? ? ?* @param splitPath ? ? ? ? 分割之后片段所在文件夾 ? ? ?* @return ? ? ?* @throws Exception ? ? ?*/ ? ? public static int splitFile(String sourceFilePath, int partFileLength, String splitPath) throws Exception { ? ? ? ? File sourceFile = null; ? ? ? ? File targetFile = null; ? ? ? ? InputStream ips = null; ? ? ? ? OutputStream ops = null; ? ? ? ? OutputStream configOps = null;//該文件流用于存儲(chǔ)文件分割后的相關(guān)信息,包括分割后的每個(gè)子文件的編號(hào)和路徑,以及未分割前文件名 ? ? ? ? Properties partInfo = null;//properties用于存儲(chǔ)文件分割的信息 ? ? ? ? byte[] buffer = null; ? ? ? ? int partNumber = 1; ? ? ? ? sourceFile = new File(sourceFilePath);//待分割文件 ? ? ? ? ips = new FileInputStream(sourceFile);//找到讀取源文件并獲取輸入流 ? ? ? ? //創(chuàng)建一個(gè)存放分片的文件夾 ? ? ? ? File tempFile = new File(splitPath); ? ? ? ? if (!tempFile.exists()) { ? ? ? ? ? ? tempFile.mkdirs(); ? ? ? ? } ? ? ? ? configOps = new FileOutputStream(new File(tempFile.getAbsolutePath() + File.separator + "config.properties")); ? ? ? ? buffer = new byte[partFileLength];//開(kāi)辟緩存空間 ? ? ? ? int tempLength = 0; ? ? ? ? partInfo = new Properties();//key:1開(kāi)始自動(dòng)編號(hào) value:文件路徑 ? ? ? ? ? int sliceCount = 0; ? ? ? ? while ((tempLength = ips.read(buffer, 0, partFileLength)) != -1) { ? ? ? ? ? ? String targetFilePath = tempFile.getAbsolutePath() + File.separator + "part_" + (partNumber);//分割后的文件路徑+文件名 ? ? ? ? ? ? sliceCount = partNumber; ? ? ? ? ? ? partInfo.setProperty((partNumber++) + "", targetFilePath);//將相關(guān)信息存儲(chǔ)進(jìn)properties ? ? ? ? ? ? targetFile = new File(targetFilePath); ? ? ? ? ? ? ops = new FileOutputStream(targetFile);//分割后文件 ? ? ? ? ? ? ops.write(buffer, 0, tempLength);//將信息寫(xiě)入碎片文件 ? ? ? ? ? ? ? ops.close();//關(guān)閉碎片文件 ? ? ? ? } ? ? ? ? partInfo.setProperty("name", sourceFile.getName());//存儲(chǔ)源文件名 ? ? ? ? partInfo.setProperty("sliceCount", sliceCount + "");//存儲(chǔ)分片個(gè)數(shù) ? ? ? ? partInfo.store(configOps, "ConfigFile");//將properties存儲(chǔ)進(jìn)實(shí)體文件中 ? ? ? ? ips.close();//關(guān)閉源文件流 ? ? ? ? ? return sliceCount; ? ? }
接下來(lái),和服務(wù)器協(xié)商接口,一共2個(gè)接口
1.uploadLargeFilePre,傳入?yún)?shù)除了常規(guī)上傳文件參數(shù)之外加了分片個(gè)數(shù)sliceCount和fileHashcode。這一步是給服務(wù)器開(kāi)辟存放分片的控件的,不執(zhí)行上傳操作,文件哈希值作為識(shí)別分片歸屬的唯一標(biāo)準(zhǔn)。返回int類(lèi)型rCode,根據(jù)rCode結(jié)果判斷是否執(zhí)行第2步上傳動(dòng)作
2.uploadLargeFile,傳入?yún)?shù)除了常規(guī)上傳文件參數(shù)之外加了分片path,分片index,isFinished。isFinished是最后一片的依據(jù)。客戶(hù)端就在上傳接口的response里繼續(xù)上傳下一個(gè)分片,直到最后一片上傳完成,服務(wù)器才會(huì)返給這個(gè)大文件的url。
看代碼
protected void addFileMsg(String path) { ? ? ? ? forceLogin(); ? ? ? ? ? if (path == null) { ? ? ? ? ? ? return; ? ? ? ? } ? ? ? ? File file = new File(path); ? ? ? ? if (file.exists()) { ? ? ? ? ? ? ImMsg msg = new ImMsg(); ? ? ? ? ? ? msg.setType(ImMsg.MSG_TYPE_FILE); ? ? ? ? ? ? msg.setTime(System.currentTimeMillis()); ? ? ? ? ? ? msg.setMsgReaded(); ? ? ? ? ? ? msg.setReceiveTime(System.currentTimeMillis()); ? ? ? ? ? ? AccountInfo accountInfo = IMApp.instance().getAccountInfo(); ? ? ? ? ? ? msg.setUserId(accountInfo.getUserId()); ? ? ? ? ? ? msg.setSex(accountInfo.getSex()); ? ? ? ? ? ? msg.setUserName(accountInfo.mNickName); ? ? ? ? ? ? msg.setHeadUrl(accountInfo.mHead); ? ? ? ? ? ? msg.mMasterId = mMasterId; ? ? ? ? ? ? msg.setMsg(new File(path).getName()); ? ? ? ? ? ? msg.setPicPath(path); ? ? ? ? ? ? msg.setState(ImMsg.STATE_SEND_UPLOADING); ? ? ? ? ? ? String ext = null; ? ? ? ? ? ? if (path.endsWith("doc") || path.endsWith("docx")) { ? ? ? ? ? ? ? ? ext = "doc"; ? ? ? ? ? ? } else if (path.endsWith("xls") || path.endsWith("xlsx")) { ? ? ? ? ? ? ? ? ext = "xls"; ? ? ? ? ? ? } else if (path.endsWith("ppt") || path.endsWith("pptx")) { ? ? ? ? ? ? ? ? ext = "ppt"; ? ? ? ? ? ? } else if (path.endsWith("pdf")) { ? ? ? ? ? ? ? ? ext = "pdf"; ? ? ? ? ? ? } ? ? ? ? ? ? msg.setMsg_extend3(ext); ? ? ? ? ? ? ? msg.mFileSize = (int) new File(path).length(); ? ? ? ? ? ? msg.setHasAtt(hasAtt()); ? ? ? ? ? ? addMsgToDB(msg); ? ? ? ? ? ? ? isFileListSingle = fileList.size() == 1; ? ? ? ? ? ? SPHelper spHelper = SPHelper.build(); ? ? ? ? ? ? int lastSlices = spHelper.get(slice_old, 0); ? ? ? ? ? ? String aesPath = spHelper.get(slice_aesEncPath, ""); ? ? ? ? ? ? String lastPath = spHelper.get(slice_picPath, ""); ? ? ? ? ? ? int tempTotalCount = spHelper.get(CommonUtils.FAILED_TEMP_SEND_TOTAL_COUNT, 0);//實(shí)際發(fā)送總個(gè)數(shù) ? ? ? ? ? ? if (lastSlices == 1 && tempTotalCount > 1) { ? ? ? ? ? ? ? ? /** ? ? ? ? ? ? ? ? ?* 讀取上次失敗文件的進(jìn)度,如果還剩一個(gè)失敗文件,但是上次發(fā)送的總文件個(gè)數(shù)大于1, ? ? ? ? ? ? ? ? ?* 則fileList.size() == 1這個(gè)判斷不能用,在所有判斷處加一個(gè)標(biāo)志 ? ? ? ? ? ? ? ? ?*/ ? ? ? ? ? ? ? ? isFileListSingle = false; ? ? ? ? ? ? } ? ? ? ? ? ? //根據(jù)文件大小,判斷是否用分片上傳 modify hexiaokang 2019年11月5日11點(diǎn)01分 ? ? ? ? ? ? if (new File(path).length() < Global.FILE_SPILT_LENGTH) {//文件小于5M,常規(guī)上傳方式 ? ? ? ? ? ? ? ? upLoadFile(msg); ? ? ? ? ? ? } else { ? ? ? ? ? ? ? ? ? File sourceFile = new File(path); ? ? ? ? ? ? ? ? //分片所在文件夾,以未做AES加密的源文件名作為 分片文件夾名字 ? ? ? ? ? ? ? ? String sliceDir = sourceFile.getParent() + File.separator + sourceFile.getName() + "_split"; ? ? ? ? ? ? ? ? ? if (lastSlices == 1 ? ? ? ? ? ? ? ? ? ? ? ? && path.equals(lastPath) ? ? ? ? ? ? ? ? ? ? ? ? && new File(sliceDir).exists() ? ? ? ? ? ? ? ? ? ? ? ? && !aesPath.equals("") ? ? ? ? ? ? ? ? ? ? ? ? && new File(aesPath).exists()) {//發(fā)送上次的舊文件中斷的分片 ? ? ? ? ? ? ? ? ? ? //只走一次 ? ? ? ? ? ? ? ? ? ? spHelper.put(slice_old, 0); ? ? ? ? ? ? ? ? ? ? sliceIndex = spHelper.get(slice_sliceIndex, 0); ? ? ? ? ? ? ? ? ? ? int count = spHelper.get(slice_sliceCount, 0); ? ? ? ? ? ? ? ? ? ? LogUtil2.i(TAG + "&onUploadComplete", "sendOldFiles sliceIndex = " + sliceIndex + ", sliceCount = " + count); ? ? ? ? ? ? ? ? ? ? largeFilePre = true; ? ? ? ? ? ? ? ? ? ? upLoadLargeFilePre(msg, count, sliceDir, aesPath); ? ? ? ? ? ? ? ? } else {//發(fā)送大文件正常流程 ? ? ? ? ? ? ? ? ? ? //給文件分片 ? ? ? ? ? ? ? ? ? ? int partFileLength = Global.FILE_SPILT_LENGTH;//指定分割的子文件大小為5M ? ? ? ? ? ? ? ? ? ? //先對(duì)文件做AES加密,再進(jìn)行分片,這里很重要 ? ? ? ? ? ? ? ? ? ? String aesEncPath = EncryptMgr.encFile(path, accountInfo.getEncTime(), accountInfo.getEncKey()); ? ? ? ? ? ? ? ? ? ? File f = new File(aesEncPath); ? ? ? ? ? ? ? ? ? ? LogUtil2.i(TAG + "&onUploadComplete", "ChatMsgActivity.addFileMsg: big file enc path=" + path); ? ? ? ? ? ? ? ? ? ? ? try { ? ? ? ? ? ? ? ? ? ? ? ? sliceCount = FileSliceUtil.splitFile(aesEncPath, partFileLength, sliceDir);//將文件分割 ? ? ? ? ? ? ? ? ? ? } catch (Exception e) { ? ? ? ? ? ? ? ? ? ? ? ? LogUtil2.e(TAG, "split.e:" + e.getMessage()); ? ? ? ? ? ? ? ? ? ? ? ? e.printStackTrace(); ? ? ? ? ? ? ? ? ? ? } // ? ? ? ? ? ? ? ? ?LogUtil2.e(TAG+"&onUploadComplete", "ChatMsgActivity.addFileMsg: sliceCount:" + sliceCount); ? ? ? ? ? ? ? ? ? ? ? //分片上傳 ? ? ? ? ? ? ? ? ? ? largeFilePre = false; ? ? ? ? ? ? ? ? ? ? upLoadLargeFilePre(msg, sliceCount, sliceDir, aesEncPath); ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } ? ? ? ? } ? ? }
上面這一塊代碼,除了小文件常規(guī)上傳,就是大文件上傳方式了。大文件上傳這里分了2種情況,
1.發(fā)送上次中斷的大文件分片,這里就不用分片了,直接從sp拿到上次中斷的分片count、index等信息直接上傳
2.從分片到發(fā)送的全部流程,因?yàn)槲疫@里對(duì)文件做了AES加密,所以是加密之后再分片
接下來(lái)就是上傳過(guò)程
public void upLoadLargeFilePre(final ImMsg msg, final int sliceCount, final String sliceDir, final String aesEncPath) { ? ? ? ? if (msg.getState() != ImMsg.STATE_SEND_WAITING) { ? ? ? ? ? ? msg.setState(ImMsg.STATE_SEND_UPLOADING); ? ? ? ? ? ? mListAdapter.notifyDataSetChanged(); ? ? ? ? } ? ? ? ? AccountInfo accountInfo = IMApp.instance().getAccountInfo(); ? ? ? ? UploadFileHelper helper = new UploadFileHelper(accountInfo.getEncTime(), accountInfo.getEncKey(), ? ? ? ? ? ? ? ? new UploadFileCallback() { ? ? ? ? ? ? ? ? ? ? ? @Override ? ? ? ? ? ? ? ? ? ? public void onError(Call call, Exception e) { ? ? ? ? ? ? ? ? ? ? ? ? e.printStackTrace(); ? ? ? ? ? ? ? ? ? ? ? ? LogUtil2.e("onUploadComplete", "ChatMsgActivity.onError: error(split_upload):" + e.toString()+", call = "+call); ? ? ? ? ? ? ? ? ? ? ? ? failCount++; // ? ? ? ? ? ? ? ? ? ? ? ? ? ?if (msg.getPicPath() != null && msg.getPicPath().contains(SDCardUtil.getSDcardPathEx())) { // ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?new File(msg.getPicPath()).delete(); // ? ? ? ? ? ? ? ? ? ? ? ? ? ?} ? ? ? ? ? ? ? ? ? ? ? ? btn_other_sendfile.setClickable(true); ? ? ? ? ? ? ? ? ? ? ? ? CommonUtils.isSendBtnClickable = true; ? ? ? ? ? ? ? ? ? ? ? ? Intent comIntent = new Intent(); ? ? ? ? ? ? ? ? ? ? ? ? comIntent.setAction(CommonUtils.USBFILE_COMPLETE_SEND); ? ? ? ? ? ? ? ? ? ? ? ? comIntent.putExtra("fail_count", failCount); ? ? ? ? ? ? ? ? ? ? ? ? sendBroadcast(comIntent); ? ? ? ? ? ? ? ? ? ? ? ? ? tempProgress = 0; ? ? ? ? ? ? ? ? ? ? ? ? largeFilePre = false; ? ? ? ? ? ? ? ? ? ? ? ? //todo 上傳失敗,上傳任務(wù)終止 (需要保存失敗msg的信息,以及分片信息) ? ? ? ? ? ? ? ? ? ? ? ? String picPath = msg.getPicPath(); ? ? ? ? ? ? ? ? ? ? ? ? // 保存picPath, sliceIndex, sliceCount, aesEncPath ? ? ? ? ? ? ? ? ? ? ? ? SPHelper spHelper = SPHelper.build(); ? ? ? ? ? ? ? ? ? ? ? ? spHelper.put(slice_picPath, picPath); ? ? ? ? ? ? ? ? ? ? ? ? spHelper.put(slice_sliceIndex, sliceIndex); ? ? ? ? ? ? ? ? ? ? ? ? spHelper.put(slice_sliceCount, sliceCount); ? ? ? ? ? ? ? ? ? ? ? ? spHelper.put(slice_aesEncPath, aesEncPath); ? ? ? ? ? ? ? ? ? ? ? ? spHelper.put(slice_old, 1);//標(biāo)記,1表示有上次失敗的碎片,處理完上次失敗的碎片之后設(shè)置為0 ? ? ? ? ? ? ? ? ? ? ? ? return; ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? @Override ? ? ? ? ? ? ? ? ? ? public void onResponse(UploadFileAckPacket uploadFileAckPacket) { ? ? ? ? ? ? ? ? ? ? ? ? LogUtil2.i("onUploadComplete", "ChatMsgActivity.onResponse: pre upload ack packet code="+uploadFileAckPacket.getRetCode()+", desc="+uploadFileAckPacket.getRetDesc()); ? ? ? ? ? ? ? ? ? ? ? ? if (getMsgFromDB(msg.getId()) == null) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? msg.setState(ImMsg.STATE_SEND_FAILED); ? ? ? ? ? ? ? ? ? ? ? ? ? ? LogUtil2.i("onUploadComplete", "msg not exist d = (split_upload)" + msg.getId()); ? ? ? ? ? ? ? ? ? ? ? ? ? ? updateMsgToDB(msg); ? ? ? ? ? ? ? ? ? ? ? ? ? ? mListAdapter.notifyDataSetChanged(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? failCount++; ? ? ? ? ? ? ? ? ? ? ? ? ? ? btn_other_sendfile.setClickable(true); ? ? ? ? ? ? ? ? ? ? ? ? ? ? CommonUtils.isSendBtnClickable = true; ? ? ? ? ? ? ? ? ? ? ? ? ? ? Intent comIntent = new Intent(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? comIntent.setAction(CommonUtils.USBFILE_COMPLETE_SEND); ? ? ? ? ? ? ? ? ? ? ? ? ? ? sendBroadcast(comIntent); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? tempProgress = 0; ? ? ? ? ? ? ? ? ? ? ? ? ? ? return; ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? if (uploadFileAckPacket != null && uploadFileAckPacket.isSuccess()) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? LogUtil2.i("onUploadComplete", "msg exist and sucess(uploadFileAckPacket.sliceIndex(split_upload)):" + uploadFileAckPacket.sliceIndex+", sliceCount="+sliceCount+", url="+uploadFileAckPacket.mUrl); ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (sliceIndex < sliceCount && TextUtils.isEmpty(uploadFileAckPacket.mUrl)) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //更新進(jìn)度條 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (isFileListSingle) {//單個(gè)大文件 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? int pro = 100 * sliceIndex / sliceCount; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Intent uploadIntent = new Intent(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? uploadIntent.setAction(CommonUtils.USBFILE_PROGRESS_SEND); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? uploadIntent.putExtra("sentCount", -1);//-1 代表發(fā)送的是單個(gè)文件 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? uploadIntent.putExtra("sentPro", pro); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? sendBroadcast(uploadIntent); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? } else {//一次發(fā)送多個(gè)文件,包括大文件 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //刪除掉上傳成功的分片 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? String slicePath = sliceDir + File.separator + "part_" + (sliceIndex); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? new File(slicePath).delete(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? sliceIndex++; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //還有待上傳的分片 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? upLoadLargeFilePre(msg, sliceCount, sliceDir, aesEncPath); ? ? ? ? ? ? ? ? ? ? ? ? ? ? } else { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //所有分片上傳完成 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? largeFilePre = false; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? LogUtil2.i("onUploadComplete", "ChatMsgActivity.onResponse: 所有分片上傳完成 largeFilePre="+largeFilePre); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? msg.updateImageUpLoadProgress(100); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? msg.setPicBigUrl(uploadFileAckPacket.mUrl); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //這里刪除原文件 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (msg.getPicPath() != null && msg.getPicPath().contains(SDCardUtil.getSDcardPathEx())) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? File file = new File(msg.getPicPath()); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //刪除分片所在的文件夾 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? FileUtil.deleteFolderFile(sliceDir, true); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //刪除文件 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? file.delete(); // ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?EventBus.getDefault().post(new EncFileEvent(EncFileEvent.COM_FILE_DELETE, msg.getPicPath(), 0)); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? msg.setPicPath(""); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (msg.getType() == ImMsg.MSG_TYPE_IMAGE) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? msg.setPicSmallUrl(uploadFileAckPacket.mThumbnail); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? msg.mThumbWidth = this.mThumbWidth; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? msg.mThumbHeight = this.mThumbHeight; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? LogUtil2.i("onUploadComplete", "msg exist and sucess(msg.getPicBigUrl()(split_upload)):" + msg.getPicBigUrl()); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? sendMsg(msg); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? sentCount++; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? sliceIndex = 1; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (isFileListSingle) {//單個(gè)文件不用處理 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? } else { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //傳遞上傳進(jìn)度 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Intent uploadIntent = new Intent(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? uploadIntent.setAction(CommonUtils.USBFILE_PROGRESS_SEND); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? uploadIntent.putExtra("sentCount", sentCount); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? sendBroadcast(uploadIntent); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //繼續(xù)上傳下一個(gè)文件 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (sentCount < fileList.size()) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? addFileMsg(fileList.get(sentCount).getAbsolutePath()); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? } else { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //所有文件上傳完成 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? btn_other_sendfile.setClickable(true); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? CommonUtils.isSendBtnClickable = true; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Intent comIntent = new Intent(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? comIntent.setAction(CommonUtils.USBFILE_COMPLETE_SEND); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? sendBroadcast(comIntent); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? tempProgress = 0; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? } else { ? ? ? ? ? ? ? ? ? ? ? ? ? ? LogUtil2.e("onUploadComplete", "rCode(split_upload)):" + uploadFileAckPacket.getRetCode()+", sliceIndex="+uploadFileAckPacket.sliceIndex); ? ? ? ? ? ? ? ? ? ? ? ? ? ? if(uploadFileAckPacket.getRetCode()==1343688774){ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? LogUtil2.e("onUploadComplete", "ChatMsgActivity.onResponse: 缺片了!"); ? ? ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? ? ? msg.setState(ImMsg.STATE_SEND_FAILED); ? ? ? ? ? ? ? ? ? ? ? ? ? ? updateMsgToDB(msg); ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (!IMMsgMgr.notifyActivity(IMMsgMgr.IM_CMD_IMP2PMSG_ACK, msg.getUserId(), msg.hasAtt(), false, msg)) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? ? ? mListAdapter.notifyDataSetChanged(); ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? @Override ? ? ? ? ? ? ? ? ? ? public void inProgress(float progress) { ? ? ? ? ? ? ? ? ? ? ? ? super.inProgress(progress); // ? ? ? ? ? ? ? ? ? ? ? ?LogUtil2.i("onUploadProgress", "inProgress " + progress+", path="+msg.getPicPath()+", sliceDir="+sliceDir); ? ? ? ? ? ? ? ? ? ? ? ? LogUtil2.i("onUploadProgress", "ChatMsgActivity.inProgress: sliceCount="+sliceCount+", sliceIndex="+sliceIndex+", sentCount="+sentCount+", list.size="+fileList.size()+", progress="+progress+", tempProgress="+tempProgress); ? ? ? ? ? ? ? ? ? ? ? ? int pro = (int) (progress * 100); ? ? ? ? ? ? ? ? ? ? ? ? if (new File(msg.getPicPath()).length() < Global.FILE_SPILT_LENGTH) { // ? ? ? ? ? ? ? ? ? ? ? ? }else{ ? ? ? ? ? ? ? ? ? ? ? ? ? ? int allPro= (int)(100*(progress+(sliceIndex-1))/sliceCount); ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (isFileListSingle && allPro - tempProgress >= 1) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //todo 分片上傳,進(jìn)度條重新計(jì)算, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //多個(gè)文件上傳不用考慮,這里重新計(jì)算單個(gè)文件的上傳問(wèn)題 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? LogUtil2.i("onUploadProgress", "ChatMsgActivity.inProgress: big file allPro="+allPro); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? Intent uploadIntent = new Intent(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? uploadIntent.setAction(CommonUtils.USBFILE_PROGRESS_SEND); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? uploadIntent.putExtra("sentCount", -1);//-1代表發(fā)送的是單個(gè)文件,這里是針對(duì)用戶(hù)感知而言的代碼邏輯 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? uploadIntent.putExtra("sentPro", allPro); ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? tempProgress = allPro; ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? sendBroadcast(uploadIntent); ? ? ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? // 更新 ? ? ? ? ? ? ? ? ? ? ? ? mListAdapter.notifyDataSetChanged(); ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? }, msg); ? ? ? ? LogUtil2.i("onUploadComplete", "ChatMsgActivity.upLoadLargeFilePre: largeFilePre="+largeFilePre); ? ? ? ? if (largeFilePre) {//todo 是否有過(guò)預(yù)處理 ? ? ? ? ? ? String slicePath = sliceDir + File.separator + "part_" + (sliceIndex); ? ? ? ? ? ? int isFinished = sliceIndex == sliceCount ? 1 : 0; ? ? ? ? ? ? helper.upLoadLargeFile(aesEncPath, slicePath, sliceIndex, isFinished); ? ? ? ? } else { ? ? ? ? ? ? //上傳大文件 預(yù)處理 ? ? ? ? ? ? int rCode = helper.upLoadLargeFilePre(aesEncPath, sliceCount); ? ? ? ? ? ? if (rCode == 0) {//預(yù)處理成功,可以執(zhí)行上傳任務(wù) ? ? ? ? ? ? ? ? largeFilePre = true; ? ? ? ? ? ? ? ? String slicePath = sliceDir + File.separator + "part_" + (sliceIndex); ? ? ? ? ? ? ? ? int isFinished = sliceIndex == sliceCount ? 1 : 0; ? ? ? ? ? ? ? ? helper.upLoadLargeFile(aesEncPath, slicePath, sliceIndex, isFinished); ? ? ? ? ? ? } else { ? ? ? ? ? ? ? ? //預(yù)處理失敗,不執(zhí)行上傳任務(wù) ? ? ? ? ? ? ? ? LogUtil2.i("onUploadComplete", "somewordsrCode:" + rCode+", before plus faileCount="+failCount); ? ? ? ? ? ? ? ? ? msg.setState(ImMsg.STATE_SEND_FAILED); ? ? ? ? ? ? ? ? updateMsgToDB(msg); ? ? ? ? ? ? ? ? mListAdapter.notifyDataSetChanged(); ? ? ? ? ? ? ? ? failCount++; ? ? ? ? ? ? ? ? btn_other_sendfile.setClickable(true); ? ? ? ? ? ? ? ? CommonUtils.isSendBtnClickable = true; ? ? ? ? ? ? ? ? Intent comIntent = new Intent(); ? ? ? ? ? ? ? ? comIntent.putExtra("upload_error", 0); ? ? ? ? ? ? ? ? comIntent.putExtra("fail_count",failCount); ? ? ? ? ? ? ? ? comIntent.setAction(CommonUtils.USBFILE_COMPLETE_SEND); ? ? ? ? ? ? ? ? LogUtil.LogShow("onUploadComplete", "ChatMsgActivity.upLoadLargeFilePre: before sendIntent failCount="+failCount); ? ? ? ? ? ? ? ? sendBroadcast(comIntent); ? ? ? ? ? ? ? ? ? failCount=0; ? ? ? ? ? ? ? ? tempProgress = 0; ? ? ? ? ? ? } ? ? ? ? } ? ? }
上面這一塊就是上傳過(guò)程
int rCode = helper.upLoadLargeFilePre(aesEncPath, sliceCount);
這一句為第一個(gè)接口預(yù)處理,根據(jù)結(jié)果決定是否執(zhí)行上傳。
helper.upLoadLargeFile(aesEncPath, slicePath, sliceIndex, isFinished);
這一句執(zhí)行上傳,在onResponse里處理上傳結(jié)果,我這里有多個(gè)文件連續(xù)上傳,所以結(jié)果處理看起來(lái)有點(diǎn)凌亂。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- RecyclerView實(shí)現(xiàn)側(cè)滑拖拽功能
- android RecyclerView側(cè)滑菜單,滑動(dòng)刪除,長(zhǎng)按拖拽,下拉刷新上拉加載
- Android recyclerview實(shí)現(xiàn)拖拽排序和側(cè)滑刪除
- android的RecyclerView實(shí)現(xiàn)拖拽排序和側(cè)滑刪除示例
- RecyclerView進(jìn)階:使用ItemTouchHelper實(shí)現(xiàn)拖拽和側(cè)滑刪除效果
- LRecyclerView側(cè)滑iOS阻塞效果不完整的解決辦法
- Android實(shí)現(xiàn)多線程斷點(diǎn)續(xù)傳
- 詳解Android使用OKHttp3實(shí)現(xiàn)下載(斷點(diǎn)續(xù)傳、顯示進(jìn)度)
- android實(shí)現(xiàn)多線程下載文件(支持暫停、取消、斷點(diǎn)續(xù)傳)
- RecyclerView實(shí)現(xiàn)側(cè)滑和網(wǎng)絡(luò)斷點(diǎn)續(xù)傳
相關(guān)文章
Android--SQLite(增,刪,改,查)操作實(shí)例代碼
Android--SQLite(增,刪,改,查)操作實(shí)例代碼,需要的朋友可以參考一下2013-02-02Android 自定義SeekBar 實(shí)現(xiàn)分段顯示不同背景顏色的示例代碼
這篇文章主要介紹了Android 自定義SeekBar 實(shí)現(xiàn)分段顯示不同背景顏色,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-06-06Suspend函數(shù)與回調(diào)的互相轉(zhuǎn)換示例詳解
這篇文章主要為大家介紹了Suspend函數(shù)與回調(diào)的互相轉(zhuǎn)換示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01解決Android自定義view獲取attr中自定義顏色的問(wèn)題
這篇文章主要介紹了Android自定義view獲取attr中自定義顏色的問(wèn)題解決方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-12-12獲取Android手機(jī)中所有短信的實(shí)現(xiàn)代碼
這篇文章主要介紹了獲取Android手機(jī)中所有短信的實(shí)現(xiàn)代碼,需要的朋友可以參考下2014-08-08Android實(shí)現(xiàn)動(dòng)態(tài)添加數(shù)據(jù)與堆疊折線圖詳解流程
堆疊折線圖是折線圖的一種,堆積折線圖用于顯示每一數(shù)值所占大小隨時(shí)間或有序類(lèi)別而變化的趨勢(shì),可能顯示數(shù)據(jù)點(diǎn)以表示單個(gè)數(shù)據(jù)值,也可能不顯示這些數(shù)據(jù)點(diǎn)。堆疊折線圖中,類(lèi)別數(shù)據(jù)沿水平軸均勻分布,所有值數(shù)據(jù)沿垂直軸均勻分布2021-10-10Android 多種dialog的實(shí)現(xiàn)方法(推薦)
下面小編就為大家分享一篇Android 多種dialog的實(shí)現(xiàn)方法(推薦),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-01-01Android中關(guān)于自定義相機(jī)預(yù)覽界面拉伸問(wèn)題
這篇文章主要為大家詳細(xì)介紹了Android中關(guān)于自定義相機(jī)預(yù)覽界面拉伸問(wèn)題,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-02-02Java操作FreeMarker模板引擎的基本用法示例小結(jié)
這篇文章主要介紹了Java操作FreeMarker模板引擎的基本用法示例小結(jié),FreeMarker本身由Java寫(xiě)成,用模板來(lái)生成文本輸出,需要的朋友可以參考下2016-02-02用xutils3.0進(jìn)行下載項(xiàng)目更新
這篇文章主要介紹了用xutils3.0進(jìn)行下載項(xiàng)目更新的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2016-08-08