Android檔案下載之進度檢測

小破孩123發表於2016-02-27

近期因為專案的需要,研究了一下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就為大家分享完畢,希望對大家的學習有所幫助。

相關文章