Android中带有进度条百分比显示的可以从网络下载文件的适配器

来源:互联网 发布:jsp点击按钮删除数据 编辑:程序博客网 时间:2024/05/16 17:04

http://blog.csdn.net/SunBo_Java/article/details/8234092


该Demo抛弃了ListView控件的使用,是直接使用ViewGroup或其子类进行多个子控件封装,从而达到修正多个附件同时下载时,列表中每个控件的显示错乱的问题(如有更好的方法,欢迎交流)。

该Demo采用单线程下载模式,因为项目的需求,所以一直没改。大家可以直接将单线程改为多线程同步,因为该Demo中所用到的适配器就是根据多线程同步而设计的。

下面我会给出整个Demo的完整范例,但没有程序源码,大家可以直接Copy,因为这是直接从我项目中的抽出来的,还请见谅!

好了,废话不多说,开始:

 

1,先看看适配器的每个Item布局

[html] view plaincopy
  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     style="@style/width_fullscreen"  
  4.     android:padding="7dp"  
  5.     android:background="@drawable/list_selector_bg">  
  6.     <TextView  
  7.         android:id="@+id/AffixName"  
  8.         style="@style/width_fullscreen"  
  9.         android:textSize="17sp"  
  10.         android:textStyle="bold"  
  11.         android:maxLines="2"  
  12.         android:drawablePadding="3.4dp"  
  13.         android:layout_toLeftOf="@+id/AffixDownload" />  
  14.     <TextView  
  15.         android:id="@+id/AffixNotfoundFileErrormsg"  
  16.         style="@style/width_fullscreen"  
  17.         android:text="@string/download_notfoundfile_errormsg"  
  18.         android:textSize="12sp"  
  19.         android:textColor="@color/red"  
  20.         android:layout_marginTop="5dp"  
  21.         android:layout_marginLeft="20dp"  
  22.         android:layout_marginRight="25dp"  
  23.         android:drawableLeft="@drawable/message_status_fail"  
  24.         android:layout_below="@+id/AffixName"  
  25.         android:background="@drawable/popup"  
  26.         android:visibility="gone" />  
  27.     <Button  
  28.         android:id="@+id/AffixDownload"  
  29.         style="@style/width_height_free"  
  30.         android:text="@string/download"  
  31.         android:textColor="@color/DarkSlateGray"  
  32.         android:paddingLeft="10.5dp"  
  33.         android:paddingRight="10.5dp"  
  34.         android:drawableRight="@drawable/icon_download_ics"  
  35.         android:drawablePadding="3dp"  
  36.         android:layout_alignParentRight="true"  
  37.         android:layout_alignTop="@+id/AffixName"  
  38.         android:background="@drawable/button_call_bg" />  
  39.     <RelativeLayout  
  40.         android:id="@+id/AffixDownloadProgressPanel"  
  41.         style="@style/width_fullscreen"  
  42.         android:layout_below="@+id/AffixDownload"  
  43.         android:layout_marginTop="6.5dp"  
  44.         android:visibility="gone">  
  45.         <ProgressBar  
  46.             android:id="@+id/AffixDownloadProgressbar"  
  47.             style="?android:attr/progressBarStyleHorizontal"  
  48.             android:layout_width="match_parent"  
  49.             android:layout_height="13dp"  
  50.             android:progressDrawable="@drawable/progressbar_background" />  
  51.         <TextView  
  52.             android:id="@+id/AffixDownloadProgressValue"  
  53.             style="@style/width_height_free"  
  54.             android:textSize="11sp"  
  55.             android:textColor="@color/ghostwhite"  
  56.             android:layout_centerHorizontal="true" />  
  57.     </RelativeLayout>  
  58. </RelativeLayout>  


 

2,对应的适配器类:

