Flutter安全作用域资源访问插件accessing_security_scoped_resource的使用

Flutter安全作用域资源访问插件accessing_security_scoped_resource的使用

调用iOS / macOS的startAccessingSecurityScopedResourcestopAccessingSecurityScopedResource在Flutter中。

使用方法

final _plugin = AccessingSecurityScopedResource();

final folderPath = /* 获取文件夹路径 */;

// 获取访问权限。
final hasAccess = await _plugin.startAccessingSecurityScopedResourceWithFilePath(folderPath);

// 释放访问权限。
_plugin.stopAccessingSecurityScopedResourceWithFilePath(folderPath);

URL-based APIs:

  • startAccessingSecurityScopedResourceWithURL
  • stopAccessingSecurityScopedResourceWithURL

完整示例代码

以下是一个完整的示例代码,展示了如何使用accessing_security_scoped_resource插件来获取和释放文件夹的访问权限。

import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'dart:async';

import 'package:accessing_security_scoped_resource/accessing_security_scoped_resource.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  [@override](/user/override)
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String _output = '';
  String? _dir;
  final _accessingSecurityScopedResourcePlugin =
      AccessingSecurityScopedResource();

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('插件示例应用'),
        ),
        body: Padding(
          padding: const EdgeInsets.all(12),
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              OutlinedButton(
                  onPressed: _selectDir,
                  child: const Text('选择一个目录')),
              if (_dir != null) Text(_dir!),
              _sep(),
              OutlinedButton(
                  onPressed: _dir != null ? _start : null,
                  child: const Text('startAccessingSecurityScopedResource (URL)')),
              _sep(),
              OutlinedButton(
                  onPressed: _dir != null ? _stop : null,
                  child: const Text('stopAccessingSecurityScopedResource (URL)')),
              _sep(),
              OutlinedButton(
                  onPressed: _dir != null ? _startPath : null,
                  child: const Text('startAccessingSecurityScopedResource (FilePath)')),
              _sep(),
              OutlinedButton(
                  onPressed: _dir != null ? _stopPath : null,
                  child: const Text('stopAccessingSecurityScopedResource (FilePath)')),
              _sep(),
              Text(_output)
            ],
          ),
        ),
      ),
    );
  }

  Widget _sep() {
    return const SizedBox(
      height: 10,
    );
  }

  Future<void> _selectDir() async {
    try {
      var dir = await FilePicker.platform.getDirectoryPath();
      if (dir == null) {
        return;
      }
      setState(() {
        _dir = dir;
      });
    } catch (err) {
      setState(() {
        _output = err.toString();
      });
    }
  }

  void _start() async {
    if (_dir == null) {
      return;
    }
    final hasAccess = await _accessingSecurityScopedResourcePlugin
        .startAccessingSecurityScopedResourceWithURL(Uri.directory(_dir!).toString());
    setState(() {
      _output = 'Has access: $hasAccess';
    });
  }

  void _stop() {
    if (_dir == null) {
      return;
    }
    _accessingSecurityScopedResourcePlugin
        .stopAccessingSecurityScopedResourceWithURL(Uri.directory(_dir!).toString());
    setState(() {
      _output = '';
    });
  }

  void _startPath() async {
    if (_dir == null) {
      return;
    }
    final hasAccess = await _accessingSecurityScopedResourcePlugin
        .startAccessingSecurityScopedResourceWithFilePath(_dir!);
    setState(() {
      _output = 'Has access: $hasAccess';
    });
  }

  void _stopPath() {
    if (_dir == null) {
      return;
    }
    _accessingSecurityScopedResourcePlugin
        .stopAccessingSecurityScopedResourceWithFilePath(_dir!);
    setState(() {
      _output = '';
    });
  }
}

更多关于Flutter安全作用域资源访问插件accessing_security_scoped_resource的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter安全作用域资源访问插件accessing_security_scoped_resource的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在Flutter中,accessing_security_scoped_resource 插件允许你安全地访问受保护的系统资源,比如照片库、文件系统等。以下是一个如何使用该插件访问照片库的示例代码。

首先,你需要在 pubspec.yaml 文件中添加依赖:

dependencies:
  flutter:
    sdk: flutter
  accessing_security_scoped_resource: ^x.y.z  # 请替换为最新版本号

然后,运行 flutter pub get 来获取依赖。

接下来,在 android/app/src/main/AndroidManifest.xml 文件中添加必要的权限:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.yourapp">

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    <application
        ... >
        ...
    </application>
</manifest>

对于iOS,你需要在 ios/Runner/Info.plist 文件中添加权限描述(例如,访问照片库):

<key>NSPhotoLibraryUsageDescription</key>
<string>We need access to your photo library</string>

接下来是主要的Flutter代码部分。以下是一个简单的示例,展示如何使用 accessing_security_scoped_resource 插件访问照片库中的图片:

import 'package:flutter/material.dart';
import 'package:accessing_security_scoped_resource/accessing_security_scoped_resource.dart';
import 'package:image_picker/image_picker.dart'; // 用于选择图片

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final ImagePicker _picker = ImagePicker();
  File? _imageFile;

  Future<void> _pickImage() async {
    final pickedFile = await _picker.pickImage(source: ImageSource.gallery);

    if (pickedFile != null) {
      // 使用accessing_security_scoped_resource插件处理文件
      final ScopedStorageAccess scopedStorageAccess = ScopedStorageAccess();
      final ScopedStorageAccessResult result = await scopedStorageAccess.requestAccess(pickedFile.path);

      if (result.isGranted) {
        setState(() {
          _imageFile = File(result.filePath);
        });
      } else {
        // 处理权限被拒绝的情况
        ScaffoldMessenger.of(context).showSnackBar(SnackBar(
          content: Text('Access to the file was denied'),
        ));
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Access Security Scoped Resource Example'),
      ),
      body: Center(
        child: _imageFile == null
            ? ElevatedButton(
                onPressed: _pickImage,
                child: Text('Pick Image from Gallery'),
              )
            : Image.file(_imageFile!),
      ),
    );
  }
}

在这个示例中,我们首先使用 image_picker 插件从照片库中选择图片。然后,我们使用 accessing_security_scoped_resource 插件请求对该文件的访问权限。如果权限被授予,我们将文件路径存储在 _imageFile 变量中,并在UI中显示该图片。

请注意,accessing_security_scoped_resource 插件本身不直接提供文件选择功能,而是用于处理已经获得的文件路径的权限请求。因此,通常你会结合其他插件(如 image_picker)一起使用。

此外,由于权限请求和文件系统访问的复杂性,请确保在实际应用中妥善处理各种可能的异常和边缘情况,以提高应用的健壮性和用户体验。

回到顶部