DownloadUtils
public class DownloadUtils {
private static final String TAG = "DownloadUtils";
private static volatile DownloadUtils instance;
private File file;
private String filePath;
private OkHttpClient client;
private File downloadFile;
private long startPosition;
private Call call;
private DownloadUtils() {
client = new OkHttpClient();
}
private DownloadListener listener;
public void setListener(DownloadListener listener) {
this.listener = listener;
}
/**
* 初始化下载父路径
*
* @param path
*/
public void initDownload(String path) {
file = new File(path);
if (!file.getParentFile().exists()) {
file.getParentFile().mkdir();
}
if (!file.exists()) {
file.mkdir();
}
filePath = file.getAbsolutePath();
Log.i(TAG, "initDownload: " + filePath);
}
public static DownloadUtils getInstance() {
if (null == instance) {
synchronized (DownloadUtils.class) {
if (instance == null) {
instance = new DownloadUtils();
}
}
}
return instance;
}
public void startDownload(String url) {
if (TextUtils.isEmpty(url)) {
return;
}
if (url.contains(".")) {
String typeName = url.substring(url.lastIndexOf(".") + 1);
if (url.contains("/")) {
String name = url.substring(url.lastIndexOf("/") + 1, url.lastIndexOf("."));
String fn = name + "." + typeName;
downloadFile = new File(file, fn);
}
}
startPosition = 0;
if (downloadFile.exists()) {
startPosition = downloadFile.length();
}
Request request = new Request.Builder()
.addHeader("RANGE", "bytes=" + startPosition + "-")
.url(url)
.build();
call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
}
@Override
public void onResponse(Call call, Response response) throws IOException {
listener.startDownload();
ResponseBody body = response.body();
long totalLength = body.contentLength() + startPosition;
Log.i(TAG, "totalLength: " + totalLength + "----");
InputStream is = body.byteStream();
byte[] buf = new byte[2048];
int length = 0;
long totalNum = startPosition;
RandomAccessFile raf = new RandomAccessFile(downloadFile, "rw");
raf.seek(totalNum);
while ((length = is.read(buf, 0, buf.length)) != -1) {
raf.write(buf, 0, length);
totalNum += length;
listener.downloadProgress(totalNum * 100 / totalLength);
}
Log.i(TAG, "totalNum==" + totalNum + "---");
listener.finishDownload(downloadFile.getAbsolutePath());
body.close();
}
});
}
public void pauseDownload() {
listener.pauseDownload();
if (call != null && call.isExecuted()) {
call.cancel();
}
}
}
DownloadListener
public interface DownloadListener {
void startDownload();
void pauseDownload();
void finishDownload(String path);
void downloadProgress(long progress);
}
MainActivity
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private TextView tv_pro;
private ProgressBar progressBar;
private Button btn_start;
private Button btn_pause;
private String downloadUrl = "http://acj3.pc6.com/pc6_soure/2017-12/com.yek.android.kfc.activitys_3820.apk";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_pro = findViewById(R.id.tv_pro);
progressBar = findViewById(R.id.progressbar);
btn_start = findViewById(R.id.start);
btn_pause = findViewById(R.id.pause);
btn_start.setOnClickListener(this);
btn_pause.setOnClickListener(this);
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
File storageDirectory = Environment.getExternalStorageDirectory();
String absolutePath = storageDirectory.getAbsolutePath();
final String path = absolutePath + "/Download/";
Log.i("zzz", "下载路径 " + path);
DownloadUtils.getInstance().initDownload(path);
DownloadUtils.getInstance().setListener(new DownloadListener() {
@Override
public void startDownload() {
}
@Override
public void pauseDownload() {
}
@Override
public void finishDownload(String path) {
installApk(new File(path));
}
@Override
public void downloadProgress(final long progress) {
runOnUiThread(new Runnable() {
@Override
public void run() {
tv_pro.setText((int)progress + "%");
progressBar.setProgress((int) progress);
}
});
}
});
}
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.start:
DownloadUtils.getInstance().startDownload(downloadUrl);
break;
case R.id.pause:
DownloadUtils.getInstance().pauseDownload();
break;
}
}
/**
* 安装apk
*
* @param file
*/
private void installApk(File file) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.addCategory("android.intent.category.DEFAULT");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
startActivity(intent);
android.os.Process.killProcess(android.os.Process.myPid());
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.bwie.com.wangruixin20171227.MainActivity">
<TextView
android:id="@+id/tv_pro"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="0%" />
<ProgressBar
android:id="@+id/progressbar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_below="@+id/tv_pro"
android:layout_marginTop="12dp"
android:max="100"
android:progress="0" />
<Button
android:id="@+id/start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_below="@+id/progressbar"
android:layout_marginTop="15dp"
android:text="开始下载" />
<Button
android:id="@+id/pause"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_below="@+id/start"
android:layout_marginTop="26dp"
android:text="暂停下载" />
</RelativeLayout>