我们公司有点击下载按钮,下载视频或者pdf文件,并能在下载列表中显示出来。网上查阅很多,发现OKgo刚好适合。
下面是框架的简单使用。(另外新增下载完成,可用手机自带软件观看pdf或视频)
界面如下:
代码实现:可参考GitHub网站OKgo的使用:
1.配置文件
compile 'com.android.support:recyclerview-v7:26+'
compile 'com.android.support:design:26+'
compile 'com.github.bumptech.glide:glide:3.7.0'
compile 'com.lzy.net:okgo:3.0.4'
compile 'com.lzy.net:okrx2:2.0.2'
compile 'com.lzy.net:okserver:2.0.5'
compile 'com.jakewharton:butterknife:7.0.1'
compile 'com.lzy.widget:imagepicker:0.3.2'
2.待下载列表:需检查sd权限
package com.example.downloadlistdemo;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import com.example.downloadlistdemo.base.BaseActivity;
import com.example.downloadlistdemo.model.FileModel;
import com.example.downloadlistdemo.utils.DownloadUtils;
import com.lzy.okgo.db.DownloadManager;
import com.lzy.okgo.model.Progress;
import com.lzy.okserver.OkDownload;
import java.util.ArrayList;
import java.util.List;
import butterknife.Bind;
import butterknife.ButterKnife;
import butterknife.OnClick;
public class DownloadListActivity extends BaseActivity {
private static final int REQUEST_PERMISSION_STORAGE = 0x01;
@Bind(R.id.toolbar)
Toolbar toolbar;
@Bind(R.id.targetFolder)
TextView folder;
@Bind(R.id.recyclerView)
RecyclerView recyclerView;
private List<FileModel> apks;
private DownloadListAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_download_list);
initToolBar(toolbar, false, "开始下载");
initData();
OkDownload.getInstance().setFolder(Environment.getExternalStorageDirectory().getAbsolutePath() + "/aaa/");
OkDownload.getInstance().getThreadPool().setCorePoolSize(3);
folder.setText(String.format("下载路径: %s", OkDownload.getInstance().getFolder()));
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.addItemDecoration(new DividerItemDecoration(this, LinearLayoutManager.VERTICAL));
//从数据库中恢复数据
List<Progress> progressList = DownloadManager.getInstance().getAll();
OkDownload.restore(progressList);
adapter = new DownloadListAdapter(this);
recyclerView.setAdapter(adapter);
checkSDCardPermission();
}
/** 检查SD卡权限 */
protected void checkSDCardPermission() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_PERMISSION_STORAGE);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_PERMISSION_STORAGE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
//获取权限
} else {
showToast("权限被禁止,无法下载文件!");
}
}
}
// @OnClick(R.id.startAll)
// public void startAll(View view) {
// for (FileModel apk : apks) {
//
// //这里只是演示,表示请求可以传参,怎么传都行,和okgo使用方法一样
// GetRequest<File> request = OkGo.<File>get(apk.url)//
// .headers("aaa", "111")//
// .params("bbb", "222");
//
// //这里第一个参数是tag,代表下载任务的唯一标识,传任意字符串都行,需要保证唯一,我这里用url作为了tag
// OkDownload.request(apk.url, request)//
// .priority(apk.priority)//
// .extra1(apk)//
// .save()//
// .register(new LogDownloadListener())//
// .start();
//
// adapter.notifyDataSetChanged();
// }
// }
@Override
protected void onResume() {
super.onResume();
adapter.notifyDataSetChanged();
}
private class DownloadListAdapter extends BaseRecyclerAdapter<FileModel, ViewHolder> {
DownloadListAdapter(Context context) {
super(context, apks);
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.item_download_list, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
FileModel fileModel = mDatas.get(position);
holder.bind(fileModel);
}
}
public class ViewHolder extends RecyclerView.ViewHolder {
@Bind(R.id.name)
TextView name;
@Bind(R.id.icon)
ImageView icon;
@Bind(R.id.download)
Button download;
private FileModel apk;
public ViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
public void bind(FileModel apk) {
this.apk = apk;
if (OkDownload.getInstance().getTask(apk.url) != null) {
//download.setText("已在队列");
//download.setEnabled(false);
} else {
//download.setText("下载");
//download.setEnabled(true);
}
name.setText(apk.name);
displayImage(apk.iconUrl, icon);
}
@OnClick(R.id.download)
public void download() {
DownloadUtils.download(apk);
}
}
private void initData() {
apks = new ArrayList<>();
FileModel apk1 = new FileModel();
apk1.name = "pdf文件";
apk1.iconUrl = "http://file.market.xiaomi.com/thumbnail/PNG/l114/AppStore/0c10c4c0155c9adf1282af008ed329378d54112ac";
apk1.url = "http://www.ti.com.cn/cn/lit/ug/tidub07/tidub07.pdf";
apks.add(apk1);
FileModel apk2 = new FileModel();
apk2.name = "视频文件";
apk2.iconUrl = "http://file.market.xiaomi.com/thumbnail/PNG/l114/AppStore/00814b5dad9b54cc804466369c8cb18f23e23823f";
apk2.url = "http://vd3.bdstatic.com/mda-hkjm4bjixgj9t5km/mda-hkjm4bjixgj9t5km.mp4";
apks.add(apk2);
FileModel apk3 = new FileModel();
apk3.name = "视频文件";
apk3.iconUrl = "http://file.market.xiaomi.com/thumbnail/PNG/l114/AppStore/01db44d7f809430661da4fff4d42e703007430f38";
apk3.url = "http://vd3.bdstatic.com/mda-hkjm4bjixgj9t5km/mda-hkjm4bjixgj9t5km.mp4";
apks.add(apk3);
FileModel apk4 = new FileModel();
apk4.name = "pdf文件";
apk4.iconUrl = "http://file.market.xiaomi.com/thumbnail/PNG/l114/AppStore/072725ca573700292b92e636ec126f51ba4429a50";
apk4.url = "http://api.stepelectric.com/api/Pan/Down/434";
apks.add(apk4);
FileModel apk5 = new FileModel();
apk5.name = "陌陌";
apk5.iconUrl = "http://file.market.xiaomi.com/thumbnail/PNG/l114/AppStore/06006948e655c4dd11862d060bd055b4fd2b5c41b";
apk5.url = "http://api.stepelectric.com/SM.11SF-A (V4)UCMP检测子系统型式试验证书和报告.pdf";
apks.add(apk5);
FileModel apk6 = new FileModel();
apk6.name = "手机淘宝";
apk6.iconUrl = "http://file.market.xiaomi.com/thumbnail/PNG/l114/AppStore/017a859792d09d7394108e0a618411675ec43f220";
apk6.url = "http://121.29.10.1/f3.market.xiaomi.com/download/AppStore/0afc00452eb1a4dc42b20c9351eacacab4692a953/com.taobao.taobao.apk";
apks.add(apk6);
FileModel apk7 = new FileModel();
apk7.name = "酷狗音乐";
apk7.iconUrl = "http://file.market.xiaomi.com/thumbnail/PNG/l114/AppStore/0f2f050e21e42f75c7ecca55d01ac4e5e4e40ca8d";
apk7.url = "http://121.18.239.1/f5.market.xiaomi.com/download/AppStore/053ed49c1545c6eec3e3e23b31568c731f940934f/com.kugou.android.apk";
apks.add(apk7);
FileModel apk8 = new FileModel();
apk8.name = "网易云音乐";
apk8.iconUrl = "http://file.market.xiaomi.com/thumbnail/PNG/l114/AppStore/02374548ac39f3b7cdbf5bea4b0535b5d1f432f23";
apk8.url = "http://121.18.239.1/f4.market.xiaomi.com/download/AppStore/0f458c5661acb492e30b808a2e3e4c8672e6b55e2/com.netease.cloudmusic.apk";
apks.add(apk8);
FileModel apk9 = new FileModel();
apk9.name = "ofo共享单车";
apk9.iconUrl = "http://file.market.xiaomi.com/thumbnail/PNG/l114/AppStore/0fe1a5c6092f3d9fa5c4c1e3158e6ff33f6418152";
apk9.url = "http://60.28.125.1/f4.market.mi-img.com/download/AppStore/06954949fcd48414c16f726620cf2d52200550f56/so.ofo.labofo.apk";
apks.add(apk9);
FileModel apk10 = new FileModel();
apk10.name = "摩拜单车";
apk10.iconUrl = "http://file.market.xiaomi.com/thumbnail/PNG/l114/AppStore/0863a058a811148a5174d9784b7be2f1114191f83";
apk10.url = "http://60.28.125.1/f4.market.xiaomi.com/download/AppStore/00cdeb4865c5a4a7d350fe30b9f812908a569cc8a/com.mobike.mobikeapp.apk";
apks.add(apk10);
FileModel apk11 = new FileModel();
apk11.name = "贪吃蛇大作战";
apk11.iconUrl = "http://file.market.xiaomi.com/thumbnail/PNG/l114/AppStore/09f7f5756d9d63bb149b7149b8bdde0769941f09b";
apk11.url = "http://60.22.46.1/f3.market.xiaomi.com/download/AppStore/0b02f24ffa8334bd21b16bd70ecacdb42374eb9cb/com.wepie.snake.new.mi.apk";
apks.add(apk11);
FileModel apk12 = new FileModel();
apk12.name = "蘑菇街";
apk12.iconUrl = "http://file.market.xiaomi.com/thumbnail/PNG/l114/AppStore/0ab53044735e842c421a57954d86a77aea30cc1da";
apk12.url = "http://121.29.10.1/f5.market.xiaomi.com/download/AppStore/07a6ee4955e364c3f013b14055c37b8e4f6668161/com.mogujie.apk";
apks.add(apk12);
FileModel apk13 = new FileModel();
apk13.name = "聚美优品";
apk13.iconUrl = "http://file.market.xiaomi.com/thumbnail/PNG/l114/AppStore/080ed520b76d943e5533017a19bc76d9f554342d0";
apk13.url = "http://121.29.10.1/f5.market.mi-img.com/download/AppStore/0e70a572cd5fd6a3718941328238d78d71942aee0/com.jm.android.jumei.apk";
apks.add(apk13);
FileModel apk14 = new FileModel();
apk14.name = "全民K歌";
apk14.iconUrl = "http://file.market.xiaomi.com/thumbnail/PNG/l114/AppStore/0f1f653261ff8b3a64324097224e40eface432b99";
apk14.url = "http://60.28.123.129/f4.market.xiaomi.com/download/AppStore/04f515e21146022934085454a1121e11ae34396ae/com.tencent.karaoke.apk";
apks.add(apk14);
FileModel apk15 = new FileModel();
apk15.name = "书旗小说";
apk15.iconUrl = "http://file.market.xiaomi.com/thumbnail/PNG/l114/AppStore/0c9ce345aa2734b1202ddf32b6545d9407b18ba0b";
apk15.url = "http://60.28.125.129/f5.market.mi-img.com/download/AppStore/02d9c4035b248753314f46600cf7347a306426dc1/com.shuqi.controller.apk";
apks.add(apk15);
}
}
2. 点击下载调用下载工具类中下载:
package com.example.download.utils;
import android.content.Context;
import com.example.download.LogDownloadListener;
import com.example.download.model.CourseModel;
import com.lzy.okgo.OkGo;
import com.lzy.okgo.request.GetRequest;
import com.lzy.okserver.OkDownload;
import java.io.File;
/**
* Created by 付刚 on 2018/3/20.
*/
public class DownloadUtils {
public static void download(CourseModel courseModel) {
//这里只是演示,表示请求可以传参,怎么传都行,和okgo使用方法一样
GetRequest<File> request = OkGo.<File>get(courseModel.courseAddress)//
.headers("aaa", "111")//
.params("bbb", "222");
//这里第一个参数是tag,代表下载任务的唯一标识,传任意字符串都行,需要保证唯一,我这里用courseAddress作为了tag
OkDownload.request(courseModel.courseAddress, request)//
.extra1(courseModel)//
.save()//
.register(new LogDownloadListener())//
.start();
}
public static String getMIMEType(Context context, String filePath) {
String type="";
File file = new File(filePath);
String fileName = file.getName();
if(fileName.endsWith("pdf")){
type="application/pdf";
}else if (fileName.endsWith("mp4")){
type="video/*";
}else {
type="video/*";
}
return type;
}
}
3.展示下载列表及情况
package com.example.downloadlistdemo;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.widget.TextView;
import com.example.downloadlistdemo.base.BaseActivity;
import com.lzy.okserver.OkDownload;
import com.lzy.okserver.task.XExecutor;
import butterknife.Bind;
public class DownloadingActivity extends BaseActivity implements XExecutor.OnAllTaskEndListener {
private DownloadAdapter adapter;
private OkDownload okDownload;
@Bind(R.id.toolbar)
Toolbar toolbar;
@Bind(R.id.title)
TextView title;
@Bind(R.id.recyclerView)
RecyclerView recyclerView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_downloading);
initToolBar(toolbar, true, "");
title.setText("我的下载");
okDownload = OkDownload.getInstance();
adapter = new DownloadAdapter(this);
adapter.updateData(DownloadAdapter.TYPE_ALL);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);
//okDownload.addOnAllTaskEndListener(this);
}
@Override
public void onAllTaskEnd() {
showToast("所有下载任务已结束");
}
@Override
protected void onDestroy() {
super.onDestroy();
//okDownload.removeOnAllTaskEndListener(this);
adapter.unRegister();
}
@Override
public void onBackPressed() {
super.onBackPressed();
finish();
System.out.println("按下了back键 onBackPressed()");
Log.e("fff", "按下了back键");
}
@Override
protected void onResume() {
super.onResume();
adapter.notifyDataSetChanged();
}
}
adapter:
package com.example.downloadlistdemo;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.support.v4.content.FileProvider;
import android.support.v7.widget.RecyclerView;
import android.text.format.Formatter;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.bumptech.glide.Glide;
import com.example.downloadlistdemo.model.FileModel;
import com.example.downloadlistdemo.utils.FileUtils;
import com.lzy.okgo.db.DownloadManager;
import com.lzy.okgo.model.Progress;
import com.lzy.okserver.OkDownload;
import com.lzy.okserver.download.DownloadListener;
import com.lzy.okserver.download.DownloadTask;
import java.io.File;
import java.text.NumberFormat;
import java.util.List;
import java.util.Map;
import butterknife.Bind;
import butterknife.ButterKnife;
import butterknife.OnClick;
public class DownloadAdapter extends RecyclerView.Adapter<DownloadAdapter.ViewHolder> {
public static final int TYPE_ALL = 0;
public static final int TYPE_FINISH = 1;
public static final int TYPE_ING = 2;
private List<DownloadTask> values;
private NumberFormat numberFormat;
private LayoutInflater inflater;
private Context context;
private int type;
public DownloadAdapter(Context context) {
this.context = context;
numberFormat = NumberFormat.getPercentInstance();
numberFormat.setMinimumFractionDigits(2);
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
public void updateData(int type) {
//这里是将数据库的数据恢复
this.type = type;
if (type == TYPE_ALL) values = OkDownload.restore(DownloadManager.getInstance().getAll());
if (type == TYPE_FINISH)
values = OkDownload.restore(DownloadManager.getInstance().getFinished());
if (type == TYPE_ING)
values = OkDownload.restore(DownloadManager.getInstance().getDownloading());
notifyDataSetChanged();
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = inflater.inflate(R.layout.item_download_manager, parent, false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
DownloadTask task = values.get(position);
String tag = createTag(task);
task.register(new ListDownloadListener(tag, holder))//
.register(new LogDownloadListener());
holder.setTag(tag);
holder.setTask(task);
holder.bind();
holder.refresh(task.progress);
}
public void unRegister() {
Map<String, DownloadTask> taskMap = OkDownload.getInstance().getTaskMap();
for (DownloadTask task : taskMap.values()) {
task.unRegister(createTag(task));
}
}
private String createTag(DownloadTask task) {
return type + "_" + task.progress.tag;
}
@Override
public int getItemCount() {
return values == null ? 0 : values.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
@Bind(R.id.icon)
ImageView icon;
@Bind(R.id.name)
TextView name;
@Bind(R.id.downloadSize)
TextView downloadSize;
@Bind(R.id.tvProgress)
TextView tvProgress;
@Bind(R.id.netSpeed)
TextView netSpeed;
@Bind(R.id.pbProgress)
NumberProgressBar pbProgress;
@Bind(R.id.start)
Button download;
private DownloadTask task;
private String tag;
public ViewHolder(View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
}
public void setTask(DownloadTask task) {
this.task = task;
}
public void bind() {
Progress progress = task.progress;
FileModel apk = (FileModel) progress.extra1;
if (apk != null) {
Glide.with(context).load(apk.iconUrl).error(R.mipmap.ic_launcher).into(icon);
name.setText(apk.name);
} else {
name.setText(progress.fileName);
}
//
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Progress progress = task.progress;
if (progress.status == Progress.FINISH) {
Intent intent = new Intent();
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setAction(Intent.ACTION_VIEW);
String type = FileUtils.getMIMEType(context, progress.filePath);
File file = new File(progress.filePath);
//设置intent的data和Type属性。
Log.e("fff", "" + type + "11" + Uri.fromFile(file));
Uri url = FileProvider.getUriForFile(context, context.getApplicationContext().getPackageName() + ".provider", file);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(url, type);
context.startActivity(intent);
}
}
});
}
public void refresh(Progress progress) {
String currentSize = Formatter.formatFileSize(context, progress.currentSize);
String totalSize = Formatter.formatFileSize(context, progress.totalSize);
downloadSize.setText(currentSize + "/" + totalSize);
switch (progress.status) {
case Progress.NONE:
netSpeed.setText("停止");
download.setText("下载");
break;
case Progress.PAUSE:
netSpeed.setText("暂停中");
download.setText("继续");
break;
case Progress.ERROR:
netSpeed.setText("下载出错");
download.setText("出错");
break;
case Progress.WAITING:
netSpeed.setText("等待中");
download.setText("等待");
break;
case Progress.FINISH:
netSpeed.setText("下载完成");
download.setText("完成");
break;
case Progress.LOADING:
String speed = Formatter.formatFileSize(context, progress.speed);
netSpeed.setText(String.format("%s/s", speed));
download.setText("暂停");
break;
}
tvProgress.setText(numberFormat.format(progress.fraction));
pbProgress.setMax(10000);
pbProgress.setProgress((int) (progress.fraction * 10000));
}
@OnClick(R.id.start)
public void start() {
Progress progress = task.progress;
switch (progress.status) {
case Progress.PAUSE:
case Progress.NONE:
case Progress.ERROR:
task.start();
break;
case Progress.LOADING:
task.pause();
break;
case Progress.FINISH:
Toast.makeText(context, "下载完成:" + progress.filePath, Toast.LENGTH_LONG).show();
break;
}
refresh(progress);
}
@OnClick(R.id.remove)
public void remove() {
task.remove(true);
updateData(type);
}
@OnClick(R.id.restart)
public void restart() {
task.restart();
}
public void setTag(String tag) {
this.tag = tag;
}
public String getTag() {
return tag;
}
}
private class ListDownloadListener extends DownloadListener {
private ViewHolder holder;
ListDownloadListener(Object tag, ViewHolder holder) {
super(tag);
this.holder = holder;
}
@Override
public void onStart(Progress progress) {
}
@Override
public void onProgress(Progress progress) {
if (tag == holder.getTag()) {
holder.refresh(progress);
}
}
@Override
public void onError(Progress progress) {
Throwable throwable = progress.exception;
if (throwable != null) throwable.printStackTrace();
}
@Override
public void onFinish(File file, Progress progress) {
Toast.makeText(context, "下载完成:" + progress.filePath, Toast.LENGTH_LONG).show();
updateData(type);
}
@Override
public void onRemove(Progress progress) {
}
}
}
其中下载完成点击item会自动询问手机相关应用打开下载后的文件
使用的fileprovider
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.downloadlistdemo">
<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.MOUNT_UNMOUNT_FILESYSTEMS"/>
<application
android:name=".GApp"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".DownloadingActivity"
android:theme="@style/AppTheme.NoActionBar">
</activity>
<activity
android:name=".DownloadListActivity"
android:theme="@style/AppTheme.NoActionBar"></activity>
</application>
</manifest>
功能基本上实现,还有okgo的初始化可参考网址https://github.com/jeasonlzy/okhttp-OkGo
附上上述demo:https://download.csdn.net/download/fugang1230/10313806