|
| 1 | +# protocol_handler |
| 2 | + |
| 3 | +[![pub version][pub-image]][pub-url] [![][discord-image]][discord-url] |
| 4 | + |
| 5 | +[pub-image]: https://img.shields.io/pub/v/protocol_handler.svg |
| 6 | +[pub-url]: https://pub.dev/packages/protocol_handler |
| 7 | + |
| 8 | +[discord-image]: https://img.shields.io/discord/884679008049037342.svg |
| 9 | +[discord-url]: https://discord.gg/zPa6EZ2jqb |
| 10 | + |
| 11 | +这个插件允许 Flutter **桌面** 应用注册及处理自定义协议(即深度链接)。 |
| 12 | + |
| 13 | +--- |
| 14 | + |
| 15 | +[English](./README.md) | 简体中文 |
| 16 | + |
| 17 | +--- |
| 18 | + |
| 19 | +<!-- START doctoc generated TOC please keep comment here to allow auto update --> |
| 20 | +<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> |
| 21 | + |
| 22 | +- [protocol_handler](#protocol_handler) |
| 23 | + - [平台支持](#平台支持) |
| 24 | + - [快速开始](#快速开始) |
| 25 | + - [安装](#安装) |
| 26 | + - [用法](#用法) |
| 27 | + - [macOS](#macos) |
| 28 | + - [Windows](#windows) |
| 29 | + - [监听事件](#监听事件) |
| 30 | + - [谁在用使用它?](#谁在用使用它) |
| 31 | + - [许可证](#许可证) |
| 32 | + |
| 33 | +<!-- END doctoc generated TOC please keep comment here to allow auto update --> |
| 34 | + |
| 35 | +## 平台支持 |
| 36 | + |
| 37 | +| Linux | macOS | Windows | |
| 38 | +| :---: | :---: | :-----: | |
| 39 | +| ➖ | ✔️ | ✔️ | |
| 40 | + |
| 41 | +## 快速开始 |
| 42 | + |
| 43 | +### 安装 |
| 44 | + |
| 45 | +将此添加到你的软件包的 pubspec.yaml 文件: |
| 46 | + |
| 47 | +```yaml |
| 48 | +dependencies: |
| 49 | + protocol_handler: ^0.1.0 |
| 50 | +``` |
| 51 | +
|
| 52 | +或 |
| 53 | +
|
| 54 | +```yaml |
| 55 | +dependencies: |
| 56 | + protocol_handler: |
| 57 | + git: |
| 58 | + url: https://github.com/leanflutter/protocol_handler.git |
| 59 | + ref: main |
| 60 | +``` |
| 61 | +
|
| 62 | +### 用法 |
| 63 | +
|
| 64 | +##### macOS |
| 65 | +
|
| 66 | +更改文件 `macos/Runner/Info.plist` 如下: |
| 67 | + |
| 68 | +```diff |
| 69 | +<?xml version="1.0" encoding="UTF-8"?> |
| 70 | +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> |
| 71 | +<plist version="1.0"> |
| 72 | +<dict> |
| 73 | + <key>CFBundleDevelopmentRegion</key> |
| 74 | + <string>$(DEVELOPMENT_LANGUAGE)</string> |
| 75 | + <key>CFBundleExecutable</key> |
| 76 | + <string>$(EXECUTABLE_NAME)</string> |
| 77 | + <key>CFBundleIconFile</key> |
| 78 | + <string></string> |
| 79 | + <key>CFBundleIdentifier</key> |
| 80 | + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> |
| 81 | + <key>CFBundleInfoDictionaryVersion</key> |
| 82 | + <string>6.0</string> |
| 83 | + <key>CFBundleName</key> |
| 84 | + <string>$(PRODUCT_NAME)</string> |
| 85 | + <key>CFBundlePackageType</key> |
| 86 | + <string>APPL</string> |
| 87 | + <key>CFBundleShortVersionString</key> |
| 88 | + <string>$(FLUTTER_BUILD_NAME)</string> |
| 89 | + <key>CFBundleVersion</key> |
| 90 | + <string>$(FLUTTER_BUILD_NUMBER)</string> |
| 91 | + <key>LSMinimumSystemVersion</key> |
| 92 | + <string>$(MACOSX_DEPLOYMENT_TARGET)</string> |
| 93 | + <key>NSHumanReadableCopyright</key> |
| 94 | + <string>$(PRODUCT_COPYRIGHT)</string> |
| 95 | + <key>NSMainNibFile</key> |
| 96 | + <string>MainMenu</string> |
| 97 | ++ <key>CFBundleURLTypes</key> |
| 98 | ++ <array> |
| 99 | ++ <dict> |
| 100 | ++ <key>CFBundleTypeRole</key> |
| 101 | ++ <string>Editor</string> |
| 102 | ++ <key>CFBundleURLName</key> |
| 103 | ++ <string></string> |
| 104 | ++ <key>CFBundleURLSchemes</key> |
| 105 | ++ <array> |
| 106 | ++ <string>myprotocol</string> |
| 107 | ++ </array> |
| 108 | ++ </dict> |
| 109 | ++ </array> |
| 110 | + <key>NSPrincipalClass</key> |
| 111 | + <string>NSApplication</string> |
| 112 | +</dict> |
| 113 | +</plist> |
| 114 | +} |
| 115 | +``` |
| 116 | + |
| 117 | +##### Windows |
| 118 | + |
| 119 | +更改文件 `windows/runner/main.cpp` 如下: |
| 120 | + |
| 121 | +```diff |
| 122 | +#include <flutter/dart_project.h> |
| 123 | +#include <flutter/flutter_view_controller.h> |
| 124 | +#include <windows.h> |
| 125 | +
|
| 126 | +#include "flutter_window.h" |
| 127 | +#include "utils.h" |
| 128 | +
|
| 129 | ++#include <protocol_handler/protocol_handler_plugin.h> |
| 130 | +
|
| 131 | +int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev, |
| 132 | + _In_ wchar_t *command_line, _In_ int show_command) { |
| 133 | ++ HWND hwnd = ::FindWindow(L"FLUTTER_RUNNER_WIN32_WINDOW", L"protocol_handler_example"); |
| 134 | ++ if (hwnd != NULL) { |
| 135 | ++ DispatchToProtocolHandler(hwnd); |
| 136 | ++ |
| 137 | ++ ::ShowWindow(hwnd, SW_NORMAL); |
| 138 | ++ ::SetForegroundWindow(hwnd); |
| 139 | ++ return EXIT_FAILURE; |
| 140 | ++ } |
| 141 | +
|
| 142 | + // Attach to console when present (e.g., 'flutter run') or create a |
| 143 | + // new console when running with a debugger. |
| 144 | + if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) { |
| 145 | + CreateAndAttachConsole(); |
| 146 | + } |
| 147 | +
|
| 148 | + // Initialize COM, so that it is available for use in the library and/or |
| 149 | + // plugins. |
| 150 | + ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); |
| 151 | +
|
| 152 | + flutter::DartProject project(L"data"); |
| 153 | +
|
| 154 | + std::vector<std::string> command_line_arguments = |
| 155 | + GetCommandLineArguments(); |
| 156 | +
|
| 157 | + project.set_dart_entrypoint_arguments(std::move(command_line_arguments)); |
| 158 | +
|
| 159 | + FlutterWindow window(project); |
| 160 | + Win32Window::Point origin(10, 10); |
| 161 | + Win32Window::Size size(1280, 720); |
| 162 | + if (!window.CreateAndShow(L"protocol_handler_example", origin, size)) { |
| 163 | + return EXIT_FAILURE; |
| 164 | + } |
| 165 | + window.SetQuitOnClose(true); |
| 166 | +
|
| 167 | + ::MSG msg; |
| 168 | + while (::GetMessage(&msg, nullptr, 0, 0)) { |
| 169 | + ::TranslateMessage(&msg); |
| 170 | + ::DispatchMessage(&msg); |
| 171 | + } |
| 172 | +
|
| 173 | + ::CoUninitialize(); |
| 174 | + return EXIT_SUCCESS; |
| 175 | +} |
| 176 | +``` |
| 177 | + |
| 178 | +```dart |
| 179 | +import 'package:protocol_handler/protocol_handler.dart'; |
| 180 | +
|
| 181 | +void main() async { |
| 182 | + // 必须加上这一行。 |
| 183 | + WidgetsFlutterBinding.ensureInitialized(); |
| 184 | +
|
| 185 | + // 注册一个自定义协议。 |
| 186 | + // 对于 macOS 平台需要在 ios/Runner/Info.plist 中声明 scheme。 |
| 187 | + await protocolHandler.register('myprotocol'); |
| 188 | +
|
| 189 | + runApp(MyApp()); |
| 190 | +} |
| 191 | +``` |
| 192 | + |
| 193 | +### 监听事件 |
| 194 | + |
| 195 | +```dart |
| 196 | +class HomePage extends StatefulWidget { |
| 197 | + const HomePage({Key? key}) : super(key: key); |
| 198 | +
|
| 199 | + @override |
| 200 | + _HomePageState createState() => _HomePageState(); |
| 201 | +} |
| 202 | +
|
| 203 | +class _HomePageState extends State<HomePage> with ProtocolListener { |
| 204 | + @override |
| 205 | + void initState() { |
| 206 | + protocolHandler.addListener(this); |
| 207 | + super.initState(); |
| 208 | + } |
| 209 | +
|
| 210 | + @override |
| 211 | + void dispose() { |
| 212 | + protocolHandler.removeListener(this); |
| 213 | + super.dispose(); |
| 214 | + } |
| 215 | +
|
| 216 | + @override |
| 217 | + Widget build(BuildContext context) { |
| 218 | + // ... |
| 219 | + } |
| 220 | +
|
| 221 | + @override |
| 222 | + void onProtocolUrlReceived(String url) { |
| 223 | + String log = 'Url received: $url)'; |
| 224 | + print(log); |
| 225 | + } |
| 226 | +} |
| 227 | +``` |
| 228 | + |
| 229 | +> 请看这个插件的示例应用,以了解完整的例子。 |
| 230 | + |
| 231 | +## 谁在用使用它? |
| 232 | + |
| 233 | +- [比译](https://biyidev.com/) - 一个便捷的翻译和词典应用程序。 |
| 234 | + |
| 235 | +## 许可证 |
| 236 | + |
| 237 | +[MIT](./LICENSE) |
0 commit comments