Unknown URL content://downloads/my_downloads 三星引发的血案

【我的Android进阶之旅】 解决bug: Expected file scheme in URI: content://downloads/my_downloads/12 一、错误描述今天测试MM用HTC手机测试某个模块的时候crash了,抓log后发现是使用DownloadManager下载apk安装包然后自动安装的时候,抛了异常:java.lang.IllegalArgumentException: Expected file scheme in URI: content://downloads/my_downloads/12具体crash错误信息如下所示: 11 阅读详情

这是一个使用DownloadManager在三星手机引发的血案。

定义:
DownloadManager是从API 9开始加入的,用来处理http长连接的一个系统服务,我们可以使用它请求一个URI来下载到一个目标文件。DownloadManager会把下载放在后台执行,并且会在http连接失败后一旦网络恢复或者系统重启时自动尝试重新下载。我们可以通过contex.getSystemService(DOWNLOAD_SERVICE)获得一个DownloadManager实例。

场景:
每个app里面都会用到下载功能,谷歌也考虑到了这个问题,所以给我们提供了DownloadManager这个下载器来进行下载管理。下面是我用到的主要跟下载有关的代码(完整代码网上很多这里不提供了,主要说说遇到的问题):

public static void installUpdateApk(final String url,
            final String fileName, final String description) {
        new Thread() {

            public void run() {
                Looper.prepare();
                try {
                    download(url, fileName, description);
                } catch (Exception e) {
                    APK_DOWNLOADING = false;
                    e.printStackTrace();
                }
            }

            @SuppressWarnings("deprecation")
            @SuppressLint({ "InlinedApi", "NewApi" })
            private void download(final String url, String fileName,
                    String description) {
                File d = new File(AppConfig.DOWNLOAD_DIR);
                if (!d.exists()) {
                    d.mkdirs();
                }
                File f = new File(AppConfig.DOWNLOAD_DIR + fileName);
                if (f.exists()) {
                    f.delete();
                }
                APK_DOWNLOADING = true;
                if (mContext == null) {
                    APK_DOWNLOADING = false;
                    return;
                }
                String downloadUrl = url;
                if (downloadUrl == null) {
                    APK_DOWNLOADING = false;
                    Toast.makeText(mContext, "下载失败!", Toast.LENGTH_LONG).show();
                    return;
                }
                // check if support download manager
                if (!isDownloadManagerAvailable(mContext)) {

                    Intent intent = new Intent();
                    intent.setAction("android.intent.action.VIEW");
                    Uri content_url = Uri.parse(downloadUrl);
                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    intent.setData(content_url);
                    mContext.startActivity(intent);
                    APK_DOWNLOADING = false;
                    return;
                }
                manager = (DownloadManager) mContext
                        .getSystemService(Context.DOWNLOAD_SERVICE);
                // 创建下载请求
                DownloadManager.Request down = new DownloadManager.Request(
                        Uri.parse(downloadUrl));
                // 设置允许使用的网络类型,这里是移动网络和wifi都可以
                // down.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);
                down.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_MOBILE
                        | DownloadManager.Request.NETWORK_WIFI);

                down.setMimeType("application/vnd.android.package-archive");
                down.setDescription(description);
                // 禁止发出通知,既后台下载
                down.setShowRunningNotification(true);
                // 不显示下载界面
                down.setVisibleInDownloadsUi(true);
                down.setDestinationInExternalPublicDir(
                        AppConfig.PROJECT_FOLDER_NAME + "/download",
                        fileName);

                // 将下载请求放入队列
                manager.enqueue(down);
            }
        }.start();
    }
public static boolean isDownloadManagerAvailable(Context context) {
        try {
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.GINGERBREAD) {
                return false;
            }
            return true;
        } catch (Exception e) {
            return false;
        }
    }

遇到的问题:
既然知道是从api 9 后才加入的所以用isDownloadManagerAvailable() 方法做下判断如果是低版本则采用浏览器的方式下载。一般这么做判断后大部分手机是没有问题的。可是实际使用总会带给我们惊喜,某一天一个同事拿着一个三星手机来告诉我下载不好用了,无奈经过调试后发现报如标题所示的错误了,最后经过查找才发现原来它手机里面装了手机卫士,系统自带的下载管理器被禁用了(这里我就**了)!

解决方案:
还好办法总会多过问题,为了防止其他手机会出现类似的问题,这里采用的是判断系统的下载器是否可用进而选择下载方式。通过context.getPackageManager().getApplicationEnabledSetting("com.android.providers.downloads") 这个方法我们能得到系统反馈的信息有:0、1、2、3、4。 通过查找源码具体如下:

