flutter 如何保存文件到下载文件夹在Android >=33

holgip5t  于 2023-10-22  发布在  Flutter
关注(0)|答案(2)|浏览(238)

我有一个Flutter应用程序与音频文件从网络下载。我想下载一个音频文件到我的设备下载文件夹,使其可用于以后使用,如使其成为铃声或类似。
以前我通过permission handler包的Permission.storage使用了WRITE_EXTERNAL_PROCESSION权限。
从他们的医生那里,
自Android SDK 30(Android 11)起,WRITE_EXTERNAL_REQ权限被视为高风险或敏感权限。如果您打算通过Google Play商店发布应用程序,则需要声明使用这些权限。
因此,要在Downloads文件夹中保存文件,我需要MANAGE_EXTERNAL_PROFILE(通过PROFILE)。manageExternalStorage)。但是当我添加此权限并提交应用程序时,更新被谷歌拒绝,称这不是我添加的核心功能,我应该使用风险较小的API来访问数据。
那么,如果我的目标是API 33或以上,我如何下载音频文件到我的Android设备下载文件夹?

izj3ouym

izj3ouym1#

显然,在Android>=33,要在外部存储器上写入文件,你根本不需要权限!
Android的最新版本更多地依赖于文件的用途,而不是其位置来确定应用访问和写入给定文件的能力。特别是,如果您的应用面向Android 11(API级别30)或更高版本,则WRITE_EXTERNAL_REQ权限对您的应用访问存储空间没有任何影响。这种基于目的的存储模式提高了用户隐私,因为应用仅被授予访问设备文件系统中它们实际使用的区域的权限。
https://developer.android.com/training/data-storage

5us2dqdw

5us2dqdw2#

安卓系统:以下代码适用于Android 11及更高版本(API level 30+)

根据 *Google Play商店 * 的新政策,无需从存储中获取/请求write or read文件的任何权限。这仅适用于(您的)应用程序拥有的目录,例如:缓存、临时、外部、文档、下载目录等
但是要访问此目录/storage/emulated/0/Download或此级别,您必须使用 permission_handler(如Permission.manageExternalStorage.request())获取权限,并且必须在Android Manifest文件<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" android:maxSdkVersion="34"/>中声明权限。
如果您的应用程序使用Permission.manageExternalStorage.request()等,那么在上传到PlayStore时,您必须提交详细信息和使用此类高级权限的原因。您可以阅读有关此MANAGE_EXTERNAL_STORAGE权限here的更多信息。

import 'dart:io';

import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';

class HomeScreen extends StatefulWidget {
  const HomeScreen({
    super.key,
  });
  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> with TickerProviderStateMixin {
  final String imageUrl =
      'https://satsang-foundation.org/wp-content/uploads/2022/08/Ganesha-Chathurthi-TSF-4.jpg';
  final Dio dio = Dio();
  double progress = 0.0;
  bool loading = false;

  Future<bool> saveFile(String url) async {
    try {
      if (Platform.isAndroid) {
        Directory? directory;
        directory = await getDownloadsDirectory();
        String path = '${directory!.path}/Shri Ganesha.jpeg';
        File savePath = File(path);
        await dio.download(
          url,
          savePath.path,
          onReceiveProgress: (downloadedSize, totalSize) {
            setState(() {
              progress = downloadedSize / totalSize;
            });
          },
        );
      }
    } catch (e) {
      print(e);
    }

    return false;
  }

  void downloadImage() async {
    bool download = await saveFile(imageUrl);
  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        backgroundColor: Theme.of(context).colorScheme.onPrimary,
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.spaceAround,
            children: [
              Padding(
                padding: const EdgeInsets.all(8.0),
                child: Image.network(
                  imageUrl,
                  fit: BoxFit.fitHeight,
                ),
              ),
              LinearProgressIndicator(
                minHeight: 10.0,
                value: progress,
              ),
              ElevatedButton(
                onPressed: downloadImage,
                child: const Text('Download'),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

相关问题