Android文件下载之进度检测

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android文件下载之进度检测相关的知识,希望对你有一定的参考价值。

  近期因为项目的需要,研究了一下android文件下载进度显示的功能实现,接下来就和大家一起分享学习一下,希望对广大初学者有帮助。
  先上效果图:

  技术分享

  上方的蓝色进度条,会根据文件下载量的百分比进行加载,中部的文本控件用来现在文件下载的百分比,最下方的ImageView用来展示下载好的文件,项目的目的就是动态向用户展示文件的下载量。

  下面看代码实现:首先是布局文件:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="${relativePackage}.${activityClass}" >

    <ProgressBar
        android:id="@+id/progressBar"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:max="100" />

    <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/progressBar"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="24dp"
        android:text="TextView" />

    <ImageView
        android:id="@+id/imageView"
        android:layout_marginTop="24dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_below="@+id/textView"
        android:contentDescription="@string/app_name"
        android:src="@drawable/ic_launcher" />

</RelativeLayout>

  接下来的主Activity代码:

public class MainActivity extends Activity {

	ProgressBar pb;   
	TextView tv; 
	ImageView imageView;
    int fileSize;    
    int downLoadFileSize;    
    String fileEx,fileNa,filename;  
    //用来接收线程发送来的文件下载量,进行UI界面的更新
    private Handler handler = new Handler(){    
        @Override    
        public void handleMessage(Message msg)    
        {//定义一个Handler,用于处理下载线程与UI间通讯
          if (!Thread.currentThread().isInterrupted())
          {    
            switch (msg.what)
            {    
              case 0:    
                pb.setMax(fileSize);
              case 1:    
                pb.setProgress(downLoadFileSize);    
                int result = downLoadFileSize * 100 / fileSize;    
                tv.setText(result + "%");    
                break;    
              case 2:    
                Toast.makeText(MainActivity.this, "文件下载完成", Toast.LENGTH_SHORT).show();   
                FileInputStream fis = null;
				try {
					fis = new FileInputStream(Environment.getExternalStorageDirectory() + File.separator + "/ceshi/" + filename);
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				}
                Bitmap bitmap = BitmapFactory.decodeStream(fis);  ///把流转化为Bitmap图
                imageView.setImageBitmap(bitmap);
                break;    
     
              case -1:    
                String error = msg.getData().getString("error");
                Toast.makeText(MainActivity.this, error, Toast.LENGTH_SHORT).show();    
                break;    
            }    
          }    
          super.handleMessage(msg);    
        }    
      };
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		pb=(ProgressBar)findViewById(R.id.progressBar);
        tv=(TextView)findViewById(R.id.textView);
        imageView = (ImageView) findViewById(R.id.imageView);
        tv.setText("0%");
        new Thread(){
            public void run(){
                try {
                	//下载文件,参数:第一个URL,第二个存放路径
                	down_file("http://cdnq.duitang.com/uploads/item/201406/15/20140615203435_ABQMa.jpeg", Environment.getExternalStorageDirectory() + File.separator + "/ceshi/");
                } catch (ClientProtocolException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }   
            }    
        }.start();    
     
    }    
	
	/**
	 * 文件下载
	 * @param url:文件的下载地址
	 * @param path:文件保存到本地的地址
	 * @throws IOException
	 */
    public void down_file(String url,String path) throws IOException{    
        //下载函数          
        filename=url.substring(url.lastIndexOf("/") + 1);
        //获取文件名    
        URL myURL = new URL(url);
        URLConnection conn = myURL.openConnection();    
        conn.connect();    
        InputStream is = conn.getInputStream();    
        this.fileSize = conn.getContentLength();//根据响应获取文件大小    
        if (this.fileSize <= 0) throw new RuntimeException("无法获知文件大小 ");    
        if (is == null) throw new RuntimeException("stream is null"); 
        File file1 = new File(path);
        File file2 = new File(path+filename);
        if(!file1.exists()){
        	file1.mkdirs();
        }
        if(!file2.exists()){
        	file2.createNewFile();
        }
        FileOutputStream fos = new FileOutputStream(path+filename);    
        //把数据存入路径+文件名    
        byte buf[] = new byte[1024];
        downLoadFileSize = 0;    
        sendMsg(0);    
        do{    
            //循环读取    
            int numread = is.read(buf);    
            if (numread == -1)    
            {    
              break;    
            }    
            fos.write(buf, 0, numread);    
            downLoadFileSize += numread;    
     
            sendMsg(1);//更新进度条    
        } while (true);  
        
        sendMsg(2);//通知下载完成    
        
        try{    
            is.close();    
        } catch (Exception ex) {    
            Log.e("tag", "error: " + ex.getMessage(), ex);    
        }    
     
    }    
    
    //在线程中向Handler发送文件的下载量,进行UI界面的更新
    private void sendMsg(int flag)    
    {    
        Message msg = new Message();    
        msg.what = flag;    
        handler.sendMessage(msg);    
    }        
     
}

  最后一定要注意的是:在AndroidManifest.xml文件中,添加访问网络的权限

<uses-permission android:name="android.permission.INTERNET"/>

  到这里关于Android文件下载动态显示下载进度的小demo就为大家分享完毕,希望对大家的学习有所帮助。

以上是关于Android文件下载之进度检测的主要内容,如果未能解决你的问题,请参考以下文章

我的Android进阶之旅NDK开发之在C++代码中使用Android Log打印日志,打印出C++的函数耗时以及代码片段耗时详情

Android:使用Tab检测单个片段viewpager

UI控件之ProgressBar(进度条)

从mysql的片段中加载ListView

一起学Android之ProgressBar

更改片段时显示 ProgressBar - Android