[java] view plaincopy
  1. import java.io.File;  
  2. import java.util.List;  
  3.   
  4. import android.content.Context;  
  5. import android.content.SharedPreferences;  
  6. import android.content.SharedPreferences.Editor;  
  7. import android.os.Bundle;  
  8. import android.os.Handler;  
  9. import android.os.Message;  
  10. import android.view.LayoutInflater;  
  11. import android.view.View;  
  12. import android.view.View.OnClickListener;  
  13. import android.view.ViewGroup;  
  14. import android.widget.Button;  
  15. import android.widget.ProgressBar;  
  16. import android.widget.RelativeLayout;  
  17. import android.widget.TextView;  
  18.   
  19. import com.hwttnet.oa.mobile.aas.R;  
  20. import com.hwttnet.oa.mobile.app.App;  
  21. import com.hwttnet.oa.mobile.app.App.Shared;  
  22. import com.hwttnet.oa.mobile.listener.OnThreadListener;  
  23. import com.hwttnet.oa.mobile.service.ThreadService;  
  24. import com.hwttnet.oa.mobile.util.LocationDataProcess;  
  25. import com.hwttnet.oa.mobile.util.ViewUtil;  
  26. import com.hwttnet.other.model.AffixInfoBean;  
  27.   
  28. /** 
  29.  * 提供多附件下载时的列表适配器 
  30.  * <HR> 
  31.  * 作者:孙博 
  32.  * <P> 
  33.  * 时间:2012-11-26 下午4:08:33 
  34.  * <P> 
  35.  * 电子邮件:sunb@hwttnet.com 
  36.  * <P> 
  37.  * QQ:497733379 
  38.  * <P> 
  39.  * Gmail : sunbo.java@gmail.com 
  40.  */  
  41. public class AffixDownloadAdapter implements OnClickListener, OnThreadListener  
  42. {  
  43.     private final Context context;  
  44.     private final SharedPreferences affixShared;  
  45.       
  46.     private final ThreadService threadService = new ThreadService();  
  47.     private final LocationDataProcess locationDateProcess;  
  48.       
  49.     private final ViewUtil mViewUtil;  
  50.       
  51.     public AffixDownloadAdapter(Context context)  
  52.     {  
  53.         this.context = context;  
  54.         affixShared = context.getSharedPreferences(Shared.DOWNLOADAFFIXINFO, Context.MODE_PRIVATE);  
  55.         threadService.setOnThreadListener(this);  
  56.         locationDateProcess = new LocationDataProcess(context);  
  57.         mViewUtil = new ViewUtil(context);  
  58.     }  
  59.       
  60.     public void setupViews(ViewGroup mViewGroup, List<AffixInfoBean> affixs)  
  61.     {  
  62.         if(null == mViewGroup)  
  63.             return;  
  64.         if(mViewGroup.getChildCount() > 0)  
  65.             mViewGroup.removeAllViews();  
  66.         LayoutInflater layoutInflater = LayoutInflater.from(context);  
  67.         for(AffixInfoBean affix : affixs)  
  68.         {  
  69.             ViewHolder mViewHolder = new ViewHolder();  
  70.             mViewHolder.affix = affix;  
  71.             mViewHolder.isOpen = false;  
  72.             View convertView = layoutInflater.inflate(R.layout.affix_download_item, null);  
  73.             mViewHolder.mAffixName = (TextView) convertView.findViewById(R.id.AffixName);  
  74.             mViewHolder.mNotfoundFileErrormsg = (TextView) convertView.findViewById(R.id.AffixNotfoundFileErrormsg);  
  75.             mViewHolder.mButton = (Button) convertView.findViewById(R.id.AffixDownload);  
  76.             mViewHolder.mDownloadProgressPanel = (RelativeLayout) convertView.findViewById(R.id.AffixDownloadProgressPanel);  
  77.             mViewHolder.mProgressBar = (ProgressBar) convertView.findViewById(R.id.AffixDownloadProgressbar);  
  78.             mViewHolder.mDownloadProgressValue = (TextView) convertView.findViewById(R.id.AffixDownloadProgressValue);  
  79.             String identityName = affix.getAffixId() + affix.getAffixName();  
  80.             String key = identityName.substring(0, identityName.lastIndexOf("."));  
  81.             String affixAbspath = affixShared.getString(key, null);  
  82.             if(affixAbspath != null)  
  83.             {  
  84.                 mViewHolder.mAffixName.setCompoundDrawablesWithIntrinsicBounds(R.drawable.result_ok, 000);  
  85.                 mViewHolder.mButton.setText(R.string.open);  
  86.                 mViewHolder.mButton.setCompoundDrawablesWithIntrinsicBounds(00, R.drawable.icon_open_file, 0);  
  87.                 mViewHolder.isOpen = true;  
  88.             }  
  89.             mViewHolder.mAffixName.setText(affix.getAffixName());  
  90.             mViewHolder.mButton.setTag(mViewHolder);  
  91.             mViewHolder.mButton.setOnClickListener(this);  
  92.             mViewGroup.addView(convertView);  
  93.         }  
  94.     }  
  95.       
  96.     @Override  
  97.     public void onClick(View v)  
  98.     {  
  99.         Object object = v.getTag();  
  100.         if(object instanceof ViewHolder)  
  101.         {  
  102.             ViewHolder mViewHolder = (ViewHolder) object;  
  103.             if(mViewHolder.isOpen)  
  104.             {  
  105.                 AffixInfoBean affix = mViewHolder.affix;  
  106.                 String key = affix.getAffixId() + affix.getAffixName();  
  107.                 String affixAbspath = affixShared.getString(key.substring(0, key.lastIndexOf(".")), "");  
  108.                 File file = new File(affixAbspath);  
  109.                 if(!file.exists())  
  110.                 {  
  111.                     mViewHolder.mButton.setText(R.string.redownload);  
  112.                     mViewHolder.mButton.setCompoundDrawablesWithIntrinsicBounds(00, R.drawable.icon_download_ics, 0);  
  113.                     mViewHolder.mAffixName.setCompoundDrawablesWithIntrinsicBounds(R.drawable.attitude_falseinfo_icon, 000);  
  114.                     mViewUtil.showAnimView(mViewHolder.mNotfoundFileErrormsg);  
  115.                     mViewHolder.isOpen = false;  
  116.                 } else  
  117.                     switch(locationDateProcess.openFile(affixAbspath))  
  118.                     {  
  119.                     // 成功打开  
  120.                     case 0:  
  121.                         break;  
  122.                     // 没有找到被打开的文件  
  123.                     case -1:  
  124.                         break;  
  125.                     // 没有找到对应的查看编辑器  
  126.                     case -2:  
  127.                         App.makeText(context, R.string.find_no_editor);  
  128.                         break;  
  129.                     }  
  130.             } else  
  131.                 if(!threadService.isAlive())  
  132.                 {  
  133.                     threadService.setTag(mViewHolder);  
  134.                     threadService.start();  
  135.                 } else  
  136.                     App.makeText(context, R.string.please_wait);  
  137.         }  
  138.     }  
  139.       
  140.     @Override  
  141.     public void onRun(Handler mHandler)  
  142.     {  
  143.         ViewHolder mViewHolder = (ViewHolder) threadService.getTag();  
  144.         String fileName = mViewHolder.affix.getAffixName();  
  145.         String downloadUrl = mViewHolder.affix.getDownloadUrl();  
  146.         locationDateProcess.download(mHandler, fileName, downloadUrl);  
  147.     }  
  148.       
  149.     @Override  
  150.     public void onResult(Message msg)  
  151.     {  
  152.         ViewHolder mViewHolder = (ViewHolder) threadService.getTag();  
  153.         Bundle data = msg.getData();  
  154.         int filesize = data.getInt("FILE_SIZE");  
  155.         switch(msg.what)  
  156.         {  
  157.         // 下载成功  
  158.         case 0:  
  159.             mViewHolder.mProgressBar.setProgress(filesize);  
  160.             mViewHolder.mDownloadProgressValue.setText(R.string.download_ok);  
  161.             mViewHolder.mAffixName.setCompoundDrawablesWithIntrinsicBounds(R.drawable.result_ok, 000);  
  162.             mViewHolder.mButton.setText(R.string.open);  
  163.             mViewHolder.mButton.setEnabled(true);  
  164.             mViewHolder.mButton.setCompoundDrawablesWithIntrinsicBounds(00, R.drawable.icon_open_file, 0);  
  165.             mViewHolder.isOpen = true;  
  166.             String filePath = data.getString("FILE_CACHE_PATH");  
  167.             Editor editor = affixShared.edit();  
  168.             String key = mViewHolder.affix.getAffixId() + mViewHolder.affix.getAffixName();  
  169.             editor.putString(key.substring(0, key.lastIndexOf(".")), filePath);  
  170.             editor.commit();  
  171.             break;  
  172.         // 开始下载  
  173.         case 1:  
  174.             mViewUtil.hideAnimView(mViewHolder.mNotfoundFileErrormsg, false);  
  175.             mViewUtil.showAnimView(mViewHolder.mDownloadProgressPanel);  
  176.             mViewHolder.mAffixName.setCompoundDrawablesWithIntrinsicBounds(R.drawable.icon_download_manage_downloading, 000);  
  177.             mViewHolder.mProgressBar.setMax(filesize);  
  178.             mViewHolder.mDownloadProgressValue.setText(R.string.start_download);  
  179.             mViewHolder.mButton.setText(R.string.downloading);  
  180.             mViewHolder.mButton.setEnabled(false);  
  181.             break;  
  182.         // 正在下载  
  183.         case 2:  
  184.             int downProgress = data.getInt("DOWN_PROGRESS");  
  185.             int progress = (int) ((((float) downProgress) / ((float) filesize)) * 100);  
  186.             mViewHolder.mProgressBar.setProgress(downProgress);  
  187.             mViewHolder.mDownloadProgressValue.setText(progress + "%");  
  188.             break;  
  189.         // 下载失败  
  190.         case -1:  
  191.             mViewHolder.mAffixName.setCompoundDrawablesWithIntrinsicBounds(R.drawable.icon_download_manage_fail, 000);  
  192.             mViewHolder.mDownloadProgressValue.setText(R.string.download_failed);  
  193.             mViewHolder.mButton.setText(R.string.retry);  
  194.             mViewHolder.mButton.setEnabled(true);  
  195.             mViewHolder.isOpen = false;  
  196.             break;  
  197.         // 文件已存在  
  198.         case -2:  
  199.             mViewUtil.hideAnimView(mViewHolder.mDownloadProgressPanel, false);  
  200.             mViewHolder.mAffixName.setCompoundDrawablesWithIntrinsicBounds(R.drawable.result_ok, 000);  
  201.             mViewHolder.mButton.setText(R.string.open);  
  202.             mViewHolder.mButton.setCompoundDrawablesWithIntrinsicBounds(00, R.drawable.icon_open_file, 0);  
  203.             mViewHolder.mButton.setEnabled(true);  
  204.             mViewHolder.isOpen = true;  
  205.             String haveFilePath = data.getString("FILE_CACHE_PATH");  
  206.             Editor haveEditor = affixShared.edit();  
  207.             String haveKey = mViewHolder.affix.getAffixId() + mViewHolder.affix.getAffixName();  
  208.             haveEditor.putString(haveKey.substring(0, haveKey.lastIndexOf(".")), haveFilePath);  
  209.             haveEditor.commit();  
  210.             App.makeText(context, R.string.file_already_exists);  
  211.             break;  
  212.         // 创建文件失败  
  213.         case -3:  
  214.             mViewUtil.hideAnimView(mViewHolder.mDownloadProgressPanel, false);  
  215.             App.makeText(context, R.string.download_failed);  
  216.             break;  
  217.         }  
  218.     }  
  219.       
  220.     private final class ViewHolder  
  221.     {  
  222.         private TextView mAffixName;  
  223.         private TextView mNotfoundFileErrormsg;  
  224.         private Button mButton;  
  225.         private RelativeLayout mDownloadProgressPanel;  
  226.         private ProgressBar mProgressBar;  
  227.         private TextView mDownloadProgressValue;  
  228.         private boolean isOpen;  
  229.         private AffixInfoBean affix;  
  230.     }  
  231. }  


 

