近期在做一个项目时,实现了扫码下载的功能,其基本流程如下:
1.集成了zxing的扫描库,当识别了二维码后,跳转到一个WebView页面。
2.设置此WebView的的下载监听器,如下。
3.调用Android系统的DownloadManager进行下载动作,并在通知栏显示下载进度。
// 设置WebView下载监听器
wvDetail.setDownloadListener(new DownloadListener() {
@Override
public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimeType, long contentLength) {
showWillDownloadDialog(url, contentDisposition, mimeType);
}
});
做了以上三步后,扫码下载的功能基本实现了。
我通过应用宝,百度手机助手等获取一些App的下载地址,并通过草料二维码网站生成相应的二维码,再通过我们的扫码下载功能进行扫描下载。经过测试发现,这些Android市场的下载链接都能正常下载,下载完成后,点击通知栏,都能正常弹出安装页面,但是,在公司一些平台上托管的App,我们扫描相应的二维码,也能正常下载,并在通知栏显示下载进度,下载完成,点击通知栏,弹出“无法打开”的提示语。
这是怎么回事?为什么应用宝,百度手机助手的App,扫码下载完成后点击能正常弹出安装页面,有些就不行呢?
没关系!有问题并可怕,我们都能解决掉。
手机连上电脑,复现“无法打开”的问题,仔细查看Android Studio控制台打印的系统log,发现有下面的log:
I/ActivityManager: START u0 {act=android.intent.action.VIEW dat=content://com.android.providers.downloads.documents/document/21 typ=application/octet-stream flg=0x10000003} from uid 10017
08-14 11:13:19.394 16343-16362/android.process.media W/DownloadManager: Failed to start Intent { act=android.intent.action.VIEW dat=content://com.android.providers.downloads.documents/document/21 typ=application/octet-stream flg=0x10000003 }: android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=content://com.android.providers.downloads.documents/document/21 typ=application/octet-stream flg=0x10000003 }
上面错误log的大体意思是:type=application/octet-stream,action=android.intent.action.VIEW,dat=content://com.android.providers.downloads.documents/document/21,无法找到相应的系统Activity来进行相应的操作。
找到了问题的症结所在,接下来就要想办法解决。
因为我们下载的apk文件,要想能点击弹出安装页面,就需要将mimeType设置为mimeType = "application/vnd.android.package-archive",所以,我们可以在调用系统DownloadManager进行下载时,进行相应的判断和处理,具体实现如下:
/**
* 调用系统下载器进行下载
*
* @param url
* @param contentDisposition
* @param mimeType
*/
private void downloadBySystem(String url, String contentDisposition, String mimeType) {
// 指定下载地址
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
// 允许媒体扫描,根据下载的文件类型被加入相册、音乐等媒体库
request.allowScanningByMediaScanner();
// 设置通知的显示类型,下载进行时和完成后显示通知
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
// 允许在计费流量下下载
// request.setAllowedOverMetered(false);
// 允许该记录在下载管理界面可见
request.setVisibleInDownloadsUi(false);
// 允许漫游时下载
request.setAllowedOverRoaming(true);
// 允许下载的网路类型
// request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);
// 设置下载文件保存的路径和文件名
String fileName = URLUtil.guessFileName(url, contentDisposition, mimeType);
LogUtil.w("fileName:{}" + fileName);
if (fileName != null && fileName.endsWith(ConstantUtil.FILE_EXTENSION_NAME) && SPECIAL_MIME_TYPE.equals(mimeType)) {
mimeType = "application/vnd.android.package-archive";
}
request.setMimeType(mimeType);
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName);
// 另外可选一下方法,自定义下载路径
// request.setDestinationUri()
// request.setDestinationInExternalFilesDir(ContextUtil.getAppContext(), ContextUtil.getAppContext().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath(), fileName);
final DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
// 添加一个下载任务
long downloadId = downloadManager.enqueue(request);
LogUtil.w("downloadId:{}" + downloadId);
}
经过在Android7.1,Android8.1反复验证,问题解决。
热烈欢迎大家积极留言反馈,小编会为大家不断提供更加优质的技术干货。
网友评论