在PackageManager类里:

/**
     * Flag for {@link #setApplicationEnabledSetting(String, int, int)}
     * and {@link #setComponentEnabledSetting(ComponentName, int, int)}: This
     * component or application is in its default enabled state (as specified
     * in its manifest).
     */
    public static final int COMPONENT_ENABLED_STATE_DEFAULT = 0;

    /**
     * Flag for {@link #setApplicationEnabledSetting(String, int, int)}
     * and {@link #setComponentEnabledSetting(ComponentName, int, int)}: This
     * component or application has been explictily enabled, regardless of
     * what it has specified in its manifest.
     */
    public static final int COMPONENT_ENABLED_STATE_ENABLED = 1;

    /**
     * Flag for {@link #setApplicationEnabledSetting(String, int, int)}
     * and {@link #setComponentEnabledSetting(ComponentName, int, int)}: This
     * component or application has been explicitly disabled, regardless of
     * what it has specified in its manifest.
     */
    public static final int COMPONENT_ENABLED_STATE_DISABLED = 2;

    /**
     * Flag for {@link #setApplicationEnabledSetting(String, int, int)} only: The
     * user has explicitly disabled the application, regardless of what it has
     * specified in its manifest.  Because this is due to the user's request,
     * they may re-enable it if desired through the appropriate system UI.  This
     * option currently <strong>cannot</strong> be used with
     * {@link #setComponentEnabledSetting(ComponentName, int, int)}.
     */
    public static final int COMPONENT_ENABLED_STATE_DISABLED_USER = 3;

    /**
     * Flag for {@link #setApplicationEnabledSetting(String, int, int)} only: This
     * application should be considered, until the point where the user actually
     * wants to use it.  This means that it will not normally show up to the user
     * (such as in the launcher), but various parts of the user interface can
     * use {@link #GET_DISABLED_UNTIL_USED_COMPONENTS} to still see it and allow
     * the user to select it (as for example an IME, device admin, etc).  Such code,
     * once the user has selected the app, should at that point also make it enabled.
     * This option currently <strong>can not</strong> be used with
     * {@link #setComponentEnabledSetting(ComponentName, int, int)}.
     */
    public static final int COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED = 4;

这里简单说下 0:只要在AndroidManifest里面开启了网络访问权限则为可用状态。
1:不管是否在AndroidManifest开启了权限都为可用状态。
2:不管是否在AndroidManifest开启了权限都为不可用状态。
3:用户禁止使用状态。
4:用户不选择允许使用之前都不可用状态。

由此可以看出只有状态为0 或者1 的时候我们的app才能正常使用DownloadManager,这样我们就可以做判断了,只需要改下isDownloadManagerAvailable 方法 如下:

public static boolean isDownloadManagerAvailable(Context context) {
        try {
            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.GINGERBREAD
                    || context.getPackageManager()
                            .getApplicationEnabledSetting(
                                    "com.android.providers.downloads") == context
                            .getPackageManager().COMPONENT_ENABLED_STATE_DISABLED_USER
                    || context.getPackageManager()
                            .getApplicationEnabledSetting(
                                    "com.android.providers.downloads") == context
                            .getPackageManager().COMPONENT_ENABLED_STATE_DISABLED
                    || context.getPackageManager()
                            .getApplicationEnabledSetting(
                                    "com.android.providers.downloads") == context
                        .getPackageManager().COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED ) {

                return false;
            }
            return true;
        } catch (Exception e) {
            return false;
        }
    }

好了以上就是本人在使用DownloadManager的时候遇到的问题,特此在这里做下记录。 (-_-) !

Android使用DownloadManager实现版本更新 Android使用DownloadManager实现版本更新:http://luosifan.com/2014/09/21/Android-versionUpdate/ 立即下载

相关推荐

南京邮电大学电工电子实验(二)复习一

本文给电工电子实验(二)的复习进行一些知识点的提醒

YOUXISUN的博客 2957

DownloadProvider介绍

一、介绍 DownloadProvider提供了一个保存数据的格式,如content://downloads/my_downloads/1,或content://downloads/all_downloads/2。第三方应用可以使用DownloadManager的enqueue(Request)方法来请求下载,并可以使用ContentResolver的query()方法来查询,注意这里只能查到他

羊之草叶的专栏 9002

python数据处理与分析案例,python如何进行数据处理

