前言

工作中遇到一个功能,下载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
    };
截图

下载完后点击通知会弹出选择打开方式。

android 10 system 永久_Android