webview进行下载踩坑记录

webview下载操作的踩坑记录

背景记录

由于公司需要, 需要在在webview中执行下载操作, 而且下载完成之后还需要跳转到自动安装页面~~~~
接下来就是踩坑报告

1.webview执行下载操作

思路

经过查找资料发现webview有三种下载方式

  • 1,跳转到浏览器进行下载
  • 2,使用系统服务进行下载
  • 3,自定义下载任务进行下载

发现跳转到浏览器进行下载最简单,但是做完之后领导说这样不行,要在咱们app内部进行下载.于是就开始进行修改~~~~

在余下的两种方法中进行选择,发现还是使用系统服务进行下载比较简单
于是就开始调试

实现

根据看api和在网上查找资料之后发现webview有一个下载的监听


 webView.setDownloadListener(new DownloadListener() {
            @Override
            public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) {
                
        });
  • onDownloadStart参数
  • url 访问的下载链接
  • userAgent HTTP请求头部用来标识客户端信息的字符串
  • contentDisposition 保存文件提供一个默认的文件名
  • mimetype 资源的媒体类型
  • contentLength 资源的大小
不在多说,直接贴下载代码
webView.setDownloadListener(new DownloadListener() {
            @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
            @Override
            public void onDownloadStart(final String url, String userAgent, final String contentDisposition, final String mimetype, long contentLength) {

/**
			android6.0之上需要适配动态权限获取
			6.0之下则不需要进行适配
			别忘了在AndroidManifest.xml中配置网络权限和外置存储读写权限
			这个地方我没有进行适配,如果直接复制的话需要自己手动添加权限获取
*/
                // 指定下载地址
                DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
                // 允许媒体扫描,根据下载的文件类型被加入相册、音乐等媒体库
                request.allowScanningByMediaScanner();
                // 设置通知的显示类型,下载进行时和完成后显示通知
                request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
                // 允许在计费流量下下载
                request.setAllowedOverMetered(false);
                // 允许该记录在下载管理界面可见
                request.setVisibleInDownloadsUi(true);
                // 允许漫游时下载
                request.setAllowedOverRoaming(true);
                // 允许下载的网路类型
                request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);
                // 设置下载文件保存的路径和文件名
                String fileName  = URLUtil.guessFileName(url, contentDisposition, mimetype);
                request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName);
//        		另外可选一下方法,自定义下载路径
//        		request.setDestinationUri()
//        		request.setDestinationInExternalFilesDir()
                final DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
                // 添加一个下载任务
                long downloadId = downloadManager.enqueue(request);
            }
        });

就这样就完成了在webview中实现下载

在这算是下载实现完成

下载完成之后自动安装

系统下载服务,在下载完成之后会发送一条广播,在广播中会有任务ID
我们就可以通过DownloadManager获取到具体的文件信息,进行apk的安装处理.

废话不多说直接上代码

我这里是新建Receiver进行监听,具体实现安装任务
也可以使用内部类的方法进行实现

public class DownloadReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent != null) {
            if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(intent.getAction())) {
            //获取downloadId
                long downloadId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
//                Log.e("downloadId:{}", downloadId+"<><>");
//				获取下载管理器,文件的具体信息都在这个里面
                DownloadManager downloadManager = (DownloadManager) context.getSystemService(DOWNLOAD_SERVICE);
                //获取type
                String type = downloadManager.getMimeTypeForDownloadedFile(downloadId);
//                Log.e("eForDownloadedFile:{}", type);
                if (TextUtils.isEmpty(type)) {
                    type = "*/*";
                }
                //获取文件uri
                //android7获取的是content格式
                //android7之下获取的file:///格式
                Uri uri = downloadManager.getUriForDownloadedFile(downloadId);
                Log.e("UriForDownloadedFile:{}", uri.toString());
                if (uri != null) {
                	//8.0之前适用
                	//Intent handlerIntent = new Intent(Intent.ACTION_VIEW);
                	//8.0之后适用,向下兼容
                    Intent handlerIntent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
                    //适配android7之上的版本
                    //如果不做适配则不会进行自动安装
                    //需要对文件所对应的uri进行临时授权
                    //如果低于android7的话则不用进行
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { // 适配Android 7系统版本
                        handlerIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); //添加这一句表示对目标应用临时授权该Uri所代表的文件
                    }
                    handlerIntent.setDataAndType(uri, type);
                    handlerIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    context.startActivity(handlerIntent);
                }
            }
        }
    }
}

代码片段中注释很详细这就不进行详细介绍

需要的权限

android6之后需要动态获取权限,否则活报错

<!--读取写入权限-->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     <!--android7之后安装文件权限-->
    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>

provider处理

需要在res文件下新建xml文件夹,在xml文件夹下新建file_paths.xml
有其他的需要可以在进行添加

	<external-path
        name="files_root"
        path="Android/data/" />
    <external-files-path name="external_files_path" path="Download" />

在AndroidManifest.xml中添加代码

<application
		...
        ...>

        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="${applicationId}.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>
 </application>

到此坑踩了不少,中间也填了一些,如果还有什么bug发现的朋友们可以提出来看,一块进行修改

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值