类中所用到的其他相关类和方法:

1,ThreadService.java

[java] view plaincopy
  1. import android.os.Handler;  
  2. import android.os.Message;  
  3.   
  4. import com.hwttnet.oa.mobile.listener.OnThreadListener;  
  5.   
  6. /** 
  7.  * 服务于整个程序中所有耗时的操作,调用{@link #start()}方法即可将耗时的程序转入新线程中执行 
  8.  * <P> 
  9.  * <I>线程执行方法不保证线程安全和数据传输绝对正常</I> 
  10.  * <P> 
  11.  * 该类不可被继承 
  12.  * <HR> 
  13.  * 作者:孙博 
  14.  * <P> 
  15.  * 时间:2012-10-18 下午3:42:55 
  16.  * <P> 
  17.  * 电子邮件:sunb@hwttnet.com 
  18.  * <P> 
  19.  * QQ:497733379 
  20.  * <P> 
  21.  * Gmail : sunbo.java@gmail.com 
  22.  */  
  23. public final class ThreadService  
  24. {  
  25.     private Thread thread;  
  26.     private Object tag;  
  27.   
  28.     private OnThreadListener onThreadListener;  
  29.   
  30.     private final Handler mHandler = new Handler()  
  31.     {  
  32.         @Override  
  33.         public void handleMessage(Message msg)  
  34.         {  
  35.             if (onThreadListener != null)  
  36.                 onThreadListener.onResult(msg);  
  37.         }  
  38.     };  
  39.   
  40.     /** 
  41.      * 开启一个新的线程来执行一些耗时的操作 
  42.      * <P> 
  43.      * 注意:<I>在调用该方法之前应该先为其设置线程运行监听器: 
  44.      * <P> 
  45.      * {@link #setOnThreadListener(OnThreadListener)} </I> 
  46.      */  
  47.     public void start()  
  48.     {  
  49.         thread = new Thread()  
  50.         {  
  51.             @Override  
  52.             public void run()  
  53.             {  
  54.                 if (onThreadListener != null)  
  55.                     onThreadListener.onRun(mHandler);  
  56.             }  
  57.         };  
  58.         thread.start();  
  59.     }  
  60.   
  61.     /** 
  62.      * 检测线程是否处于活动状态 
  63.      *  
  64.      * @return 如果是活动状态,返回{@code true},否则返回{@code false} 
  65.      */  
  66.     public boolean isAlive()  
  67.     {  
  68.         if (thread != null)  
  69.             return thread.isAlive();  
  70.         return false;  
  71.     }  
  72.   
  73.     /** 
  74.      * 为当前执行的线程设置运行时监听器以实时捕捉线程运行时到运行结束的过程 
  75.      *  
  76.      * @param onThreadListener 
  77.      *            定义了线程运行时到运行结束的过程的监听器对象 
  78.      */  
  79.     public void setOnThreadListener(OnThreadListener onThreadListener)  
  80.     {  
  81.         this.onThreadListener = onThreadListener;  
  82.     }  
  83.   
  84.     public Object getTag()  
  85.     {  
  86.         return tag;  
  87.     }  
  88.   
  89.     public void setTag(Object tag)  
  90.     {  
  91.         this.tag = tag;  
  92.     }  
  93. }  


 

