android 附件(图片)上传下载功能开发

来源:互联网 发布:qq农场矿山数据 编辑:程序博客网 时间:2024/05/22 06:54

说明:附件上传,选择上传的附件只做了从图库选择图片或者拍照获取图片,实际也可以上传其他类型的文件,附件分为11中状态,未上传,准备上传,上传中,上传失败,上传成功,未下载,准备下载,下载中,下载成功,下载失败,已和服务器同步,看似有点复杂,其实也挺简单。

下面我将从无到有,一个一个伴随着效果图以及代码片段进行讲解

一:空白的附件列表界面如下:



点击“添加图片”按钮后:会弹出如下的选择菜单,提示是从图库选择图片还是拍照获取图片
二:选择图片菜单界面如下:





三:当选择4张图片或者拍照得到图片后,显示界面如下所示:

可以看到每个条目有一张缩略图,文件名,文件大小,最后修改日期,文件状态,以及右侧的操作按钮组成,文件状态还有一个隐藏的TextView,可以用来显示上传或下载的进度


四:点击题目中的文件名,可以修改文件的名字(只有未上传状态可以修改)
这里点击第二张范爷的图片的文件名
界面如图所示:


五:重命名后的界面如图所示:文件名改成了范爷一枚.jpg了



六:点击每个条目的上传按钮,可以讲它们加入未上传队列,这时候图片将一张张上传到服务器,每一张图片的状态依次改变为:未上传→准备上传→上传中(这是现实进度)→上传完成→已和服务器同步
如图所示:


七:所有的上传队列中图片上传完成后,会弹出确认框,是否保存刚刚上传的这些图片,如果确认,图片的状态就变成了“已和服务器同步”状态了,失败的会变成未上传状态
如图所示:




这里可以看到最后又张图片上传失败了,可以进行重试






前面讲解的都是添加上传的操作,下载讲解删除和下载的操作
说明:所有的删除和取消相关的操作,都是长按条目弹出的
一:删除未上传的图片
长按上面图片的范爷条目,会弹出如下对话框



点击删除按钮后这张图片便被移除了



二:删除已和“已和服务器同步状态”,点击条目,会弹出一样的删除对话框,但是点击删除按钮后,可以选择只从本地删除还是从服务器和本地都删除,如图所示:


如果点击“服务器和本地都删除”则图片会被从本地列表和服务器删除,但是如果点击“只从本地删除”则图片变成“未下载”状态
三:将所有的图片只从本地删除后,界面如图所示


这时候,和上传功能相反,如果点击右侧的下载按钮,图片的状态变化如下:
未下载→准备下载→下载中(显示进度)→下载完成(下次进入附件列表会变成已和服务器同步),如果下载失败会显示“下载失败”并可以重试

四:下载界面如图所示:



五:位于上传下载队列中,但是还没有开始上传和下载的都是可以取消操作的,这里就不截图了
当然,点击本地存在的图片或者已下载完成的图片,是可以发起系统调用查看图片的(实际上任何文件都可以查看)


下面就是核心的代码了:主要是一个Activity:AttachmentActivity,这个就是主界面了,3个帮助类DownLoadUtil:用来下载的帮助类,UploadUtil:用来上传的帮助类,FileIconHelper:用来显示缩略图的帮助类,AttachmentInfo附件实体类,至于其他一些简单常量及没有提到的方法,就不多少了,自行替换就是了。

