例:
测试地址 :
http://abv.cn/music/%E5%85%89%E8%BE%89%E5%B2%81%E6%9C%88.mp3
加权限:
<uses-permission android:name="android.permission.INTERNET"/>//因特网 <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>//读 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>//写 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>//判断
主方法类:
public class MainActivity extends AppCompatActivity { private ProgressBar progressBar; private EditText etUrl; private Button btnDown; private int total = 0; private boolean downloading = false; private URL url; private File file; private List<HashMap<String, Integer>> threadList; private int length; private TextView text; // Handler handler = new Handler(new Handler.Callback() { // @Override // public boolean handleMessage(Message msg) { // if (msg.what == 0) { // progressBar.setProgress(msg.arg1); // if (msg.arg1 == length) { // Toast.makeText(MainActivity.this, "下载完成!", Toast.LENGTH_SHORT).show(); // total = 0; // } // } // return false; // } // }); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); progressBar = (ProgressBar) findViewById(R.id.progressBar); etUrl = (EditText) findViewById(R.id.et_fileUrl); btnDown = (Button) findViewById(R.id.btn_down); text = (TextView) findViewById(R.id.text); threadList = new ArrayList<>(); } public void onClickDown(View view) { if (downloading) { downloading = false; btnDown.setText("下载"); return; } downloading = true; btnDown.setText("暂停"); if (threadList.size() == 0) { new Thread(new Runnable() { @Override public void run() { try { url = new URL(etUrl.getText().toString()); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setConnectTimeout(5000); connection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727)"); length = connection.getContentLength(); progressBar.setMax(length); progressBar.setProgress(0); if (length < 0) { runOnUiThread(new Runnable() { @Override public void run() { Toast.makeText(MainActivity.this, "File not found !", Toast.LENGTH_SHORT).show(); } }); return; } file = new File(Environment.getExternalStorageDirectory(), getFileName(etUrl.getText().toString())); RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw"); randomAccessFile.setLength(length); int blockSize = length / 3; for (int i = 0; i < 3; i++) { int begin = i * blockSize; int end = (i + 1) * blockSize - 1; if (i == 2) { end = length; } HashMap<String, Integer> map = new HashMap<>(); map.put("begin", begin); map.put("end", end); map.put("finished", 0); threadList.add(map); //创建线程 下载文件 new Thread(new DownloadRunnable(begin, end, i, file, url)).start(); } } catch (MalformedURLException e) { e.printStackTrace(); Toast.makeText(MainActivity.this, "URL Error !", Toast.LENGTH_SHORT).show(); } catch (IOException e) { e.printStackTrace(); } } }).start(); } else { //恢复下载 for (int i = 0; i < threadList.size(); i++) { HashMap<String, Integer> map = threadList.get(i); int begin = map.get("begin"); int end = map.get("end"); int finished = map.get("finished"); new Thread(new DownloadRunnable(begin + finished, end, i, file, url)).start(); } } } private String getFileName(String url) { int index = url.lastIndexOf("/") + 1; return url.substring(index); } class DownloadRunnable implements Runnable { private int begin; private int end; private int id; private File file; private URL url; public DownloadRunnable(int begin, int end, int id, File file, URL url) { this.begin = begin; this.end = end; this.id = id; this.file = file; this.url = url; } @Override public void run() { try { if (begin > end) { return; } HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); connection.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727)"); connection.setRequestProperty("Range", "bytes=" + begin + "-" + end); InputStream is = connection.getInputStream(); byte[] buf = new byte[1024 * 1024]; RandomAccessFile randomAccessFile = new RandomAccessFile(file, "rw"); randomAccessFile.seek(begin); int len; HashMap<String, Integer> map = threadList.get(id); while ((len = is.read(buf)) != -1 && downloading) { randomAccessFile.write(buf, 0, len); updateProgress(len); map.put("finished", map.get("finished") + len); System.out.println("Download:" + total); } is.close(); } catch (IOException e) { e.printStackTrace(); } } } synchronized private void updateProgress(int len) { total += len; // handler.obtainMessage(0, total, 0).sendToTarget(); runOnUiThread(new Runnable() { @Override public void run() { text.setText((total * 100) / length + "%"); progressBar.setProgress(total); if (total == length) { Toast.makeText(MainActivity.this, "下载完成!", Toast.LENGTH_SHORT).show(); total = 0; btnDown.setText("完成"); } } }); } }
activity_main 布局:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingBottom="10dp" android:paddingLeft="10dp" android:paddingRight="10dp" android:paddingTop="10dp" tools:context=".MainActivity"> <EditText android:id="@+id/et_fileUrl" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="textUri" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/text" android:text="0%" /> <ProgressBar android:id="@+id/progressBar" style="@style/Widget.AppCompat.ProgressBar.Horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" /> <Button android:id="@+id/btn_down" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="onClickDown" android:text="下载" /> </LinearLayout>