android 保存文件到手机

前言:文件包括,图片,视频,音频和非媒体文件,如果目标文件是在服务器端,那么操作流程是:
1.先通过okhttp将文件下载下来,下载完成后得到文件对象file。
2.再通过io流将文件保存到本地,注意此操作需要放到子线程中进行。
3.保存文件的路径需要注意,如果文件不想被当前的手机用户在文件管理器中查看到,
则推荐context.getFilesDir(),具体代码如下:

//File targetDir = new File(context.getFilesDir(), "private_file");
/**
     * 从缓存目录复制到应用私有持久化目录(不会被系统清理)
     */
    public static File saveToPrivateFilesDir(Context context,String path) {
        // 1. 源文件(你的下载文件)
        File sourceFile = new File(path);//"/data/user/0/com.sportal/cache/55D0A490-EEB8-4903-9A64-05F8C6207A5F.mov"
        if (!sourceFile.exists()) {
            return null; // 源文件不存在
        }
        //context.getFilesDir(),该目录下,用户不能从文件管理器中查找到,需要root权限
        // 2. 目标目录:应用私有 files 目录(持久化存储,不会被系统随意清理)
        File targetDir = new File(context.getFilesDir(), "savo_file"); // 子目录:videos
        if (!targetDir.exists()) {
            targetDir.mkdirs(); // 创建目录
        }
        // 3. 目标文件(使用原文件名)
        File targetFile = new File(targetDir, sourceFile.getName());

        // 4. 复制文件
        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream(sourceFile);
            fos = new FileOutputStream(targetFile);

            byte[] buffer = new byte[1024 * 4];
            int len;
            while ((len = fis.read(buffer)) != -1) {
                fos.write(buffer, 0, len);
            }
            fos.flush();
            return targetFile; // 保存成功,返回目标文件
        } catch (IOException e) {
            e.printStackTrace();
            if (targetFile.exists()) {
                targetFile.delete(); // 失败则删除不完整文件
            }
            return null;
        } finally {
            // 关闭流
            try {
                if (fis != null) fis.close();
                if (fos != null) fos.close();
                Log.i("xxx","下载完成");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

如果保存的文件想要让用户在文件管理器中查找到,则推荐公共目录,如:

//如果手机系统是Android 10+,通过 MediaStore 写入公共下载目录(无需权限)
//Android 10 以下:直接写入公共下载目录(需 WRITE_EXTERNAL_STORAGE 权限),具体代码如下:
public static Uri saveToPublicDownloadDir(Context context, String path) {
        // 1. 源文件(下载的缓存文件)
        File sourceFile = new File(path);
        if (!sourceFile.exists()) {
            Log.e("xxx", "源文件不存在");
            return null;
        }

        // 2. 配置公共下载目录的存储信息(适配 Android 10+)
        String fileName = sourceFile.getName(); // 保留原文件名(如 55D0A490...mov)
        ContentResolver resolver = context.getContentResolver();
        Uri targetUri = null;

        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                // Android 10+:通过 MediaStore 写入公共下载目录(无需权限)
                ContentValues values = new ContentValues();
                values.put(MediaStore.Downloads.DISPLAY_NAME, fileName); // 文件名
                values.put(MediaStore.Downloads.MIME_TYPE, getMimeType(fileName)); // 文件类型
                values.put(MediaStore.Downloads.RELATIVE_PATH, Environment.DIRECTORY_DOWNLOADS); // 公共下载目录

                // 插入到 MediaStore 并获取 Uri
                targetUri = resolver.insert(MediaStore.Downloads.EXTERNAL_CONTENT_URI, values);
                if (targetUri == null) {
                    Log.e("xxx", "无法获取目标 Uri");
                    return null;
                }

                // 3. 将源文件数据写入目标 Uri
                try (FileInputStream fis = new FileInputStream(sourceFile);
                     OutputStream os = resolver.openOutputStream(targetUri)) {

                    byte[] buffer = new byte[1024 * 4];
                    int len;
                    while ((len = fis.read(buffer)) != -1) {
                        os.write(buffer, 0, len);
                    }
                    Log.i("xxx", "该文件已保存到手机");
                }
            } else {
                // Android 10 以下:直接写入公共下载目录(需 WRITE_EXTERNAL_STORAGE 权限)
                File downloadDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
                File targetFile = new File(downloadDir, fileName);

                // 复制文件
                try (FileInputStream fis = new FileInputStream(sourceFile);
                     OutputStream fos = new FileOutputStream(targetFile)) {

                    byte[] buffer = new byte[1024 * 4];
                    int len;
                    while ((len = fis.read(buffer)) != -1) {
                        fos.write(buffer, 0, len);
                    }
                    // 通知系统刷新文件管理器
                    resolver.notifyChange(Uri.fromFile(targetFile), null);
                    targetUri = Uri.fromFile(targetFile);
                    Log.i("xxx", "文件已保存到公共下载目录");
                }
            }
            return targetUri; // 返回保存后的 Uri(方便后续使用)
        } catch (IOException e) {
            e.printStackTrace();
            // 失败时删除已创建的空文件
            if (targetUri != null) {
                resolver.delete(targetUri, null, null);
            }
            Log.e("xxx", "保存失败:" + e.getMessage());
            return null;
        }
    }
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容