前言
工作中遇到一个功能,下载pdf到本地。我选择调系统管理器下载完后弹出选择打开方式弹框,比如QQ pdf查看器。
在配置文件添加权限
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
判断有权限后调用downLoadPDF方法
String path="https://download.brother.com/welcome/docp000648/cv_pt3600_schn_sig_lad962001.pdf";
downLoadPDF(mContext,path);
/**
* 下载pdf文件
* @param context
* @param url
*/
private void downLoadPDF(Context context,String url){
try {
//使用系统时间命名文件
String time=String.valueOf(System.currentTimeMillis()).substring(5);
String subPath="invoice"+time+".pdf";
/*String subPath = "pdf/invoice" + time + ".pdf";*/
Uri uri = Uri.parse(url);
//得到系统的下载管理
DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
//得到连接请求对象
DownloadManager.Request requestPDF = new DownloadManager.Request(uri);
//指定在什么网络下允许下载
requestPDF.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);
requestPDF.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE);
//指定下载文件的保存路径{缓存目录还是sd卡或者手机存储}。注意:用手机自带的文件管理器看不到缓存路径(Android\data\项目包名\files\Download\subPath)
/*requestPDF.setDestinationInExternalFilesDir(context,Environment.DIRECTORY_DOWNLOADS,subPath);*/
requestPDF.setDestinationUri(getDownloadPath(context,subPath));
//表示允许MediaScanner扫描到这个文件,默认不允许
requestPDF.allowScanningByMediaScanner();
//设置显示下载界面
requestPDF.setVisibleInDownloadsUi(true);
requestPDF.setTitle("APP名字");
requestPDF.setDescription("PDF下载");
//MIME_MapTable是所有文件的后缀名所对应的MIME类型的一个String数组 比如{".apk", "application/vnd.android.package-archive"},
requestPDF.setMimeType("application/pdf");
// 下载完成后该Notification才会被显示
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.HONEYCOMB) {
// Android 3.0版本 以后才有该方法
//在下载过程中通知栏会一直显示该下载的Notification,在下载完成后该Notification会继续显示,直到用户点击该Notification或者消除该Notification
requestPDF.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
}
//启动下载,该方法返回系统为当前下载请求分配的一个唯一的ID
long downLoadId = manager.enqueue(requestPDF);
}catch (Exception e){
Uri uri = Uri.parse(url);
//String android.intent.action.VIEW 比较通用,会根据用户的数据类型打开相应的Activity。如:浏览器,电话,播放器,地图
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
}
指定下载路径
pdf存到缓存目录有随时可能被清理的风险。而且用手机自带的文件管理器也找不到这个文件。所以改成了指定路径:
/**
* 获取下载路径Uri
*/
private Uri getDownloadPath(Context context, String subPath) {
File rootDir;
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
//如果外部存储可写,新建一个app名的文件夹
rootDir = new File(Environment.getExternalStorageDirectory(), getAppName(context));
} else {
//外部存储不可写,调用ContextWrapper的getFilesDir方法。
rootDir = MyApplication.getInstance().getFilesDir();
}
if (!rootDir.exists()) {
//文件不存在则创建
rootDir.mkdirs();
}
// 下载文件的位置
File saveFile = new File(rootDir, subPath);
return Uri.fromFile(saveFile);
}
/**
* 获取app名称
*
* @return
*/
private static String getAppName(Context context) {
ApplicationInfo appInfo;
try {
appInfo = context.getPackageManager().getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
String appName = appInfo.loadLabel(context.getPackageManager()) + "";
return appName;
} catch (Exception e) {
//特定情况下可能获取为空,比如一些多渠道打包工具打包的时候动态改变android:label设置App名
e.printStackTrace();
return "AppName";
}
}
关于缓存下载路径(Android\data\项目包名\files\?\subPath)
上面有设置下载的位置,有用到系统变量里的文件Download,下面来看还有什么路径可选的:
public static final String[] STANDARD_DIRECTORIES = {
DIRECTORY_MUSIC,
DIRECTORY_PODCASTS,
DIRECTORY_RINGTONES,
DIRECTORY_ALARMS,
DIRECTORY_NOTIFICATIONS,
DIRECTORY_PICTURES,
DIRECTORY_MOVIES,
DIRECTORY_DOWNLOADS,
DIRECTORY_DCIM,
DIRECTORY_DOCUMENTS
};
截图
下载完后点击通知会弹出选择打开方式。