2,OnThreadListener.java

[java] view plaincopy
  1. import android.os.Handler;  
  2. import android.os.Message;  
  3.   
  4. /** 
  5.  * 线程调用时的回调接口,该接口中定义了线程运行时和结束后的回调方法 
  6.  * <HR> 
  7.  * 作者:孙博 
  8.  * <P> 
  9.  * 时间:2012-10-18 下午2:48:11 
  10.  * <P> 
  11.  * 电子邮件:sunb@hwttnet.com 
  12.  * <P> 
  13.  * QQ:497733379 
  14.  * <P> 
  15.  * Gmail : sunbo.java@gmail.com 
  16.  */  
  17. public interface OnThreadListener  
  18. {  
  19.     /** 
  20.      * 监听线程开始后的运行时状态,可在该方法中执行需要线程来操作的程序 
  21.      *  
  22.      * @param mHandler 
  23.      *            已实例化且做好在线程中发送消息的对象 
  24.      */  
  25.     public void onRun(Handler mHandler);  
  26.   
  27.     /** 
  28.      * 监听线程在结束后的状态,可在该方法中执行线程结束后需要操作的程序 
  29.      *  
  30.      * @param msg 
  31.      *            在线程运行时得到的一个装载着消息内容的消息对象 
  32.      */  
  33.     public void onResult(Message msg);  
  34. }  


3,LocationDataProcess.java