大家好,本文将围绕基于python的数据处理案例展开说明,python数据处理与分析案例是一个很多人都想弄明白的事情,想搞清楚python如何进行数据处理需要先了解以下几个事情。大家好,小编来为大家解答以下问题,python数据处理案例步骤及其代码,python数据处理与分析教程,今天让我们一起来看看吧!哈喽~今天学习记录的是数据分析实训小案例。就用这个案例来好好巩固一下 python 数据分析三剑客。

a17348的博客 1237

android获取未知字符串,android – 未知的URL内容:// downloads / my_dow...

我正在使用Download Manger下载一些多媒体文件并对其进行分类.我也在使用Crashlytics,这是一个错误,我经常在不同的设备和Android版本上得到它.我正在寻找你的解决方案/建议!java.lang.IllegalArgumentException: Unknown URL content://downloads/my_downloadsat android.content.C...

weixin_29689845的博客 519

SWMM建模与案例应用

4、排水系统控制规则通过控制功能,可以在模拟进行过程中,通过条件判断,对闸门、水泵、管道、孔口、堰进行控制,实现排水系统实时控制。5、SWMM与其他模型对比分析分析:STORM、MOUSE、Info Works、SUSTAIN、SWC。1、模型初始设置主要参数:雨量计、汇水区、节点、出水口、管渠、分流器、蓄水池等参数前缀的设置。2、气象数据设置温度、蒸发、风速、融雪、面积亏损、气候调整、雨量计。1、多软件数据交互:CAD、Arcgis、SWMM。(1)节点、管段、水泵、孔口、堰、雨水口和街道。

m0_74575633的博客 3417

ANSYS 12.1避坑全记录:当Win7+VMware14遇到FLEXlm报错时的自救指南

本文详细介绍了在Windows 7和VMware14环境下安装和运行ANSYS 12.1时遇到的FLEXlm报错问题及其解决方案。通过虚拟机技术隔离时间同步问题,提供从环境配置到许可证管理的完整指南,帮助用户稳定运行这一老旧版本的工程仿真软件。

tt34567的博客 644

W/System.err﹕ java.lang.IllegalArgumentException: Unknown URL content://downloads/my_downloads

异常:W/System.err﹕ java.lang.IllegalArgumentException: Unknown URL content://downloads/my_downloads 原文位置:http://stackoverflow.com/questions/21551538/how-to-enable-android-download-manager 问题描述

沐怡旸的专栏 1万+

FastGPT智能体开发:FastGPT OpenAPI 知识库接口

FastGPT OpenAPI 知识库接口

王国平的博客 322

Android文件选择Download目录闪退解决思路及方案(在选择文件时跳到下载内容模块选择里面的文件报错)

Android文件选择Download目录闪退解决思路及方案,主要兼容Android 11以上,针对content://com.android.providers.media.documents/document/document:xxxx路径文件进行解析

qq_43100098的博客 33万+

从养殖场到科技前沿:YOLOv11+OpenCV精准计数鸡蛋与鸡

YOLOv11结合OpenCV技术,精准识别和计数鸡蛋与鸡,广泛应用于养殖场、市场监控和自动化包装。通过深度学习与计算机视觉,提升农业生产效率,让智能化管理更简单高效。

专注于深入研究多种编程语言,以实战为导向,逐步拓展开发技能,提升工程化编码和思维能力,展现无敌技术实力。 1204

华为OD机试 - 去除多余空格(Python/JS/C/C++ 2024 E卷 100分)

本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。去除文本多余空格,但不去除配对单引号之间的多余空格。给出关键词的起始和结束下标,去除多余空格后刷新关键词的起始和结束下标。条件约束:输入为两行字符串:第一行:待去除多余空格的文本,用例保证如果有单引号,则单引号成对出现,且单引号可能有多对。 第二

学Java,找哪吒 1215

Unknown URL content://downloads/my_downloads

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_33781606的博客 867

PCB_Project.PrjPcb 4 Not in version control

Altium Designer中PCB项目出现"NOT in version control"错误的解决方法:1. 禁用不需要的版本控制集成(DXP→Preferences→Version Control);2. 清理项目缓存(Projects面板右键→Clean Project);3. 检查文件读写权限;4. 如无效可新建项目重新添加文件。如需使用SVN版本控制,需正确配置SVN客户端路径,创建或连接SVN仓库,并将项目文件提交至版本控制系统。注意新建SVN仓库必须使用空目录,建议使用

whm128的博客 1583

android n下载地址,Android N - 下载管理器通知取消按钮

另一种解决方案是使用ContentObserver。下载管理器的内容uri应该是content://downloads/my_downloads,我们可以监视这个数据库的变化。当您使用下载ID开始下载时,将会创建一行content://downloads/my_downloads/{downloadId}。我们可以检查这个指针来知道这个任务是否被取消。如果返回的游标为空或空,则在数据库中找不到记录...