各个功能点都在代码中有详细的注释:请看代码
AttachmentInfo:
package com.flagcloud.android.mqservice.model.entity;import java.io.File;import java.util.Date;import java.util.HashMap;import com.flagcloud.android.mqservice.util.CommonHelper;import com.flagcloud.android.mqservice.util.ConvertUtil;import android.text.format.Time;/** * 附件信息实体类 *  * @author hdp *  */public class AttachmentInfo {public static final int NOT_UPLOAD = 1, PREPARE_UPLOAD = 2, UP_LOADING = 3,UP_LOADING_SUCCESS = 4, UP_LOADING_FAIL = 5, NOT_DOWNLOAD = 6,PREPARE_DOWNLOAD = 7, DOWN_LOADING = 8, DOWN_LOADING_SUCCESS = 9,DOWN_LOADING_FAIL = 10, ALREADY_SAVE = 11;// 本地有,服务器也已保存,则为已保存状态static {addToStateMap(1, "未上传");addToStateMap(2, "准备上传");addToStateMap(3, "上传中:");addToStateMap(4, "上传完成");addToStateMap(5, "上传失败");addToStateMap(6, "未下载");addToStateMap(7, "准备下载");addToStateMap(8, "下载中:");addToStateMap(9, "下载完成");addToStateMap(10, "下载失败");addToStateMap(11, "已和服务器同步");}public static HashMap<Integer, String> stateMap;// 服务器返回属性public String id;public String fileName; // 文件名public String path; // 文件路径,服务器路径public long size; // 文件大小,字节public String time;// 自定义属性public int state; //文件状态public int progress = 0; // 操作进度public String fileNativePath; // 文件在本地的地址public static void addToStateMap(int state, String stateText) {if (stateMap == null) {stateMap = new HashMap<Integer, String>();}stateMap.put(state, stateText);}public AttachmentInfo() {}public AttachmentInfo(String name, String path, long size,String modifyTime, int state, int progress, String fileNativePath) {super();this.fileName = name;this.path = path;this.size = size;this.time = modifyTime;this.state = state;this.progress = progress;this.fileNativePath = fileNativePath;}public AttachmentInfo(File file, int state) {if (file.exists()) {// 如果文件存在this.state = state;this.fileName = file.getName();this.fileNativePath = file.getAbsolutePath();this.size = file.length();try {this.time = ConvertUtil.dateToString(new Date(file.lastModified()));} catch (Exception e) {CommonHelper.log("根据文件信息创建附件转化时间时不正确", e.getMessage());}}}}



AttachmentActivity:
package com.flagcloud.android.mqservice.biz.attachment;import java.io.File;import java.io.FileOutputStream;import java.io.OutputStream;import java.lang.reflect.Type;import java.net.URLEncoder;import java.util.ArrayList;import java.util.UUID;import android.app.Activity;import android.app.Dialog;import android.content.ContentValues;import android.content.Intent;import android.content.SharedPreferences;import android.database.Cursor;import android.graphics.Bitmap;import android.graphics.Bitmap.CompressFormat;import android.net.Uri;import android.os.AsyncTask;import android.os.Build;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.preference.PreferenceManager;import android.provider.MediaStore;import android.text.TextUtils;import android.util.Log;import android.view.KeyEvent;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.view.View.OnClickListener;import android.view.ViewGroup;import android.view.ViewGroup.LayoutParams;import android.view.Window;import android.view.WindowManager;import android.widget.AdapterView;import android.widget.AdapterView.OnItemClickListener;import android.widget.AdapterView.OnItemLongClickListener;import android.widget.Button;import android.widget.LinearLayout;import android.widget.ListView;import android.widget.RelativeLayout;import android.widget.TextView;import android.widget.Toast;import com.flagcloud.android.mqservice.R;import com.flagcloud.android.mqservice.adapter.AttachmentAdapter;import com.flagcloud.android.mqservice.async.DownLoadAttachmentListTask;import com.flagcloud.android.mqservice.async.DownLoadAttachmentListTask.OnDownLoadAtListFinishedListener;import com.flagcloud.android.mqservice.async.ServiceNoteOperationTask;import com.flagcloud.android.mqservice.async.ServiceNoteOperationTask.OnServiceNoteOperationFinishedListener;import com.flagcloud.android.mqservice.biz.attachment.DownLoadUtil.OnDownLoadProcessListener;import com.flagcloud.android.mqservice.biz.attachment.UploadUtil.OnUploadProcessListener;import com.flagcloud.android.mqservice.common.Constant;import com.flagcloud.android.mqservice.common.ResponseObjectUtil;import com.flagcloud.android.mqservice.model.bindingmodel.ServiceNoteAttachmentsBindingModel;import com.flagcloud.android.mqservice.model.entity.AttachmentInfo;import com.flagcloud.android.mqservice.model.entity.ServiceNoteAttachmentInfo;import com.flagcloud.android.mqservice.model.listitem.OperationListItemViewModel;import com.flagcloud.android.mqservice.util.CommonHelper;import com.flagcloud.android.mqservice.util.FileUtil;import com.flagcloud.android.mqservice.util.GetAbsolutePathUtil;import com.flagcloud.android.mqservice.util.GsonUtil;import com.flagcloud.android.mqservice.util.ImageUtil;import com.flagcloud.android.mqservice.view.dialog.ConfirmDialog;import com.flagcloud.android.mqservice.view.dialog.InputAndConfirmDialog;import com.google.gson.reflect.TypeToken;//附件活动public class AttachmentActivity extends Activity implementsOnUploadProcessListener, OnDownLoadProcessListener {private static final String TAG = "AttachmentActivity";private static final String PHOTO_PATH = FileUtil.sdcardPath+ File.separator + FileUtil.APP_FILE_DIRECTOR + File.separator+ FileUtil.PHOTO_DIR; // 压缩后的图片存放的目录// 自定义上传相关消息private static final int TO_UPLOAD_FILE = 1;// 去上传文件private static final int UPLOAD_FILE_DONE = 2; // 上传完的响应private static final int UPLOAD_IN_PROCESS = 4; // 上传中(更新进度)// 自定义下载相关消息private static final int TO_DOWNLOAD_FILE = 5; // 去下载文件private static final int DOWNLOAD_FILE_DONE = 6; // 下载文件完成private static final int DOWNLOAD_IN_PROCESS = 7; // 文件下载中(更新进度)private ArrayList<AttachmentInfo> attachmentInfoList = new ArrayList<AttachmentInfo>();private SharedPreferences sp;private File photoFile;public static final int REQUEST_CODE_JOBREPORT = 0x0061,REQUEST_CODE_OTHER = 0x0062;private Uri photoUri;private String subPhotoPath; // 图片目录private String serviceNoteId = null;private AttachmentInfo currentUpLoadPhotoInfo; // 当前正在上传的对象private AttachmentInfo currentDownLoadFileInfo; // 当前正在下载的对象private AttachmentAdapter attachmentAdapter;private boolean isFirstComeIn; // 是否是首次进入private int longClickPosition = -1; // 长按的位置private Boolean isUpLoading = false; // 是否有图片正在上传private Boolean isDownLoading = false; // 是否有文件正在下载private int currentUploadFileTotalSize = 0; // 图片大小加上头部尾部长度private long currentDownLoadFileTotalSize = 0; // 当前下载的文件大小private Button goBackButton;private ListView fileInfoListView;private TextView topTitle;private InputAndConfirmDialog changeFileNameDialog;private Button selectFileButton; // 选择附件的按钮private RelativeLayout selectFileRL; // 下部选择文件的整体布局private AttachmentInfo selectedNewInfo; // 用户选择的新的附件private Button delButton;private Button undoButton;private Button cancelButton;private Dialog menuDialog;private Dialog selectImageDialog;private ConfirmDialog confirmDialog;private Dialog selectDeleteTypeDialog;// 下载附件列表的异步任务private DownLoadAttachmentListTask downLoadSNList;@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {if (keyCode == KeyEvent.KEYCODE_BACK) {doGoBack();}return super.onKeyDown(keyCode, event);}@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_up_load_attachment);// 创建图片的保存目录initializeView();addListener();sp = PreferenceManager.getDefaultSharedPreferences(this);// 将选择的图片保存到应用目录下的photos+任务单id为文件夹的子目录下// 进入即创建图片缓存目录,创建photos目录boolean success = FileUtil.createSDDir(FileUtil.APP_FILE_DIRECTOR+ File.separator + FileUtil.PHOTO_DIR);if (!success) {Toast.makeText(this, "文件夹创建失败", Toast.LENGTH_SHORT).show();return;}Log.i(TAG, "getAttachmentListFromServer执行了");Intent i = getIntent();serviceNoteId = i.getStringExtra("serviceNoteId");if (TextUtils.isEmpty(serviceNoteId)) {Toast.makeText(this, "任务单id有误", Toast.LENGTH_SHORT).show();return;}// 创建子目录boolean success2 = FileUtil.createSDDir(FileUtil.APP_FILE_DIRECTOR+ File.separator + FileUtil.PHOTO_DIR + File.separator+ serviceNoteId);if (!success2) {Toast.makeText(this, "创建子目录失败", Toast.LENGTH_SHORT).show();return;}// 这里初始化每个任务单对应的目录subPhotoPath = FileUtil.sdcardPath + File.separator+ FileUtil.APP_FILE_DIRECTOR + File.separator+ FileUtil.PHOTO_DIR + File.separator + serviceNoteId;Log.i(TAG, "onCreate执行了,当前list大小:" + attachmentInfoList.size());// 看是异常进入还是初次进入if (savedInstanceState == null) {// 初次进入,则从服务器获取getAttachmentListFromServer();isFirstComeIn = true;Log.i(TAG, "savedInstanceState为空");} else {isFirstComeIn = false;}}// 初始化试图public void initializeView() {topTitle = (TextView) findViewById(R.id.top_layout_onlygoback_tv_topTitle);goBackButton = (Button) findViewById(R.id.top_layout_onlygoback_btn_goBack);fileInfoListView = (ListView) findViewById(R.id.attachment_lv_fileInfoList);selectFileButton = (Button) findViewById(R.id.attachment_btn_selectFileBtn);selectFileRL = (RelativeLayout) findViewById(R.id.attachment_rl_bottomLine);topTitle.setText("附件列表");}// 从服务器获取附件信息的列表private void getAttachmentListFromServer() {try {if (downLoadSNList != null) {if (AsyncTask.Status.RUNNING.name().equals(downLoadSNList.getStatus().name())|| AsyncTask.Status.FINISHED.name().equals(downLoadSNList.getStatus().name())) {downLoadSNList.cancel(true);downLoadSNList = null;}}if (downLoadSNList == null) {// 测试实体接口// urlString url = Constant.GET_ATTACHMENTLIST;String encoderserviceNoteId = URLEncoder.encode(serviceNoteId,"utf-8");url += "?id=" + encoderserviceNoteId;// 返回对象类型Type responseObjectType = new TypeToken<ArrayList<AttachmentInfo>>() {}.getType();downLoadSNList = new DownLoadAttachmentListTask();downLoadSNList.setContext(this);downLoadSNList.setOnDownLoadAtListFinishedListener(onDownLoadAtListFinishedListener);downLoadSNList.execute(new Object[] { url, null, null,responseObjectType });downLoadSNList.showWaitingDialog(this, new Handler(),"正在载入数据...", null);}} catch (Exception e) {CommonHelper.log(TAG + ":doRefresh:", e.getMessage());}}private OnDownLoadAtListFinishedListener onDownLoadAtListFinishedListener = new OnDownLoadAtListFinishedListener() {@Overridepublic void resultCallBack(Object object) {try {if (ResponseObjectUtil.ResponseObjectIsNullOrException(AttachmentActivity.this, object)) {return;}// 先清空列表attachmentInfoList.clear();attachmentInfoList = (ArrayList<AttachmentInfo>) object;// 和本地目录进行比对,看每个文件在本地是否存在Log.i(TAG, "从服务器获取到附近列表大小是" + attachmentInfoList.size());compareAllAttachment();attachmentAdapter = new AttachmentAdapter(AttachmentActivity.this, attachmentInfoList,fileInfoListView, operationListener);fileInfoListView.setAdapter(attachmentAdapter);attachmentAdapter.notifyDataSetChanged();fileInfoListView.invalidate();Log.i(TAG, "加入本地未上传文件后的大小是:" + attachmentInfoList.size());} catch (Exception e) {CommonHelper.log(TAG + ":onDownLoadSNListFinishedListener",e.getMessage());}}};// 比对所有的文件private void compareAllAttachment() {File FileDir = new File(PHOTO_PATH + File.separator + serviceNoteId);if (FileDir.exists() && FileDir.isDirectory()) {// 根据当前附件列表遍历本地文件for (int j = 0; j < attachmentInfoList.size(); j++) {AttachmentInfo info = attachmentInfoList.get(j);// 服务器附件默认状态设置为未下载info.state = AttachmentInfo.NOT_DOWNLOAD;File[] allFiles = FileDir.listFiles();// 在本地有,在服务器没有的图片文件应该显示未上传if (allFiles != null) {for (int i = 0; i < allFiles.length; i++) {File tempFile = allFiles[i];if (info.fileName != null&& info.fileName.equals(tempFile.getName())) {// 如果有同名文件,则给本地地址赋值info.fileNativePath = tempFile.getAbsolutePath();info.state = AttachmentInfo.ALREADY_SAVE;}}}}// 根据本地文件遍历附件列表,如果没有,则加入并显示未上传ArrayList<AttachmentInfo> tempList = new ArrayList<AttachmentInfo>();File[] allFiles = FileDir.listFiles();if (allFiles != null) {for (int i = 0; i < allFiles.length; i++) {File tempFile = allFiles[i];boolean isAlreadyUpload = false;for (int j = 0; j < attachmentInfoList.size(); j++) {AttachmentInfo info = attachmentInfoList.get(j);String fileName = info.fileName;if (!TextUtils.isEmpty(fileName)) {if (fileName.equals(tempFile.getName())) {isAlreadyUpload = true;}}}if (!isAlreadyUpload) {// 本地有服务器没有的,如果是图片,加入列表,并显示未上传tempList.add(new AttachmentInfo(tempFile,AttachmentInfo.NOT_UPLOAD));}}}// 更新总的列表attachmentInfoList.addAll(tempList);}}private void addListener() {goBackButton.setOnClickListener(onClickListener);fileInfoListView.setOnItemClickListener(onFileItemClickListener);// 长按弹出optionsMenufileInfoListView.setOnItemLongClickListener(itemLongClickListener);selectFileButton.setOnClickListener(onClickListener);}// 长按条目的监听private OnItemLongClickListener itemLongClickListener = new OnItemLongClickListener() {@Overridepublic boolean onItemLongClick(AdapterView<?> parent, View view,int position, long id) {// 打开菜单longClickPosition = position;showMenuDialog();return false;}};// 根据图片的状态,显示不同的长按菜单private void showMenuDialog() {try {View view = getLayoutInflater().inflate(R.layout.upload_file_menu_dialog, null);// 删除操作delButton = (Button) view.findViewById(R.id.attachment_dialog_btn_button1);// 取消操作undoButton = (Button) view.findViewById(R.id.attachment_dialog_btn_button2);// 取消按钮cancelButton = (Button) view.findViewById(R.id.attachment_dialog_btn_cancel);cancelButton.setOnClickListener(menuDialogItemListener);delButton.setOnClickListener(menuDialogItemListener);undoButton.setOnClickListener(menuDialogItemListener);menuDialog = new Dialog(this, R.style.transparentFrameWindowStyle);menuDialog.setContentView(view, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));Window window = menuDialog.getWindow();// 设置显示动画window.setWindowAnimations(R.style.main_menu_animstyle);WindowManager.LayoutParams wl = window.getAttributes();wl.x = 0;wl.y = getWindowManager().getDefaultDisplay().getHeight();// 以下这两句是为了保证按钮可以水平满屏wl.width = ViewGroup.LayoutParams.MATCH_PARENT;wl.height = ViewGroup.LayoutParams.WRAP_CONTENT;// 设置显示位置menuDialog.onWindowAttributesChanged(wl);// 设置点击外围解散menuDialog.setCanceledOnTouchOutside(true);menuDialog.show();// 根据不同的装填,显示不同的提示if (longClickPosition >= 0) {AttachmentInfo info = attachmentInfoList.get(longClickPosition);int state = info.state;if (state == AttachmentInfo.UP_LOADING) {undoButton.setText("取消上传");undoButton.setEnabled(false);// 暂时禁用取消正在上传的操作// 禁用掉删除按钮delButton.setEnabled(false);} else if (state == AttachmentInfo.PREPARE_UPLOAD) {// 准备上传undoButton.setText("取消上传");} else if (state == AttachmentInfo.NOT_UPLOAD) {// 未上传,undoButton.setText("取消上传");undoButton.setEnabled(false);} else if (state == AttachmentInfo.NOT_DOWNLOAD) {// 未下载undoButton.setText("取消下载");undoButton.setEnabled(false);} else if (state == AttachmentInfo.PREPARE_DOWNLOAD) {undoButton.setText("取消下载");} else if (state == AttachmentInfo.DOWN_LOADING) {undoButton.setText("取消下载");delButton.setEnabled(false);// 暂时禁用取消正在下载的操作} else {undoButton.setEnabled(false);}}} catch (Exception e) {CommonHelper.log(TAG + ":showMenuDialog", e.getMessage());}}private View.OnClickListener menuDialogItemListener = new OnClickListener() {@Overridepublic void onClick(View v) {if (menuDialog != null) {menuDialog.dismiss();menuDialog = null;}if (v == delButton) {// 删除文件操作deleteLongClickItem();} else if (v == undoButton) {// 取消上传doMenuTwoAction();}}};// 第二个菜单的响应事件,第二个按钮只做取消操作private void doMenuTwoAction() {if (longClickPosition >= 0) {AttachmentInfo info = attachmentInfoList.get(longClickPosition);int state = info.state;// 如果是取消上传菜单,将状态置为为上传if (state == AttachmentInfo.NOT_UPLOAD) {// 未上传// info.state = AttachmentInfo.PREPARE_UPLOAD;} else if (state == AttachmentInfo.PREPARE_UPLOAD) {// 准备上传info.state = AttachmentInfo.NOT_UPLOAD;} else if (state == AttachmentInfo.UP_LOADING) {// 上传中} else if (state == AttachmentInfo.NOT_DOWNLOAD) {// 未下载} else if (state == AttachmentInfo.PREPARE_DOWNLOAD) {// 准备下载info.state = AttachmentInfo.NOT_DOWNLOAD;} else if (state == AttachmentInfo.DOWN_LOADING) {// 下载中info.state = AttachmentInfo.NOT_DOWNLOAD;} else {// 其他状态设置成未上传info.state = AttachmentInfo.NOT_UPLOAD;}attachmentAdapter.notifyDataSetChanged();fileInfoListView.invalidate();}}// 点击图片的监听private OnItemClickListener onFileItemClickListener = new OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position,long id) {AttachmentInfo info = attachmentInfoList.get(position);showAttachment(info);}};// 点击条目后显示详情的视图private void showAttachment(AttachmentInfo info) {try {int state = info.state;// 只有是已下载完成或者所有上传相关的状态,才能够查看详情if (state == AttachmentInfo.NOT_UPLOAD|| state == AttachmentInfo.PREPARE_UPLOAD|| state == AttachmentInfo.UP_LOADING|| state == AttachmentInfo.UP_LOADING_SUCCESS|| state == AttachmentInfo.UP_LOADING_FAIL|| state == AttachmentInfo.DOWN_LOADING_SUCCESS|| state == AttachmentInfo.ALREADY_SAVE) {// 发出查看文件的意图com.flagcloud.android.mqservice.common.IntentBuilder.viewFile(this, info.fileNativePath);}} catch (Exception e) {CommonHelper.log(TAG + ":showAttachment", e.getMessage());}}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// 删除menu.add(0, Constant.Delete_ITEMID, 0, "删除");return super.onCreateOptionsMenu(menu);}// 从服务器删除长按条目private void doDeleteAttachmentFromServer() {try {Log.i(TAG, "进入了从服务器删除照片的方法");AttachmentInfo longClickInfo = attachmentInfoList.get(longClickPosition);String attachId = longClickInfo.id;String encoderId = URLEncoder.encode(attachId, "utf-8");// urlString url = Constant.DELETE_ATTACHMENT_ITEM + "?id=" + encoderId;// 返回对象类型Type responseObjectType = OperationListItemViewModel.class;ServiceNoteOperationTask serviceNoteOperationTask = new ServiceNoteOperationTask();serviceNoteOperationTask.setContext(this);serviceNoteOperationTask.setOnServiceNoteOperationFinishedListener(deleteAttamentItemFinishedListener);serviceNoteOperationTask.showWaitingDialog(this, new Handler(),"正在删除所选附件...", null);serviceNoteOperationTask.execute(new Object[] { url, null, null,responseObjectType });} catch (Exception e) {CommonHelper.log(TAG + ":doDeleteAttachmentFromServer",e.getMessage());}}private OnServiceNoteOperationFinishedListener deleteAttamentItemFinishedListener = new OnServiceNoteOperationFinishedListener() {@Overridepublic void resultCallBack(Object object) {if (ResponseObjectUtil.ResponseObjectIsNullOrException(AttachmentActivity.this, object)) {Toast.makeText(AttachmentActivity.this, "附件删除失败",Toast.LENGTH_SHORT).show();return;}// 删除成功Toast.makeText(AttachmentActivity.this, "附件删除成功!",Toast.LENGTH_SHORT).show();// 本地是否存在,如果存在,则本地文件也删除try {AttachmentInfo info = attachmentInfoList.get(longClickPosition);File tempFile = new File(info.fileNativePath);if (tempFile != null && tempFile.exists()) {tempFile.delete();}// 从视图列表中移除attachmentInfoList.remove(longClickPosition);// 更新视图attachmentAdapter.notifyDataSetChanged();fileInfoListView.invalidate();} catch (Exception e) {CommonHelper.log(TAG + ":deleteAttamentItemFinishedListener",e.getMessage());}}};private void showDeleteFromServerConfirmDialog() {try {Log.i(TAG, "进入了从服务器删除的确认对话框");final ConfirmDialog deleteConfirmDialog = new ConfirmDialog(AttachmentActivity.this, R.style.serviceNoteOperationDialog);deleteConfirmDialog.setAgreeListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if (deleteConfirmDialog != null) {deleteConfirmDialog.dismiss();}doDeleteAttachmentFromServer();}});deleteConfirmDialog.setDeclineListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if (deleteConfirmDialog != null) {deleteConfirmDialog.dismiss();}}});deleteConfirmDialog.show();deleteConfirmDialog.setTvTitle("删除附件");deleteConfirmDialog.setTvContent("确认从服务器删除吗?");} catch (Exception e) {CommonHelper.log(TAG + ":showDeleteFromServerConfirmDialog",e.getMessage());}}// 已上传至服务器的附件,提示是从本地删除还是从服务器删除private void showSelectDeleteTypeDialog() {try {// 进入选择删除类型的对话框Log.i(TAG, "进入了选择删除类型的对话框");View view = getLayoutInflater().inflate(R.layout.upload_file_menu_dialog, null);// 只从本地删除按钮Button nativeDelButton = (Button) view.findViewById(R.id.attachment_dialog_btn_button1);// 本地和服务器都删除按钮Button bothDelButton = (Button) view.findViewById(R.id.attachment_dialog_btn_button2);// 取消按钮Button cancelButton = (Button) view.findViewById(R.id.attachment_dialog_btn_cancel);cancelButton.setOnClickListener(selectDeleteTypeItemClickListener);nativeDelButton.setOnClickListener(selectDeleteTypeItemClickListener);bothDelButton.setOnClickListener(selectDeleteTypeItemClickListener);selectDeleteTypeDialog = new Dialog(this,R.style.transparentFrameWindowStyle);selectDeleteTypeDialog.setContentView(view, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));Window window = selectDeleteTypeDialog.getWindow();// 设置显示动画window.setWindowAnimations(R.style.main_menu_animstyle);WindowManager.LayoutParams wl = window.getAttributes();wl.x = 0;wl.y = getWindowManager().getDefaultDisplay().getHeight();// 以下这两句是为了保证按钮可以水平满屏wl.width = ViewGroup.LayoutParams.MATCH_PARENT;wl.height = ViewGroup.LayoutParams.WRAP_CONTENT;// 设置显示位置selectDeleteTypeDialog.onWindowAttributesChanged(wl);// 设置点击外围解散selectDeleteTypeDialog.setCanceledOnTouchOutside(true);selectDeleteTypeDialog.show();// 根据不同的装填,显示不同的提示nativeDelButton.setText("只从本地删除");bothDelButton.setText("服务器和本地都删除");} catch (Exception e) {CommonHelper.log(TAG + ":showSelectDeleteTypeDialog",e.getMessage());}}// 只从本地删除private void doDeleteAttachmentOnlyFromNative() {try {AttachmentInfo info = attachmentInfoList.get(longClickPosition);File tempFile = new File(info.fileNativePath);if (tempFile != null && tempFile.exists()) {// 存在,则从本地删除if (tempFile.delete()) {// 如果删除成功,则将状态设置成未下载info.state = AttachmentInfo.NOT_DOWNLOAD;attachmentAdapter.notifyDataSetChanged();fileInfoListView.invalidate();} else {Toast.makeText(this, "本地文件删除失败", Toast.LENGTH_SHORT).show();}}} catch (Exception e) {CommonHelper.log(TAG + ":doDeleteOnlayFromNative", e.getMessage());}}private View.OnClickListener selectDeleteTypeItemClickListener = new OnClickListener() {@Overridepublic void onClick(View v) {if (selectDeleteTypeDialog != null) {selectDeleteTypeDialog.dismiss();selectDeleteTypeDialog = null;}int id = v.getId();if (id == R.id.attachment_dialog_btn_button1) {// 只从本地删除doDeleteAttachmentOnlyFromNative();} else if (id == R.id.attachment_dialog_btn_button2) {// 从服务器和本地都删除showDeleteFromServerConfirmDialog();} else if (id == R.id.attachment_dialog_btn_cancel) {// 取消}}};// 删除长按的条目public void deleteLongClickItem() {try {if (longClickPosition >= 0) {if (attachmentInfoList.size() - 1 >= longClickPosition) {// 根据任务单的状态,提示是只从本地删除还是从服务器删除// 从文件夹下移除,从列表中移除AttachmentInfo info = attachmentInfoList.get(longClickPosition);int state = info.state;if (state == AttachmentInfo.NOT_DOWNLOAD) {// 未下载,提示是否从服务器删除showDeleteFromServerConfirmDialog();} else if (state == AttachmentInfo.ALREADY_SAVE|| state == AttachmentInfo.DOWN_LOADING_SUCCESS) {// 已保存至服务器或者下载完成状态,提示是从本地删除还是从服务器删除showSelectDeleteTypeDialog();} else {// 其他状态,直接删除本地,如果本地有File tempFile = new File(info.fileNativePath);if (tempFile.exists()) {tempFile.delete();}attachmentInfoList.remove(longClickPosition);attachmentAdapter.notifyDataSetChanged();fileInfoListView.invalidate();}}}} catch (Exception e) {CommonHelper.log(TAG + ":deleteLongClickItem", e.getMessage());}}private OnClickListener onClickListener = new OnClickListener() {@Overridepublic void onClick(View v) {if (v == goBackButton) {doGoBack();} else if (v == selectFileButton) {// 发送一个要上传图片的消息if (selectImageDialog != null) {if (!selectImageDialog.isShowing()) {showSelectImageDialog();}} else {showSelectImageDialog();}}}};private void showSelectImageDialog() {try {View view = getLayoutInflater().inflate(R.layout.upload_file_menu_dialog, null);// 图库Button selectImageButton = (Button) view.findViewById(R.id.attachment_dialog_btn_button1);// 相机Button cameraButton = (Button) view.findViewById(R.id.attachment_dialog_btn_button2);// 取消按钮Button cancelButton = (Button) view.findViewById(R.id.attachment_dialog_btn_cancel);cancelButton.setOnClickListener(selectPhotoListener);selectImageButton.setOnClickListener(selectPhotoListener);cameraButton.setOnClickListener(selectPhotoListener);selectImageDialog = new Dialog(this,R.style.transparentFrameWindowStyle);selectImageDialog.setContentView(view, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));Window window = selectImageDialog.getWindow();// 设置显示动画window.setWindowAnimations(R.style.main_menu_animstyle);WindowManager.LayoutParams wl = window.getAttributes();wl.x = 0;wl.y = getWindowManager().getDefaultDisplay().getHeight();// 以下这两句是为了保证按钮可以水平满屏wl.width = ViewGroup.LayoutParams.MATCH_PARENT;wl.height = ViewGroup.LayoutParams.WRAP_CONTENT;// 设置显示位置selectImageDialog.onWindowAttributesChanged(wl);// 设置点击外围解散selectImageDialog.setCanceledOnTouchOutside(true);selectImageDialog.show();selectImageButton.setText("图库");cameraButton.setText("相机");} catch (Exception e) {CommonHelper.log(TAG + ":showMenuDialog", e.getMessage());}}private View.OnClickListener selectPhotoListener = new OnClickListener() {@Overridepublic void onClick(View v) {if (selectImageDialog != null) {selectImageDialog.dismiss();selectImageDialog = null;}int id = v.getId();if (id == R.id.attachment_dialog_btn_button1) {// 相册Intent i = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);startActivityForResult(i, Constant.SELECT_PHOTO_CODE);} else if (id == R.id.attachment_dialog_btn_button2) {// 直接保存到相册Intent intentCamera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);ContentValues values = new ContentValues();photoUri = AttachmentActivity.this.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);intentCamera.putExtra(android.provider.MediaStore.EXTRA_OUTPUT,photoUri);startActivityForResult(intentCamera, Constant.CHECK_PHOTO_CODE);}}};// 开始上传public void doUpLoadFile(AttachmentInfo info) {try {currentUpLoadPhotoInfo = info;String fileKey = "file";UploadUtil uploadUtil = UploadUtil.getInstance();uploadUtil.setCancelFlag(false);uploadUtil.setOnUploadProcessListener(this); // 设置监听器监听上传状态uploadUtil.uploadFile(info.fileNativePath, fileKey,Constant.UPLOAD_PHOTO);currentUpLoadPhotoInfo.state = AttachmentInfo.UP_LOADING;attachmentAdapter.notifyDataSetChanged();fileInfoListView.invalidate();} catch (Exception e) {CommonHelper.log(TAG + ":doUpLoad", e.getMessage());}}public void doGoBack() {try {// 判断是否有正在下载或上传的任务if (isDownLoading || isUpLoading) {// 提示当前正在有任务正在下载或上传,退出将取消正在进行的任务final ConfirmDialog backConfirmDialog = new ConfirmDialog(AttachmentActivity.this,R.style.serviceNoteOperationDialog);// 确认新建backConfirmDialog.setAgreeListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {UploadUtil.getInstance().setCancelFlag(true);DownLoadUtil.getInstance().setCancelFlag(true);AttachmentActivity.this.finish();overridePendingTransition(R.anim.no_anim,R.anim.slide_out_right);if (backConfirmDialog != null) {backConfirmDialog.dismiss();}}});// 不新建backConfirmDialog.setDeclineListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if (backConfirmDialog != null) {backConfirmDialog.dismiss();}}});backConfirmDialog.show();backConfirmDialog.setTvTitle("退出确认");backConfirmDialog.setTvContent("当前有任务进行,确认退出吗?");} else {AttachmentActivity.this.finish();overridePendingTransition(R.anim.no_anim,R.anim.slide_out_right);}} catch (Exception e) {CommonHelper.log(TAG + ":goBack", e.getMessage());}}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {switch (requestCode) {case Constant.SELECT_PHOTO_CODE:selectToAddPhoto(resultCode, data);break;case Constant.CHECK_PHOTO_CODE:addAttachementByTakePhoto(resultCode, data);break;case REQUEST_CODE_JOBREPORT:if (resultCode == RESULT_OK) {this.finish();}break;default:break;}Log.i(TAG, "onActivityResult执行完,当期list大小是:" + attachmentInfoList.size());super.onActivityResult(requestCode, resultCode, data);}// 通过拍照的方式添加附件(图片)private void addAttachementByTakePhoto(int resultCode, Intent data) {if (resultCode == RESULT_OK) {//String[] pojo = { MediaStore.Images.Media.DATA };Cursor cursor = managedQuery(photoUri, pojo, null, null, null);String picPath = null;if (cursor != null) {int columnIndex = cursor.getColumnIndexOrThrow(pojo[0]);cursor.moveToFirst();picPath = cursor.getString(columnIndex);try {// 4.0以上的版本会自动关闭 (4.0--14;; 4.0.3--15)if (Integer.parseInt(Build.VERSION.SDK) < 14) {// 只有4.0以下才需要手动关闭cursor.close();}} catch (Exception e) {CommonHelper.log(TAG + ":addPhoto", e.getMessage());}}Log.i(TAG, "imagePath = " + picPath);if (ImageUtil.isImage(picPath)) {// change image sizetry {Bitmap newFile = CommonHelper.getSmallBitmap(picPath);photoFile = new File(PHOTO_PATH + File.separator+ serviceNoteId, UUID.randomUUID().toString().replace("-", "")+ Constant.ATTACH_TYPE_IMAGE_POSTFIX_JPEG);OutputStream os = new FileOutputStream(photoFile);newFile.compress(CompressFormat.JPEG, 98, os);os.flush();os.close();newFile.recycle();// 将复制到自己目录的图片文件添加到列表selectedNewInfo = new AttachmentInfo(photoFile, 1);} catch (Exception e) {CommonHelper.log(this.getClass().getName(),"addPhoto->zoom:" + e.getMessage());}} else {Toast.makeText(this, "选择图片文件不正确", Toast.LENGTH_LONG).show();}}}// 通过相册选择附件(图片)private void selectToAddPhoto(int arg1, Intent arg2) {if (arg2 != null && arg2.getData() != null) {String imagePath = GetAbsolutePathUtil.getAbsolutePathFromURI(arg2.getData(), this);if (ImageUtil.isImage(imagePath)) {FileUtil util = new FileUtil(getBaseContext());String fileName = UUID.randomUUID().toString().replace("-", "")+ Constant.ATTACH_TYPE_IMAGE_POSTFIX_JPEG;photoFile = new File(PHOTO_PATH + File.separator+ serviceNoteId, fileName);// 复制到自己的缓存目录util.copyFileFromTo(imagePath, PHOTO_PATH + File.separator+ serviceNoteId, fileName);// change image sizetry {// 将图片压缩并保存到photoFileBitmap newFile = CommonHelper.getSmallBitmap(photoFile.getAbsolutePath());OutputStream os = new FileOutputStream(photoFile);newFile.compress(CompressFormat.JPEG, 98, os);os.flush();os.close();newFile.recycle();selectedNewInfo = new AttachmentInfo(photoFile, 1);} catch (Exception e) {CommonHelper.log(this.getClass().getName(),"addPhoto->zoom:" + e.getMessage());}} else {Toast.makeText(AttachmentActivity.this,getResources().getString(R.string.wrong_picture_or_path),Toast.LENGTH_LONG).show();}}}@Overrideprotected void onSaveInstanceState(Bundle outState) {Log.i(TAG, "onSaveInstanceState执行了,当期那listview大小是:"+ attachmentInfoList.size());super.onSaveInstanceState(outState);}@Overrideprotected void onRestoreInstanceState(Bundle savedInstanceState) {Log.i(TAG, "onSaveInstanceState执行了,当期那listview大小是:"+ attachmentInfoList.size());super.onRestoreInstanceState(savedInstanceState);}@Overrideprotected void onResume() {try {if (!isFirstComeIn) {// 不是首次进入,则从sp文件中恢复数据attachmentInfoList.clear();// 和每个任务单的id绑定String json = sp.getString(serviceNoteId + "attachment", null);if (json != null) {attachmentInfoList = GsonUtil.GetGsonObj().fromJson(json,new TypeToken<ArrayList<AttachmentInfo>>() {}.getType());}// 如果是恢复,则每次将listview滚动到底部fileInfoListView.setSelection(attachmentAdapter.getCount() - 1);// 恢复保存的子文件夹目录subPhotoPath = sp.getString("subPhotoPath", "");}if (selectedNewInfo != null) {attachmentInfoList.add(selectedNewInfo);selectedNewInfo = null;}attachmentAdapter = new AttachmentAdapter(this, attachmentInfoList,fileInfoListView, operationListener);fileInfoListView.setAdapter(attachmentAdapter);attachmentAdapter.notifyDataSetChanged();fileInfoListView.invalidate();// 恢复之后将sp中保存的数据清空sp.edit().putString(serviceNoteId + "attachment", "").commit();Log.i(TAG, "onResume执行了,当前list大小:" + attachmentInfoList.size());} catch (Exception e) {CommonHelper.log(TAG + ":onRestoreInstanceState", e.getMessage());}super.onResume();}@Overrideprotected void onPause() {try {// 保存列表数据到sp文件中String jsonStr = GsonUtil.GetGsonObj().toJson(attachmentInfoList,new TypeToken<ArrayList<AttachmentInfo>>() {}.getType());sp.edit().putString(serviceNoteId + "attachment", jsonStr).commit();Log.i(TAG, "onPause执行了,当前list大小:" + attachmentInfoList.size());// 保存子文件夹目录sp.edit().putString("subPhotoPath", subPhotoPath).commit();} catch (Exception e) {CommonHelper.log(TAG + ":onSaveInstanceState", e.getMessage());}super.onPause();}// 上传,取消,下载,取消,删除等操作的监听private OnClickListener operationListener = new OnClickListener() {@Overridepublic void onClick(View v) {int id = v.getId();if (id == R.id.file_list_item_fileName) {// 点击了文件名AttachmentInfo tag = (AttachmentInfo) v.getTag();int state = tag.state;if (state == AttachmentInfo.UP_LOADING|| state == AttachmentInfo.DOWN_LOADING|| state == AttachmentInfo.ALREADY_SAVE|| state == AttachmentInfo.NOT_DOWNLOAD|| state == AttachmentInfo.DOWN_LOADING_SUCCESS|| state == AttachmentInfo.DOWN_LOADING_FAIL|| state == AttachmentInfo.UP_LOADING_FAIL|| state == AttachmentInfo.UP_LOADING_SUCCESS) {// 正在上传,正在下载,已和服务器同步状态,未下载,不允许重命名return;}showChangeFileNameDialog(tag);} else if ((id == R.id.file_list_item_upordownLoad)|| (id == R.id.file_list_item_operationFrameLayout)) {// 点击了操作图标,或者整个操作布局// 获取绑定的对象AttachmentInfo tag = (AttachmentInfo) v.getTag();// 上传相关只有未上传和上传失败才显示操作按钮int state = tag.state;switch (state) {// 按钮主要出发积极操作case AttachmentInfo.NOT_UPLOAD:// 未上传,点击表示准备上传,加入上传队列tag.state = AttachmentInfo.PREPARE_UPLOAD;// 发送一个上传文件的消息handler.sendEmptyMessage(TO_UPLOAD_FILE);break;case AttachmentInfo.UP_LOADING_FAIL:// 上传失败,点击表示重新上传tag.state = AttachmentInfo.PREPARE_UPLOAD;handler.sendEmptyMessage(TO_UPLOAD_FILE);break;case AttachmentInfo.NOT_DOWNLOAD:// 未下载tag.state = AttachmentInfo.PREPARE_DOWNLOAD;handler.sendEmptyMessage(TO_DOWNLOAD_FILE);break;case AttachmentInfo.DOWN_LOADING_FAIL:// 下载失败tag.state = AttachmentInfo.PREPARE_DOWNLOAD;handler.sendEmptyMessage(TO_DOWNLOAD_FILE);break;default:break;}}attachmentAdapter.notifyDataSetChanged();fileInfoListView.invalidate();}};// 显示给图片重命名的对话框public void showChangeFileNameDialog(final AttachmentInfo attachmentInfo) {try {if (changeFileNameDialog == null) {changeFileNameDialog = new InputAndConfirmDialog(this,R.style.serviceNoteOperationDialog);changeFileNameDialog.setAgreeListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {String inputText = changeFileNameDialog.getInputText();doChangeFileName(attachmentInfo, inputText);if (changeFileNameDialog != null) {changeFileNameDialog.dismiss();changeFileNameDialog = null;}}});changeFileNameDialog.setDeclineListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if (changeFileNameDialog != null) {changeFileNameDialog.dismiss();changeFileNameDialog = null;}}});changeFileNameDialog.show();changeFileNameDialog.setOriginalInputText(attachmentInfo.fileName);changeFileNameDialog.setInputPrompt("请输入新文件名");changeFileNameDialog.setTitle("文件重命名");}changeFileNameDialog.show();} catch (Exception e) {CommonHelper.log(TAG + ":clickAddCommnets", e.getMessage());}}// 重命名后保存操作的对话框private void doChangeFileName(AttachmentInfo info, String newName) {try {File oldFile = new File(info.fileNativePath);if (oldFile.exists()) {File newFile = new File(PHOTO_PATH + File.separator+ serviceNoteId + File.separator + newName);if (oldFile.renameTo(newFile)) {// 重命名成功的话oldFile.delete();info.fileName = newName;info.fileNativePath = newFile.getAbsolutePath();attachmentAdapter.notifyDataSetChanged();fileInfoListView.invalidate();// 这里应该发一个重命名的请求} else {Toast.makeText(this, "重命名失败", Toast.LENGTH_SHORT).show();}}} catch (Exception e) {CommonHelper.log(TAG + ":addPhotoDesc", e.getMessage());}}private ArrayList<ServiceNoteAttachmentInfo> getAttachmentInfos() {ArrayList<ServiceNoteAttachmentInfo> attachments = new ArrayList<ServiceNoteAttachmentInfo>();for (AttachmentInfo info : attachmentInfoList) {// 如果状态为已完成,则添加到保存列表if (AttachmentInfo.UP_LOADING_SUCCESS == info.state) {ServiceNoteAttachmentInfo snatInfo = new ServiceNoteAttachmentInfo();snatInfo.fileName = info.fileName;snatInfo.path = info.path;// 只有保存的时候用到的是path,其他是本地地址// 描述赞为空snatInfo.description = "";attachments.add(snatInfo);}}return attachments;}// 保存所有已上传完成附件的操作private void doSaveAllUploadAttachments() {try {if (confirmDialog != null) {confirmDialog.dismiss();}ServiceNoteAttachmentsBindingModel model = new ServiceNoteAttachmentsBindingModel();model.serviceNoteId = this.serviceNoteId;model.attachments = getAttachmentInfos();// urlString url = Constant.SAVE_ATTACHMENTLIST;// 请求对象Object requestObject = model;// 请求对象类型Type requestObjectType = ServiceNoteAttachmentsBindingModel.class;// 返回对象类型Type responseObjectType = OperationListItemViewModel.class;ServiceNoteOperationTask serviceNoteOperationTask = new ServiceNoteOperationTask();serviceNoteOperationTask.setContext(this);serviceNoteOperationTask.setOnServiceNoteOperationFinishedListener(saveAttamentsFinishedListener);serviceNoteOperationTask.showWaitingDialog(this, new Handler(),"正在保存上传附件", null);serviceNoteOperationTask.execute(new Object[] { url, requestObject,requestObjectType, responseObjectType });} catch (Exception e) {CommonHelper.log(TAG + "doSaveAlluploadAttachemnts", e.getMessage());}}private OnServiceNoteOperationFinishedListener saveAttamentsFinishedListener = new OnServiceNoteOperationFinishedListener() {@Overridepublic void resultCallBack(Object object) {if (ResponseObjectUtil.ResponseObjectIsNullOrException(AttachmentActivity.this, object)) {if (confirmDialog != null) {// 保存失败,则重试confirmDialog.show();}return;}// 保存成功后刷新整个列表getAttachmentListFromServer();}};// 不保存上传成功的所有附件public void doNoteSaveAllUploadAttachments() {try {if (confirmDialog != null) {confirmDialog.dismiss();}ServiceNoteAttachmentsBindingModel model = new ServiceNoteAttachmentsBindingModel();model.serviceNoteId = this.serviceNoteId;model.attachments = getAttachmentInfos();// urlString url = Constant.CANCEL_ATTACHMENT_LIST;// 请求对象Object requestObject = model;// 请求对象类型Type requestObjectType = ServiceNoteAttachmentsBindingModel.class;// 返回对象类型Type responseObjectType = null;ServiceNoteOperationTask serviceNoteOperationTask = new ServiceNoteOperationTask();serviceNoteOperationTask.setContext(this);serviceNoteOperationTask.setOnServiceNoteOperationFinishedListener(null);serviceNoteOperationTask.execute(new Object[] { url, requestObject,requestObjectType, responseObjectType });// 执行之后直接将取消保存的设置成未上传状态,不管返回状态setStateToNotUpload(model.attachments);} catch (Exception e) {CommonHelper.log(TAG + ":doNotSaveAllUploadAttachments",e.getMessage());}}// 将传入列表中的所有状态设置成未上传public void setStateToNotUpload(ArrayList<ServiceNoteAttachmentInfo> satList) {try {// 比较当前集合和取消保存上传结果的集合for (ServiceNoteAttachmentInfo serviceNoteAttachmentInfo : satList) {for (AttachmentInfo attachmentInfo : attachmentInfoList) {// 通过name进行比较String fileName = serviceNoteAttachmentInfo.fileName;if (fileName != null&& fileName.equals(attachmentInfo.fileName)) {attachmentInfo.state = AttachmentInfo.NOT_UPLOAD;}}}// 执行完后刷新视图attachmentAdapter.notifyDataSetChanged();fileInfoListView.invalidate();} catch (Exception e) {CommonHelper.log(TAG + ":setStateToNotUpload", e.getMessage());}}// 准备上传图片public void prepareUploadFile(Message msg) {// 标志是否所有准备上传的都上传完成boolean isAllUpload = true;for (AttachmentInfo photoInfo : attachmentInfoList) {if (photoInfo.state == AttachmentInfo.PREPARE_UPLOAD&& !TextUtils.isEmpty(photoInfo.fileName)) {// 有准备上传状态的,表示不是所有准备上传的都上传完成了isAllUpload = false;// 未上传并且路径不为空,则上传if (!isUpLoading) {isUpLoading = true;doUpLoadFile(photoInfo);break;}}}if (isAllUpload) {// 所有都上传完成,则提示是否进行保存附件操作,for (int i = 0; i < attachmentInfoList.size(); i++) {AttachmentInfo tempInfo = attachmentInfoList.get(i);// 只要有一个是上传完成的状态的if (AttachmentInfo.UP_LOADING_SUCCESS == tempInfo.state) {// 遍历附件列表,如果有显示上传完成的,则提示保存附件confirmDialog = new ConfirmDialog(AttachmentActivity.this,R.style.serviceNoteOperationDialog);// 确认保存confirmDialog.setAgreeListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {doSaveAllUploadAttachments();}});// 不保存confirmDialog.setDeclineListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {if (confirmDialog != null) {confirmDialog.dismiss();confirmDialog = null;doNoteSaveAllUploadAttachments();}}});confirmDialog.show();confirmDialog.setTvTitle("保存上传附件");confirmDialog.setTvContent("确认要保存上传的附件吗?");// 这里要break;否则弹出多个确认对话框break;}}}}// 上传图片完成的操作private void doUploadFileDone(Message msg) {try {// arg1带回的返回码,obj带回的String类型的消息int responseCode = msg.arg1;String resultMessage = (String) msg.obj;// 是否有文件正在上传标志置为否isUpLoading = false;if (responseCode == UploadUtil.UPLOAD_SUCCESS_CODE) {// 上传成功currentUpLoadPhotoInfo.state = AttachmentInfo.UP_LOADING_SUCCESS;// 这里保存文件在服务器的地址currentUpLoadPhotoInfo.path = resultMessage;} else if (responseCode == UploadUtil.UPLOAD_SERVER_ERROR_CODE) {// 上传失败Toast.makeText(AttachmentActivity.this, resultMessage,Toast.LENGTH_SHORT).show();currentUpLoadPhotoInfo.state = AttachmentInfo.UP_LOADING_FAIL;} else if (responseCode == UploadUtil.UPLOAD_FILE_NOT_EXISTS_CODE) {currentUpLoadPhotoInfo.state = AttachmentInfo.UP_LOADING_FAIL;Toast.makeText(AttachmentActivity.this, resultMessage,Toast.LENGTH_SHORT).show();}// 有一张图片上传完成,则发送一个继续上传的消息currentUploadFileTotalSize = 0;handler.sendEmptyMessage(TO_UPLOAD_FILE);attachmentAdapter.notifyDataSetChanged();fileInfoListView.invalidate();} catch (Exception e) {CommonHelper.log(TAG + ":doUploadFileDone", e.getMessage());}}// 消息处理器private Handler handler = new Handler() {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {// 处理上传相关消息case TO_UPLOAD_FILE:prepareUploadFile(msg);break;case UPLOAD_IN_PROCESS:currentUpLoadPhotoInfo.state = AttachmentInfo.UP_LOADING;// msg.arg1带回的是上传的进度currentUpLoadPhotoInfo.progress = msg.arg1;attachmentAdapter.notifyDataSetChanged();fileInfoListView.invalidate();break;case UPLOAD_FILE_DONE:doUploadFileDone(msg);break;// 处理下载相关消息case TO_DOWNLOAD_FILE:toDownLoadFile(msg);break;case DOWNLOAD_IN_PROCESS:currentDownLoadFileInfo.state = AttachmentInfo.DOWN_LOADING;currentDownLoadFileInfo.progress = msg.arg1;attachmentAdapter.notifyDataSetChanged();fileInfoListView.invalidate();break;case DOWNLOAD_FILE_DONE:doDownLoadFileDone(msg);break;default:break;}super.handleMessage(msg);}};// 下载相关消息的处理函数在下方:private void doDownLoadFileDone(Message msg) {try {// arg1带回的返回码,obj带回的String类型的消息int responseCode = msg.arg1;String resultMessage = (String) msg.obj;// 是否有文件正在上传标志置为否isDownLoading = false;if (responseCode == DownLoadUtil.DOWNLOAD_SUCCESS_CODE) {// 下载成功currentDownLoadFileInfo.state = AttachmentInfo.DOWN_LOADING_SUCCESS;// 将下载文件的路径改成本地路径currentDownLoadFileInfo.fileNativePath = subPhotoPath+ File.separator + currentDownLoadFileInfo.fileName;} else if (responseCode == DownLoadUtil.DOWNLOAD_SERVER_ERROR_CODE) {// 下载失败Toast.makeText(AttachmentActivity.this, resultMessage,Toast.LENGTH_SHORT).show();currentDownLoadFileInfo.state = AttachmentInfo.DOWN_LOADING_FAIL;} else if (responseCode == DownLoadUtil.DOWNLOAD_USER_CANCEL_CODE) {// 用户取消下载currentDownLoadFileInfo.state = AttachmentInfo.NOT_DOWNLOAD;Toast.makeText(AttachmentActivity.this, resultMessage,Toast.LENGTH_SHORT).show();}// 有一张图片下载完成,则发送一个继续下载下一张准备下载状态的消息currentDownLoadFileTotalSize = 0;handler.sendEmptyMessage(TO_DOWNLOAD_FILE);attachmentAdapter.notifyDataSetChanged();fileInfoListView.invalidate();} catch (Exception e) {CommonHelper.log(TAG + ":doDownLoadFileDone", e.getMessage());}}private void toDownLoadFile(Message msg) {try {// 标志是否所有准备下载的都下载完成boolean isAlldownload = true;// 遍历列表for (AttachmentInfo fileInfo : attachmentInfoList) {if (fileInfo.state == AttachmentInfo.PREPARE_DOWNLOAD&& !TextUtils.isEmpty(fileInfo.fileName)) {// 有准备下载状态的,表示不是所有准备下载的都下载完成了isAlldownload = false;// 未上传并且路径不为空,则上传if (!isDownLoading) {isDownLoading = true;doDownLoadFile(fileInfo);break;}}}if (isAlldownload) {}} catch (Exception e) {CommonHelper.log(TAG + ":doDownLoadFile", e.getMessage());}}// 进行下载操作private void doDownLoadFile(AttachmentInfo fileInfo) {try {currentDownLoadFileInfo = fileInfo;DownLoadUtil downLoadUtil = DownLoadUtil.getInstance();downLoadUtil.setCancelFlag(false);downLoadUtil.setOnDownLoadProcessListener(this);String fileUrl = Constant.UPDATE_URL + fileInfo.path;downLoadUtil.downLoadFile(fileUrl, subPhotoPath, fileInfo.fileName);currentDownLoadFileInfo.state = AttachmentInfo.DOWN_LOADING;attachmentAdapter.notifyDataSetChanged();fileInfoListView.invalidate();} catch (Exception e) {CommonHelper.log(TAG + ":doDownLoadFile", e.getMessage());}}@Overridepublic void onUploadDone(int responseCode, String message) {Message msg = Message.obtain();msg.what = UPLOAD_FILE_DONE;msg.arg1 = responseCode;msg.obj = message;handler.sendMessage(msg);}@Overridepublic void onUploadProcess(int uploadSize) {Message msg = Message.obtain();msg.what = UPLOAD_IN_PROCESS;// 获取当前上传文件的总大小,计算出上传百分比if (currentUploadFileTotalSize != 0) {Log.i(TAG, "已上传了:" + uploadSize + "总大小是:"+ currentUploadFileTotalSize);int upLoadPercent = (int) (uploadSize * 100 / currentUploadFileTotalSize);Log.i(TAG, "进度更新为:" + upLoadPercent);msg.arg1 = upLoadPercent;handler.sendMessage(msg);}}@Overridepublic void initUpload(int fileSize) {currentUploadFileTotalSize = fileSize;}@Overridepublic void onDownLoadDone(int responseCode, String message) {Message msg = Message.obtain();msg.what = DOWNLOAD_FILE_DONE;msg.arg1 = responseCode;msg.obj = message;handler.sendMessage(msg);}@Overridepublic void onDownLoadProcess(int downLoadSize) {Message msg = Message.obtain();msg.what = DOWNLOAD_IN_PROCESS;// 获取当前上传文件的总大小,计算出上传百分比if (currentDownLoadFileTotalSize != 0) {Log.i(TAG, "已下载了:" + downLoadSize + "总大小是:"+ currentDownLoadFileTotalSize);int downLoadPercent = (int) (downLoadSize * 100 / currentDownLoadFileTotalSize);Log.i(TAG, "进度更新为:" + downLoadPercent);msg.arg1 = downLoadPercent;handler.sendMessage(msg);}}@Overridepublic void initDownload(int fileSize) {currentDownLoadFileTotalSize = fileSize;}}


DownLoadUtil:
package com.flagcloud.android.mqservice.biz.attachment;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.OutputStream;import java.net.HttpURLConnection;import java.net.URL;import android.util.Log;import com.flagcloud.android.mqservice.common.Constant;import com.flagcloud.android.mqservice.util.CommonHelper;public class DownLoadUtil {private static DownLoadUtil downLoadUtil;private static final String TAG = "DownLoadUtil";private OnDownLoadProcessListener ondownLoadProcessListener;private static boolean isCancel = false; // 是否停止下载的标志private static final String CHARSET = "utf-8"; // 设置编码public static final int DOWNLOAD_SUCCESS_CODE = 1;// 下载成功public static final int DOWNLOAD_SERVER_ERROR_CODE = 2;// 服务器出错public static final int DOWNLOAD_USER_CANCEL_CODE = 3;// 用户取消下载public static DownLoadUtil getInstance() {if (null == downLoadUtil) {downLoadUtil = new DownLoadUtil();}return downLoadUtil;}public void setCancelFlag(boolean c) {isCancel = c;}// 设置回调监听public void setOnDownLoadProcessListener(OnDownLoadProcessListener ondownLoadProcessListener) {this.ondownLoadProcessListener = ondownLoadProcessListener;}/** * 开启线程执行下载操作 *  * @param fileUrl * @param destPath * @param fileName */public void downLoadFile(final String fileUrl, final String destPath,final String fileName) {// 关键是这里怎么进行处理new Thread(new Runnable() { // 开启线程上传文件@Overridepublic void run() {toDownLoadFile(fileUrl, destPath, fileName);}}).start();}/** *  * @param url *            请求的url * @param desPath *            文件存放的地址 * @param fileName *            存放的文件名 */private void toDownLoadFile(String fileUrl, String destPath, String fileName) {try {Log.i(TAG, "doInBackground执行了...");String urlString = fileUrl;InputStream inputstream = null;OutputStream outputstream = null;HttpURLConnection urlConn = null;URL url;File resultFile = null;try {url = new URL(urlString);urlConn = (HttpURLConnection) url.openConnection();urlConn.setConnectTimeout(Constant.NETWORK_CONNECT_TIMEOUT);urlConn.setReadTimeout(Constant.NETWORK_TIMEOUT);int resCode = urlConn.getResponseCode();if (resCode == 200) {int totalLength = urlConn.getContentLength();ondownLoadProcessListener.initDownload(totalLength);inputstream = urlConn.getInputStream();// 重名的逻辑怎么处理resultFile = new File(destPath + File.separator + fileName);outputstream = new FileOutputStream(resultFile);byte[] buffer = new byte[1024];int len = 0;int progress = 0;while ((len = inputstream.read(buffer)) != -1) {if (!isCancel) {outputstream.write(buffer, 0, len);progress += len;// 回调更新进度ondownLoadProcessListener.onDownLoadProcess(progress);} else {return;}}outputstream.flush();sendMessage(DOWNLOAD_SUCCESS_CODE, "下载成功");return;} else {// 返回码不是200Log.i(TAG, "request error");sendMessage(DOWNLOAD_SERVER_ERROR_CODE, "下载失败:code="+ resCode);return;}} catch (IOException e) {Log.i(TAG + ":doInBackground", e.getMessage());sendMessage(DOWNLOAD_SERVER_ERROR_CODE,"下载失败:error=IOException,message=" + e.getMessage());} finally {try {if (outputstream != null) {outputstream.close();}if (inputstream != null) {inputstream.close();}if (urlConn != null) {urlConn.disconnect();}} catch (IOException e) {e.printStackTrace();}}} catch (Exception e) {CommonHelper.log(TAG + ":downLoadFile", e.getMessage());sendMessage(DOWNLOAD_SERVER_ERROR_CODE,"下载失败:error=" + e.getMessage());}}/** * 发送上传结果 *  * @param responseCode * @param responseMessage */private void sendMessage(int responseCode, String responseMessage) {ondownLoadProcessListener.onDownLoadDone(responseCode, responseMessage);}public static interface OnDownLoadProcessListener {/** * 下载响应 *  * @param responseCode * @param message */void onDownLoadDone(int responseCode, String message);/** * 上传中 *  * @param uploadSize */void onDownLoadProcess(int uploadSize);/** * 准备上传 *  * @param fileSize */void initDownload(int fileSize);}}

UploadUtil:
package com.flagcloud.android.mqservice.biz.attachment;import java.io.BufferedReader;import java.io.DataOutputStream;import java.io.File;import java.io.FileInputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.net.HttpURLConnection;import java.net.MalformedURLException;import java.net.URL;import java.util.Iterator;import java.util.Map;import java.util.UUID;import java.util.zip.GZIPInputStream;import com.flagcloud.android.mqservice.common.MQServiceHttpURLConnection;import android.text.TextUtils;import android.util.Log;/** *  * 上传工具类 */public class UploadUtil {private static UploadUtil uploadUtil;private static final String BOUNDARY = UUID.randomUUID().toString(); // 边界标识,随机生成private static final String PREFIX = "--";private static final String LINE_END = "\r\n";private static final String CONTENT_TYPE = "multipart/form-data"; // 内容类型private static boolean isCancel = false;public void setCancelFlag(boolean c) {isCancel = c;}private UploadUtil() {}/** * 单例模式获取上传工具类 *  * @return */public static UploadUtil getInstance() {if (null == uploadUtil) {uploadUtil = new UploadUtil();}return uploadUtil;}private static final String TAG = "UploadUtil";private int readTimeOut = 10 * 1000; // 读取超时private int connectTimeout = 10 * 1000; // 超时时间/*** * 请求使用多长时间 */private static int requestTime = 0;private static final String CHARSET = "utf-8"; // 设置编码/*** * 上传成功 */public static final int UPLOAD_SUCCESS_CODE = 1;/** * 文件不存在 */public static final int UPLOAD_FILE_NOT_EXISTS_CODE = 2;/** * 服务器出错 */public static final int UPLOAD_SERVER_ERROR_CODE = 3;public static final int UPLOAD_HEADER_ERROR_CODE = 4;protected static final int WHAT_TO_UPLOAD = 1;protected static final int WHAT_UPLOAD_DONE = 2;/** * android上传文件到服务器 *  * @param filePath *            需要上传的文件的路径 * @param fileKey *            在网页上<input type=file name=xxx/> xxx就是这里的fileKey * @param RequestURL *            请求的URL */public void uploadFile(String filePath, String fileKey, String RequestURL) {if (filePath == null) {sendMessage(UPLOAD_FILE_NOT_EXISTS_CODE, "文件不存在");return;}try {File file = new File(filePath);uploadFile(file, fileKey, RequestURL);} catch (Exception e) {sendMessage(UPLOAD_FILE_NOT_EXISTS_CODE, "文件不存在");e.printStackTrace();return;}}/** * android上传文件到服务器 *  * @param file *            需要上传的文件 * @param fileKey *            在网页上<input type=file name=xxx/> xxx就是这里的fileKey * @param RequestURL *            请求的URL */public void uploadFile(final File file, final String fileKey,final String RequestURL) {if (file == null || (!file.exists())) {sendMessage(UPLOAD_FILE_NOT_EXISTS_CODE, "文件不存在");return;}Log.i(TAG, "请求的fileName=" + file.getName());Log.i(TAG, "请求的fileKey=" + fileKey);// 关键是这里怎么进行处理new Thread(new Runnable() { // 开启线程上传文件@Overridepublic void run() {toUploadFile(file, fileKey, RequestURL);}}).start();}private void toUploadFile(File file, String fileKey, String RequestURL) {String result = null;requestTime = 0;HttpURLConnection conn = null;DataOutputStream dos = null;InputStreamReader inputStreamReader = null;try {URL url = new URL(RequestURL);conn = (HttpURLConnection) url.openConnection();int beforeLength = 0;int endLength = 0;int totalLength = 0;StringBuffer beforeBuffer = null;beforeBuffer = new StringBuffer();beforeBuffer.append(PREFIX).append(BOUNDARY).append(LINE_END);beforeBuffer.append("Content-Disposition:form-data; name=\""+ fileKey + "\"; filename=\"" + file.getName() + "\""+ LINE_END);beforeBuffer.append(LINE_END);beforeLength = beforeBuffer.length();byte[] end_data = (LINE_END + PREFIX + BOUNDARY + PREFIX + LINE_END).getBytes();endLength = end_data.length;totalLength = (int) (beforeLength + file.length() + endLength);
<span style="white-space:pre"></span><span style="color:#ff0000;">//在开始上传之前一定要知道总的长度,才能获取上传进度</span>conn.setFixedLengthStreamingMode(totalLength);conn.setReadTimeout(readTimeOut);conn.setConnectTimeout(connectTimeout);onUploadProcessListener.initUpload(totalLength);// 初始化总长度// 设置基本头部try {MQServiceHttpURLConnection.SetBasicHeader(conn);} catch (Exception e) {sendMessage(UPLOAD_HEADER_ERROR_CODE, "上传结果:" + e.getMessage());}conn.setDoInput(true); // 允许输入流conn.setDoOutput(true); // 允许输出流conn.setUseCaches(false); // 不允许使用缓存conn.setRequestMethod("POST"); // 请求方式conn.setRequestProperty("Charset", CHARSET); // 设置编码conn.setRequestProperty("connection", "keep-alive");conn.setRequestProperty("Content-Type", CONTENT_TYPE + ";boundary="+ BOUNDARY);dos = new DataOutputStream(conn.getOutputStream());// 写内容开始int curLen = 0; // 当前已经传送的总长度dos.write(beforeBuffer.toString().getBytes());curLen += beforeLength;onUploadProcessListener.onUploadProcess(beforeLength);/** 上传文件 */InputStream inputstream = new FileInputStream(file);int len = 0;byte[] bytes = new byte[1024];while ((len = inputstream.read(bytes)) != -1) {if (!isCancel) {// 如果没有退出curLen += len;dos.write(bytes, 0, len);onUploadProcessListener.onUploadProcess(curLen);} else {return;}}inputstream.close();dos.write(end_data);dos.flush();/** * 获取响应码 200=成功 当响应成功,获取响应的流 */int res = conn.getResponseCode();Log.e(TAG, "response code:" + res);if (res == 200) {// 成功会返回文件在服务器的地址String serverPath = null;InputStream is = null;is = conn.getInputStream();String conEncoding = conn.getContentEncoding();if (!TextUtils.isEmpty(conEncoding)) {Log.i(TAG, "contentype是:" + conEncoding);if (conEncoding.contains("gzip")) {Log.i(TAG, "创建gzip流");is = new GZIPInputStream(is);}} else {Log.i(TAG, "contentType为空");}inputStreamReader = new InputStreamReader(is);BufferedReader bufferReader = new BufferedReader(inputStreamReader);StringBuffer outputBuffer = new StringBuffer();String line = null;while ((line = bufferReader.readLine()) != null) {outputBuffer.append(line);}// 读取返回地址完成后更新进度为100%onUploadProcessListener.onUploadProcess(totalLength);// 去掉收尾的引号serverPath = outputBuffer.toString().substring(1,outputBuffer.length() - 1);sendMessage(UPLOAD_SUCCESS_CODE, serverPath);return;} else {sendMessage(UPLOAD_SERVER_ERROR_CODE, "上传失败:code=" + res);return;}} catch (MalformedURLException e) {sendMessage(UPLOAD_SERVER_ERROR_CODE,"上传失败:error=MalformedURLException,message="+ e.getMessage());e.printStackTrace();return;} catch (IOException e) {sendMessage(UPLOAD_SERVER_ERROR_CODE,"上传失败:error=IOException,message=" + e.getMessage());e.printStackTrace();return;} finally {try {if (dos != null) {dos.close();dos = null;}if (inputStreamReader != null) {inputStreamReader.close();inputStreamReader = null;}if (conn != null) {conn.disconnect();conn = null;}} catch (Exception e2) {}}}/** * 发送上传结果 *  * @param responseCode * @param responseMessage */private void sendMessage(int responseCode, String responseMessage) {onUploadProcessListener.onUploadDone(responseCode, responseMessage);}/** * 下面是一个自定义的回调函数,用到回调上传文件是否完成 *  * @author shimingzheng *  */public static interface OnUploadProcessListener {/** * 上传响应 *  * @param responseCode * @param message */void onUploadDone(int responseCode, String message);/** * 上传中 *  * @param uploadSize */void onUploadProcess(int uploadSize);/** * 准备上传 *  * @param fileSize */void initUpload(int fileSize);}private OnUploadProcessListener onUploadProcessListener;public void setOnUploadProcessListener(OnUploadProcessListener onUploadProcessListener) {this.onUploadProcessListener = onUploadProcessListener;}public int getReadTimeOut() {return readTimeOut;}public void setReadTimeOut(int readTimeOut) {this.readTimeOut = readTimeOut;}public int getConnectTimeout() {return connectTimeout;}public void setConnectTimeout(int connectTimeout) {this.connectTimeout = connectTimeout;}/** * 获取上传使用的时间 *  * @return */public static int getRequestTime() {return requestTime;}public static interface uploadProcessListener {}}


FileIconHelper:这个类就是讲后缀名和显示的缩略图做映射
package com.flagcloud.android.mqservice.biz.attachment;import java.util.HashMap;import com.flagcloud.android.mqservice.R;public class FileIconHelper {private static final String TAG = "FileIconHelper";private static HashMap<String, Integer> fileExtToIcons = new HashMap<String, Integer>();static {addItem(new String[] { "mp3" }, R.drawable.mp3);addItem(new String[] { "wma" }, R.drawable.wma);addItem(new String[] { "wav" }, R.drawable.wav);addItem(new String[] { "mid" }, R.drawable.file_audio);addItem(new String[] { "mp4" }, R.drawable.mp4);addItem(new String[] { "wmv" }, R.drawable.wmv);addItem(new String[] { "mpeg" }, R.drawable.mpeg);addItem(new String[] { "asf" }, R.drawable.asf);addItem(new String[] { "avi" }, R.drawable.avi);addItem(new String[] { "mov" }, R.drawable.mov);addItem(new String[] { "vob" }, R.drawable.vob);addItem(new String[] { "m4v", "3gp", "3gpp", "3g2", "3gpp2" },R.drawable.file_video);addItem(new String[] { "jpg" }, R.drawable.jpg);addItem(new String[] { "gif" }, R.drawable.gif);addItem(new String[] { "png" }, R.drawable.png);addItem(new String[] { "bmp" }, R.drawable.bmp);addItem(new String[] { "ico" }, R.drawable.ico);addItem(new String[] { "jpeg", "wbmp" }, R.drawable.file_image);addItem(new String[] { "txt" }, R.drawable.txt);addItem(new String[] { "xml" }, R.drawable.xml);addItem(new String[] { "log" }, R.drawable.log);addItem(new String[] { "html" }, R.drawable.html);addItem(new String[] { "ini", "lrc" }, R.drawable.file_doc);addItem(new String[] { "doc", "docx" }, R.drawable.doc);addItem(new String[] { "ppt", "pptx" }, R.drawable.ppt);addItem(new String[] { "xsl", "xslx", }, R.drawable.xls);addItem(new String[] { "pdf" }, R.drawable.pdf);addItem(new String[] { "zip" }, R.drawable.zip);addItem(new String[] { "rar" }, R.drawable.rar);addItem(new String[] { "mtz", "7z" }, R.drawable.file_archive);addItem(new String[] { "apk" }, R.drawable.iapk);}private static void addItem(String[] exts, int resId) {if (exts != null) {for (String ext : exts) {fileExtToIcons.put(ext.toLowerCase(), resId);}}}public static int getFileIcon(String ext) {Integer i = fileExtToIcons.get(ext.toLowerCase());if (i != null) {return i.intValue();} else {return R.drawable.default_fileicon;}}}
关键是上传下载帮助类,以及状态的控制,通过回调接口监听上传下载的状态,在回调方法中通过handler发送消息去更新图片的当前状态,更新列表和视图








0 0
原创粉丝点击