[java] view plaincopy
  1. import java.io.BufferedOutputStream;  
  2. import java.io.File;  
  3. import java.io.FileOutputStream;  
  4. import java.io.IOException;  
  5. import java.io.InputStream;  
  6. import java.net.URL;  
  7. import java.net.URLConnection;  
  8. import java.text.SimpleDateFormat;  
  9. import java.util.Date;  
  10. import java.util.LinkedHashMap;  
  11.   
  12. import android.content.ActivityNotFoundException;  
  13. import android.content.Context;  
  14. import android.content.Intent;  
  15. import android.content.SharedPreferences;  
  16. import android.content.SharedPreferences.Editor;  
  17. import android.content.res.Resources;  
  18. import android.net.Uri;  
  19. import android.os.Bundle;  
  20. import android.os.Handler;  
  21. import android.os.Message;  
  22.   
  23. import com.hwttnet.oa.mobile.aas.R;  
  24. import com.hwttnet.oa.mobile.app.App;  
  25.   
  26. /** 
  27.  * 本类包含了用于处理本地数据的基本方法: 
  28.  * <UL> 
  29.  * <LI>记录并获取程序中每个列表刷新的时间</LI> 
  30.  * </UL> 
  31.  * <HR> 
  32.  * 作者:孙博 
  33.  * <P> 
  34.  * 时间:2012-10-18 上午11:29:49 
  35.  * <P> 
  36.  * 电子邮件:sunb@hwttnet.com 
  37.  * <P> 
  38.  * QQ:497733379 
  39.  * <P> 
  40.  * Gmail : sunbo.java@gmail.com 
  41.  *  
  42.  */  
  43. public class LocationDataProcess  
  44. {  
  45.     private final Context context;  
  46.     /** 
  47.      * @param context 
  48.      *            正在运行时的程序上下文对象 
  49.      */  
  50.     public LocationDataProcess(Context context)  
  51.     {  
  52.         this.context = context;  
  53.     }  
  54.   
  55.     /** 
  56.      * 从网络中下载文件 
  57.      *  
  58.      * <PRE> 
  59.      * Message msg = mHandler.obtainMessage(); 
  60.      * msg.what = msgWhat; // -1:失败;-2:文件已存在;-3:新文件创建失败;0:成功;1:开始下载;2:下载过程中 
  61.      * Bundle data = msg.getData(); 
  62.      * data.putInt("<B>FILE_SIZE</B>", fileSize); 
  63.      * data.putInt("<B>DOWN_PROGRESS</B>", downProgress); 
  64.      * data.putString("<B>FILE_CACHE_PATH</B>", imageFilePath); 
  65.      * mHandler.sendMessage(msg); 
  66.      * </PRE> 
  67.      *  
  68.      * @param mHandler 
  69.      *            处理实时跟踪下载中向主线程发送的消息队列,一个已经被实例化的消息处理对象 
  70.      * @param fileName 
  71.      *            要下载的文件标准名称,含后缀 
  72.      * @param downloadUrl 
  73.      *            一个标准的网络文件{@code HTTP}地址 
  74.      * @throws IOException 
  75.      *             如果网络异常或读取图片流出现问题,则抛出该异常 
  76.      */  
  77.     public void download(Handler mHandler, String fileName, String downloadUrl)  
  78.     {  
  79.         if (null == mHandler || null == downloadUrl)  
  80.         {  
  81.             this.sendMessage(mHandler, -100null);  
  82.             return;  
  83.         }  
  84.         try  
  85.         {  
  86.             int downProgress = 0;  
  87.             URL url = new URL(downloadUrl);  
  88.             URLConnection connection = url.openConnection();  
  89.             connection.setConnectTimeout(1000 * 30);  
  90.             connection.connect();  
  91.             InputStream inputStream = connection.getInputStream();  
  92.             int fileSize = connection.getContentLength();  
  93.             if (fileSize < 1 || null == inputStream)  
  94.                 this.sendMessage(mHandler, -1, fileSize, downProgress, null);  
  95.             else  
  96.             {  
  97.                 this.sendMessage(mHandler, 1, fileSize, downProgress, null);  
  98.                 File downloadFolder = new File(App.AFFIXSTORAGEPATH);  
  99.                 if (!downloadFolder.exists())  
  100.                     downloadFolder.mkdirs();  
  101.                 File downloadFile = new File(downloadFolder.getAbsolutePath() + "/" + fileName);  
  102.                 if (downloadFile.exists())  
  103.                     this.sendMessage(mHandler, -2, fileSize, downProgress, downloadFile.getAbsolutePath());  
  104.                 else if (downloadFile.createNewFile())  
  105.                 {  
  106.                     byte[] buffer = new byte[1024 * 8];  
  107.                     int length = -1;  
  108.                     BufferedOutputStream bufferOutStream = new BufferedOutputStream(new FileOutputStream(downloadFile));  
  109.                     while ((length = inputStream.read(buffer)) != -1)  
  110.                     {  
  111.                         bufferOutStream.write(buffer, 0, length);  
  112.                         downProgress += length;  
  113.                         this.sendMessage(mHandler, 2, fileSize, downProgress, downloadFile.getAbsolutePath());  
  114.                     }  
  115.                     bufferOutStream.flush();  
  116.                     bufferOutStream.close();  
  117.                     inputStream.close();  
  118.                     this.sendMessage(mHandler, 0, fileSize, downProgress, downloadFile.getAbsolutePath());  
  119.                 } else  
  120.                     this.sendMessage(mHandler, -3, fileSize, downProgress, null);  
  121.             }  
  122.             // 异常捕捉应该更详细  
  123.         } catch (IOException e)  
  124.         {  
  125.             e.printStackTrace();  
  126.             this.sendMessage(mHandler, -100null);  
  127.         }  
  128.     }  
  129.   
  130.     private void sendMessage(Handler mHandler, int msgWhat, int fileSize,  
  131.             int downProgress, String imageFilePath)  
  132.     {  
  133.         Message msg = mHandler.obtainMessage();  
  134.         msg.what = msgWhat;  
  135.         Bundle data = msg.getData();  
  136.         data.putInt("FILE_SIZE", fileSize);  
  137.         data.putInt("DOWN_PROGRESS", downProgress);  
  138.         data.putString("FILE_CACHE_PATH", imageFilePath);  
  139.         mHandler.sendMessage(msg);  
  140.     }  
  141.   
  142.     /** 
  143.      * 根据指定的文件路径自动在系统中寻找与之对应的编辑器并打开该文件 
  144.      * <P> 
  145.      * 支持共计38种不同后缀的文件,主要可被分类为: 
  146.      *  
  147.      * @param filePath 
  148.      *            一个有效的文件绝对路径 
  149.      * @return 返回一个打开时的状态,具体如下: 
  150.      *         <UL> 
  151.      *         <LI>0:表示成功打开</LI> 
  152.      *         <LI>-1:表示无法找到被打开的文件</LI> 
  153.      *         <LI>-2:表示无法找到打开该文件的相关编辑器</LI> 
  154.      *         </UL> 
  155.      */  
  156.     public int openFile(String filePath)  
  157.     {  
  158.         File openFile = new File(filePath);  
  159.         if (!openFile.exists())  
  160.             return -1;  
  161.         int openStauts = 0;  
  162.         String filename = openFile.getName();  
  163.         String suffixName = filename.substring(filename.lastIndexOf("."), filename.length());  
  164.         try  
  165.         {  
  166.             Resources r = context.getResources();  
  167.             String[] officEndingNames = r.getStringArray(R.array.FILEENDINGOFFIC);  
  168.             for(String endingName : officEndingNames)  
  169.                 if(suffixName.equals(endingName))  
  170.                     context.startActivity(this.getDefaultFileIntent(openFile));  
  171.             String[] mediaEndingNames = r.getStringArray(R.array.FILENDINGMEDIA);  
  172.             for(String endingName : mediaEndingNames)  
  173.                 if(suffixName.equals(endingName))  
  174.                     context.startActivity(this.getMediaFileIntent(openFile));  
  175.             String[] htmlEndingNames = r.getStringArray(R.array.FILEENDINGHTML);  
  176.             for(String endingName : htmlEndingNames)  
  177.                 if(suffixName.equals(endingName))  
  178.                     context.startActivity(this.getHtmlFileIntent(openFile));  
  179.             String[] packEndingNames = r.getStringArray(R.array.FILEENDINGPACK);  
  180.             for(String endingName : packEndingNames)  
  181.                 if(suffixName.equals(endingName))  
  182.                     context.startActivity(this.getPackFileIntent(openFile));  
  183.         } catch (ActivityNotFoundException e)  
  184.         {  
  185.             e.printStackTrace();  
  186.             openStauts = -2;  
  187.         }  
  188.         return openStauts;  
  189.     }  
  190.       
  191.     private Intent getDefaultFileIntent(File defaultFile)  
  192.     {  
  193.         Intent intent = new Intent(Intent.ACTION_VIEW);  
  194.         intent.addCategory(Intent.CATEGORY_DEFAULT);  
  195.         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
  196.         Uri uri = Uri.fromFile(defaultFile);  
  197.         String filename = defaultFile.getName();  
  198.         String suffixName = filename.substring(filename.lastIndexOf("."), filename.length());  
  199.         intent.setDataAndType(uri, DT.get(suffixName));  
  200.         return intent;  
  201.     }  
  202.       
  203.     private Intent getHtmlFileIntent(File htmlFile)  
  204.     {  
  205.         Uri uri = Uri.parse(htmlFile.toString()).buildUpon().encodedAuthority("com.android.htmlfileprovider").scheme("content").encodedPath(htmlFile.toString()).build();  
  206.         Intent intent = new Intent(Intent.ACTION_VIEW);  
  207.         String filename = htmlFile.getName();  
  208.         String suffixName = filename.substring(filename.lastIndexOf("."), filename.length());  
  209.         intent.setDataAndType(uri, DT.get(suffixName));  
  210.         return intent;  
  211.     }  
  212.       
  213.     private Intent getMediaFileIntent(File audioFile)  
  214.     {  
  215.         Intent intent = new Intent(Intent.ACTION_VIEW);  
  216.         intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);  
  217.         intent.putExtra("oneshot"0);  
  218.         intent.putExtra("configchange"0);  
  219.         Uri uri = Uri.fromFile(audioFile);  
  220.         String filename = audioFile.getName();  
  221.         String suffixName = filename.substring(filename.lastIndexOf("."), filename.length());  
  222.         intent.setDataAndType(uri, DT.get(suffixName));  
  223.         return intent;  
  224.     }  
  225.       
  226.     private Intent getPackFileIntent(File packFile)  
  227.     {  
  228.         Intent intent = new Intent();  
  229.         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
  230.         intent.setAction(android.content.Intent.ACTION_VIEW);  
  231.         Uri uri = Uri.fromFile(packFile);  
  232.         String filename = packFile.getName();  
  233.         String suffixName = filename.substring(filename.lastIndexOf("."), filename.length());  
  234.         intent.setDataAndType(uri, DT.get(suffixName));  
  235.         return intent;  
  236.     }  
  237.       
  238.     private final LinkedHashMap<String, String> DT = new LinkedHashMap<String, String>();  
  239.     {  
  240.         // 图片  
  241.         DT.put(".png""image/*");  
  242.         DT.put(".gif""image/*");  
  243.         DT.put(".jpg""image/*");  
  244.         DT.put(".jpeg""image/*");  
  245.         DT.put(".bmp""image/*");  
  246.         // 音频  
  247.         DT.put(".mp3""audio/*");  
  248.         DT.put(".wav""audio/*");  
  249.         DT.put(".ogg""audio/*");  
  250.         DT.put(".midi""audio/*");  
  251.         // 视频  
  252.         DT.put(".mp4""video/*");  
  253.         DT.put(".rmvb""video/*");  
  254.         DT.put(".avi""video/*");  
  255.         DT.put(".flv""video/*");  
  256.         // 办公  
  257.         DT.put(".ppt""application/vnd.ms-powerpoint");  
  258.         DT.put(".pptx""application/vnd.ms-powerpoint");  
  259.         DT.put(".xls""application/vnd.ms-excel");  
  260.         DT.put(".xlsx""application/vnd.ms-excel");  
  261.         DT.put(".doc""application/msword");  
  262.         DT.put(".docx""application/msword");  
  263.         DT.put(".txt""text/plain");  
  264.         DT.put(".java""text/plain");  
  265.         DT.put(".c""text/plain");  
  266.         DT.put(".cpp""text/plain");  
  267.         DT.put(".py""text/plain");  
  268.         DT.put(".xml""text/plain");  
  269.         DT.put(".json""text/plain");  
  270.         DT.put(".log""text/plain");  
  271.         DT.put(".pdf""application/pdf");  
  272.         // 浏览器  
  273.         DT.put(".htm""text/html");  
  274.         DT.put(".html""text/html");  
  275.         DT.put(".php""text/html");  
  276.         DT.put(".jsp""text/html");  
  277.         // 文件包  
  278.         DT.put(".jar""application/vnd.android.package-archive");  
  279.         DT.put(".zip""application/vnd.android.package-archive");  
  280.         DT.put(".rar""application/vnd.android.package-archive");  
  281.         DT.put(".gz""application/vnd.android.package-archive");  
  282.         DT.put(".apk""application/vnd.android.package-archive");  
  283.         DT.put(".img""application/vnd.android.package-archive");  
  284.     }  
  285. }  