weixin_42682925的博客 416

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

failed to find provider info for downloads Unknown URL content://downloads解决办法.

在调用系统下载功能时,如出现如下异常 failed to find provider info for downloads FATAL EXCEPTION: main java.lang.IllegalArgumentException: Unknown URL content://downloads/my_downloads at android.content.C...

songwin88的博客 630

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Android app基于DownloadProvider实现下载管理功能

下载功能是一个很常见的功能,在很多app中都有这种功能的存在。很多应用的做法是:写一个单线程或者多线程下载,写一个DownloadThread建立HTTP请求用来下载存储文件,存储到一个地方,然后写一个UI界面,用于展示文件列表。如果需求多了呢?加个控制,暂停、取消、重新下载、文件分类,再加上一些其他所谓的特定需求,加上数据库的操作管理会让你头大,况且下载功能,在很多细节方面还是需要处理很多的情况

a0407240134的专栏 3885

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

java.lang.IllegalArgumentException Unknown URL contentdownloadsmy_downloads

异常:java.lang.IllegalArgumentException Unknown URL contentdownloadsmy_downloads 原因:手机下载管理器没有打开 解决办法:在手机(华为)上选择:设置——>管理应用程序——>全部——>找到 下载管理器点击启动

songyunbiao的专栏 1025

java.lang.IllegalArgumentException Unknown URI: content://downloads/public_downloads/

当使用如下代码调用安卓的自带文件选择 如果在选择时使用的文件选择器为下载内容将会导致使用返回的URI获取绝对路径时出现类似如下错误 解决办法: if (isDownloadsDocument(uri)) { final String id = DocumentsContract.getDocumentId(uri); if (id != null && id.startsWith("raw:")) { return id.substrin...

litao515852的专栏 2618

java.lang.IllegalArgumentException Unknown URI: content://downloads/public_downloads/ 解决方案

当使用如下代码调用安卓的自带文件选择 Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.setType("video/*"); intent.addCategory(intent.CATEGORY_OPENABLE); startActivityForResult(Intent.createChooser(intent, "...

sinat_17133389的博客 2万+

uniapp 安卓 plus调用原生文件选择

【代码】uniapp 安卓 plus调用原生文件选择。

学吧 2619

android 打开h5文件下载,【APICloud】Android文件选择Download目录闪退解决思路及方案...

最近客户返回之前实现的一个文件选择功能,选择文件后闪退或者无法选择文件,楼主看了一下,是使用了模块库里面的(selectFile)模块.不过原模块不维护了,也没有可代替模块,楼主就决定自己来试着修复一下===================================================================根据这个模块的功能,应该是调用了安装自带的文件管理器Intent...

weixin_42515045的博客 10万+

Android上传和下载文件

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录前言一、pandas是什么?二、使用步骤1.引入库2.读入数据总结 前言 提示:这里可以添加本文要记录的大概内容: 例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。 提示:以下是本篇文章正文内容,下面案例可供参考 一、pandas是什么? 示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。 二、使用步骤 1.引入库 代码

Lyn4444的博客 3171

Android 开发之PackageManager使用

PackageManager类中一些变量和方法的介绍:COMPONENT_ENABLED_STATE_DEFAULT、COMPONENT_ENABLED_STATE_DISABLED、 COMPONENT_ENABLED_STATE_DISABLED_USER、 COMPONENT_ENABLED_STATE_ENABLED

weicaihui2008的博客 4113

adb Android禁用四大组件与如何冻结APP

adb 相关的命令,Android如何禁用四大组件、如何启用、如何冻结APP

qq_36651718的博客 3984

Android -- 实现应用的禁止

这个方法的作用是启用或者禁用四大组件,比如我们想禁用一个服务,就可以使用下面的方法,传入的参数就是服务的名称。PackageManager提供了一个方法,setComponentEnabledSetting(),App使用上述方法需要权限和android.uid.system,让APP运行在 system 进程。

sinat_37429535的博客 1516

android选择并上传pdf

下面显示了我是如何尝试的,当我从Android11的最近使用的文件夹中选择一个NulllPointException文件时,它会给我一个PDF : Uri。请告诉我如何从最近使用的文件夹中获取pdf文件路径。原文链接:https://cloud.tencent.com/developer/ask/sof/289269。

aishangqian的博客 940
上一篇: Android AndFix 热修复框架
下一篇: Android Studio 掌握这些调试技巧,Debug能力不能再高啦
Mackkill
博客等级 码龄15年 65粉丝 39原创
评论 8
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值