Flutter内容访问插件content_resolver的使用
Flutter内容访问插件 content_resolver
的使用
content_resolver
插件用于解析 Android 中常用的 Content Providers 所使用的 content:
URI。下面将详细介绍如何安装和使用这个插件,并提供一个完整的示例代码。
安装
在你的 pubspec.yaml
文件中添加以下依赖并执行 flutter pub get
:
dependencies:
content_resolver: ^0.3.2
使用
解析内容
下面是一个使用 app_links
插件来接收 content:
URI 内容的片段示例:
import 'package:app_links/app_links.dart';
import 'package:content_resolver/content_resolver.dart';
final _appLinks = AppLinks(onAppLink: (uri) async {
// 如果数据是一些图片,你可以直接将数据传递给 Image.data 或其他组件。
final Content content = await ContentResolver.resolveContent(uri);
// 处理接收到的内容
});
写入内容
下面是一个向 content:
URI 写入数据的片段示例:
import 'dart:typed_data';
import 'package:content_resolver/content_resolver.dart';
final data = Uint8List.fromList(utf8.encode('Hello World'));
await ContentResolver.writeContent(uri.toString(), data);
// 注意:如果 URI 不可写,则会抛出异常。
完整示例 Demo
以下是一个完整的示例代码,展示了如何处理通过 content:
URI 接收的内容,并将其保存到本地存储中:
import 'dart:async';
import 'dart:io';
import 'dart:typed_data';
import 'package:app_links/app_links.dart';
import 'package:content_resolver/content_resolver.dart';
import 'package:flutter/material.dart';
import 'package:path_provider/path_provider.dart';
import 'package:rxdart/rxdart.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
final _contentSubject = PublishSubject<Content>();
late final StreamSubscription<String> _appLinksSub;
@override
void initState() {
super.initState();
// 示例说明了如何使用 ContentResolver 处理内容意图。
_appLinksSub = AppLinks().stringLinkStream.listen(_handleUri);
Future.microtask(() async {
_handleUri(await AppLinks().getInitialLinkString());
});
}
Future<void> _handleUri(String? uri) async {
if (uri == null) return;
final metadata = await ContentResolver.resolveContentMetadata(uri);
final bb = BytesBuilder();
ContentResolver.resolveContentToStream(uri).listen((event) {
bb.add(event);
}, onDone: () {
_save(bb.toBytes());
_contentSubject.add(
Content(
data: bb.toBytes(),
mimeType: metadata.mimeType,
fileName: metadata.fileName,
),
);
});
}
Future<void> _save(Uint8List data) async {
final dir = await getExternalStorageDirectory();
await dir!.create(recursive: true);
await File('${dir.path}/test.jpg').writeAsBytes(data);
}
@override
void dispose() {
_appLinksSub.cancel();
_contentSubject.close();
super.dispose();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('ContentResolver example app'),
),
body: StreamBuilder<Content>(
stream: _contentSubject.stream,
builder: (context, snapshot) {
return Center(
child: snapshot.hasData
? Image.memory(snapshot.data!.data)
: Text('Nothing received.'),
);
}),
),
);
}
}
class Content {
final Uint8List data;
final String mimeType;
final String fileName;
Content({required this.data, required this.mimeType, required this.fileName});
}
此示例展示了如何监听应用链接中的 content:
URI,解析内容并将其保存到设备的外部存储中。最后,它会在屏幕上显示接收到的图像。请确保你已经添加了必要的权限(如读取和写入外部存储)到你的 AndroidManifest.xml
文件中。
更多关于Flutter内容访问插件content_resolver的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter内容访问插件content_resolver的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在Flutter中,如果你想访问Android设备上的内容(如文件、图片等),通常会使用到content_resolver
相关的功能。尽管Flutter本身没有直接名为content_resolver
的插件,但你可以通过platform_channels
与原生Android代码进行交互,从而实现访问内容的功能。
下面是一个简单的示例,展示如何在Flutter中通过Platform Channels调用Android的ContentResolver
来访问设备上的图片。
1. 创建Flutter项目
首先,确保你已经安装了Flutter SDK,并创建了一个新的Flutter项目。
flutter create content_resolver_example
cd content_resolver_example
2. 在Android原生代码中实现ContentResolver功能
编辑android/app/src/main/kotlin/.../MainActivity.kt
(如果你使用的是Kotlin)或android/app/src/main/java/.../MainActivity.java
(如果你使用的是Java)。
Kotlin示例
package com.example.content_resolver_example
import android.content.ContentResolver
import android.content.ContentUris
import android.content.Context
import android.database.Cursor
import android.net.Uri
import android.provider.MediaStore
import androidx.annotation.NonNull
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel
class MainActivity: FlutterActivity() {
private val CHANNEL = "com.example.content_resolver_example/channel"
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine)
MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result ->
if (call.method == "getImages") {
val images = getImageUris(this)
result.success(images)
} else {
result.notImplemented()
}
}
}
private fun getImageUris(context: Context): List<String> {
val projection = arrayOf(MediaStore.Images.Media._ID)
val selection = "${MediaStore.Images.Media.MIME_TYPE} = ? OR ${MediaStore.Images.Media.MIME_TYPE} = ?"
val selectionArgs = arrayOf("image/jpeg", "image/png")
val sortOrder = "${MediaStore.Images.Media._ID} DESC"
val resolver = context.contentResolver
val uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
val cursor: Cursor? = resolver.query(
uri, projection, selection, selectionArgs, sortOrder
)
val imageUris = mutableListOf<String>()
cursor?.use {
if (it.moveToFirst()) {
do {
val id = it.getLong(it.getColumnIndexOrThrow(MediaStore.Images.Media._ID))
val contentUri = ContentUris.withAppendedId(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id)
imageUris.add(contentUri.toString())
} while (it.moveToNext())
}
}
return imageUris
}
}
3. 在Flutter中调用原生方法
编辑lib/main.dart
文件,添加一个按钮来调用原生方法并显示结果。
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
static const platform = const MethodChannel('com.example.content_resolver_example/channel');
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Content Resolver Example'),
),
body: Center(
child: ElevatedButton(
onPressed: _getImages,
child: Text('Get Images'),
),
),
),
);
}
Future<void> _getImages() async {
try {
final String result = await platform.invokeMethod('getImages');
// 假设返回的是JSON数组格式的字符串,需要转换成List<String>
final List<dynamic> imageUris = jsonDecode(result);
print('Image URIs: $imageUris');
// 你可以在这里显示图片,比如使用Image.network(uri)
} on PlatformException catch (e) {
print("Failed to invoke: '${e.message}'.");
}
}
}
4. 运行应用
确保你已经连接了一个Android设备或启动了Android模拟器,然后运行Flutter应用。
flutter run
点击按钮后,你应该能在控制台看到从设备中检索到的图片URI列表。你可以进一步处理这些URI,例如在Flutter应用中显示这些图片。
这个示例展示了如何通过Platform Channels在Flutter中调用Android的ContentResolver
。你可以根据需要扩展这个示例,以实现更复杂的功能。