4,ViewUtil.java

[java] view plaincopy
  1. import android.content.Context;  
  2. import android.os.Handler;  
  3. import android.view.View;  
  4. import android.view.animation.AnimationUtils;  
  5.   
  6. /** 
  7.  * 提供界面中有关控件操作的所有相关方法 
  8.  *  
  9.  * <HR> 
  10.  * 作者:孙博 
  11.  * <P> 
  12.  * 时间:2012-10-18 下午2:25:13 
  13.  * <P> 
  14.  * 电子邮件:sunb@hwttnet.com 
  15.  * <P> 
  16.  * QQ:497733379 
  17.  * <P> 
  18.  * Gmail : sunbo.java@gmail.com 
  19.  *  
  20.  */  
  21. public final class ViewUtil  
  22. {  
  23.     private final Context context;  
  24.   
  25.     private View mView;  
  26.   
  27.     public ViewUtil(Context context)  
  28.     {  
  29.         this.context = context;  
  30.     }  
  31.   
  32.     /** 
  33.      * 检测判断界面中某一个控件是否正处于显示状态 
  34.      *  
  35.      * @param view 
  36.      *            要检测的界面控件 
  37.      * @return 如果是显示状态返回{@code true},否则返回{@code false} 
  38.      */  
  39.     public boolean isShown(View view)  
  40.     {  
  41.         if (view.getVisibility() == View.VISIBLE)  
  42.             return true;  
  43.         return false;  
  44.     }  
  45.   
  46.     /** 
  47.      * 显示一个在界面存在但已经隐藏的控件 
  48.      *  
  49.      * @param view 
  50.      *            要显示的界面控件,该控件必须是从<CODE>{@link android.view.View}</CODE>派生而来 
  51.      */  
  52.     public void showView(View view)  
  53.     {  
  54.         if (!this.isShown(view))  
  55.             view.setVisibility(View.VISIBLE);  
  56.     }  
  57.   
  58.     /** 
  59.      * 以动画方式显示一个在界面存在但已经隐藏的控件 
  60.      *  
  61.      * @param view 
  62.      *            要显示的界面控件,该控件必须是从<CODE>{@link android.view.View}</CODE>派生而来 
  63.      */  
  64.     public void showAnimView(View view)  
  65.     {  
  66.         if (!this.isShown(view))  
  67.         {  
  68.             view.setAnimation(AnimationUtils.loadAnimation(context,  
  69.                     android.R.anim.fade_in));  
  70.             view.setVisibility(View.VISIBLE);  
  71.         }  
  72.     }  
  73.   
  74.     /** 
  75.      * 以动画方式显示一个在界面存在但已经隐藏的控件 
  76.      *  
  77.      * @param view 
  78.      *            要显示的界面控件,该控件必须是从<CODE>{@link android.view.View}</CODE>派生而来 
  79.      * @param id 
  80.      *            指定控件显示时的动画来源 
  81.      */  
  82.     public void showAnimView(View view, int id)  
  83.     {  
  84.         if (!this.isShown(view))  
  85.         {  
  86.             view.setAnimation(AnimationUtils.loadAnimation(context, id));  
  87.             view.setVisibility(View.VISIBLE);  
  88.         }  
  89.     }  
  90.   
  91.     /** 
  92.      * 隐藏一个正显示中的控件 
  93.      *  
  94.      * @param view 
  95.      *            要隐藏的界面控件,该控件必须是从<CODE>{@link android.view.View}</CODE>派生而来 
  96.      * @param isKeepSeat 
  97.      *            是否保留该控件之前的所在位置 
  98.      */  
  99.     public void hideView(View view, boolean isKeepSeat)  
  100.     {  
  101.         if (this.isShown(view))  
  102.             if (isKeepSeat)  
  103.                 view.setVisibility(View.INVISIBLE);  
  104.             else  
  105.                 view.setVisibility(View.GONE);  
  106.     }  
  107.   
  108.     /** 
  109.      * 以动画方式隐藏一个正显示中的控件 
  110.      *  
  111.      * @param view 
  112.      *            要隐藏的界面控件,该控件必须是从<CODE>{@link android.view.View}</CODE>派生而来 
  113.      * @param isKeepSeat 
  114.      *            是否保留该控件之前的所在位置 
  115.      */  
  116.     public void hideAnimView(View view, boolean isKeepSeat)  
  117.     {  
  118.         if (this.isShown(view))  
  119.         {  
  120.             view.setAnimation(AnimationUtils.loadAnimation(context,  
  121.                     android.R.anim.fade_out));  
  122.             if (isKeepSeat)  
  123.                 view.setVisibility(View.INVISIBLE);  
  124.             else  
  125.                 view.setVisibility(View.GONE);  
  126.         }  
  127.     }  
  128.   
  129.     /** 
  130.      * 以动画方式隐藏一个正显示中的控件 
  131.      *  
  132.      * @param view 
  133.      *            要隐藏的界面控件,该控件必须是从<CODE>{@link android.view.View}</CODE>派生而来 
  134.      * @param id 
  135.      *            指定控件从屏幕中消失时的动画来源 
  136.      * @param isKeepSeat 
  137.      *            是否保留该控件之前的所在位置 
  138.      */  
  139.     public void hideAnimView(View view, int id, boolean isKeepSeat)  
  140.     {  
  141.         if (this.isShown(view))  
  142.         {  
  143.             view.setAnimation(AnimationUtils.loadAnimation(context, id));  
  144.             if (isKeepSeat)  
  145.                 view.setVisibility(View.INVISIBLE);  
  146.             else  
  147.                 view.setVisibility(View.GONE);  
  148.         }  
  149.     }  
  150.   
  151.     /** 
  152.      * 以动画形式显示一个控件,并设置该控件在屏幕中应该显示多长时间,在控件消失后,将不会再占用其在屏幕中的原有位置 
  153.      *  
  154.      * @param view 
  155.      *            将要被显示的某个实例化控件对象 
  156.      * @param displayTime 
  157.      *            指定控件将要在屏幕中显示的时间。<I>单位为毫秒</I> 
  158.      */  
  159.     public void setTimeShowAnimView(View view, long displayTime)  
  160.     {  
  161.         this.mView = view;  
  162.         mHandler.removeCallbacks(runnable);  
  163.         this.showAnimView(view);  
  164.         mHandler.postDelayed(runnable, displayTime);  
  165.     }  
  166.   
  167.     private final Handler mHandler = new Handler();  
  168.     private final Runnable runnable = new Runnable()  
  169.     {  
  170.         @Override  
  171.         public void run()  
  172.         {  
  173.             hideAnimView(mView, false);  
  174.         }  
  175.     };  
  176. }  


