Flutter浏览器扩展交互插件chrome_extension的使用
Flutter浏览器扩展交互插件chrome_extension的使用
chrome_extension.dart
chrome_extension.dart
是一个用于访问Chrome扩展中可用的 chrome.*
APIs 的库。
这使得我们可以用 Dart & Flutter 构建 Chrome 扩展,并与原生 API 轻松互操作,提供高级类型安全接口。JS 互操作基于 dart:js_interop
(静态互操作),使其为未来的 WASM 编译做好准备。
使用该库
示例
chrome.tabs
import 'package:chrome_extension/tabs.dart';
void main() async {
var tabs = await chrome.tabs.query(QueryInfo(
active: true,
currentWindow: true,
));
print(tabs.first.title);
}
chrome.alarms
import 'package:chrome_extension/alarms.dart';
void main() async {
await chrome.alarms.create('MyAlarm', AlarmCreateInfo(delayInMinutes: 2));
var alarm = await chrome.alarms.get('MyAlarm');
print(alarm!.name);
}
chrome.power
import 'package:chrome_extension/power.dart';
void main() {
chrome.power.requestKeepAwake(Level.display);
}
chrome.runtime
import 'dart:js_interop';
import 'package:chrome_extension/runtime.dart';
void main() async {
chrome.runtime.onInstalled.listen((e) {
print('OnInstalled: ${e.reason}');
});
chrome.runtime.onMessage.listen((e) {
e.sendResponse.callAsFunction(null, {'the_response': 1}.jsify());
});
}
chrome.storage
import 'package:chrome_extension/storage.dart';
void main() async {
await chrome.storage.local.set({'mykey': 'value'});
var values = await chrome.storage.local.get(null /* all */);
print(values['mykey']);
}
可用的 APIs
以下是部分可用的 API 列表:
package:chrome_extension/accessibility_features.dart
(API reference)package:chrome_extension/action.dart
(API reference)package:chrome_extension/alarms.dart
(API reference)package:chrome_extension/audio.dart
(API reference)package:chrome_extension/bookmarks.dart
(API reference)- …(更多API详见官方文档)
文档
- Chrome Extensions API reference
- 查看 example folder 获取一些使用 Flutter 和 Dart 构建 Chrome 扩展的示例
使用 Flutter 构建 Chrome 扩展的技巧
使用 Flutter Desktop 开发应用
为了在具备热重载功能的舒适环境中开发,大部分应用程序(UI部分)应该使用 Flutter desktop 开发。
这需要在 UI 和 chrome_extension
API 之间创建一个抽象层。
在桌面入口点,使用此抽象层的假实现,例如:
// lib/main_desktop.dart
void main() {
// 注入一个不使用真实 chrome_extension 包的假服务
var service = FakeBookmarkService();
runApp(MyExtensionPopup(service));
}
abstract class BookmarkService {
Future<List<Bookmark>> getBookmarks();
}
class FakeBookmarkService implements BookmarkService {
@override
Future<List<Bookmark>> getBookmarks() async => [Bookmark()];
}
通过以下命令启动此入口点:
flutter run -t lib/main_desktop.dart -d macos|windows|linux
实际编译扩展中使用的真正入口点如下所示:
// lib/main.dart
void main() {
var service = ChromeBookmarkService();
runApp(MyExtensionPopup(service));
}
class ChromeBookmarkService implements BookmarkService {
@override
Future<List<Bookmark>> getBookmarks() async {
// 真实实现使用 chrome.bookmarks
return (await chrome.bookmarks.getTree()).map(Bookmark.new).toList();
}
}
构建脚本
web/manifest.json
{
"manifest_version": 3,
"name": "my_extension",
"permissions": [
"activeTab"
],
"options_page": "options.html",
"background": {
"service_worker": "background.dart.js"
},
"action": {
"default_popup": "index.html",
"default_icon": {
"16": "icons-16.png"
}
},
"content_security_policy": {
"extension_pages": "script-src 'self' 'wasm-unsafe-eval'; object-src 'self';"
}
}
tool/build.dart
void main() async {
await _process.runProcess([
'flutter',
'build',
'web',
'-t',
'web/popup.dart',
'--csp',
'--web-renderer=canvaskit',
'--no-web-resources-cdn',
]);
for (var script in [
'background.dart',
'content_script.dart',
'options.dart'
]) {
await _process.runProcess([
Platform.resolvedExecutable,
'compile',
'js',
'web/$script',
'--output',
'build/web/$script.js',
]);
}
}
它会构建 Flutter 应用并编译所有其他 Dart 脚本(例如:options.dart.js, popup.dart.js, background.dart.js)
测试
编写使用 puppeteer-dart 的测试代码如下:
import 'package:collection/collection.dart';
import 'package:puppeteer/puppeteer.dart';
void main() async {
// 编译扩展
var extensionPath = '...';
var browser = await puppeteer.launch(
headless: false,
args: [
'--disable-extensions-except=$extensionPath',
'--load-extension=$extensionPath',
// 如果需要从扩展内部连接到 puppeteer,则允许进行测试
'--remote-allow-origins=*',
],
);
// 查找后台页面目标
var targetName = 'service_worker';
var backgroundPageTarget =
browser.targets.firstWhereOrNull((t) => t.type == targetName);
backgroundPageTarget ??=
await browser.waitForTarget((target) => target.type == targetName);
var worker = (await backgroundPageTarget.worker)!;
var url = Uri.parse(worker.url!);
assert(url.scheme == 'chrome-extension');
var extensionId = url.host;
// 前往弹出页面
await (await browser.pages)
.first
.goto('chrome-extension://$extensionId/popup.html');
// 更多测试代码...
}
以上就是关于 chrome_extension
插件的详细介绍和使用方法,希望对您有所帮助!
更多关于Flutter浏览器扩展交互插件chrome_extension的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter浏览器扩展交互插件chrome_extension的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter应用中与Chrome扩展进行交互的示例代码,使用chrome_extension
插件。请注意,由于chrome_extension
插件的具体实现和API可能会根据插件版本和Chrome扩展的复杂性有所不同,以下代码是一个简化的示例,用于展示基本思路。
首先,确保你的Flutter项目已经添加了chrome_extension
插件。你可以在pubspec.yaml
文件中添加以下依赖项:
dependencies:
flutter:
sdk: flutter
chrome_extension: ^x.y.z # 替换为最新版本号
然后运行flutter pub get
来安装依赖。
接下来,我们假设你有一个Chrome扩展,它提供了一个名为myExtension
的对象,并且这个对象有一个方法sendMessage
,用于发送消息到扩展。以下是如何在Flutter中使用这个扩展的示例代码:
- 在
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.INTERNET" />
<!-- 如果需要其他权限,也请在这里添加 -->
</manifest>
- 在
ios/Runner/Info.plist
中添加必要的配置(如果需要与iOS上的Chrome交互):
确保你的iOS应用有适当的权限和配置来与Chrome应用交互。
- 在Flutter代码中与Chrome扩展交互:
import 'package:flutter/material.dart';
import 'package:chrome_extension/chrome_extension.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
String responseFromExtension = '';
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter Chrome Extension Interaction'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Response from Chrome Extension:'),
Text(responseFromExtension),
SizedBox(height: 20),
ElevatedButton(
onPressed: _sendMessageToExtension,
child: Text('Send Message to Extension'),
),
],
),
),
),
);
}
Future<void> _sendMessageToExtension() async {
try {
// 假设Chrome扩展的ID是`my-extension-id`,并且它提供了一个全局对象`myExtension`
var extension = await ChromeExtension.connect('my-extension-id');
// 发送消息到扩展
var result = await extension.sendMessage({
'type': 'hello',
'message': 'Hello from Flutter app!',
});
// 更新状态以显示响应
setState(() {
responseFromExtension = result.toString();
});
} catch (error) {
print('Error communicating with Chrome extension: $error');
setState(() {
responseFromExtension = 'Error: $error';
});
}
}
}
注意:
-
上述代码中的
ChromeExtension.connect('my-extension-id')
和extension.sendMessage(...)
是假设的方法调用,实际使用时需要参考chrome_extension
插件的文档和API。 -
Chrome扩展的ID和全局对象名称需要替换为你实际使用的值。
-
由于Chrome扩展的复杂性,可能需要在Chrome扩展中编写特定的代码来监听和处理来自Flutter应用的消息。
-
确保Chrome扩展已经正确安装并启用,且其权限和配置允许与Flutter应用进行交互。
-
在实际开发中,可能还需要处理更多的错误情况和边界情况。
由于chrome_extension
插件的具体实现细节可能有所不同,建议查阅该插件的官方文档和示例代码以获取更准确的信息。