5,App.Shared.java

[java] view plaincopy
  1. /** 记录本地一些基本的数据 */  
  2.     public static final class Shared  
  3.     {  
  4.         /** 记录是否自动登录的标记 */  
  5.         public static final String AUTOLOGIN = "AUTOLOGIN";  
  6.         /** 记录不同的警告对话框是否要显示 */  
  7.         public static final String WHETHERWARNING = "WHETHERWARNING";  
  8.         /** 已下载附件记录文件名称 */  
  9.         public static final String DOWNLOADAFFIXINFO = "AFFIXINFO";  
  10.     }  

6,AffixInfoBean.java


 

[java] view plaincopy
  1. import java.io.Serializable;  
  2.   
  3. /** 
  4.  * 封装有附件全部相关信息的对应属性 
  5.  * <HR> 
  6.  * 作者:孙博 
  7.  * <P> 
  8.  * 时间:2012-11-26 下午3:41:46 
  9.  * <P> 
  10.  * 电子邮件:sunb@hwttnet.com 
  11.  * <P> 
  12.  * QQ:497733379 
  13.  * <P> 
  14.  * Gmail : sunbo.java@gmail.com 
  15.  */  
  16. public class AffixInfoBean implements Serializable  
  17. {  
  18.     private static final long serialVersionUID = -5184133590762842112L;  
  19.     private String affixId;  
  20.     private String affixName;  
  21.     private String downloadUrl;  
  22.     private String affixAffiliation;  
  23.   
  24.     public String getAffixId()  
  25.     {  
  26.         return affixId;  
  27.     }  
  28.   
  29.     public void setAffixId(String affixId)  
  30.     {  
  31.         this.affixId = affixId;  
  32.     }  
  33.   
  34.     public String getAffixName()  
  35.     {  
  36.         return affixName;  
  37.     }  
  38.   
  39.     public void setAffixName(String affixName)  
  40.     {  
  41.         this.affixName = affixName;  
  42.     }  
  43.   
  44.     public String getDownloadUrl()  
  45.     {  
  46.         return downloadUrl;  
  47.     }  
  48.   
  49.     public void setDownloadUrl(String downloadUrl)  
  50.     {  
  51.         this.downloadUrl = downloadUrl;  
  52.     }  
  53.   
  54.     public String getAffixAffiliation()  
  55.     {  
  56.         return affixAffiliation;  
  57.     }  
  58.   
  59.     public void setAffixAffiliation(String affixAffiliation)  
  60.     {  
  61.         this.affixAffiliation = affixAffiliation;  
  62.     }  
  63. }  


若有其他没有被上传的,还请见谅,因为太细了,需要什么,请回复,我会尽快的加上去!

3,最后就是调用,至于怎么调用,这里就不说了。

 

关于布局中所用到的相关资源:图片,文字信息等,在这里可以直接下载


原创粉丝点击