├── example
├── linux
│ ├── .gitignore
│ ├── main.cc
│ ├── flutter
│ │ ├── generated_plugin_registrant.h
│ │ ├── generated_plugin_registrant.cc
│ │ ├── generated_plugins.cmake
│ │ └── CMakeLists.txt
│ ├── my_application.h
│ ├── my_application.cc
│ └── CMakeLists.txt
├── ios
│ ├── Runner
│ │ ├── Runner-Bridging-Header.h
│ │ ├── Assets.xcassets
│ │ │ ├── LaunchImage.imageset
│ │ │ │ ├── LaunchImage.png
│ │ │ │ ├── LaunchImage@2x.png
│ │ │ │ ├── LaunchImage@3x.png
│ │ │ │ ├── README.md
│ │ │ │ └── Contents.json
│ │ │ └── AppIcon.appiconset
│ │ │ │ ├── Icon-App-20x20@1x.png
│ │ │ │ ├── Icon-App-20x20@2x.png
│ │ │ │ ├── Icon-App-20x20@3x.png
│ │ │ │ ├── Icon-App-29x29@1x.png
│ │ │ │ ├── Icon-App-29x29@2x.png
│ │ │ │ ├── Icon-App-29x29@3x.png
│ │ │ │ ├── Icon-App-40x40@1x.png
│ │ │ │ ├── Icon-App-40x40@2x.png
│ │ │ │ ├── Icon-App-40x40@3x.png
│ │ │ │ ├── Icon-App-60x60@2x.png
│ │ │ │ ├── Icon-App-60x60@3x.png
│ │ │ │ ├── Icon-App-76x76@1x.png
│ │ │ │ ├── Icon-App-76x76@2x.png
│ │ │ │ ├── Icon-App-1024x1024@1x.png
│ │ │ │ ├── Icon-App-83.5x83.5@2x.png
│ │ │ │ └── Contents.json
│ │ ├── AppDelegate.swift
│ │ ├── Base.lproj
│ │ │ ├── Main.storyboard
│ │ │ └── LaunchScreen.storyboard
│ │ └── Info.plist
│ ├── Flutter
│ │ ├── Debug.xcconfig
│ │ ├── Release.xcconfig
│ │ └── AppFrameworkInfo.plist
│ ├── Runner.xcodeproj
│ │ ├── project.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata
│ │ │ │ ├── WorkspaceSettings.xcsettings
│ │ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── Runner.xcscheme
│ ├── Runner.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ ├── WorkspaceSettings.xcsettings
│ │ │ └── IDEWorkspaceChecks.plist
│ ├── .gitignore
│ ├── RunnerTests
│ │ └── RunnerTests.swift
│ └── Podfile
├── web
│ ├── favicon.png
│ ├── icons
│ │ ├── Icon-192.png
│ │ ├── Icon-512.png
│ │ ├── Icon-maskable-192.png
│ │ └── Icon-maskable-512.png
│ ├── manifest.json
│ └── index.html
├── assets
│ ├── flutter_logo.png
│ └── ic_launcher.png
├── android
│ ├── gradle.properties
│ ├── app
│ │ ├── src
│ │ │ ├── main
│ │ │ │ ├── res
│ │ │ │ │ ├── mipmap-hdpi
│ │ │ │ │ │ └── ic_launcher.png
│ │ │ │ │ ├── mipmap-mdpi
│ │ │ │ │ │ └── ic_launcher.png
│ │ │ │ │ ├── mipmap-xhdpi
│ │ │ │ │ │ └── ic_launcher.png
│ │ │ │ │ ├── mipmap-xxhdpi
│ │ │ │ │ │ └── ic_launcher.png
│ │ │ │ │ ├── mipmap-xxxhdpi
│ │ │ │ │ │ └── ic_launcher.png
│ │ │ │ │ ├── drawable
│ │ │ │ │ │ └── launch_background.xml
│ │ │ │ │ ├── drawable-v21
│ │ │ │ │ │ └── launch_background.xml
│ │ │ │ │ ├── values
│ │ │ │ │ │ └── styles.xml
│ │ │ │ │ └── values-night
│ │ │ │ │ │ └── styles.xml
│ │ │ │ ├── kotlin
│ │ │ │ │ └── com
│ │ │ │ │ │ └── fitem
│ │ │ │ │ │ └── flutter_util_code_example
│ │ │ │ │ │ └── MainActivity.kt
│ │ │ │ └── AndroidManifest.xml
│ │ │ ├── debug
│ │ │ │ └── AndroidManifest.xml
│ │ │ └── profile
│ │ │ │ └── AndroidManifest.xml
│ │ └── build.gradle
│ ├── gradle
│ │ └── wrapper
│ │ │ └── gradle-wrapper.properties
│ ├── .gitignore
│ ├── settings.gradle
│ └── build.gradle
├── macos
│ ├── Runner
│ │ ├── Configs
│ │ │ ├── Debug.xcconfig
│ │ │ ├── Release.xcconfig
│ │ │ ├── Warnings.xcconfig
│ │ │ └── AppInfo.xcconfig
│ │ ├── Assets.xcassets
│ │ │ └── AppIcon.appiconset
│ │ │ │ ├── app_icon_128.png
│ │ │ │ ├── app_icon_16.png
│ │ │ │ ├── app_icon_256.png
│ │ │ │ ├── app_icon_32.png
│ │ │ │ ├── app_icon_512.png
│ │ │ │ ├── app_icon_64.png
│ │ │ │ ├── app_icon_1024.png
│ │ │ │ └── Contents.json
│ │ ├── AppDelegate.swift
│ │ ├── Release.entitlements
│ │ ├── DebugProfile.entitlements
│ │ ├── MainFlutterWindow.swift
│ │ └── Info.plist
│ ├── .gitignore
│ ├── Flutter
│ │ ├── Flutter-Debug.xcconfig
│ │ ├── Flutter-Release.xcconfig
│ │ └── GeneratedPluginRegistrant.swift
│ ├── Runner.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ │ └── IDEWorkspaceChecks.plist
│ ├── Runner.xcodeproj
│ │ ├── project.xcworkspace
│ │ │ └── xcshareddata
│ │ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── Runner.xcscheme
│ ├── RunnerTests
│ │ └── RunnerTests.swift
│ ├── Podfile
│ └── Podfile.lock
├── lib
│ ├── router
│ │ ├── router.dart
│ │ ├── router_name.dart
│ │ └── router_page.dart
│ ├── function
│ │ ├── shared_prefs
│ │ │ ├── sp_constants.dart
│ │ │ └── shared_prefs_page.dart
│ │ ├── home_page.dart
│ │ ├── toast_page.dart
│ │ ├── app_page.dart
│ │ ├── uuid_page.dart
│ │ ├── device_page.dart
│ │ ├── log_page.dart
│ │ ├── connectivity_page.dart
│ │ ├── url_launcher_page.dart
│ │ ├── permission_page.dart
│ │ ├── path_page.dart
│ │ ├── encrypted_page.dart
│ │ └── share_page.dart
│ ├── main.dart
│ └── widget
│ │ └── display_screen.dart
├── windows
│ ├── runner
│ │ ├── resources
│ │ │ └── app_icon.ico
│ │ ├── resource.h
│ │ ├── utils.h
│ │ ├── runner.exe.manifest
│ │ ├── flutter_window.h
│ │ ├── main.cpp
│ │ ├── CMakeLists.txt
│ │ ├── utils.cpp
│ │ ├── flutter_window.cpp
│ │ ├── Runner.rc
│ │ └── win32_window.h
│ ├── .gitignore
│ ├── flutter
│ │ ├── generated_plugin_registrant.h
│ │ ├── generated_plugins.cmake
│ │ ├── generated_plugin_registrant.cc
│ │ └── CMakeLists.txt
│ └── CMakeLists.txt
├── README.md
├── .gitignore
├── test
│ └── widget_test.dart
├── analysis_options.yaml
└── pubspec.yaml
├── lib
├── constants
│ └── sp_constants.dart
├── log_utils.dart
├── utils.dart
├── uuid_utils.dart
├── app_utils.dart
├── null_safety_utils.dart
├── connectivity_utils.dart
├── permission_utils.dart
├── format_utils.dart
├── shared_prefs_utils.dart
├── url_launcher_utils.dart
├── share_utils.dart
├── toast_utils.dart
└── date_utils.dart
├── analysis_options.yaml
├── CHANGELOG-ZH.md
├── LICENSE
├── CHANGELOG.md
├── test
├── null_safety_test.dart
├── format_test.dart
├── date_test.dart
└── encrypt_test.dart
├── .metadata
├── .gitignore
└── pubspec.yaml
/example/linux/.gitignore:
--------------------------------------------------------------------------------
1 | flutter/ephemeral
2 |
--------------------------------------------------------------------------------
/example/ios/Runner/Runner-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | #import "GeneratedPluginRegistrant.h"
2 |
--------------------------------------------------------------------------------
/example/web/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fitem/flutter_util_code/HEAD/example/web/favicon.png
--------------------------------------------------------------------------------
/example/assets/flutter_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fitem/flutter_util_code/HEAD/example/assets/flutter_logo.png
--------------------------------------------------------------------------------
/example/assets/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fitem/flutter_util_code/HEAD/example/assets/ic_launcher.png
--------------------------------------------------------------------------------
/example/web/icons/Icon-192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fitem/flutter_util_code/HEAD/example/web/icons/Icon-192.png
--------------------------------------------------------------------------------
/example/web/icons/Icon-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fitem/flutter_util_code/HEAD/example/web/icons/Icon-512.png
--------------------------------------------------------------------------------
/example/android/gradle.properties:
--------------------------------------------------------------------------------
1 | org.gradle.jvmargs=-Xmx1536M
2 | android.useAndroidX=true
3 | android.enableJetifier=true
4 |
--------------------------------------------------------------------------------
/example/macos/Runner/Configs/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include "../../Flutter/Flutter-Debug.xcconfig"
2 | #include "Warnings.xcconfig"
3 |
--------------------------------------------------------------------------------
/example/macos/Runner/Configs/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include "../../Flutter/Flutter-Release.xcconfig"
2 | #include "Warnings.xcconfig"
3 |
--------------------------------------------------------------------------------
/example/web/icons/Icon-maskable-192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fitem/flutter_util_code/HEAD/example/web/icons/Icon-maskable-192.png
--------------------------------------------------------------------------------
/example/web/icons/Icon-maskable-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fitem/flutter_util_code/HEAD/example/web/icons/Icon-maskable-512.png
--------------------------------------------------------------------------------
/example/lib/router/router.dart:
--------------------------------------------------------------------------------
1 | /// Name:
2 | /// Created by Fitem on 2023/5/31
3 | export 'router_name.dart';
4 | export 'router_page.dart';
--------------------------------------------------------------------------------
/example/macos/.gitignore:
--------------------------------------------------------------------------------
1 | # Flutter-related
2 | **/Flutter/ephemeral/
3 | **/Pods/
4 |
5 | # Xcode-related
6 | **/dgph
7 | **/xcuserdata/
8 |
--------------------------------------------------------------------------------
/example/ios/Flutter/Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/example/ios/Flutter/Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2 | #include "Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/example/windows/runner/resources/app_icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fitem/flutter_util_code/HEAD/example/windows/runner/resources/app_icon.ico
--------------------------------------------------------------------------------
/example/macos/Flutter/Flutter-Debug.xcconfig:
--------------------------------------------------------------------------------
1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
2 | #include "ephemeral/Flutter-Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fitem/flutter_util_code/HEAD/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fitem/flutter_util_code/HEAD/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fitem/flutter_util_code/HEAD/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fitem/flutter_util_code/HEAD/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/example/macos/Flutter/Flutter-Release.xcconfig:
--------------------------------------------------------------------------------
1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
2 | #include "ephemeral/Flutter-Generated.xcconfig"
3 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fitem/flutter_util_code/HEAD/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/lib/constants/sp_constants.dart:
--------------------------------------------------------------------------------
1 | /// Name: SP Constants
2 | /// Created by Fitem on 2023/6/5
3 | class SPConstants {
4 | /// 设备ID
5 | static const String deviceId = 'device_id';
6 | }
--------------------------------------------------------------------------------
/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | include: package:flutter_lints/flutter.yaml
2 |
3 | # Additional information about this file can be found at
4 | # https://dart.dev/guides/language/analysis-options
5 |
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fitem/flutter_util_code/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
--------------------------------------------------------------------------------
/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fitem/flutter_util_code/HEAD/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_128.png
--------------------------------------------------------------------------------
/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fitem/flutter_util_code/HEAD/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_16.png
--------------------------------------------------------------------------------
/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fitem/flutter_util_code/HEAD/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_256.png
--------------------------------------------------------------------------------
/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fitem/flutter_util_code/HEAD/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_32.png
--------------------------------------------------------------------------------
/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fitem/flutter_util_code/HEAD/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_512.png
--------------------------------------------------------------------------------
/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fitem/flutter_util_code/HEAD/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_64.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fitem/flutter_util_code/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fitem/flutter_util_code/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
--------------------------------------------------------------------------------
/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fitem/flutter_util_code/HEAD/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/app_icon_1024.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fitem/flutter_util_code/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fitem/flutter_util_code/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fitem/flutter_util_code/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fitem/flutter_util_code/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fitem/flutter_util_code/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fitem/flutter_util_code/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fitem/flutter_util_code/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fitem/flutter_util_code/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fitem/flutter_util_code/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fitem/flutter_util_code/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fitem/flutter_util_code/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fitem/flutter_util_code/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fitem/flutter_util_code/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fitem/flutter_util_code/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Fitem/flutter_util_code/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
--------------------------------------------------------------------------------
/example/linux/main.cc:
--------------------------------------------------------------------------------
1 | #include "my_application.h"
2 |
3 | int main(int argc, char** argv) {
4 | g_autoptr(MyApplication) app = my_application_new();
5 | return g_application_run(G_APPLICATION(app), argc, argv);
6 | }
7 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/android/app/src/main/kotlin/com/fitem/flutter_util_code_example/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.fitem.flutter_util_code_example
2 |
3 | import io.flutter.embedding.android.FlutterActivity
4 |
5 | class MainActivity: FlutterActivity() {
6 | }
7 |
--------------------------------------------------------------------------------
/example/android/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | zipStoreBase=GRADLE_USER_HOME
4 | zipStorePath=wrapper/dists
5 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip
6 |
--------------------------------------------------------------------------------
/example/macos/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import Cocoa
2 | import FlutterMacOS
3 |
4 | @NSApplicationMain
5 | class AppDelegate: FlutterAppDelegate {
6 | override func applicationShouldTerminateAfterLastWindowClosed(_ sender: NSApplication) -> Bool {
7 | return true
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/example/macos/Runner/Release.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/macos/Runner.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/macos/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/macos/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/example/android/.gitignore:
--------------------------------------------------------------------------------
1 | gradle-wrapper.jar
2 | /.gradle
3 | /captures/
4 | /gradlew
5 | /gradlew.bat
6 | /local.properties
7 | GeneratedPluginRegistrant.java
8 |
9 | # Remember to never publicly share your keystore.
10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
11 | key.properties
12 | **/*.keystore
13 | **/*.jks
14 |
--------------------------------------------------------------------------------
/example/windows/.gitignore:
--------------------------------------------------------------------------------
1 | flutter/ephemeral/
2 |
3 | # Visual Studio user-specific files.
4 | *.suo
5 | *.user
6 | *.userosscache
7 | *.sln.docstates
8 |
9 | # Visual Studio build-related files.
10 | x64/
11 | x86/
12 |
13 | # Visual Studio cache files
14 | # files ending in .cache can be ignored
15 | *.[Cc]ache
16 | # but keep track of directories ending in .cache
17 | !*.[Cc]ache/
18 |
--------------------------------------------------------------------------------
/example/lib/function/shared_prefs/sp_constants.dart:
--------------------------------------------------------------------------------
1 | /// Name: SharedPreferences协议
2 | /// Created by Fitem on 2023/5/31
3 | class SPConstants {
4 | /// 年龄
5 | static const age = "age";
6 | /// 姓名
7 | static const name = "name";
8 | /// 身高
9 | static const height = "height";
10 | /// 性别
11 | static const gender = "gender";
12 | /// 家庭成员
13 | static const family = "family";
14 | }
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md:
--------------------------------------------------------------------------------
1 | # Launch Screen Assets
2 |
3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory.
4 |
5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
--------------------------------------------------------------------------------
/example/linux/flutter/generated_plugin_registrant.h:
--------------------------------------------------------------------------------
1 | //
2 | // Generated file. Do not edit.
3 | //
4 |
5 | // clang-format off
6 |
7 | #ifndef GENERATED_PLUGIN_REGISTRANT_
8 | #define GENERATED_PLUGIN_REGISTRANT_
9 |
10 | #include
11 |
12 | // Registers Flutter plugins.
13 | void fl_register_plugins(FlPluginRegistry* registry);
14 |
15 | #endif // GENERATED_PLUGIN_REGISTRANT_
16 |
--------------------------------------------------------------------------------
/example/windows/flutter/generated_plugin_registrant.h:
--------------------------------------------------------------------------------
1 | //
2 | // Generated file. Do not edit.
3 | //
4 |
5 | // clang-format off
6 |
7 | #ifndef GENERATED_PLUGIN_REGISTRANT_
8 | #define GENERATED_PLUGIN_REGISTRANT_
9 |
10 | #include
11 |
12 | // Registers Flutter plugins.
13 | void RegisterPlugins(flutter::PluginRegistry* registry);
14 |
15 | #endif // GENERATED_PLUGIN_REGISTRANT_
16 |
--------------------------------------------------------------------------------
/example/android/app/src/debug/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/android/app/src/profile/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/example/macos/Runner/DebugProfile.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.cs.allow-jit
8 |
9 | com.apple.security.network.server
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/example/ios/Runner/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | import UIKit
2 | import Flutter
3 |
4 | @UIApplicationMain
5 | @objc class AppDelegate: FlutterAppDelegate {
6 | override func application(
7 | _ application: UIApplication,
8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
9 | ) -> Bool {
10 | GeneratedPluginRegistrant.register(with: self)
11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions)
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/example/macos/Runner/MainFlutterWindow.swift:
--------------------------------------------------------------------------------
1 | import Cocoa
2 | import FlutterMacOS
3 |
4 | class MainFlutterWindow: NSWindow {
5 | override func awakeFromNib() {
6 | let flutterViewController = FlutterViewController()
7 | let windowFrame = self.frame
8 | self.contentViewController = flutterViewController
9 | self.setFrame(windowFrame, display: true)
10 |
11 | RegisterGeneratedPlugins(registry: flutterViewController)
12 |
13 | super.awakeFromNib()
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/example/linux/my_application.h:
--------------------------------------------------------------------------------
1 | #ifndef FLUTTER_MY_APPLICATION_H_
2 | #define FLUTTER_MY_APPLICATION_H_
3 |
4 | #include
5 |
6 | G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION,
7 | GtkApplication)
8 |
9 | /**
10 | * my_application_new:
11 | *
12 | * Creates a new Flutter-based application.
13 | *
14 | * Returns: a new #MyApplication.
15 | */
16 | MyApplication* my_application_new();
17 |
18 | #endif // FLUTTER_MY_APPLICATION_H_
19 |
--------------------------------------------------------------------------------
/example/windows/runner/resource.h:
--------------------------------------------------------------------------------
1 | //{{NO_DEPENDENCIES}}
2 | // Microsoft Visual C++ generated include file.
3 | // Used by Runner.rc
4 | //
5 | #define IDI_APP_ICON 101
6 |
7 | // Next default values for new objects
8 | //
9 | #ifdef APSTUDIO_INVOKED
10 | #ifndef APSTUDIO_READONLY_SYMBOLS
11 | #define _APS_NEXT_RESOURCE_VALUE 102
12 | #define _APS_NEXT_COMMAND_VALUE 40001
13 | #define _APS_NEXT_CONTROL_VALUE 1001
14 | #define _APS_NEXT_SYMED_VALUE 101
15 | #endif
16 | #endif
17 |
--------------------------------------------------------------------------------
/example/android/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
4 | def properties = new Properties()
5 |
6 | assert localPropertiesFile.exists()
7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
8 |
9 | def flutterSdkPath = properties.getProperty("flutter.sdk")
10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
12 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/drawable/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/drawable-v21/launch_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "LaunchImage.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "LaunchImage@2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "LaunchImage@3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/lib/log_utils.dart:
--------------------------------------------------------------------------------
1 | import 'dart:developer';
2 |
3 | import 'package:flutter/foundation.dart';
4 |
5 | /// Name: Log工具类
6 | /// Created by Fitem on 2023/5/31
7 | class LogUtils {
8 |
9 | /// 是否开启日志,默认Debug模式下开启
10 | static bool isOpenLog = kDebugMode;
11 |
12 | /// 调试打印
13 | static void println(String obj) {
14 | if (isOpenLog) debugPrint(obj);
15 | }
16 |
17 | /// Log 用于网络请求等长内容日志
18 | static void logger(String obj, {StackTrace? stackTrace, int level = 0}){
19 | if (isOpenLog) log(obj, stackTrace: stackTrace, level: level);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/example/macos/Runner/Configs/Warnings.xcconfig:
--------------------------------------------------------------------------------
1 | WARNING_CFLAGS = -Wall -Wconditional-uninitialized -Wnullable-to-nonnull-conversion -Wmissing-method-return-type -Woverlength-strings
2 | GCC_WARN_UNDECLARED_SELECTOR = YES
3 | CLANG_UNDEFINED_BEHAVIOR_SANITIZER_NULLABILITY = YES
4 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE
5 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES
6 | CLANG_WARN_PRAGMA_PACK = YES
7 | CLANG_WARN_STRICT_PROTOTYPES = YES
8 | CLANG_WARN_COMMA = YES
9 | GCC_WARN_STRICT_SELECTOR_MATCH = YES
10 | CLANG_WARN_OBJC_REPEATED_USE_OF_WEAK = YES
11 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES
12 | GCC_WARN_SHADOW = YES
13 | CLANG_WARN_UNREACHABLE_CODE = YES
14 |
--------------------------------------------------------------------------------
/example/README.md:
--------------------------------------------------------------------------------
1 | # flutter_util_code_example
2 |
3 | Demonstrates how to use the flutter_util_code plugin.
4 |
5 | ## Getting Started
6 |
7 | This project is a starting point for a Flutter application.
8 |
9 | A few resources to get you started if this is your first Flutter project:
10 |
11 | - [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
12 | - [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
13 |
14 | For help getting started with Flutter development, view the
15 | [online documentation](https://docs.flutter.dev/), which offers tutorials,
16 | samples, guidance on mobile development, and a full API reference.
17 |
--------------------------------------------------------------------------------
/lib/utils.dart:
--------------------------------------------------------------------------------
1 | /// Name:
2 | /// Created by Fitem on 2023/5/31
3 | export 'log_utils.dart';
4 | export 'shared_prefs_utils.dart';
5 | export 'toast_utils.dart';
6 | export 'uuid_utils.dart';
7 | export 'device_utils.dart';
8 | export 'app_utils.dart';
9 | export 'path_utils.dart';
10 | export 'encrypt_utils.dart';
11 | export 'url_launcher_utils.dart';
12 | export 'null_safety_utils.dart';
13 | export 'share_utils.dart';
14 | export 'connectivity_utils.dart';
15 | export 'package:connectivity_plus/connectivity_plus.dart';
16 | export 'permission_utils.dart';
17 | export 'package:permission_handler/permission_handler.dart';
18 | export 'format_utils.dart';
19 | export 'date_utils.dart';
20 |
--------------------------------------------------------------------------------
/example/macos/Runner/Configs/AppInfo.xcconfig:
--------------------------------------------------------------------------------
1 | // Application-level settings for the Runner target.
2 | //
3 | // This may be replaced with something auto-generated from metadata (e.g., pubspec.yaml) in the
4 | // future. If not, the values below would default to using the project name when this becomes a
5 | // 'flutter create' template.
6 |
7 | // The application's name. By default this is also the title of the Flutter window.
8 | PRODUCT_NAME = flutter_util_code_example
9 |
10 | // The application's bundle identifier
11 | PRODUCT_BUNDLE_IDENTIFIER = com.fitem.flutterUtilCodeExample
12 |
13 | // The copyright displayed in application information
14 | PRODUCT_COPYRIGHT = Copyright © 2023 com.fitem. All rights reserved.
15 |
--------------------------------------------------------------------------------
/example/ios/.gitignore:
--------------------------------------------------------------------------------
1 | **/dgph
2 | *.mode1v3
3 | *.mode2v3
4 | *.moved-aside
5 | *.pbxuser
6 | *.perspectivev3
7 | **/*sync/
8 | .sconsign.dblite
9 | .tags*
10 | **/.vagrant/
11 | **/DerivedData/
12 | Icon?
13 | **/Pods/
14 | **/.symlinks/
15 | profile
16 | xcuserdata
17 | **/.generated/
18 | Flutter/App.framework
19 | Flutter/Flutter.framework
20 | Flutter/Flutter.podspec
21 | Flutter/Generated.xcconfig
22 | Flutter/ephemeral/
23 | Flutter/app.flx
24 | Flutter/app.zip
25 | Flutter/flutter_assets/
26 | Flutter/flutter_export_environment.sh
27 | ServiceDefinitions.json
28 | Runner/GeneratedPluginRegistrant.*
29 |
30 | # Exceptions to above rules.
31 | !default.mode1v3
32 | !default.mode2v3
33 | !default.pbxuser
34 | !default.perspectivev3
35 |
--------------------------------------------------------------------------------
/example/windows/runner/utils.h:
--------------------------------------------------------------------------------
1 | #ifndef RUNNER_UTILS_H_
2 | #define RUNNER_UTILS_H_
3 |
4 | #include
5 | #include
6 |
7 | // Creates a console for the process, and redirects stdout and stderr to
8 | // it for both the runner and the Flutter library.
9 | void CreateAndAttachConsole();
10 |
11 | // Takes a null-terminated wchar_t* encoded in UTF-16 and returns a std::string
12 | // encoded in UTF-8. Returns an empty std::string on failure.
13 | std::string Utf8FromUtf16(const wchar_t* utf16_string);
14 |
15 | // Gets the command line arguments passed in as a std::vector,
16 | // encoded in UTF-8. Returns an empty std::vector on failure.
17 | std::vector GetCommandLineArguments();
18 |
19 | #endif // RUNNER_UTILS_H_
20 |
--------------------------------------------------------------------------------
/example/linux/flutter/generated_plugin_registrant.cc:
--------------------------------------------------------------------------------
1 | //
2 | // Generated file. Do not edit.
3 | //
4 |
5 | // clang-format off
6 |
7 | #include "generated_plugin_registrant.h"
8 |
9 | #include
10 | #include
11 |
12 | void fl_register_plugins(FlPluginRegistry* registry) {
13 | g_autoptr(FlPluginRegistrar) fast_rsa_registrar =
14 | fl_plugin_registry_get_registrar_for_plugin(registry, "FastRsaPlugin");
15 | fast_rsa_plugin_register_with_registrar(fast_rsa_registrar);
16 | g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
17 | fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
18 | url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
19 | }
20 |
--------------------------------------------------------------------------------
/example/lib/main.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter/services.dart';
3 | import 'package:get/get.dart';
4 |
5 | import 'router/router.dart';
6 |
7 | void main() {
8 | WidgetsFlutterBinding.ensureInitialized();
9 | // 强制竖屏
10 | SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]);
11 | runApp(const MyApp());
12 | }
13 |
14 | class MyApp extends StatelessWidget {
15 | const MyApp({super.key});
16 |
17 | @override
18 | Widget build(BuildContext context) {
19 | return GetMaterialApp(
20 | debugShowCheckedModeBanner: false,
21 | onGenerateTitle: (context) => 'FlutterUtilCode',
22 | initialRoute: RouterName.home,
23 | getPages: RouterPage.pages,
24 | );
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/example/ios/RunnerTests/RunnerTests.swift:
--------------------------------------------------------------------------------
1 | import Flutter
2 | import UIKit
3 | import XCTest
4 |
5 | @testable import flutter_util_code
6 |
7 | // This demonstrates a simple unit test of the Swift portion of this plugin's implementation.
8 | //
9 | // See https://developer.apple.com/documentation/xctest for more information about using XCTest.
10 |
11 | class RunnerTests: XCTestCase {
12 |
13 | func testGetPlatformVersion() {
14 | let plugin = FlutterUtilCodePlugin()
15 |
16 | let call = FlutterMethodCall(methodName: "getPlatformVersion", arguments: [])
17 |
18 | let resultExpectation = expectation(description: "result block must be called.")
19 | plugin.handle(call) { result in
20 | XCTAssertEqual(result as! String, "iOS " + UIDevice.current.systemVersion)
21 | resultExpectation.fulfill()
22 | }
23 | waitForExpectations(timeout: 1)
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/example/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 | migrate_working_dir/
12 |
13 | # IntelliJ related
14 | *.iml
15 | *.ipr
16 | *.iws
17 | .idea/
18 |
19 | # The .vscode folder contains launch configuration and tasks you configure in
20 | # VS Code which you may wish to be included in version control, so this line
21 | # is commented out by default.
22 | #.vscode/
23 |
24 | # Flutter/Dart/Pub related
25 | **/doc/api/
26 | **/ios/Flutter/.last_build_id
27 | .dart_tool/
28 | .flutter-plugins
29 | .flutter-plugins-dependencies
30 | .packages
31 | .pub-cache/
32 | .pub/
33 | /build/
34 |
35 | # Symbolication related
36 | app.*.symbols
37 |
38 | # Obfuscation related
39 | app.*.map.json
40 |
41 | # Android Studio will place build artifacts here
42 | /android/app/debug
43 | /android/app/profile
44 | /android/app/release
45 |
--------------------------------------------------------------------------------
/example/lib/router/router_name.dart:
--------------------------------------------------------------------------------
1 | /// Name: 路由名称
2 | /// Created by Fitem on 2023/5/31
3 | class RouterName {
4 | /// 首页
5 | static const home = "/";
6 | /// 日志工具类
7 | static const log = "/log";
8 | /// SharedPreferences工具类
9 | static String sharedPreference = "/shared_preference";
10 | /// Toast工具类
11 | static String toast = "/toast";
12 | /// UUID工具类
13 | static String uuid = "/uuid";
14 | /// 设备Device工具类
15 | static String device = "/device";
16 | /// App工具类
17 | static String app = "/app";
18 | /// Path工具类
19 | static String path = "/path";
20 | /// Encrypt工具类
21 | static String encrypt = "/encrypt";
22 | /// UrlLauncher工具类
23 | static String urlLauncher = "/url_launcher";
24 | /// Share工具类
25 | static String share = "/share";
26 | /// 网络工具类
27 | static String connectivity = "/connectivity";
28 | /// 权限工具类
29 | static String permission = "/permission";
30 | }
--------------------------------------------------------------------------------
/example/linux/flutter/generated_plugins.cmake:
--------------------------------------------------------------------------------
1 | #
2 | # Generated file, do not edit.
3 | #
4 |
5 | list(APPEND FLUTTER_PLUGIN_LIST
6 | fast_rsa
7 | url_launcher_linux
8 | )
9 |
10 | list(APPEND FLUTTER_FFI_PLUGIN_LIST
11 | )
12 |
13 | set(PLUGIN_BUNDLED_LIBRARIES)
14 |
15 | foreach(plugin ${FLUTTER_PLUGIN_LIST})
16 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin})
17 | target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
18 | list(APPEND PLUGIN_BUNDLED_LIBRARIES $)
19 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
20 | endforeach(plugin)
21 |
22 | foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
23 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin})
24 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
25 | endforeach(ffi_plugin)
26 |
--------------------------------------------------------------------------------
/example/ios/Flutter/AppFrameworkInfo.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | App
9 | CFBundleIdentifier
10 | io.flutter.flutter.app
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | App
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1.0
23 | MinimumOSVersion
24 | 11.0
25 |
26 |
27 |
--------------------------------------------------------------------------------
/CHANGELOG-ZH.md:
--------------------------------------------------------------------------------
1 | # CHANGELOG
2 |
3 | Language: [English](CHANGELOG.md) | 简体中文
4 |
5 | ## 0.6.0
6 | - 新增 DateUtils: 日期工具类
7 |
8 | ## 0.5.0
9 | - 新增 FormatUtils: 格式化工具类
10 |
11 | ## 0.4.0
12 | - 新增 PermissionUtils: 权限工具类
13 |
14 | ## 0.3.0
15 | - 调整 SharedPrefsUtils 返回值改为非空
16 |
17 | ## 0.2.0
18 | - 新增 ConnectivityUtils: 网络监听工具类
19 |
20 | ## 0.1.0
21 | - 新增 ShareUtils: 分享工具类
22 |
23 | ## 0.0.9
24 | - 新增 NullSafetyUtils: 空安全工具类
25 |
26 | ## 0.0.8
27 | - 新增 UrlLauncherUtils: URL跳转工具类
28 |
29 | ## 0.0.7
30 | - 更新 Flutter 依赖,设置 Flutter >=3.3.0 和 Dart >=2.18.0 <4.0.0
31 |
32 | ## 0.0.6
33 | - 新增 EncryptUtils: 加密工具类
34 |
35 | ## 0.0.5
36 | - 新增 PathUtils: Path工具类
37 |
38 | ## 0.0.4
39 | - 新增 AppUtils: App工具类
40 |
41 | ## 0.0.3
42 | - 新增 UuidUtils: UUID工具类
43 | - 新增 DeviceUtils: Device工具类
44 |
45 | ## 0.0.2
46 | - 新增 ToastUtils: Toast工具类
47 |
48 | ## 0.0.1
49 | - 新增 LogUtils: 日志工具类
50 | - 新增 SharedPresUtils: SharedPreferences工具类
51 |
--------------------------------------------------------------------------------
/example/macos/RunnerTests/RunnerTests.swift:
--------------------------------------------------------------------------------
1 | import FlutterMacOS
2 | import Cocoa
3 | import XCTest
4 |
5 | @testable import flutter_util_code
6 |
7 | // This demonstrates a simple unit test of the Swift portion of this plugin's implementation.
8 | //
9 | // See https://developer.apple.com/documentation/xctest for more information about using XCTest.
10 |
11 | class RunnerTests: XCTestCase {
12 |
13 | func testGetPlatformVersion() {
14 | let plugin = FlutterUtilCodePlugin()
15 |
16 | let call = FlutterMethodCall(methodName: "getPlatformVersion", arguments: [])
17 |
18 | let resultExpectation = expectation(description: "result block must be called.")
19 | plugin.handle(call) { result in
20 | XCTAssertEqual(result as! String,
21 | "macOS " + ProcessInfo.processInfo.operatingSystemVersionString)
22 | resultExpectation.fulfill()
23 | }
24 | waitForExpectations(timeout: 1)
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/example/windows/runner/runner.exe.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PerMonitorV2
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/example/windows/flutter/generated_plugins.cmake:
--------------------------------------------------------------------------------
1 | #
2 | # Generated file, do not edit.
3 | #
4 |
5 | list(APPEND FLUTTER_PLUGIN_LIST
6 | connectivity_plus
7 | fast_rsa
8 | permission_handler_windows
9 | share_plus
10 | url_launcher_windows
11 | )
12 |
13 | list(APPEND FLUTTER_FFI_PLUGIN_LIST
14 | )
15 |
16 | set(PLUGIN_BUNDLED_LIBRARIES)
17 |
18 | foreach(plugin ${FLUTTER_PLUGIN_LIST})
19 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/windows plugins/${plugin})
20 | target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
21 | list(APPEND PLUGIN_BUNDLED_LIBRARIES $)
22 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
23 | endforeach(plugin)
24 |
25 | foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
26 | add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin})
27 | list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
28 | endforeach(ffi_plugin)
29 |
--------------------------------------------------------------------------------
/example/lib/widget/display_screen.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_util_code/utils.dart';
3 |
4 | /// Name: 显示屏Widget
5 | /// Created by Fitem on 2023/6/5
6 | class DisplayScreen extends StatefulWidget{
7 |
8 | const DisplayScreen({Key? key}) : super(key: key);
9 |
10 | @override
11 | DisplayScreenState createState() => DisplayScreenState();
12 | }
13 |
14 | class DisplayScreenState extends State{
15 |
16 | String content = '';
17 | @override
18 | Widget build(BuildContext context) {
19 | return Container(
20 | color: Colors.grey[200],
21 | padding: const EdgeInsets.all(16),
22 | child: ListView(
23 | children: [Text(content, style: const TextStyle(fontSize: 14, color: Colors.black54, height: 1.5))],
24 | ),
25 | );
26 | }
27 |
28 | void addContent(String str){
29 | setState(() {
30 | content += '$str\n';
31 | LogUtils.println('content: $content');
32 | });
33 | }
34 | }
--------------------------------------------------------------------------------
/example/test/widget_test.dart:
--------------------------------------------------------------------------------
1 | // This is a basic Flutter widget test.
2 | //
3 | // To perform an interaction with a widget in your test, use the WidgetTester
4 | // utility in the flutter_test package. For example, you can send tap and scroll
5 | // gestures. You can also use WidgetTester to find child widgets in the widget
6 | // tree, read text, and verify that the values of widget properties are correct.
7 |
8 | import 'package:flutter/material.dart';
9 | import 'package:flutter_test/flutter_test.dart';
10 |
11 | import 'package:flutter_util_code_example/main.dart';
12 |
13 | void main() {
14 | testWidgets('Verify Platform version', (WidgetTester tester) async {
15 | // Build our app and trigger a frame.
16 | await tester.pumpWidget(const MyApp());
17 |
18 | // Verify that platform version is retrieved.
19 | expect(
20 | find.byWidgetPredicate(
21 | (Widget widget) => widget is Text &&
22 | widget.data!.startsWith('Running on:'),
23 | ),
24 | findsOneWidget,
25 | );
26 | });
27 | }
28 |
--------------------------------------------------------------------------------
/example/windows/runner/flutter_window.h:
--------------------------------------------------------------------------------
1 | #ifndef RUNNER_FLUTTER_WINDOW_H_
2 | #define RUNNER_FLUTTER_WINDOW_H_
3 |
4 | #include
5 | #include
6 |
7 | #include
8 |
9 | #include "win32_window.h"
10 |
11 | // A window that does nothing but host a Flutter view.
12 | class FlutterWindow : public Win32Window {
13 | public:
14 | // Creates a new FlutterWindow hosting a Flutter view running |project|.
15 | explicit FlutterWindow(const flutter::DartProject& project);
16 | virtual ~FlutterWindow();
17 |
18 | protected:
19 | // Win32Window:
20 | bool OnCreate() override;
21 | void OnDestroy() override;
22 | LRESULT MessageHandler(HWND window, UINT const message, WPARAM const wparam,
23 | LPARAM const lparam) noexcept override;
24 |
25 | private:
26 | // The project to run.
27 | flutter::DartProject project_;
28 |
29 | // The Flutter instance hosted by this window.
30 | std::unique_ptr flutter_controller_;
31 | };
32 |
33 | #endif // RUNNER_FLUTTER_WINDOW_H_
34 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/example/android/app/src/main/res/values-night/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
9 |
15 |
18 |
19 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2023 Fitem
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/example/web/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "flutter_util_code_example",
3 | "short_name": "flutter_util_code_example",
4 | "start_url": ".",
5 | "display": "standalone",
6 | "background_color": "#0175C2",
7 | "theme_color": "#0175C2",
8 | "description": "Demonstrates how to use the flutter_util_code plugin.",
9 | "orientation": "portrait-primary",
10 | "prefer_related_applications": false,
11 | "icons": [
12 | {
13 | "src": "icons/Icon-192.png",
14 | "sizes": "192x192",
15 | "type": "image/png"
16 | },
17 | {
18 | "src": "icons/Icon-512.png",
19 | "sizes": "512x512",
20 | "type": "image/png"
21 | },
22 | {
23 | "src": "icons/Icon-maskable-192.png",
24 | "sizes": "192x192",
25 | "type": "image/png",
26 | "purpose": "maskable"
27 | },
28 | {
29 | "src": "icons/Icon-maskable-512.png",
30 | "sizes": "512x512",
31 | "type": "image/png",
32 | "purpose": "maskable"
33 | }
34 | ]
35 | }
36 |
--------------------------------------------------------------------------------
/lib/uuid_utils.dart:
--------------------------------------------------------------------------------
1 | import 'package:uuid/uuid.dart';
2 |
3 | /// Name: UUID工具类
4 | /// 基于 [uuid](https://pub.dev/packages/uuid)
5 | /// Created by Fitem on 2023/6/4
6 | class UuidUtils {
7 |
8 | /// 获取uuid
9 | /// 基于uuid v1 + uuid v4 内容通过 getUuidV5 生成的uuid
10 | /// 例如:c4a760a8-dbcf-5254-a0d9-6a4474bd1b62
11 | static String getUuid(){
12 | return getUuidV5(getUuidV1() + getUuidV4());
13 | }
14 |
15 | /// 获取uuid v1
16 | /// 基于当前时间生成的uuid
17 | /// 例如:6c84fb90-12c4-11e1-840d-7b25c5ee775a
18 | static String getUuidV1() {
19 | var uuid = const Uuid();
20 | var v1 = uuid.v1();
21 | return v1;
22 | }
23 |
24 | /// 获取uuid v4
25 | /// 基于mathRNG随机数生成的uuid
26 | /// 例如:110ec58a-a0f2-4ac4-8393-c866d813b8d1
27 | static String getUuidV4() {
28 | var uuid = const Uuid();
29 | var v4 = uuid.v4();
30 | return v4;
31 | }
32 |
33 | /// 获取uuid v5
34 | /// 基于 namespace + 内容 生成的uuid
35 | /// 例如:c4a760a8-dbcf-5254-a0d9-6a4474bd1b62
36 | static String getUuidV5(String content) {
37 | var uuid = const Uuid();
38 | var v5 = uuid.v5(Uuid.NAMESPACE_URL, content);
39 | return v5;
40 | }
41 | }
--------------------------------------------------------------------------------
/example/windows/flutter/generated_plugin_registrant.cc:
--------------------------------------------------------------------------------
1 | //
2 | // Generated file. Do not edit.
3 | //
4 |
5 | // clang-format off
6 |
7 | #include "generated_plugin_registrant.h"
8 |
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include
14 |
15 | void RegisterPlugins(flutter::PluginRegistry* registry) {
16 | ConnectivityPlusWindowsPluginRegisterWithRegistrar(
17 | registry->GetRegistrarForPlugin("ConnectivityPlusWindowsPlugin"));
18 | FastRsaPluginRegisterWithRegistrar(
19 | registry->GetRegistrarForPlugin("FastRsaPlugin"));
20 | PermissionHandlerWindowsPluginRegisterWithRegistrar(
21 | registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin"));
22 | SharePlusWindowsPluginCApiRegisterWithRegistrar(
23 | registry->GetRegistrarForPlugin("SharePlusWindowsPluginCApi"));
24 | UrlLauncherWindowsRegisterWithRegistrar(
25 | registry->GetRegistrarForPlugin("UrlLauncherWindows"));
26 | }
27 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # CHANGELOG
2 |
3 | Language: English | [简体中文](CHANGELOG-ZH.md)
4 |
5 | ## 0.6.0
6 | - Add DateUtils: Date utility class
7 |
8 | ## 0.5.0
9 | - Add FormatUtils: Format utility class
10 |
11 | ## 0.4.0
12 | - Add PermissionUtils: Permission utility class
13 |
14 | ## 0.3.0
15 | - Adjust SharedPrefsUtils, The return value is non null
16 |
17 | ## 0.2.0
18 | - Add ConnectivityUtils: Network monitoring utility class
19 |
20 | ## 0.1.0
21 | - Add ShareUtils: Share utility class
22 |
23 | ## 0.0.9
24 | - Add NullSafetyUtils: Null safety utility class
25 |
26 | ## 0.0.8
27 | - Add UrlLauncherUtils: URL launcher utility class
28 |
29 | ## 0.0.7
30 | - Update Flutter dependencies, set Flutter >=3.3.0 and Dart to >=2.18.0 <4.0.0
31 |
32 | ## 0.0.6
33 | - Add EncryptUtils: Encryption utility class
34 |
35 | ## 0.0.5
36 | - Add PathUtils: Path utility class
37 |
38 | ## 0.0.4
39 | - Add AppUtils: App utility class
40 |
41 | ## 0.0.3
42 | - Add UuidUtils: UUID utility class
43 | - Add DeviceUtils: Device utility class
44 |
45 | ## 0.0.2
46 | - Add ToastUtils: Toast utility class
47 |
48 | ## 0.0.1
49 | - Add LogUtils: Logging utility class
50 | - Add SharedPresUtils: SharedPreferences utility class
--------------------------------------------------------------------------------
/example/macos/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIconFile
10 |
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | $(FLUTTER_BUILD_NAME)
21 | CFBundleVersion
22 | $(FLUTTER_BUILD_NUMBER)
23 | LSMinimumSystemVersion
24 | $(MACOSX_DEPLOYMENT_TARGET)
25 | NSHumanReadableCopyright
26 | $(PRODUCT_COPYRIGHT)
27 | NSMainNibFile
28 | MainMenu
29 | NSPrincipalClass
30 | NSApplication
31 |
32 |
33 |
--------------------------------------------------------------------------------
/example/macos/Flutter/GeneratedPluginRegistrant.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Generated file. Do not edit.
3 | //
4 |
5 | import FlutterMacOS
6 | import Foundation
7 |
8 | import connectivity_plus
9 | import device_info_plus
10 | import fast_rsa
11 | import package_info_plus
12 | import path_provider_foundation
13 | import share_plus
14 | import shared_preferences_foundation
15 | import url_launcher_macos
16 |
17 | func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
18 | ConnectivityPlugin.register(with: registry.registrar(forPlugin: "ConnectivityPlugin"))
19 | DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
20 | FastRsaPlugin.register(with: registry.registrar(forPlugin: "FastRsaPlugin"))
21 | FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin"))
22 | PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
23 | SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin"))
24 | SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
25 | UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
26 | }
27 |
--------------------------------------------------------------------------------
/example/lib/function/home_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_util_code_example/router/router.dart';
3 | import 'package:get/get.dart';
4 |
5 | /// Name: 首页
6 | /// Created by Fitem on 2023/5/31
7 | class HomePage extends StatelessWidget {
8 | HomePage({super.key});
9 |
10 | final Map _routerMap = {
11 | RouterName.log: 'Log工具类',
12 | RouterName.sharedPreference: 'SharedPreference工具类',
13 | RouterName.toast: 'Toast工具类',
14 | RouterName.uuid: 'UUID工具类',
15 | RouterName.device: '设备Device工具类',
16 | RouterName.app: 'App工具类',
17 | RouterName.path: 'Path工具类',
18 | RouterName.encrypt: 'Encrypt工具类',
19 | RouterName.urlLauncher: 'UrlLauncher工具类',
20 | RouterName.share: 'Share工具类',
21 | RouterName.connectivity: '网络工具类',
22 | RouterName.permission: '权限工具类',
23 | };
24 |
25 | @override
26 | Widget build(BuildContext context) {
27 | return Scaffold(
28 | appBar: AppBar(
29 | title: const Text('FlutterUtilCode'),
30 | ),
31 | body: ListView.builder(
32 | itemCount: _routerMap.length,
33 | itemBuilder: (_, index) {
34 | return ListTile(
35 | title: Text(_routerMap.values.elementAt(index)),
36 | onTap: () {
37 | Get.toNamed(_routerMap.keys.elementAt(index));
38 | },
39 | );
40 | },
41 | ),
42 | );
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/lib/app_utils.dart:
--------------------------------------------------------------------------------
1 | import 'package:package_info_plus/package_info_plus.dart';
2 |
3 | /// Name: App工具类
4 | /// 基于 [package_info_plus](https://pub.dev/packages/package_info_plus)
5 | /// Created by Fitem on 2023/6/7
6 | class AppUtils {
7 | /// App名称
8 | static Future getAppName() async {
9 | PackageInfo packageInfo = await PackageInfo.fromPlatform();
10 | return packageInfo.appName;
11 | }
12 |
13 | /// 包名
14 | static Future getPackageName() async {
15 | PackageInfo packageInfo = await PackageInfo.fromPlatform();
16 | return packageInfo.packageName;
17 | }
18 |
19 | /// 版本名
20 | static Future getVersionName() async {
21 | PackageInfo packageInfo = await PackageInfo.fromPlatform();
22 | return packageInfo.version;
23 | }
24 |
25 | /// 版本号
26 | static Future getVersionNumber() async {
27 | PackageInfo packageInfo = await PackageInfo.fromPlatform();
28 | return packageInfo.buildNumber;
29 | }
30 |
31 | /// 获取App构建签名
32 | /// 在 iOS 上为空字符串,在 Android 上为密钥签名(十六进制)
33 | static Future getBuildSignature() async {
34 | PackageInfo packageInfo = await PackageInfo.fromPlatform();
35 | return packageInfo.buildSignature;
36 | }
37 |
38 | /// 获取App安装商店
39 | /// 若是通过应用商店安装的应用,返回应用商店的名称,否则返回空字符串
40 | static Future getInstallerStore() async {
41 | PackageInfo packageInfo = await PackageInfo.fromPlatform();
42 | return packageInfo.installerStore ?? '';
43 | }
44 | }
--------------------------------------------------------------------------------
/example/windows/runner/main.cpp:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 |
5 | #include "flutter_window.h"
6 | #include "utils.h"
7 |
8 | int APIENTRY wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev,
9 | _In_ wchar_t *command_line, _In_ int show_command) {
10 | // Attach to console when present (e.g., 'flutter run') or create a
11 | // new console when running with a debugger.
12 | if (!::AttachConsole(ATTACH_PARENT_PROCESS) && ::IsDebuggerPresent()) {
13 | CreateAndAttachConsole();
14 | }
15 |
16 | // Initialize COM, so that it is available for use in the library and/or
17 | // plugins.
18 | ::CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
19 |
20 | flutter::DartProject project(L"data");
21 |
22 | std::vector command_line_arguments =
23 | GetCommandLineArguments();
24 |
25 | project.set_dart_entrypoint_arguments(std::move(command_line_arguments));
26 |
27 | FlutterWindow window(project);
28 | Win32Window::Point origin(10, 10);
29 | Win32Window::Size size(1280, 720);
30 | if (!window.Create(L"flutter_util_code_example", origin, size)) {
31 | return EXIT_FAILURE;
32 | }
33 | window.SetQuitOnClose(true);
34 |
35 | ::MSG msg;
36 | while (::GetMessage(&msg, nullptr, 0, 0)) {
37 | ::TranslateMessage(&msg);
38 | ::DispatchMessage(&msg);
39 | }
40 |
41 | ::CoUninitialize();
42 | return EXIT_SUCCESS;
43 | }
44 |
--------------------------------------------------------------------------------
/example/lib/function/toast_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_util_code/utils.dart';
3 |
4 | /// Name: Toast工具页
5 | /// Created by Fitem on 2023/6/4
6 | class ToastPage extends StatelessWidget {
7 | const ToastPage({Key? key}) : super(key: key);
8 |
9 | @override
10 | Widget build(BuildContext context) {
11 | return Scaffold(
12 | appBar: AppBar(
13 | title: const Text('Toast工具类'),
14 | ),
15 | body: SizedBox(
16 | width: double.infinity,
17 | height: double.infinity,
18 | child: Column(
19 | children: [
20 | ElevatedButton(onPressed: _handleToastShow, child: const Text('ToastUtils.show()')),
21 | ElevatedButton(onPressed: _handleToastShowCenter, child: const Text('ToastUtils.showCenter()')),
22 | ElevatedButton(onPressed: _handleToastShowToast, child: const Text('ToastUtils.showToast()')),
23 | ],
24 | ),
25 | ),
26 | );
27 | }
28 |
29 | /// 显示Toast
30 | void _handleToastShow() {
31 | ToastUtils.show('这是一条测试Toast');
32 | }
33 |
34 | /// 显示中间Toast
35 | void _handleToastShowCenter() {
36 | ToastUtils.showCenter('这是一条测试Toast');
37 | }
38 |
39 | /// 显示自定义Toast
40 | void _handleToastShowToast() {
41 | ToastUtils.showToast(
42 | '这是一条测试Toast',
43 | gravity: FToastGravity.snackBar,
44 | toast: FToast.lengthLong,
45 | bgColor: Colors.red,
46 | textColor: Colors.white,
47 | fontSize: 20,
48 | );
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/test/null_safety_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_test/flutter_test.dart';
2 | import 'package:flutter_util_code/utils.dart';
3 |
4 | /// Name: 空安全工具类测试
5 | /// Created by Fitem on 2023/6/27
6 | void main() {
7 | group('NullSafety', () {
8 | // 字符串空安全校验
9 | test('StringNullSafety', () {
10 | String? str;
11 | expect(str.toNonNull, '');
12 | expect(str.isNullOrEmpty, true);
13 | expect(str.isNotNullOrEmpty, false);
14 | expect(str.toNonNullString('test'), 'test');
15 | });
16 | // int空安全校验
17 | test('IntNullSafety', () {
18 | int? num;
19 | expect(num.toNonNull, 0);
20 | expect(num.isNull, true);
21 | expect(num.isNotNull, false);
22 | expect(num.toNonNullInt(1), 1);
23 | });
24 | // double空安全校验
25 | test('DoubleNullSafety', () {
26 | double? num;
27 | expect(num.toNonNull, 0.0);
28 | expect(num.isNull, true);
29 | expect(num.isNotNull, false);
30 | expect(num.toNonNullDouble(1.0), 1.0);
31 | });
32 | // bool空安全校验
33 | test('BoolNullSafety', () {
34 | bool? num;
35 | expect(num.toNonNull, false);
36 | expect(num.isNull, true);
37 | expect(num.isNotNull, false);
38 | expect(num.toNonNullBool(true), true);
39 | });
40 | // List空安全校验
41 | test('ListNullSafety', () {
42 | List? list;
43 | expect(list.toNonNull, []);
44 | expect(list.isNullOrEmpty, true);
45 | expect(list.isNotNullOrEmpty, false);
46 | expect(list.toNonNullList([1]), [1]);
47 | });
48 | });
49 | }
50 |
--------------------------------------------------------------------------------
/example/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | # This file configures the analyzer, which statically analyzes Dart code to
2 | # check for errors, warnings, and lints.
3 | #
4 | # The issues identified by the analyzer are surfaced in the UI of Dart-enabled
5 | # IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
6 | # invoked from the command line by running `flutter analyze`.
7 |
8 | # The following line activates a set of recommended lints for Flutter apps,
9 | # packages, and plugins designed to encourage good coding practices.
10 | include: package:flutter_lints/flutter.yaml
11 |
12 | linter:
13 | # The lint rules applied to this project can be customized in the
14 | # section below to disable rules from the `package:flutter_lints/flutter.yaml`
15 | # included above or to enable additional rules. A list of all available lints
16 | # and their documentation is published at
17 | # https://dart-lang.github.io/linter/lints/index.html.
18 | #
19 | # Instead of disabling a lint rule for the entire project in the
20 | # section below, it can also be suppressed for a single line of code
21 | # or a specific dart file by using the `// ignore: name_of_lint` and
22 | # `// ignore_for_file: name_of_lint` syntax on the line or in the file
23 | # producing the lint.
24 | rules:
25 | # avoid_print: false # Uncomment to disable the `avoid_print` rule
26 | # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
27 |
28 | # Additional information about this file can be found at
29 | # https://dart.dev/guides/language/analysis-options
30 |
--------------------------------------------------------------------------------
/example/macos/Podfile:
--------------------------------------------------------------------------------
1 | platform :osx, '10.14'
2 |
3 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
4 | ENV['COCOAPODS_DISABLE_STATS'] = 'true'
5 |
6 | project 'Runner', {
7 | 'Debug' => :debug,
8 | 'Profile' => :release,
9 | 'Release' => :release,
10 | }
11 |
12 | def flutter_root
13 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__)
14 | unless File.exist?(generated_xcode_build_settings_path)
15 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first"
16 | end
17 |
18 | File.foreach(generated_xcode_build_settings_path) do |line|
19 | matches = line.match(/FLUTTER_ROOT\=(.*)/)
20 | return matches[1].strip if matches
21 | end
22 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\""
23 | end
24 |
25 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
26 |
27 | flutter_macos_podfile_setup
28 |
29 | target 'Runner' do
30 | use_frameworks!
31 | use_modular_headers!
32 |
33 | flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__))
34 | target 'RunnerTests' do
35 | inherit! :search_paths
36 | end
37 | end
38 |
39 | post_install do |installer|
40 | installer.pods_project.targets.each do |target|
41 | flutter_additional_macos_build_settings(target)
42 | end
43 | end
44 |
--------------------------------------------------------------------------------
/example/ios/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment this line to define a global platform for your project
2 | # platform :ios, '11.0'
3 |
4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency.
5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true'
6 |
7 | project 'Runner', {
8 | 'Debug' => :debug,
9 | 'Profile' => :release,
10 | 'Release' => :release,
11 | }
12 |
13 | def flutter_root
14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
15 | unless File.exist?(generated_xcode_build_settings_path)
16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
17 | end
18 |
19 | File.foreach(generated_xcode_build_settings_path) do |line|
20 | matches = line.match(/FLUTTER_ROOT\=(.*)/)
21 | return matches[1].strip if matches
22 | end
23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
24 | end
25 |
26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
27 |
28 | flutter_ios_podfile_setup
29 |
30 | target 'Runner' do
31 | use_frameworks!
32 | use_modular_headers!
33 |
34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
35 | target 'RunnerTests' do
36 | inherit! :search_paths
37 | end
38 | end
39 |
40 | post_install do |installer|
41 | installer.pods_project.targets.each do |target|
42 | flutter_additional_ios_build_settings(target)
43 | end
44 | end
45 |
--------------------------------------------------------------------------------
/example/android/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | ext.kotlin_version = '1.7.10'
3 | repositories {
4 | mavenLocal()
5 | maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
6 | maven { url 'https://maven.aliyun.com/nexus/content/repositories/jcenter' }
7 | maven { url 'https://maven.aliyun.com/nexus/content/repositories/google' }
8 | maven { url 'https://maven.aliyun.com/nexus/content/repositories/gradle-plugin' }
9 | maven { url "https://storage.flutter-io.cn/download.flutter.io" }
10 | google()
11 | mavenCentral()
12 | }
13 |
14 | dependencies {
15 | classpath 'com.android.tools.build:gradle:7.3.0'
16 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
17 | }
18 | }
19 |
20 | allprojects {
21 | repositories {
22 | mavenLocal()
23 | maven { url 'https://maven.aliyun.com/nexus/content/groups/public/' }
24 | maven { url 'https://maven.aliyun.com/nexus/content/repositories/jcenter' }
25 | maven { url 'https://maven.aliyun.com/nexus/content/repositories/google' }
26 | maven { url 'https://maven.aliyun.com/nexus/content/repositories/gradle-plugin' }
27 | maven { url "https://storage.flutter-io.cn/download.flutter.io" }
28 | google()
29 | mavenCentral()
30 | }
31 | }
32 |
33 | rootProject.buildDir = '../build'
34 | subprojects {
35 | project.buildDir = "${rootProject.buildDir}/${project.name}"
36 | }
37 | subprojects {
38 | project.evaluationDependsOn(':app')
39 | }
40 |
41 | tasks.register("clean", Delete) {
42 | delete rootProject.buildDir
43 | }
44 |
--------------------------------------------------------------------------------
/example/macos/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "16x16",
5 | "idiom" : "mac",
6 | "filename" : "app_icon_16.png",
7 | "scale" : "1x"
8 | },
9 | {
10 | "size" : "16x16",
11 | "idiom" : "mac",
12 | "filename" : "app_icon_32.png",
13 | "scale" : "2x"
14 | },
15 | {
16 | "size" : "32x32",
17 | "idiom" : "mac",
18 | "filename" : "app_icon_32.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "32x32",
23 | "idiom" : "mac",
24 | "filename" : "app_icon_64.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "128x128",
29 | "idiom" : "mac",
30 | "filename" : "app_icon_128.png",
31 | "scale" : "1x"
32 | },
33 | {
34 | "size" : "128x128",
35 | "idiom" : "mac",
36 | "filename" : "app_icon_256.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "256x256",
41 | "idiom" : "mac",
42 | "filename" : "app_icon_256.png",
43 | "scale" : "1x"
44 | },
45 | {
46 | "size" : "256x256",
47 | "idiom" : "mac",
48 | "filename" : "app_icon_512.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "512x512",
53 | "idiom" : "mac",
54 | "filename" : "app_icon_512.png",
55 | "scale" : "1x"
56 | },
57 | {
58 | "size" : "512x512",
59 | "idiom" : "mac",
60 | "filename" : "app_icon_1024.png",
61 | "scale" : "2x"
62 | }
63 | ],
64 | "info" : {
65 | "version" : 1,
66 | "author" : "xcode"
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/example/ios/Runner/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/example/lib/function/app_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_util_code/utils.dart';
3 | import 'package:flutter_util_code_example/widget/display_screen.dart';
4 |
5 | /// Name: App相关工具类
6 | /// Created by Fitem on 2023/6/7
7 | class AppPage extends StatefulWidget {
8 | const AppPage({Key? key}) : super(key: key);
9 |
10 | @override
11 | AppPageState createState() => AppPageState();
12 | }
13 |
14 | class AppPageState extends State {
15 |
16 | final GlobalKey globalKey = GlobalKey();
17 |
18 | @override
19 | Widget build(BuildContext context) {
20 | return Scaffold(
21 | appBar: AppBar(
22 | title: const Text('App工具类'),
23 | ),
24 | body: SizedBox(
25 | width: double.infinity,
26 | height: double.infinity,
27 | child: Column(
28 | children: [
29 | ElevatedButton(onPressed: () async => addContent(), child: const Text('获取App信息')),
30 | const Spacer(),
31 | Expanded(
32 | flex: 2,
33 | child: DisplayScreen(key: globalKey)
34 | ),
35 | ],
36 | ),
37 | ),
38 | );
39 | }
40 |
41 | /// 添加内容
42 | Future addContent() async {
43 | StringBuffer sb = StringBuffer();
44 | sb.write('App名称: ${await AppUtils.getAppName()} \n');
45 | sb.write('App包名: ${await AppUtils.getPackageName()} \n');
46 | sb.write('App版本名称: ${await AppUtils.getVersionName()} \n');
47 | sb.write('App版本号: ${await AppUtils.getVersionNumber()} \n');
48 | sb.write('App构建签名: ${await AppUtils.getBuildSignature()} \n');
49 | sb.write('App安装商店: ${await AppUtils.getInstallerStore()} \n');
50 | globalKey.currentState?.addContent(sb.toString());
51 | }
52 |
53 | }
--------------------------------------------------------------------------------
/example/lib/function/uuid_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_util_code/utils.dart';
3 | import 'package:flutter_util_code_example/widget/display_screen.dart';
4 |
5 | /// Name: UUID工具页
6 | /// Created by Fitem on 2023/6/5
7 | class UuidPage extends StatefulWidget {
8 | const UuidPage({Key? key}) : super(key: key);
9 |
10 | @override
11 | UuidPageState createState() => UuidPageState();
12 | }
13 |
14 | class UuidPageState extends State {
15 |
16 | final GlobalKey globalKey = GlobalKey();
17 |
18 | @override
19 | Widget build(BuildContext context) {
20 | return Scaffold(
21 | appBar: AppBar(
22 | title: const Text('UUID工具类'),
23 | ),
24 | body: SizedBox(
25 | width: double.infinity,
26 | height: double.infinity,
27 | child: Column(
28 | children: [
29 | ElevatedButton(onPressed: ()=> addContent('uuid: ${UuidUtils.getUuid()}'), child: const Text('UuidUtils.getUuid()')),
30 | ElevatedButton(onPressed: ()=> addContent('uuidV1: ${UuidUtils.getUuidV1()}'), child: const Text('UuidUtils.getUuidV1()')),
31 | ElevatedButton(onPressed: ()=> addContent('uuidV4: ${UuidUtils.getUuidV4()}'), child: const Text('UuidUtils.getUuidV4()')),
32 | ElevatedButton(onPressed: ()=> addContent('uuidV5: ${UuidUtils.getUuidV5('uuid')}'), child: const Text('UuidUtils.getUuidV5()')),
33 | const Spacer(),
34 | Expanded(
35 | flex: 2,
36 | child: DisplayScreen(key: globalKey)
37 | ),
38 | ],
39 | ),
40 | ),
41 | );
42 | }
43 |
44 | /// 添加内容
45 | void addContent(String content) {
46 | globalKey.currentState?.addContent(content);
47 | }
48 |
49 | }
50 |
--------------------------------------------------------------------------------
/example/lib/function/device_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_util_code/utils.dart';
3 | import 'package:flutter_util_code_example/widget/display_screen.dart';
4 |
5 | /// Name: 设备工具页
6 | /// Created by Fitem on 2023/6/5
7 | class DevicePage extends StatelessWidget {
8 | DevicePage({Key? key}) : super(key: key);
9 |
10 | final GlobalKey globalKey = GlobalKey();
11 |
12 | @override
13 | Widget build(BuildContext context) {
14 | return Scaffold(
15 | appBar: AppBar(
16 | title: const Text('Device工具类'),
17 | ),
18 | body: SizedBox(
19 | width: double.infinity,
20 | height: double.infinity,
21 | child: Column(
22 | children: [
23 | ElevatedButton(onPressed: () async => addContent('设备唯一ID: ${await DeviceUtils.getDeviceId()}'), child: const Text('获取设备ID')),
24 | ElevatedButton(onPressed: () async => addContent('品牌: ${await DeviceUtils.getBrand()}'), child: const Text('获取设备品牌')),
25 | ElevatedButton(onPressed: () async => addContent('设备型号: ${await DeviceUtils.getModel()}'), child: const Text('获取设备型号')),
26 | ElevatedButton(onPressed: () async => addContent('系统版本: ${await DeviceUtils.getSystemVersion()}'), child: const Text('获取设备系统版本号')),
27 | ElevatedButton(onPressed: () async => addContent('版本名称: ${await DeviceUtils.getSystemName()}'), child: const Text('获取设备系统名称')),
28 | const Spacer(),
29 | Expanded(
30 | flex: 2,
31 | child: DisplayScreen(key: globalKey)
32 | ),
33 | ],
34 | ),
35 | ),
36 | );
37 | }
38 |
39 | /// 添加内容
40 | void addContent(String content) {
41 | globalKey.currentState?.addContent(content);
42 | }
43 |
44 | }
--------------------------------------------------------------------------------
/.metadata:
--------------------------------------------------------------------------------
1 | # This file tracks properties of this Flutter project.
2 | # Used by Flutter tool to assess capabilities and perform upgrades etc.
3 | #
4 | # This file should be version controlled.
5 |
6 | version:
7 | revision: 9cd3d0d9ff05768afa249e036acc66e8abe93bff
8 | channel: stable
9 |
10 | project_type: plugin
11 |
12 | # Tracks metadata for the flutter migrate command
13 | migration:
14 | platforms:
15 | - platform: root
16 | create_revision: 9cd3d0d9ff05768afa249e036acc66e8abe93bff
17 | base_revision: 9cd3d0d9ff05768afa249e036acc66e8abe93bff
18 | - platform: android
19 | create_revision: 9cd3d0d9ff05768afa249e036acc66e8abe93bff
20 | base_revision: 9cd3d0d9ff05768afa249e036acc66e8abe93bff
21 | - platform: ios
22 | create_revision: 9cd3d0d9ff05768afa249e036acc66e8abe93bff
23 | base_revision: 9cd3d0d9ff05768afa249e036acc66e8abe93bff
24 | - platform: linux
25 | create_revision: 9cd3d0d9ff05768afa249e036acc66e8abe93bff
26 | base_revision: 9cd3d0d9ff05768afa249e036acc66e8abe93bff
27 | - platform: macos
28 | create_revision: 9cd3d0d9ff05768afa249e036acc66e8abe93bff
29 | base_revision: 9cd3d0d9ff05768afa249e036acc66e8abe93bff
30 | - platform: web
31 | create_revision: 9cd3d0d9ff05768afa249e036acc66e8abe93bff
32 | base_revision: 9cd3d0d9ff05768afa249e036acc66e8abe93bff
33 | - platform: windows
34 | create_revision: 9cd3d0d9ff05768afa249e036acc66e8abe93bff
35 | base_revision: 9cd3d0d9ff05768afa249e036acc66e8abe93bff
36 |
37 | # User provided section
38 |
39 | # List of Local paths (relative to this file) that should be
40 | # ignored by the migrate tool.
41 | #
42 | # Files that are not part of the templates will be ignored by default.
43 | unmanaged_files:
44 | - 'lib/main.dart'
45 | - 'ios/Runner.xcodeproj/project.pbxproj'
46 |
--------------------------------------------------------------------------------
/test/format_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_test/flutter_test.dart';
2 | import 'package:flutter_util_code/utils.dart';
3 |
4 | /// Name: 格式化工具类测试
5 | /// Created by Fitem on 2023/7/7
6 | void main() {
7 | group('FormatUtils', () {
8 | /// 解析货币数字
9 | test('formatMoney', () {
10 | expect(FormatUtils.formatMoney(1000000), '1,000,000.00');
11 | expect(FormatUtils.formatMoney(1000000, FormatUtils.moneyIntPattern), '1,000,000');
12 | expect(FormatUtils.formatMoney(1000000, FormatUtils.moneyPattern, 'zh_CN'), '1,000,000.00');
13 | });
14 |
15 | /// 解析小数点
16 | test('formatPoint', () {
17 | expect(FormatUtils.formatPoint(1.234), '1.23');
18 | expect(FormatUtils.formatPoint(1.234, 1), '1.2');
19 | expect(FormatUtils.formatPoint(1.23456, 3, 'zh_CN'), '1.235');
20 | });
21 |
22 | /// 解析小数点,做多保留两位小数,若尾数为0,则去掉
23 | test('formatPointMax', () {
24 | expect(FormatUtils.formatPointMax(1.20), '1.2');
25 | expect(FormatUtils.formatPointMax(1.230, 3), '1.23');
26 | expect(FormatUtils.formatPointMax(1.230, 3, 'zh_CN'), '1.23');
27 | });
28 |
29 | /// 解析整数,转化为两位数,不足补0
30 | test('formatInt', () {
31 | expect(FormatUtils.formatInt(1), '01');
32 | expect(FormatUtils.formatInt(1, 3), '001');
33 | expect(FormatUtils.formatInt(1, 3, 'zh_CN'), '001');
34 | });
35 |
36 | /// 解析数字,转化为百分比
37 | test('formatPercent', () {
38 | expect(FormatUtils.formatPercent(0.1234), '12.34%');
39 | expect(FormatUtils.formatPercent(0.1), '10%');
40 | expect(FormatUtils.formatPercent(0.1, 'zh_CN'), '10%');
41 | });
42 |
43 | /// 解析数字,转化为千分比
44 | test('formatPermillage', () {
45 | expect(FormatUtils.formatPermillage(0.1234), '123.4‰');
46 | expect(FormatUtils.formatPermillage(0.1), '100‰');
47 | expect(FormatUtils.formatPermillage(0.1, 'zh_CN'), '100‰');
48 | });
49 | });
50 | }
51 |
--------------------------------------------------------------------------------
/example/ios/Runner/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleDisplayName
8 | Flutter Util Code
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | flutter_util_code_example
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | $(FLUTTER_BUILD_NAME)
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | $(FLUTTER_BUILD_NUMBER)
25 | LSRequiresIPhoneOS
26 |
27 | UILaunchStoryboardName
28 | LaunchScreen
29 | UIMainStoryboardFile
30 | Main
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 | UIViewControllerBasedStatusBarAppearance
45 |
46 | CADisableMinimumFrameDurationOnPhone
47 |
48 | UIApplicationSupportsIndirectInputEvents
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/example/lib/function/log_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_util_code/utils.dart';
3 |
4 | /// Name: Log工具类页面
5 | /// Created by Fitem on 2023/5/31
6 | class LogPage extends StatefulWidget {
7 | const LogPage({super.key});
8 |
9 | @override
10 | LogPageState createState() => LogPageState();
11 | }
12 |
13 | class LogPageState extends State {
14 | @override
15 | Widget build(BuildContext context) {
16 | return Scaffold(
17 | appBar: AppBar(
18 | title: const Text('Log工具类'),
19 | ),
20 | body: SizedBox(
21 | width: double.infinity,
22 | height: double.infinity,
23 | child: Column(
24 | children: [
25 | ElevatedButton(onPressed: _handlePrintLog, child: const Text('打印日志')),
26 | ElevatedButton(onPressed: _handlePrintLongLog, child: const Text('打印长日志')),
27 | Row(
28 | mainAxisSize: MainAxisSize.min,
29 | children: [
30 | const Text('日志开关:'),
31 | Switch(value: LogUtils.isOpenLog, onChanged: onSwitchChanged),
32 | ],
33 | ),
34 | ],
35 | ),
36 | ),
37 | );
38 | }
39 |
40 | /// 打印日志
41 | void _handlePrintLog() {
42 | LogUtils.println('这是一条测试日志');
43 | }
44 |
45 | /// 打印长日志
46 | void _handlePrintLongLog() {
47 | LogUtils.logger('这是一条非常长的日志,这是一条非常长的日志,这是一条非常长的日志,这是一条非常长的日志,这是一条非常长的日志,'
48 | '这是一条非常长的日志,这是一条非常长的日志,这是一条非常长的日志,这是一条非常长的日志,这是一条非常长的日志,这是一条非常长的日志,'
49 | '这是一条非常长的日志,这是一条非常长的日志,这是一条非常长的日志,这是一条非常长的日志,这是一条非常长的日志,这是一条非常长的日志,'
50 | '这是一条非常长的日志,这是一条非常长的日志,这是一条非常长的日志,这是一条非常长的日志,这是一条非常长的日志,这是一条非常长的日志,');
51 | }
52 |
53 | /// 日志开关
54 | void onSwitchChanged(bool value) {
55 | setState(() {
56 | if (!value) LogUtils.println('日志开关已关闭');
57 | LogUtils.isOpenLog = value;
58 | if (value) LogUtils.println('日志开关已打开');
59 | });
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/example/windows/runner/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.14)
2 | project(runner LANGUAGES CXX)
3 |
4 | # Define the application target. To change its name, change BINARY_NAME in the
5 | # top-level CMakeLists.txt, not the value here, or `flutter run` will no longer
6 | # work.
7 | #
8 | # Any new source files that you add to the application should be added here.
9 | add_executable(${BINARY_NAME} WIN32
10 | "flutter_window.cpp"
11 | "main.cpp"
12 | "utils.cpp"
13 | "win32_window.cpp"
14 | "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
15 | "Runner.rc"
16 | "runner.exe.manifest"
17 | )
18 |
19 | # Apply the standard set of build settings. This can be removed for applications
20 | # that need different build settings.
21 | apply_standard_settings(${BINARY_NAME})
22 |
23 | # Add preprocessor definitions for the build version.
24 | target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION=\"${FLUTTER_VERSION}\"")
25 | target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MAJOR=${FLUTTER_VERSION_MAJOR}")
26 | target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_MINOR=${FLUTTER_VERSION_MINOR}")
27 | target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_PATCH=${FLUTTER_VERSION_PATCH}")
28 | target_compile_definitions(${BINARY_NAME} PRIVATE "FLUTTER_VERSION_BUILD=${FLUTTER_VERSION_BUILD}")
29 |
30 | # Disable Windows macros that collide with C++ standard library functions.
31 | target_compile_definitions(${BINARY_NAME} PRIVATE "NOMINMAX")
32 |
33 | # Add dependency libraries and include directories. Add any application-specific
34 | # dependencies here.
35 | target_link_libraries(${BINARY_NAME} PRIVATE flutter flutter_wrapper_app)
36 | target_link_libraries(${BINARY_NAME} PRIVATE "dwmapi.lib")
37 | target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}")
38 |
39 | # Run the Flutter tool portions of the build. This must not be removed.
40 | add_dependencies(${BINARY_NAME} flutter_assemble)
41 |
--------------------------------------------------------------------------------
/example/lib/function/shared_prefs/shared_prefs_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_util_code/utils.dart';
3 | import 'package:flutter_util_code_example/function/shared_prefs/sp_constants.dart';
4 |
5 | /// Name: SharedPreferenceUtil 页面
6 | /// Created by Fitem on 2023/5/31
7 | class SharedPrefsPage extends StatefulWidget {
8 | const SharedPrefsPage({Key? key}) : super(key: key);
9 |
10 | @override
11 | SharedPrefsPageState createState() => SharedPrefsPageState();
12 | }
13 |
14 | class SharedPrefsPageState extends State {
15 | @override
16 | Widget build(BuildContext context) {
17 | return Scaffold(
18 | appBar: AppBar(
19 | title: const Text('SharedPreference工具类'),
20 | ),
21 | body: SizedBox(
22 | width: double.infinity,
23 | height: double.infinity,
24 | child: Column(
25 | children: [
26 | ElevatedButton(onPressed: _handlePut, child: const Text('添加数据')),
27 | ElevatedButton(onPressed: _handleGet, child: const Text('获取数据')),
28 | ],
29 | ),
30 | ),
31 | );
32 | }
33 |
34 | /// 添加数据
35 | void _handlePut() {
36 | SharedPrefsUtils.putString(SPConstants.name, '小明');
37 | SharedPrefsUtils.putInt(SPConstants.age, 18);
38 | SharedPrefsUtils.putDouble(SPConstants.height, 175.5);
39 | SharedPrefsUtils.putBool(SPConstants.gender, true);
40 | SharedPrefsUtils.putStringList(SPConstants.family, ['爸爸', '妈妈', '哥哥', '弟弟']);
41 | }
42 |
43 | /// 获取数据
44 | Future _handleGet() async {
45 | var name = await SharedPrefsUtils.getString(SPConstants.name, '');
46 | var age = await SharedPrefsUtils.getInt(SPConstants.age, 0);
47 | var height = await SharedPrefsUtils.getDouble(SPConstants.height, 0.0);
48 | var gender = await SharedPrefsUtils.getBool(SPConstants.gender, false);
49 | var family = await SharedPrefsUtils.getStringList(SPConstants.family, []);
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Miscellaneous
2 | *.class
3 | *.log
4 | *.pyc
5 | *.swp
6 | .DS_Store
7 | .atom/
8 | .buildlog/
9 | .history
10 | .svn/
11 |
12 | # IntelliJ related
13 | *.iml
14 | *.ipr
15 | *.iws
16 | .idea/
17 |
18 | # The .vscode folder contains launch configuration and tasks you configure in
19 | # VS Code which you may wish to be included in version control, so this line
20 | # is commented out by default.
21 | #.vscode/
22 |
23 | # Flutter/Dart/Pub related
24 | **/doc/api/
25 | .dart_tool/
26 | .flutter-plugins
27 | .packages
28 | .pub-cache/
29 | .pub/
30 | /build/
31 | .gradle
32 |
33 | # Android related
34 | **/android/**/gradle-wrapper.jar
35 | **/android/.gradle
36 | **/android/captures/
37 | **/android/gradlew
38 | **/android/gradlew.bat
39 | **/android/local.properties
40 | **/android/**/GeneratedPluginRegistrant.java
41 |
42 | # iOS/XCode related
43 | **/ios/**/*.mode1v3
44 | **/ios/**/*.mode2v3
45 | **/ios/**/*.moved-aside
46 | **/ios/**/*.pbxuser
47 | **/ios/**/*.perspectivev3
48 | **/ios/**/*sync/
49 | **/ios/**/.sconsign.dblite
50 | **/ios/**/.tags*
51 | **/ios/**/.vagrant/
52 | **/ios/**/DerivedData/
53 | **/ios/**/Icon?
54 | **/ios/**/Pods/
55 | **/ios/**/.symlinks/
56 | **/ios/**/profile
57 | **/ios/**/xcuserdata
58 | **/ios/.generated/
59 | **/ios/Flutter/App.framework
60 | **/ios/Flutter/Flutter.framework
61 | **/ios/Flutter/Generated.xcconfig
62 | **/ios/Flutter/app.flx
63 | **/ios/Flutter/app.zip
64 | **/ios/Flutter/flutter_assets/
65 | **/ios/ServiceDefinitions.json
66 | **/ios/Runner/GeneratedPluginRegistrant.*
67 |
68 | # Exceptions to above rules.
69 | !**/ios/**/default.mode1v3
70 | !**/ios/**/default.mode2v3
71 | !**/ios/**/default.pbxuser
72 | !**/ios/**/default.perspectivev3
73 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
74 | ios/Flutter/flutter_export_environment.sh
75 |
76 | ios/Flutter/.last_build_id
77 | ios/Flutter/Flutter.podspec
78 |
79 | .flutter-plugins-dependencies
80 | /xx/
81 | /ios/Podfile
82 | /ios/Podfile.lock
83 | /example/ios/Podfile.lock
84 |
--------------------------------------------------------------------------------
/lib/null_safety_utils.dart:
--------------------------------------------------------------------------------
1 | /// Name: 空安全工具类
2 | /// Created by Fitem on 2023/6/27
3 |
4 | /// String空安全扩展
5 | extension StringNullSafety on String? {
6 | /// 转化为非空字符串,如果为空则返回''
7 | String get toNonNull => this ?? '';
8 |
9 | /// 判断字符串是否为空
10 | bool get isNullOrEmpty => this == null || this!.isEmpty;
11 |
12 | /// 判断字符串是否不为空
13 | bool get isNotNullOrEmpty => !isNullOrEmpty;
14 |
15 | /// 判断字符串是否为空,如果为空则返回默认值
16 | String toNonNullString([String def = '']) => isNullOrEmpty ? def : this!;
17 | }
18 |
19 | /// int空安全扩展
20 | extension IntNullSafety on int? {
21 | /// 转化为非空整型,如果为空则返回0
22 | int get toNonNull => this ?? 0;
23 |
24 | /// 判断是否为空
25 | bool get isNull => this == null;
26 |
27 | /// 判断是否不为空
28 | bool get isNotNull => !isNull;
29 |
30 | /// 判断是否为null,如果为null则返回默认值
31 | int toNonNullInt([int def = 0]) => isNull ? def : this!;
32 | }
33 |
34 | /// double空安全扩展
35 | extension DoubleNullSafety on double? {
36 | /// 转化为非空浮点型,如果为空则返回0.0
37 | double get toNonNull => this ?? 0.0;
38 |
39 | /// 判断是否为空
40 | bool get isNull => this == null;
41 |
42 | /// 判断是否不为空
43 | bool get isNotNull => !isNull;
44 |
45 | /// 判断是否为null,如果为null则返回默认值
46 | double toNonNullDouble([double def = 0.0]) => isNull ? def : this!;
47 | }
48 |
49 | /// bool空安全扩展
50 | extension BoolNullSafety on bool? {
51 | /// 转化为非空布尔型,如果为空则返回false
52 | bool get toNonNull => this ?? false;
53 |
54 | /// 判断是否为空
55 | bool get isNull => this == null;
56 |
57 | /// 判断是否不为空
58 | bool get isNotNull => !isNull;
59 |
60 | /// 判断是否为null,如果为null则返回默认值
61 | bool toNonNullBool([bool def = false]) => isNull ? def : this!;
62 | }
63 |
64 | /// List空安全扩展
65 | extension ListNullSafety on List? {
66 | /// 转化为非空数组,如果为空则返回[]
67 | List get toNonNull => this ?? [];
68 |
69 | /// 判断是否为空
70 | bool get isNullOrEmpty => this == null || this!.isEmpty;
71 |
72 | /// 判断是否不为空
73 | bool get isNotNullOrEmpty => !isNullOrEmpty;
74 |
75 | /// 判断是否为空,如果为空则返回默认值
76 | List toNonNullList([List def = const []]) => isNullOrEmpty ? def : this!;
77 | }
78 |
--------------------------------------------------------------------------------
/example/windows/runner/utils.cpp:
--------------------------------------------------------------------------------
1 | #include "utils.h"
2 |
3 | #include
4 | #include
5 | #include
6 | #include
7 |
8 | #include
9 |
10 | void CreateAndAttachConsole() {
11 | if (::AllocConsole()) {
12 | FILE *unused;
13 | if (freopen_s(&unused, "CONOUT$", "w", stdout)) {
14 | _dup2(_fileno(stdout), 1);
15 | }
16 | if (freopen_s(&unused, "CONOUT$", "w", stderr)) {
17 | _dup2(_fileno(stdout), 2);
18 | }
19 | std::ios::sync_with_stdio();
20 | FlutterDesktopResyncOutputStreams();
21 | }
22 | }
23 |
24 | std::vector GetCommandLineArguments() {
25 | // Convert the UTF-16 command line arguments to UTF-8 for the Engine to use.
26 | int argc;
27 | wchar_t** argv = ::CommandLineToArgvW(::GetCommandLineW(), &argc);
28 | if (argv == nullptr) {
29 | return std::vector();
30 | }
31 |
32 | std::vector command_line_arguments;
33 |
34 | // Skip the first argument as it's the binary name.
35 | for (int i = 1; i < argc; i++) {
36 | command_line_arguments.push_back(Utf8FromUtf16(argv[i]));
37 | }
38 |
39 | ::LocalFree(argv);
40 |
41 | return command_line_arguments;
42 | }
43 |
44 | std::string Utf8FromUtf16(const wchar_t* utf16_string) {
45 | if (utf16_string == nullptr) {
46 | return std::string();
47 | }
48 | int target_length = ::WideCharToMultiByte(
49 | CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string,
50 | -1, nullptr, 0, nullptr, nullptr)
51 | -1; // remove the trailing null character
52 | int input_length = (int)wcslen(utf16_string);
53 | std::string utf8_string;
54 | if (target_length <= 0 || target_length > utf8_string.max_size()) {
55 | return utf8_string;
56 | }
57 | utf8_string.resize(target_length);
58 | int converted_length = ::WideCharToMultiByte(
59 | CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string,
60 | input_length, utf8_string.data(), target_length, nullptr, nullptr);
61 | if (converted_length == 0) {
62 | return std::string();
63 | }
64 | return utf8_string;
65 | }
66 |
--------------------------------------------------------------------------------
/example/windows/runner/flutter_window.cpp:
--------------------------------------------------------------------------------
1 | #include "flutter_window.h"
2 |
3 | #include
4 |
5 | #include "flutter/generated_plugin_registrant.h"
6 |
7 | FlutterWindow::FlutterWindow(const flutter::DartProject& project)
8 | : project_(project) {}
9 |
10 | FlutterWindow::~FlutterWindow() {}
11 |
12 | bool FlutterWindow::OnCreate() {
13 | if (!Win32Window::OnCreate()) {
14 | return false;
15 | }
16 |
17 | RECT frame = GetClientArea();
18 |
19 | // The size here must match the window dimensions to avoid unnecessary surface
20 | // creation / destruction in the startup path.
21 | flutter_controller_ = std::make_unique(
22 | frame.right - frame.left, frame.bottom - frame.top, project_);
23 | // Ensure that basic setup of the controller was successful.
24 | if (!flutter_controller_->engine() || !flutter_controller_->view()) {
25 | return false;
26 | }
27 | RegisterPlugins(flutter_controller_->engine());
28 | SetChildContent(flutter_controller_->view()->GetNativeWindow());
29 |
30 | flutter_controller_->engine()->SetNextFrameCallback([&]() {
31 | this->Show();
32 | });
33 |
34 | return true;
35 | }
36 |
37 | void FlutterWindow::OnDestroy() {
38 | if (flutter_controller_) {
39 | flutter_controller_ = nullptr;
40 | }
41 |
42 | Win32Window::OnDestroy();
43 | }
44 |
45 | LRESULT
46 | FlutterWindow::MessageHandler(HWND hwnd, UINT const message,
47 | WPARAM const wparam,
48 | LPARAM const lparam) noexcept {
49 | // Give Flutter, including plugins, an opportunity to handle window messages.
50 | if (flutter_controller_) {
51 | std::optional result =
52 | flutter_controller_->HandleTopLevelWindowProc(hwnd, message, wparam,
53 | lparam);
54 | if (result) {
55 | return *result;
56 | }
57 | }
58 |
59 | switch (message) {
60 | case WM_FONTCHANGE:
61 | flutter_controller_->engine()->ReloadSystemFonts();
62 | break;
63 | }
64 |
65 | return Win32Window::MessageHandler(hwnd, message, wparam, lparam);
66 | }
67 |
--------------------------------------------------------------------------------
/example/web/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 | flutter_util_code_example
33 |
34 |
35 |
39 |
40 |
41 |
42 |
43 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/example/android/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
15 |
23 |
27 |
31 |
32 |
33 |
34 |
35 |
36 |
38 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/lib/connectivity_utils.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 |
3 | import 'package:connectivity_plus/connectivity_plus.dart';
4 |
5 | /// 订阅者回调网络状态
6 | typedef ConnectivityResultCallBack = void Function(ConnectivityResult result);
7 |
8 | /// Name: 网络监听工具类
9 | /// 基于 [基于connectivity_plus](https://pub.dev/packages/connectivity_plus)
10 | /// Created by Fitem on 2023/7/2
11 | class ConnectivityUtils {
12 | /// 保存单例,被标记为 late 的变量 _instance 的初始化操作将会延迟到字段首次被访问时执行,而不是在类加载时就初始化
13 | static final ConnectivityUtils _instance = ConnectivityUtils._internal();
14 |
15 | /// 网络监听相关类
16 | final Connectivity _connectivity = Connectivity();
17 |
18 | /// 当前网络状态,默认为无网络
19 | ConnectivityResult connectionStatus = ConnectivityResult.none;
20 |
21 | /// 网络监听订阅
22 | StreamSubscription? _connectivitySubscription;
23 |
24 | /// 监听回调集合
25 | final List _callBackList = [];
26 |
27 | /// 私有构造函数
28 | ConnectivityUtils._internal() {
29 | _initConnectivity();
30 | }
31 |
32 | /// 获取单例方法
33 | static getInstance() => _instance;
34 |
35 | /// 初始化网络监听
36 | void _initConnectivity() {
37 | _connectivitySubscription = _connectivity.onConnectivityChanged.listen((result) {
38 | if (connectionStatus != result) {
39 | connectionStatus = result;
40 | emit();
41 | }
42 | });
43 | }
44 |
45 | /// 获取当前网络状态
46 | Future checkConnectivity() async {
47 | ConnectivityResult result = await _connectivity.checkConnectivity();
48 | connectionStatus = result;
49 | return result;
50 | }
51 |
52 | /// 监听网络状态
53 | void listen(ConnectivityResultCallBack c) {
54 | _callBackList.add(c);
55 | // 如果网络监听订阅为空,则初始化网络监听
56 | if (_connectivitySubscription == null) {
57 | _initConnectivity();
58 | }
59 | }
60 |
61 | /// 取消订阅
62 | void off(ConnectivityResultCallBack? c) {
63 | if (c != null) {
64 | _callBackList.remove(c);
65 | }
66 | }
67 |
68 | /// 取消网络监听
69 | void dispose() {
70 | _connectivitySubscription?.cancel();
71 | _connectivitySubscription = null;
72 | _callBackList.clear();
73 | }
74 |
75 | /// 发送通知
76 | void emit() {
77 | var len = _callBackList.length - 1;
78 | // 反向遍历,防止订阅者在回调中移除自身带来的下标错位
79 | for (var i = len; i > -1; --i) {
80 | _callBackList[i](connectionStatus);
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/lib/permission_utils.dart:
--------------------------------------------------------------------------------
1 | import 'package:permission_handler/permission_handler.dart';
2 |
3 | /// 授权成功回调
4 | typedef SuccessCallBack = void Function();
5 |
6 | /// 授权失败回调
7 | typedef DeniedCallBack = void Function(bool isPermanentlyDenied);
8 |
9 | /// 其他回调
10 | typedef OtherCallBack = void Function(PermissionStatus status);
11 |
12 | /// Name: PermissionUtils
13 | /// Created by Fitem on 2023/7/4
14 | class PermissionUtils {
15 |
16 | /// 获取权限状态
17 | /// [Permission] 请求的权限
18 | static Future getPermissionStatus(Permission permission) async {
19 | return await permission.status;
20 | }
21 |
22 | /// 请求权限
23 | /// [Permission] 请求的权限
24 | /// [success] 授权成功回调
25 | /// [denied] 授权失败回调; [isPermanentlyDenied] 是否永久拒绝
26 | /// [other] 其他回调
27 | static Future requestPermission(
28 | Permission permission, {
29 | SuccessCallBack? success,
30 | DeniedCallBack? denied,
31 | OtherCallBack? other,
32 | }) async {
33 | var status = await permission.request();
34 | if (status == PermissionStatus.granted) {
35 | success?.call();
36 | } else if (status == PermissionStatus.denied || status == PermissionStatus.restricted) {
37 | denied?.call(status.isPermanentlyDenied);
38 | } else {
39 | other?.call(status);
40 | }
41 | return status;
42 | }
43 |
44 | /// 请求获取多个权限
45 | /// [Permission] 请求的权限
46 | /// [success] 授权成功回调
47 | /// [denied] 授权失败回调; [isPermanentlyDenied] 是否永久拒绝
48 | /// [other] 其他回调
49 | static Future requestPermissions(
50 | List permissions, {
51 | SuccessCallBack? success,
52 | DeniedCallBack? denied,
53 | OtherCallBack? other,
54 | }) async {
55 | // 请求权限
56 | Map map = await permissions.request();
57 | // 遍历权限
58 | for (Permission key in map.keys) {
59 | var status = map[key];
60 | if (status == PermissionStatus.granted) {
61 | // 只有全部权限都被授权,才返回成功
62 | } else if (status == PermissionStatus.denied || status == PermissionStatus.restricted) {
63 | // 若有一个权限被拒绝,则返回失败
64 | denied?.call(status!.isPermanentlyDenied);
65 | return status!;
66 | } else {
67 | // 若有其他情况,则返回其他
68 | other?.call(status!);
69 | return status!;
70 | }
71 | }
72 | success?.call();
73 | return PermissionStatus.granted;
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/example/ios/Runner/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/example/lib/function/connectivity_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_util_code/utils.dart';
3 | import 'package:flutter_util_code_example/widget/display_screen.dart';
4 |
5 | /// Name: 网络监听页
6 | /// Created by Fitem on 2023/7/3
7 | class ConnectivityPage extends StatefulWidget {
8 | const ConnectivityPage({super.key});
9 |
10 | @override
11 | ConnectivityPageState createState() => ConnectivityPageState();
12 | }
13 |
14 | class ConnectivityPageState extends State {
15 | final ConnectivityUtils _connectivityUtils = ConnectivityUtils.getInstance();
16 | final GlobalKey globalKey = GlobalKey();
17 | late ConnectivityResultCallBack _callBack;
18 |
19 | @override
20 | void initState() {
21 | super.initState();
22 | _callBack = (ConnectivityResult result) {
23 | addContent('当前网络状态: $result\n');
24 | };
25 | }
26 |
27 | @override
28 | void dispose() {
29 | // 取消网络监听
30 | disposeConnectivity();
31 | super.dispose();
32 | }
33 |
34 | @override
35 | Widget build(BuildContext context) {
36 | return Scaffold(
37 | appBar: AppBar(
38 | title: const Text('网络监听工具类'),
39 | ),
40 | body: SizedBox(
41 | width: double.infinity,
42 | height: double.infinity,
43 | child: Column(
44 | children: [
45 | ElevatedButton(onPressed: checkConnectivity, child: const Text('获取当前网络状态')),
46 | ElevatedButton(onPressed: addListener, child: const Text('添加网络状态监听')),
47 | ElevatedButton(onPressed: removeListener, child: const Text('移除网络状态监听')),
48 | ElevatedButton(onPressed: disposeConnectivity, child: const Text('取消网络状态监听')),
49 | const Spacer(),
50 | Expanded(flex: 2, child: DisplayScreen(key: globalKey)),
51 | ],
52 | ),
53 | ),
54 | );
55 | }
56 |
57 | /// 检查网络状态
58 | Future checkConnectivity() async {
59 | ConnectivityResult result = await _connectivityUtils.checkConnectivity();
60 | addContent('当前网络状态: $result\n');
61 | }
62 |
63 | /// 添加监听
64 | void addListener() {
65 | _connectivityUtils.listen(_callBack);
66 | }
67 |
68 | /// 移除监听
69 | void removeListener() {
70 | _connectivityUtils.off(_callBack);
71 | }
72 |
73 | /// 取消网络监听
74 | void disposeConnectivity(){
75 | _connectivityUtils.dispose();
76 | }
77 |
78 | /// 添加内容
79 | void addContent(String content) {
80 | globalKey.currentState?.addContent(content);
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/example/android/app/build.gradle:
--------------------------------------------------------------------------------
1 | def localProperties = new Properties()
2 | def localPropertiesFile = rootProject.file('local.properties')
3 | if (localPropertiesFile.exists()) {
4 | localPropertiesFile.withReader('UTF-8') { reader ->
5 | localProperties.load(reader)
6 | }
7 | }
8 |
9 | def flutterRoot = localProperties.getProperty('flutter.sdk')
10 | if (flutterRoot == null) {
11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
12 | }
13 |
14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
15 | if (flutterVersionCode == null) {
16 | flutterVersionCode = '1'
17 | }
18 |
19 | def flutterVersionName = localProperties.getProperty('flutter.versionName')
20 | if (flutterVersionName == null) {
21 | flutterVersionName = '1.0'
22 | }
23 |
24 | apply plugin: 'com.android.application'
25 | apply plugin: 'kotlin-android'
26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
27 |
28 | android {
29 | namespace "com.fitem.flutter_util_code_example"
30 | compileSdkVersion flutter.compileSdkVersion
31 | ndkVersion flutter.ndkVersion
32 |
33 | compileOptions {
34 | sourceCompatibility JavaVersion.VERSION_1_8
35 | targetCompatibility JavaVersion.VERSION_1_8
36 | }
37 |
38 | kotlinOptions {
39 | jvmTarget = '1.8'
40 | }
41 |
42 | sourceSets {
43 | main.java.srcDirs += 'src/main/kotlin'
44 | }
45 |
46 | defaultConfig {
47 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
48 | applicationId "com.fitem.flutter_util_code_example"
49 | // You can update the following values to match your application needs.
50 | // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
51 | minSdkVersion 21
52 | targetSdkVersion flutter.targetSdkVersion
53 | versionCode flutterVersionCode.toInteger()
54 | versionName flutterVersionName
55 | }
56 |
57 | buildTypes {
58 | release {
59 | // TODO: Add your own signing config for the release build.
60 | // Signing with the debug keys for now, so `flutter run --release` works.
61 | signingConfig signingConfigs.debug
62 | }
63 | }
64 | }
65 |
66 | flutter {
67 | source '../..'
68 | }
69 |
70 | dependencies {
71 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
72 | }
73 |
--------------------------------------------------------------------------------
/lib/format_utils.dart:
--------------------------------------------------------------------------------
1 | import 'package:intl/intl.dart';
2 |
3 | /// Name: 格式化工具类
4 | /// 基于 [intl](https://pub.dev/packages/intl)
5 | /// Created by Fitem on 2023/7/7
6 | class FormatUtils {
7 | /// 货币数字格式化-整数
8 | static const String moneyIntPattern = ',###';
9 |
10 | /// 货币数字格式化-小数点后2位
11 | static const String moneyPointPattern = '.00';
12 |
13 | /// 货币数字格式化
14 | static const String moneyPattern = moneyIntPattern + moneyPointPattern;
15 |
16 | /// 解析货币数字
17 | /// [num] 数字
18 | /// [pattern] 格式化规则
19 | /// [locale] 地域
20 | /// 解析结果:1000000 -> 1,000,000.00
21 | static String formatMoney(
22 | num num, [
23 | String pattern = moneyPattern,
24 | String locale = 'en_US',
25 | ]) {
26 | return NumberFormat(pattern, locale).format(num);
27 | }
28 |
29 | /// 解析小数点,默认保留两位小数
30 | /// [num] 数字
31 | /// [digit] 保留小数位数,默认保留2位小数
32 | /// 解析结果:1.234 -> 1.23
33 | static String formatPoint(
34 | num num, [
35 | int digit = 2,
36 | String locale = 'en_US',
37 | ]) {
38 | String pattern = '.${'0' * digit}';
39 | NumberFormat format = NumberFormat(pattern, locale);
40 | return format.format(num);
41 | }
42 |
43 | /// 解析小数点,默认最多保留两位小数,若尾数为0,则去掉
44 | /// [num] 数字
45 | /// [digit] 保留小数位数,默认保留2位小数
46 | /// [locale] 地域
47 | /// 解析结果:1.20 -> 1.0
48 | static String formatPointMax(
49 | num num, [
50 | int digit = 2,
51 | String locale = 'en_US',
52 | ]) {
53 | String pattern = '.${'#' * digit}';
54 | NumberFormat format = NumberFormat(pattern, locale);
55 | return format.format(num);
56 | }
57 |
58 | /// 解析数字,转化为两位数,不足补0
59 | /// [num] 数字
60 | /// [digit] 保留位数,默认保留2位数
61 | /// [locale] 地域
62 | /// 解析结果:1 -> 01
63 | static String formatInt(
64 | int num, [
65 | int digit = 2,
66 | String locale = 'en_US',
67 | ]) {
68 | String pattern = '0' * digit;
69 | NumberFormat format = NumberFormat(pattern, locale);
70 | return format.format(num);
71 | }
72 |
73 | /// 解析数字,转化为百分比
74 | /// [num] 数字
75 | /// [locale] 地域
76 | /// 解析结果:0.1234 -> 12.34%
77 | static String formatPercent(num num, [String locale = 'en_US']) {
78 | String pattern = '#.##%';
79 | NumberFormat format = NumberFormat(pattern, locale);
80 | return format.format(num);
81 | }
82 |
83 | /// 解析数字,转化为千分比
84 | /// [num] 数字
85 | /// [locale] 地域
86 | /// 解析结果:0.1234 -> 123.4‰
87 | static String formatPermillage(num num, [String locale = 'en_US']) {
88 | String pattern = '#.##‰';
89 | NumberFormat format = NumberFormat(pattern, locale);
90 | return format.format(num);
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: flutter_util_code
2 | description: A Flutter utility class collection library that includes some commonly used functions and encapsulated system API calls to improve development efficiency.
3 | version: 0.6.0
4 | homepage: https://github.com/Fitem/flutter_util_code
5 |
6 | environment:
7 | sdk: ">=2.18.0 <4.0.0"
8 | flutter: ">=3.3.0"
9 |
10 | dependencies:
11 | flutter:
12 | sdk: flutter
13 | # SharedPreference
14 | shared_preferences: ^2.1.1
15 | # Toast
16 | fluttertoast: ^8.2.2
17 | # 设备信息
18 | device_info_plus: ^9.0.2
19 | # AndroidID
20 | android_id: ^0.3.3
21 | # UUID
22 | uuid: ^3.0.7
23 | # 包信息
24 | package_info_plus: ^4.0.2
25 | # 文件路径
26 | path_provider: ^2.0.15
27 | # 加密: SHA、MD5
28 | crypto: ^3.0.3
29 | # 加密: AES、RSA、sha256withRSA签名
30 | encrypt: ^5.0.1
31 | pointycastle: ^3.7.3
32 | # 加密: md5withRSA签名
33 | fast_rsa: ^3.5.7
34 | # URL跳转
35 | url_launcher: ^6.1.11
36 | # 分享
37 | share_plus: ^7.0.2
38 | # 网络监听
39 | connectivity_plus: ^4.0.1
40 | # 权限获取
41 | permission_handler: ^10.4.1
42 | # intl
43 | intl: ^0.18.1
44 |
45 | dev_dependencies:
46 | flutter_test:
47 | sdk: flutter
48 | flutter_lints: ^2.0.0
49 |
50 | # For information on the generic Dart part of this file, see the
51 | # following page: https://dart.dev/tools/pub/pubspec
52 |
53 | # The following section is specific to Flutter packages.
54 | flutter:
55 |
56 | # To add assets to your plugin package, add an assets section, like this:
57 | # assets:
58 | # - images/a_dot_burr.jpeg
59 | # - images/a_dot_ham.jpeg
60 | #
61 | # For details regarding assets in packages, see
62 | # https://flutter.dev/assets-and-images/#from-packages
63 | #
64 | # An image asset can refer to one or more resolution-specific "variants", see
65 | # https://flutter.dev/assets-and-images/#resolution-aware
66 |
67 | # To add custom fonts to your plugin package, add a fonts section here,
68 | # in this "flutter" section. Each entry in this list should have a
69 | # "family" key with the font family name, and a "fonts" key with a
70 | # list giving the asset and other descriptors for the font. For
71 | # example:
72 | # fonts:
73 | # - family: Schyler
74 | # fonts:
75 | # - asset: fonts/Schyler-Regular.ttf
76 | # - asset: fonts/Schyler-Italic.ttf
77 | # style: italic
78 | # - family: Trajan Pro
79 | # fonts:
80 | # - asset: fonts/TrajanPro.ttf
81 | # - asset: fonts/TrajanPro_Bold.ttf
82 | # weight: 700
83 | #
84 | # For details regarding fonts in packages, see
85 | # https://flutter.dev/custom-fonts/#from-packages
86 |
--------------------------------------------------------------------------------
/example/macos/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - device_info_plus (0.0.1):
3 | - FlutterMacOS
4 | - fast_rsa (0.6.0):
5 | - FlutterMacOS
6 | - FlutterMacOS (1.0.0)
7 | - package_info_plus (0.0.1):
8 | - FlutterMacOS
9 | - path_provider_foundation (0.0.1):
10 | - Flutter
11 | - FlutterMacOS
12 | - share_plus (0.0.1):
13 | - FlutterMacOS
14 | - shared_preferences_foundation (0.0.1):
15 | - Flutter
16 | - FlutterMacOS
17 | - url_launcher_macos (0.0.1):
18 | - FlutterMacOS
19 |
20 | DEPENDENCIES:
21 | - device_info_plus (from `Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos`)
22 | - fast_rsa (from `Flutter/ephemeral/.symlinks/plugins/fast_rsa/macos`)
23 | - FlutterMacOS (from `Flutter/ephemeral`)
24 | - package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`)
25 | - path_provider_foundation (from `Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin`)
26 | - share_plus (from `Flutter/ephemeral/.symlinks/plugins/share_plus/macos`)
27 | - shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`)
28 | - url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`)
29 |
30 | EXTERNAL SOURCES:
31 | device_info_plus:
32 | :path: Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos
33 | fast_rsa:
34 | :path: Flutter/ephemeral/.symlinks/plugins/fast_rsa/macos
35 | FlutterMacOS:
36 | :path: Flutter/ephemeral
37 | package_info_plus:
38 | :path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos
39 | path_provider_foundation:
40 | :path: Flutter/ephemeral/.symlinks/plugins/path_provider_foundation/darwin
41 | share_plus:
42 | :path: Flutter/ephemeral/.symlinks/plugins/share_plus/macos
43 | shared_preferences_foundation:
44 | :path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin
45 | url_launcher_macos:
46 | :path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos
47 |
48 | SPEC CHECKSUMS:
49 | device_info_plus: 5401765fde0b8d062a2f8eb65510fb17e77cf07f
50 | fast_rsa: 87a964a26439f5b8a603949463525110ab025944
51 | FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
52 | package_info_plus: 02d7a575e80f194102bef286361c6c326e4c29ce
53 | path_provider_foundation: eaf5b3e458fc0e5fbb9940fb09980e853fe058b8
54 | share_plus: 76dd39142738f7a68dd57b05093b5e8193f220f7
55 | shared_preferences_foundation: e2dae3258e06f44cc55f49d42024fd8dd03c590c
56 | url_launcher_macos: 5335912b679c073563f29d89d33d10d459f95451
57 |
58 | PODFILE CHECKSUM: 236401fc2c932af29a9fcf0e97baeeb2d750d367
59 |
60 | COCOAPODS: 1.11.3
61 |
--------------------------------------------------------------------------------
/test/date_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_test/flutter_test.dart';
2 | import 'package:flutter_util_code/utils.dart';
3 |
4 | /// Name: 日期工具类测试
5 | /// Created by Fitem on 2023/7/21
6 | void main() {
7 | DateTime dateTime = DateTime(2023, 7, 21, 16, 7, 21);
8 | DateTime dateTime2 = DateTime(2023, 7, 21, 17, 7, 21);
9 |
10 | group('DateUtils', () {
11 | /// 日期时间格式化
12 | test('formatDateTime', () {
13 | // yyyy-MM-dd HH:mm:ss
14 | expect(DateUtils.formatDateTime(dateTime), '2023-07-21 16:07:21');
15 | // yyyy/MM/dd HH:mm
16 | expect(DateUtils.formatDateTime(dateTime, 'yyyy/MM/dd HH:mm'), '2023/07/21 16:07');
17 | });
18 |
19 | /// 日期格式化
20 | test('formatDate', () {
21 | // yyyy-MM-dd
22 | expect(DateUtils.formatDate(dateTime), '2023-07-21');
23 | // yyyy/MM/dd
24 | expect(DateUtils.formatDate(dateTime, 'yyyy/MM/dd'), '2023/07/21');
25 | });
26 |
27 | /// 时间格式化
28 | test('formatTime', () {
29 | // HH:mm:ss
30 | expect(DateUtils.formatTime(dateTime), '16:07:21');
31 | // HH:mm
32 | expect(DateUtils.formatTime(dateTime, 'HH:mm'), '16:07');
33 | });
34 |
35 | /// 时分格式化
36 | test('formatHHmm', () {
37 | // HH:mm
38 | expect(DateUtils.formatHHmm(dateTime), '16:07');
39 | // HH:mm
40 | expect(DateUtils.formatHHmm(dateTime, 'HH:mm'), '16:07');
41 | });
42 |
43 | /// 日期时间解析
44 | test('parseDateTime', () {
45 | // yyyy-MM-dd HH:mm:ss
46 | expect(DateUtils.parseDateTime('2023-07-21 16:07:21').microsecond, dateTime.microsecond);
47 | // yyyy/MM/dd HH:mm
48 | expect(DateUtils.parseDateTime('2023/07/21 16:07:21', 'yyyy/MM/dd HH:mm:ss').microsecond, dateTime.microsecond);
49 | });
50 |
51 | /// 获取星期几
52 | test('getWeekIndex', () {
53 | // 0-6
54 | expect(DateUtils.getWeekIndex(dateTime), 4);
55 | });
56 |
57 | /// 获取星期名称
58 | test('getWeekName', () {
59 | // 周一-周日
60 | expect(DateUtils.getWeekName(dateTime), '周五');
61 | });
62 |
63 | /// 获取相差时间
64 | test('diff', () {
65 | // 一分钟内
66 | expect(DateUtils.diff(dateTime, dateTime2), DateUtils.oneHour);
67 | });
68 |
69 | /// 计算两个时间的差值范围等级
70 | test('diffRangeLevel', () {
71 | // 一小时内
72 | expect(DateUtils.diffRangeLevel(dateTime, dateTime2), 1);
73 | });
74 |
75 | /// 相差时间范围说明
76 | test('diffRangeDesc', () {
77 | // 一小时内
78 | expect(DateUtils.diffRangeName(dateTime, dateTime2), '一小时内');
79 | });
80 |
81 | /// int转化DateTime
82 | test('intToDateTime', () {
83 | DateTime dateTime3 = dateTime.millisecondsSinceEpoch.toDateTime();
84 | expect(DateUtils.formatDateTime(dateTime3), '2023-07-21 16:07:21');
85 | });
86 | });
87 | }
88 |
--------------------------------------------------------------------------------
/example/lib/function/url_launcher_page.dart:
--------------------------------------------------------------------------------
1 | import 'dart:async';
2 | import 'dart:io';
3 |
4 | import 'package:flutter/material.dart';
5 | import 'package:flutter_util_code/utils.dart';
6 |
7 | /// Name: Url跳转工具类
8 | /// Created by Fitem on 2023/6/20
9 | class UrlLauncherPage extends StatefulWidget {
10 | const UrlLauncherPage({super.key});
11 |
12 | @override
13 | UrlLauncherPageState createState() => UrlLauncherPageState();
14 | }
15 |
16 | class UrlLauncherPageState extends State {
17 | final String httpUrl = 'https://flutter.dev';
18 | final String phoneNumber = '10086';
19 | final String email = 'smith@example.org';
20 | String filePath = '';
21 |
22 | @override
23 | Widget build(BuildContext context) {
24 | return Scaffold(
25 | appBar: AppBar(
26 | title: const Text('Url跳转工具类'),
27 | ),
28 | body: SizedBox(
29 | width: double.infinity,
30 | height: double.infinity,
31 | child: Column(
32 | children: [
33 | _buildButton('浏览器打开url', () => UrlLauncherUtils.launchInBrowser(httpUrl)),
34 | _buildButton('非浏览器第三方应用打开url', () => UrlLauncherUtils.launchInNonBrowser(httpUrl)),
35 | _buildButton('WebView打开url', () => UrlLauncherUtils.launchInApp(httpUrl)),
36 | _buildButton('关闭WebView', () {
37 | UrlLauncherUtils.launchInApp(httpUrl);
38 | Timer(const Duration(seconds: 3), () => UrlLauncherUtils.onCloseInAppWebView());
39 | return Future.value(true);
40 | }),
41 | _buildButton('打电话', () => UrlLauncherUtils.onCall(phoneNumber)),
42 | _buildButton('发短信', () => UrlLauncherUtils.sendSMS(phoneNumber, content: '短信内容')),
43 | _buildButton('发送邮件', () => UrlLauncherUtils.sendEmail(email, subject: '邮件主题', content: '邮件内容')),
44 | _buildButton('打开文件', openFile),
45 | ],
46 | ),
47 | ),
48 | );
49 | }
50 |
51 | /// 通用按钮
52 | Widget _buildButton(String text, Future Function() onPressed) {
53 | return ElevatedButton(
54 | onPressed: () async {
55 | bool result = await onPressed();
56 | ToastUtils.showCenter(result ? '跳转成功' : '跳转失败');
57 | },
58 | child: Text(text));
59 | }
60 |
61 | /// 打开文件
62 | Future openFile() async {
63 | final String tempFilePath = await PathUtils.getAppSupportPath();
64 | String filePath = '$tempFilePath/temp.pdf';
65 | if(!File(tempFilePath).existsSync()) {
66 | Directory(tempFilePath).createSync(recursive: true);
67 | }
68 | final File testFile = File(filePath);
69 | await testFile.writeAsString('Hello, world!');
70 | filePath = testFile.absolute.path;
71 | return UrlLauncherUtils.openFile(filePath);
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/example/lib/router/router_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_util_code/share_utils.dart';
2 | import 'package:flutter_util_code_example/function/app_page.dart';
3 | import 'package:flutter_util_code_example/function/connectivity_page.dart';
4 | import 'package:flutter_util_code_example/function/device_page.dart';
5 | import 'package:flutter_util_code_example/function/encrypted_page.dart';
6 | import 'package:flutter_util_code_example/function/home_page.dart';
7 | import 'package:flutter_util_code_example/function/log_page.dart';
8 | import 'package:flutter_util_code_example/function/path_page.dart';
9 | import 'package:flutter_util_code_example/function/permission_page.dart';
10 | import 'package:flutter_util_code_example/function/share_page.dart';
11 | import 'package:flutter_util_code_example/function/shared_prefs/shared_prefs_page.dart';
12 | import 'package:flutter_util_code_example/function/toast_page.dart';
13 | import 'package:flutter_util_code_example/function/url_launcher_page.dart';
14 | import 'package:flutter_util_code_example/function/uuid_page.dart';
15 | import 'package:flutter_util_code_example/router/router_name.dart';
16 | import 'package:get/get.dart';
17 |
18 | /// Name: 路由页面
19 | /// Created by Fitem on 2023/5/31
20 |
21 | class RouterPage {
22 | static final pages = [
23 | /// 首页
24 | GetPage(
25 | name: RouterName.home,
26 | page: () => HomePage(),
27 | ),
28 |
29 | /// 日志工具类页
30 | GetPage(
31 | name: RouterName.log,
32 | page: () => const LogPage(),
33 | ),
34 |
35 | /// SharedPreference工具类页
36 | GetPage(
37 | name: RouterName.sharedPreference,
38 | page: () => const SharedPrefsPage(),
39 | ),
40 |
41 | /// Toast工具类页
42 | GetPage(
43 | name: RouterName.toast,
44 | page: () => const ToastPage(),
45 | ),
46 | /// UUID工具类页
47 | GetPage(
48 | name: RouterName.uuid,
49 | page: () => const UuidPage(),
50 | ),
51 | /// 设备Device工具类页
52 | GetPage(
53 | name: RouterName.device,
54 | page: () => DevicePage(),
55 | ),
56 | /// App工具类页
57 | GetPage(
58 | name: RouterName.app,
59 | page: () => const AppPage(),
60 | ),
61 | /// Path工具类页
62 | GetPage(
63 | name: RouterName.path,
64 | page: () => const PathPage(),
65 | ),
66 | /// Encrypt工具类页
67 | GetPage(
68 | name: RouterName.encrypt,
69 | page: () => const EncryptPage(),
70 | ),
71 | /// UrlLauncher工具类页
72 | GetPage(
73 | name: RouterName.urlLauncher,
74 | page: () => const UrlLauncherPage(),
75 | ),
76 | /// Share工具类页
77 | GetPage(
78 | name: RouterName.share,
79 | page: () => const SharePage(),
80 | ),
81 | /// 网络工具类页
82 | GetPage(
83 | name: RouterName.connectivity,
84 | page: () => const ConnectivityPage(),
85 | ),
86 | /// 权限工具类页
87 | GetPage(
88 | name: RouterName.permission,
89 | page: () => const PermissionPage(),
90 | ),
91 | ];
92 | }
93 |
--------------------------------------------------------------------------------
/example/linux/flutter/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # This file controls Flutter-level build steps. It should not be edited.
2 | cmake_minimum_required(VERSION 3.10)
3 |
4 | set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral")
5 |
6 | # Configuration provided via flutter tool.
7 | include(${EPHEMERAL_DIR}/generated_config.cmake)
8 |
9 | # TODO: Move the rest of this into files in ephemeral. See
10 | # https://github.com/flutter/flutter/issues/57146.
11 |
12 | # Serves the same purpose as list(TRANSFORM ... PREPEND ...),
13 | # which isn't available in 3.10.
14 | function(list_prepend LIST_NAME PREFIX)
15 | set(NEW_LIST "")
16 | foreach(element ${${LIST_NAME}})
17 | list(APPEND NEW_LIST "${PREFIX}${element}")
18 | endforeach(element)
19 | set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE)
20 | endfunction()
21 |
22 | # === Flutter Library ===
23 | # System-level dependencies.
24 | find_package(PkgConfig REQUIRED)
25 | pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
26 | pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0)
27 | pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0)
28 |
29 | set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so")
30 |
31 | # Published to parent scope for install step.
32 | set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE)
33 | set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE)
34 | set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE)
35 | set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE)
36 |
37 | list(APPEND FLUTTER_LIBRARY_HEADERS
38 | "fl_basic_message_channel.h"
39 | "fl_binary_codec.h"
40 | "fl_binary_messenger.h"
41 | "fl_dart_project.h"
42 | "fl_engine.h"
43 | "fl_json_message_codec.h"
44 | "fl_json_method_codec.h"
45 | "fl_message_codec.h"
46 | "fl_method_call.h"
47 | "fl_method_channel.h"
48 | "fl_method_codec.h"
49 | "fl_method_response.h"
50 | "fl_plugin_registrar.h"
51 | "fl_plugin_registry.h"
52 | "fl_standard_message_codec.h"
53 | "fl_standard_method_codec.h"
54 | "fl_string_codec.h"
55 | "fl_value.h"
56 | "fl_view.h"
57 | "flutter_linux.h"
58 | )
59 | list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/")
60 | add_library(flutter INTERFACE)
61 | target_include_directories(flutter INTERFACE
62 | "${EPHEMERAL_DIR}"
63 | )
64 | target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}")
65 | target_link_libraries(flutter INTERFACE
66 | PkgConfig::GTK
67 | PkgConfig::GLIB
68 | PkgConfig::GIO
69 | )
70 | add_dependencies(flutter flutter_assemble)
71 |
72 | # === Flutter tool backend ===
73 | # _phony_ is a non-existent file to force this command to run every time,
74 | # since currently there's no way to get a full input/output list from the
75 | # flutter tool.
76 | add_custom_command(
77 | OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
78 | ${CMAKE_CURRENT_BINARY_DIR}/_phony_
79 | COMMAND ${CMAKE_COMMAND} -E env
80 | ${FLUTTER_TOOL_ENVIRONMENT}
81 | "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh"
82 | ${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE}
83 | VERBATIM
84 | )
85 | add_custom_target(flutter_assemble DEPENDS
86 | "${FLUTTER_LIBRARY}"
87 | ${FLUTTER_LIBRARY_HEADERS}
88 | )
89 |
--------------------------------------------------------------------------------
/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "size" : "20x20",
5 | "idiom" : "iphone",
6 | "filename" : "Icon-App-20x20@2x.png",
7 | "scale" : "2x"
8 | },
9 | {
10 | "size" : "20x20",
11 | "idiom" : "iphone",
12 | "filename" : "Icon-App-20x20@3x.png",
13 | "scale" : "3x"
14 | },
15 | {
16 | "size" : "29x29",
17 | "idiom" : "iphone",
18 | "filename" : "Icon-App-29x29@1x.png",
19 | "scale" : "1x"
20 | },
21 | {
22 | "size" : "29x29",
23 | "idiom" : "iphone",
24 | "filename" : "Icon-App-29x29@2x.png",
25 | "scale" : "2x"
26 | },
27 | {
28 | "size" : "29x29",
29 | "idiom" : "iphone",
30 | "filename" : "Icon-App-29x29@3x.png",
31 | "scale" : "3x"
32 | },
33 | {
34 | "size" : "40x40",
35 | "idiom" : "iphone",
36 | "filename" : "Icon-App-40x40@2x.png",
37 | "scale" : "2x"
38 | },
39 | {
40 | "size" : "40x40",
41 | "idiom" : "iphone",
42 | "filename" : "Icon-App-40x40@3x.png",
43 | "scale" : "3x"
44 | },
45 | {
46 | "size" : "60x60",
47 | "idiom" : "iphone",
48 | "filename" : "Icon-App-60x60@2x.png",
49 | "scale" : "2x"
50 | },
51 | {
52 | "size" : "60x60",
53 | "idiom" : "iphone",
54 | "filename" : "Icon-App-60x60@3x.png",
55 | "scale" : "3x"
56 | },
57 | {
58 | "size" : "20x20",
59 | "idiom" : "ipad",
60 | "filename" : "Icon-App-20x20@1x.png",
61 | "scale" : "1x"
62 | },
63 | {
64 | "size" : "20x20",
65 | "idiom" : "ipad",
66 | "filename" : "Icon-App-20x20@2x.png",
67 | "scale" : "2x"
68 | },
69 | {
70 | "size" : "29x29",
71 | "idiom" : "ipad",
72 | "filename" : "Icon-App-29x29@1x.png",
73 | "scale" : "1x"
74 | },
75 | {
76 | "size" : "29x29",
77 | "idiom" : "ipad",
78 | "filename" : "Icon-App-29x29@2x.png",
79 | "scale" : "2x"
80 | },
81 | {
82 | "size" : "40x40",
83 | "idiom" : "ipad",
84 | "filename" : "Icon-App-40x40@1x.png",
85 | "scale" : "1x"
86 | },
87 | {
88 | "size" : "40x40",
89 | "idiom" : "ipad",
90 | "filename" : "Icon-App-40x40@2x.png",
91 | "scale" : "2x"
92 | },
93 | {
94 | "size" : "76x76",
95 | "idiom" : "ipad",
96 | "filename" : "Icon-App-76x76@1x.png",
97 | "scale" : "1x"
98 | },
99 | {
100 | "size" : "76x76",
101 | "idiom" : "ipad",
102 | "filename" : "Icon-App-76x76@2x.png",
103 | "scale" : "2x"
104 | },
105 | {
106 | "size" : "83.5x83.5",
107 | "idiom" : "ipad",
108 | "filename" : "Icon-App-83.5x83.5@2x.png",
109 | "scale" : "2x"
110 | },
111 | {
112 | "size" : "1024x1024",
113 | "idiom" : "ios-marketing",
114 | "filename" : "Icon-App-1024x1024@1x.png",
115 | "scale" : "1x"
116 | }
117 | ],
118 | "info" : {
119 | "version" : 1,
120 | "author" : "xcode"
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/test/encrypt_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/rendering.dart';
2 | import 'package:flutter_test/flutter_test.dart';
3 | import 'package:flutter_util_code/utils.dart';
4 |
5 | /// Name: 加密工具类测试
6 | /// Created by Fitem on 2023/6/28
7 | void main() {
8 | String publicKey = '''
9 | MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMKXEQ1npgt0l5nJODHdnUMW16
10 | /HWloj3cPLvCbbEcsTTe/gGyZTvMvt2xDewRUnVqaZefn2vGlqhurkRQ7xpmo58l
11 | wb9c70d/RIZ3I+TULJH3mqZbv8nHq/BLlTL9DVqwp3G0ysdzLWHNAzAMwf7BjaNE
12 | Ro/zc4A598XePziqQwIDAQAB
13 | ''';
14 | String privateKey = '''
15 | MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMwpcRDWemC3SXmc
16 | k4Md2dQxbXr8daWiPdw8u8JtsRyxNN7+AbJlO8y+3bEN7BFSdWppl5+fa8aWqG6u
17 | RFDvGmajnyXBv1zvR39Ehncj5NQskfeaplu/ycer8EuVMv0NWrCncbTKx3MtYc0D
18 | MAzB/sGNo0RGj/NzgDn3xd4/OKpDAgMBAAECgYEAvWoZd1i1s3N5XLXS+gvA5Chz
19 | fW4qrGBI6kMCpBFnB8q01cptwpg/kebnAXR8N1n8i5ypyrN6p4VxgTZ3NWuQXk16
20 | G4UcZcqRciButOs0E+W4Ot5+PMLuutcsFW/uYtaTRIMWHLV0GuHJjUCbLKKJolFc
21 | thMggXOwy6EucL2NALkCQQD7koP0UiHTFyMHmdHKuAESQFU4fNzypzBlvOBBNX7T
22 | 1caLiCoRjUCDEGf8ABE4CTMeDT1SVBgLkfg0o3SFxI2vAkEAz8FQTFWerhnIGkdE
23 | bm/togRUk/LbYIg3YWMfsaDhMU3ue2h4ojXWvNduEjiLm9oX1MsmsBmZdpCRSW4/
24 | 5AeFrQJBAKQ3c+Ncaa/9fmRLyGJn0mszi22gNCpBcJo4vLpUTUHCXiRe8fcbGW10
25 | nCwnbxYBC1kmk0zWkAudcUQLHtjjAQkCQHMu+4UG504hbybaol8UYUy1V+sa93QC
26 | saml2lmSF6hNS85R8qgEb4UNb7JcdVK4TQQmidGSr9njdxmeLYAQh5UCQDlMuw0H
27 | 25UPw+9QMujcT3UTvABy0lOXRInZgEUU6YAjy0rNVUxLeNoyXlObRTlpoyVz58Er
28 | fp2bts3jaD4PsSU=
29 | ''';
30 | String content = 'hello world!';
31 | String rc4Key = 'abc123';
32 | String aesKey = 'xsH/6p7B2xhebSoZ';
33 | group('EncryptedUtils', () {
34 | // MD5加密
35 | test('MD5', () {
36 | String md5 = EncryptUtils.md5Encrypt(content);
37 | expect(md5, 'fc3ff98e8c6a0d3087d515c0473f8677');
38 | });
39 | // RC4加密/解密
40 | test('RC4', () {
41 | String encrypt = EncryptUtils.rc4Encrypt(content, rc4Key);
42 | String decrypt = EncryptUtils.rc4Decrypt(encrypt, rc4Key);
43 | expect(encrypt, 'YrlMGzqCagCj9+ff');
44 | expect(decrypt, content);
45 | });
46 | // AES加密/解密
47 | test('AES', () {
48 | String encrypt = EncryptUtils.aesEncrypt(content, aesKey);
49 | String decrypt = EncryptUtils.aesDecrypt(encrypt, aesKey);
50 | expect(encrypt, 'XkxSOtpoErJzTyW5/6sGNA==');
51 | expect(decrypt, content);
52 | });
53 | // RSA加密/解密
54 | test('RSA', () async {
55 | String encrypt = EncryptUtils.rsaEncrypt(content, publicKey);
56 | String decrypt = EncryptUtils.rsaDecrypt(encrypt, privateKey);
57 | debugPrint('encrypt: $encrypt');
58 | expect(decrypt, content);
59 | });
60 | // SHA256withRSA 签名/验签
61 | test('SHA256withRSA', () {
62 | String sign = EncryptUtils.sha256withRSASign(content, privateKey);
63 | bool verify = EncryptUtils.sha256withRSAVerify(content, sign, publicKey);
64 | debugPrint('sign: $sign');
65 | expect(verify, true);
66 | });
67 | // MD5withRSA 签名/验签
68 | // 若出现库无法找到问题,需要将example项目下的build文件拷贝到根目录下
69 | test('MD5withRSA', () async {
70 | String sign = await EncryptUtils.md5withRSASign(content, privateKey);
71 | bool verify = await EncryptUtils.md5withRSAVerify(content, sign, publicKey);
72 | debugPrint('sign: $sign');
73 | expect(verify, true);
74 | });
75 | });
76 | }
77 |
--------------------------------------------------------------------------------
/example/lib/function/permission_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_util_code/utils.dart';
3 | import 'package:flutter_util_code_example/widget/display_screen.dart';
4 |
5 | /// Name: 权限页面
6 | /// Created by Fitem on 2023/7/4
7 | class PermissionPage extends StatefulWidget {
8 | const PermissionPage({Key? key}) : super(key: key);
9 |
10 | @override
11 | PermissionPageState createState() => PermissionPageState();
12 | }
13 |
14 | class PermissionPageState extends State {
15 | Permission permission = Permission.storage;
16 | List permissions = [Permission.storage, Permission.camera];
17 | final GlobalKey globalKey = GlobalKey();
18 |
19 | @override
20 | Widget build(BuildContext context) {
21 | return Scaffold(
22 | appBar: AppBar(
23 | title: const Text('分享工具类'),
24 | ),
25 | body: SizedBox(
26 | width: double.infinity,
27 | height: double.infinity,
28 | child: Column(
29 | children: [
30 | _buildButton('当前权限状态', () async {
31 | PermissionStatus status = await PermissionUtils.getPermissionStatus(permission);
32 | String message = '$permission 权限状态:$status';
33 | ToastUtils.show(message);
34 | return message;
35 | }),
36 | _buildButton('请求单个权限', () async {
37 | PermissionStatus status = await PermissionUtils.requestPermission(
38 | permission,
39 | success: () => ToastUtils.showToast('$permission 权限获取成功!'),
40 | denied: (isPermanentlyDenied) {
41 | if (isPermanentlyDenied) {
42 | ToastUtils.showToast('$permission 被拒绝请打开应用设置手动开启!');
43 | } else {
44 | ToastUtils.showToast('$permission 被拒绝,请重新授权!');
45 | }
46 | },
47 | other: (status) => ToastUtils.showToast('$permission 权限状态:$status'),
48 | );
49 | return '$permission 权限状态:$status';
50 | }),
51 | _buildButton('请求多个权限', () async {
52 | PermissionStatus status = await PermissionUtils.requestPermissions(
53 | permissions,
54 | success: () => ToastUtils.showToast('$permissions 权限获取成功!'),
55 | denied: (isPermanentlyDenied) {
56 | if (isPermanentlyDenied) {
57 | ToastUtils.showToast('$permissions 被拒绝请打开应用设置手动开启!');
58 | } else {
59 | ToastUtils.showToast('$permissions 被拒绝,请重新授权!');
60 | }
61 | },
62 | other: (status) => ToastUtils.showToast('$permissions 权限状态:$status'),
63 | );
64 | return '$permissions 权限状态:$status';
65 | }),
66 | const Spacer(),
67 | Expanded(flex: 2, child: DisplayScreen(key: globalKey)),
68 | ],
69 | ),
70 | ),
71 | );
72 | }
73 |
74 | /// 通用按钮
75 | Widget _buildButton(String text, Future Function() onPressed) {
76 | return ElevatedButton(
77 | onPressed: () async {
78 | String content = await onPressed();
79 | addContent(content);
80 | },
81 | child: Text(text));
82 | }
83 |
84 | /// 添加内容
85 | void addContent(String content) {
86 | globalKey.currentState?.addContent(content);
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/example/lib/function/path_page.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:flutter_util_code/utils.dart';
5 | import 'package:flutter_util_code_example/widget/display_screen.dart';
6 |
7 | /// Name: Path工具页
8 | /// Created by Fitem on 2023/6/5
9 | class PathPage extends StatefulWidget {
10 | const PathPage({Key? key}) : super(key: key);
11 |
12 | @override
13 | UuidPageState createState() => UuidPageState();
14 | }
15 |
16 | class UuidPageState extends State {
17 |
18 | final GlobalKey globalKey = GlobalKey();
19 |
20 | @override
21 | Widget build(BuildContext context) {
22 | return Scaffold(
23 | appBar: AppBar(
24 | title: const Text('Path工具类'),
25 | ),
26 | body: SizedBox(
27 | width: double.infinity,
28 | height: double.infinity,
29 | child: Column(
30 | children: [
31 | ElevatedButton(onPressed: _handlePath , child: const Text('获取系统Path信息')),
32 | const Spacer(),
33 | Expanded(
34 | flex: 2,
35 | child: DisplayScreen(key: globalKey)
36 | ),
37 | ],
38 | ),
39 | ),
40 | );
41 | }
42 |
43 | /// 添加内容
44 | void addContent(String content) {
45 | globalKey.currentState?.addContent(content);
46 | }
47 |
48 |
49 | Future _handlePath() async {
50 | // App缓存目录
51 | String appCachePath = await PathUtils.getAppCachePath();
52 | // App支持目录
53 | String appSupportPath = await PathUtils.getAppSupportPath();
54 | // App文档目录
55 | String appDocPath = await PathUtils.getAppDocPath();
56 | // iOS / Android 通用目录
57 | addContent('App缓存目录: $appCachePath\n');
58 | addContent('App支持目录: $appSupportPath\n');
59 | addContent('App文档目录: $appDocPath\n');
60 |
61 | // iOS独有目录
62 | if(Platform.isIOS || Platform.isMacOS) {
63 | // 下载目录 - 仅iOS
64 | String downloadPath = await PathUtils.getDownloadPath();
65 | addContent('下载目录: $downloadPath\n');
66 | } else if(Platform.isAndroid) {
67 | // Android独有目录
68 | // Android外部存储目录
69 | String androidStoragePath = await PathUtils.getAndroidStoragePath();
70 | // Android外部缓存目录
71 | List androidExternalCachePaths = await PathUtils.getAndroidExternalCachePaths();
72 | // Android图片目录
73 | List androidPicturePaths = await PathUtils.getAndroidPicturePaths();
74 | // Android视频目录
75 | List androidMoviePaths = await PathUtils.getAndroidMoviePaths();
76 | // Android音乐目录
77 | List androidMusicPaths = await PathUtils.getAndroidMusicPaths();
78 | // Android相机目录
79 | List androidDCIMPaths = await PathUtils.getAndroidDCIMPaths();
80 | // Android下载目录
81 | List androidDownloadPaths = await PathUtils.getAndroidDownloadPaths();
82 | // Android文档目录
83 | List androidDocumentPaths = await PathUtils.getAndroidDocumentPaths();
84 |
85 | addContent('Android外部存储目录: $androidStoragePath\n');
86 | addContent('Android外部缓存目录: $androidExternalCachePaths\n');
87 | addContent('Android图片目录: $androidPicturePaths\n');
88 | addContent('Android视频目录: $androidMoviePaths\n');
89 | addContent('Android音乐目录: $androidMusicPaths\n');
90 | addContent('Android相机目录: $androidDCIMPaths\n');
91 | addContent('Android下载目录: $androidDownloadPaths\n');
92 | addContent('Android文档目录: $androidDocumentPaths\n');
93 | }
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/example/windows/runner/Runner.rc:
--------------------------------------------------------------------------------
1 | // Microsoft Visual C++ generated resource script.
2 | //
3 | #pragma code_page(65001)
4 | #include "resource.h"
5 |
6 | #define APSTUDIO_READONLY_SYMBOLS
7 | /////////////////////////////////////////////////////////////////////////////
8 | //
9 | // Generated from the TEXTINCLUDE 2 resource.
10 | //
11 | #include "winres.h"
12 |
13 | /////////////////////////////////////////////////////////////////////////////
14 | #undef APSTUDIO_READONLY_SYMBOLS
15 |
16 | /////////////////////////////////////////////////////////////////////////////
17 | // English (United States) resources
18 |
19 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
20 | LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
21 |
22 | #ifdef APSTUDIO_INVOKED
23 | /////////////////////////////////////////////////////////////////////////////
24 | //
25 | // TEXTINCLUDE
26 | //
27 |
28 | 1 TEXTINCLUDE
29 | BEGIN
30 | "resource.h\0"
31 | END
32 |
33 | 2 TEXTINCLUDE
34 | BEGIN
35 | "#include ""winres.h""\r\n"
36 | "\0"
37 | END
38 |
39 | 3 TEXTINCLUDE
40 | BEGIN
41 | "\r\n"
42 | "\0"
43 | END
44 |
45 | #endif // APSTUDIO_INVOKED
46 |
47 |
48 | /////////////////////////////////////////////////////////////////////////////
49 | //
50 | // Icon
51 | //
52 |
53 | // Icon with lowest ID value placed first to ensure application icon
54 | // remains consistent on all systems.
55 | IDI_APP_ICON ICON "resources\\app_icon.ico"
56 |
57 |
58 | /////////////////////////////////////////////////////////////////////////////
59 | //
60 | // Version
61 | //
62 |
63 | #if defined(FLUTTER_VERSION_MAJOR) && defined(FLUTTER_VERSION_MINOR) && defined(FLUTTER_VERSION_PATCH) && defined(FLUTTER_VERSION_BUILD)
64 | #define VERSION_AS_NUMBER FLUTTER_VERSION_MAJOR,FLUTTER_VERSION_MINOR,FLUTTER_VERSION_PATCH,FLUTTER_VERSION_BUILD
65 | #else
66 | #define VERSION_AS_NUMBER 1,0,0,0
67 | #endif
68 |
69 | #if defined(FLUTTER_VERSION)
70 | #define VERSION_AS_STRING FLUTTER_VERSION
71 | #else
72 | #define VERSION_AS_STRING "1.0.0"
73 | #endif
74 |
75 | VS_VERSION_INFO VERSIONINFO
76 | FILEVERSION VERSION_AS_NUMBER
77 | PRODUCTVERSION VERSION_AS_NUMBER
78 | FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
79 | #ifdef _DEBUG
80 | FILEFLAGS VS_FF_DEBUG
81 | #else
82 | FILEFLAGS 0x0L
83 | #endif
84 | FILEOS VOS__WINDOWS32
85 | FILETYPE VFT_APP
86 | FILESUBTYPE 0x0L
87 | BEGIN
88 | BLOCK "StringFileInfo"
89 | BEGIN
90 | BLOCK "040904e4"
91 | BEGIN
92 | VALUE "CompanyName", "com.fitem" "\0"
93 | VALUE "FileDescription", "flutter_util_code_example" "\0"
94 | VALUE "FileVersion", VERSION_AS_STRING "\0"
95 | VALUE "InternalName", "flutter_util_code_example" "\0"
96 | VALUE "LegalCopyright", "Copyright (C) 2023 com.fitem. All rights reserved." "\0"
97 | VALUE "OriginalFilename", "flutter_util_code_example.exe" "\0"
98 | VALUE "ProductName", "flutter_util_code_example" "\0"
99 | VALUE "ProductVersion", VERSION_AS_STRING "\0"
100 | END
101 | END
102 | BLOCK "VarFileInfo"
103 | BEGIN
104 | VALUE "Translation", 0x409, 1252
105 | END
106 | END
107 |
108 | #endif // English (United States) resources
109 | /////////////////////////////////////////////////////////////////////////////
110 |
111 |
112 |
113 | #ifndef APSTUDIO_INVOKED
114 | /////////////////////////////////////////////////////////////////////////////
115 | //
116 | // Generated from the TEXTINCLUDE 3 resource.
117 | //
118 |
119 |
120 | /////////////////////////////////////////////////////////////////////////////
121 | #endif // not APSTUDIO_INVOKED
122 |
--------------------------------------------------------------------------------
/example/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: flutter_util_code_example
2 | description: Demonstrates how to use the flutter_util_code plugin.
3 | # The following line prevents the package from being accidentally published to
4 | # pub.dev using `flutter pub publish`. This is preferred for private packages.
5 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev
6 |
7 | environment:
8 | sdk: '>=3.0.2 <4.0.0'
9 |
10 | # Dependencies specify other packages that your package needs in order to work.
11 | # To automatically upgrade your package dependencies to the latest versions
12 | # consider running `flutter pub upgrade --major-versions`. Alternatively,
13 | # dependencies can be manually updated by changing the version numbers below to
14 | # the latest version available on pub.dev. To see which dependencies have newer
15 | # versions available, run `flutter pub outdated`.
16 | dependencies:
17 | flutter:
18 | sdk: flutter
19 | # 状态管理器
20 | get: 4.6.1
21 |
22 | flutter_util_code:
23 | # When depending on this package from a real application you should use:
24 | # flutter_util_code: ^x.y.z
25 | # See https://dart.dev/tools/pub/dependencies#version-constraints
26 | # The example app is bundled with the plugin so we use a path dependency on
27 | # the parent directory to use the current plugin's version.
28 | path: ../
29 |
30 | # The following adds the Cupertino Icons font to your application.
31 | # Use with the CupertinoIcons class for iOS style icons.
32 | cupertino_icons: ^1.0.2
33 |
34 | dev_dependencies:
35 | integration_test:
36 | sdk: flutter
37 | flutter_test:
38 | sdk: flutter
39 |
40 | # The "flutter_lints" package below contains a set of recommended lints to
41 | # encourage good coding practices. The lint set provided by the package is
42 | # activated in the `analysis_options.yaml` file located at the root of your
43 | # package. See that file for information about deactivating specific lint
44 | # rules and activating additional ones.
45 | flutter_lints: ^2.0.0
46 |
47 | # For information on the generic Dart part of this file, see the
48 | # following page: https://dart.dev/tools/pub/pubspec
49 |
50 | # The following section is specific to Flutter packages.
51 | flutter:
52 |
53 | # The following line ensures that the Material Icons font is
54 | # included with your application, so that you can use the icons in
55 | # the material Icons class.
56 | uses-material-design: true
57 |
58 | # To add assets to your application, add an assets section, like this:
59 | # assets:
60 | # - images/a_dot_burr.jpeg
61 | # - images/a_dot_ham.jpeg
62 | assets:
63 | - assets/
64 |
65 | # An image asset can refer to one or more resolution-specific "variants", see
66 | # https://flutter.dev/assets-and-images/#resolution-aware
67 |
68 | # For details regarding adding assets from package dependencies, see
69 | # https://flutter.dev/assets-and-images/#from-packages
70 |
71 | # To add custom fonts to your application, add a fonts section here,
72 | # in this "flutter" section. Each entry in this list should have a
73 | # "family" key with the font family name, and a "fonts" key with a
74 | # list giving the asset and other descriptors for the font. For
75 | # example:
76 | # fonts:
77 | # - family: Schyler
78 | # fonts:
79 | # - asset: fonts/Schyler-Regular.ttf
80 | # - asset: fonts/Schyler-Italic.ttf
81 | # style: italic
82 | # - family: Trajan Pro
83 | # fonts:
84 | # - asset: fonts/TrajanPro.ttf
85 | # - asset: fonts/TrajanPro_Bold.ttf
86 | # weight: 700
87 | #
88 | # For details regarding fonts from package dependencies,
89 | # see https://flutter.dev/custom-fonts/#from-packages
90 |
--------------------------------------------------------------------------------
/lib/shared_prefs_utils.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter_util_code/utils.dart';
2 | import 'package:shared_preferences/shared_preferences.dart';
3 |
4 | /// Name: SP工具类
5 | /// 基于 [shared_preferences](https://pub.dev/packages/shared_preferences)
6 | /// Created by Fitem on 2023/5/31
7 | class SharedPrefsUtils {
8 | /// 添加String类型数据
9 | /// [key] 键
10 | /// [value] 值
11 | static Future putString(String key, String value) async {
12 | _println('putString', key, value);
13 | SharedPreferences prefs = await SharedPreferences.getInstance();
14 | prefs.setString(key, value);
15 | }
16 |
17 | /// 添加int类型数据
18 | /// [key] 键
19 | /// [value] 值
20 | static Future putInt(String key, int value) async {
21 | _println('putInt', key, value);
22 | SharedPreferences prefs = await SharedPreferences.getInstance();
23 | prefs.setInt(key, value);
24 | }
25 |
26 | /// 添加bool类型数据
27 | /// [key] 键
28 | /// [value] 值
29 | static Future putBool(String key, bool value) async {
30 | _println('putBool', key, value);
31 | SharedPreferences prefs = await SharedPreferences.getInstance();
32 | prefs.setBool(key, value);
33 | }
34 |
35 | /// 添加double类型数据
36 | /// [key] 键
37 | /// [value] 值
38 | static Future putDouble(String key, double value) async {
39 | _println('putDouble', key, value);
40 | SharedPreferences prefs = await SharedPreferences.getInstance();
41 | prefs.setDouble(key, value);
42 | }
43 |
44 | /// 添加List类型数据
45 | /// [key] 键
46 | /// [value] 值
47 | static Future putStringList(String key, List value) async {
48 | _println('putStringList', key, value);
49 | SharedPreferences prefs = await SharedPreferences.getInstance();
50 | prefs.setStringList(key, value);
51 | }
52 |
53 | /// 获取String类型数据
54 | /// [key] 键
55 | /// [defValue] 默认值:默认为空字符串
56 | static Future getString(String key, [String defValue = '']) async {
57 | SharedPreferences prefs = await SharedPreferences.getInstance();
58 | String? value = prefs.getString(key) ?? defValue;
59 | _println('getString', key, value);
60 | return value;
61 | }
62 |
63 | /// 获取int类型数据,如果没有则返回默认值
64 | /// [key] 键
65 | /// [defValue] 默认值:默认为0
66 | static Future getInt(String key, [int defValue = 0]) async {
67 | SharedPreferences prefs = await SharedPreferences.getInstance();
68 | int? value = prefs.getInt(key) ?? defValue;
69 | _println('getInt', key, value);
70 | return value;
71 | }
72 |
73 | /// 获取double类型数据,如果没有则返回默认值
74 | /// [key] 键
75 | /// [defValue] 默认值:默认为0.0
76 | static Future getDouble(String key, [double defValue = 0.0]) async {
77 | SharedPreferences prefs = await SharedPreferences.getInstance();
78 | double? value = prefs.getDouble(key) ?? defValue;
79 | _println('getDouble', key, value);
80 | return value;
81 | }
82 |
83 | /// 获取bool类型数据,如果没有则返回默认值
84 | /// [key] 键
85 | /// [defValue] 默认值:默认为false
86 | static Future getBool(String key, [bool defValue = false]) async {
87 | SharedPreferences prefs = await SharedPreferences.getInstance();
88 | bool? value = prefs.getBool(key) ?? defValue;
89 | _println('getBool', key, value);
90 | return value;
91 | }
92 |
93 | /// 获取List类型数据,如果没有则返回默认值
94 | /// [key] 键
95 | /// [defValue] 默认值:默认为空List
96 | static Future> getStringList(String key, [List defValue = const []]) async {
97 | SharedPreferences prefs = await SharedPreferences.getInstance();
98 | List? value = prefs.getStringList(key) ?? defValue;
99 | _println('getStringList', key, value);
100 | return value;
101 | }
102 |
103 | /// 打印日志
104 | static void _println(String methodName, String key, dynamic value) {
105 | LogUtils.println('''SharedPref $methodName:
106 | key: $key
107 | value: $value''');
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/example/windows/runner/win32_window.h:
--------------------------------------------------------------------------------
1 | #ifndef RUNNER_WIN32_WINDOW_H_
2 | #define RUNNER_WIN32_WINDOW_H_
3 |
4 | #include
5 |
6 | #include
7 | #include
8 | #include
9 |
10 | // A class abstraction for a high DPI-aware Win32 Window. Intended to be
11 | // inherited from by classes that wish to specialize with custom
12 | // rendering and input handling
13 | class Win32Window {
14 | public:
15 | struct Point {
16 | unsigned int x;
17 | unsigned int y;
18 | Point(unsigned int x, unsigned int y) : x(x), y(y) {}
19 | };
20 |
21 | struct Size {
22 | unsigned int width;
23 | unsigned int height;
24 | Size(unsigned int width, unsigned int height)
25 | : width(width), height(height) {}
26 | };
27 |
28 | Win32Window();
29 | virtual ~Win32Window();
30 |
31 | // Creates a win32 window with |title| that is positioned and sized using
32 | // |origin| and |size|. New windows are created on the default monitor. Window
33 | // sizes are specified to the OS in physical pixels, hence to ensure a
34 | // consistent size this function will scale the inputted width and height as
35 | // as appropriate for the default monitor. The window is invisible until
36 | // |Show| is called. Returns true if the window was created successfully.
37 | bool Create(const std::wstring& title, const Point& origin, const Size& size);
38 |
39 | // Show the current window. Returns true if the window was successfully shown.
40 | bool Show();
41 |
42 | // Release OS resources associated with window.
43 | void Destroy();
44 |
45 | // Inserts |content| into the window tree.
46 | void SetChildContent(HWND content);
47 |
48 | // Returns the backing Window handle to enable clients to set icon and other
49 | // window properties. Returns nullptr if the window has been destroyed.
50 | HWND GetHandle();
51 |
52 | // If true, closing this window will quit the application.
53 | void SetQuitOnClose(bool quit_on_close);
54 |
55 | // Return a RECT representing the bounds of the current client area.
56 | RECT GetClientArea();
57 |
58 | protected:
59 | // Processes and route salient window messages for mouse handling,
60 | // size change and DPI. Delegates handling of these to member overloads that
61 | // inheriting classes can handle.
62 | virtual LRESULT MessageHandler(HWND window,
63 | UINT const message,
64 | WPARAM const wparam,
65 | LPARAM const lparam) noexcept;
66 |
67 | // Called when CreateAndShow is called, allowing subclass window-related
68 | // setup. Subclasses should return false if setup fails.
69 | virtual bool OnCreate();
70 |
71 | // Called when Destroy is called.
72 | virtual void OnDestroy();
73 |
74 | private:
75 | friend class WindowClassRegistrar;
76 |
77 | // OS callback called by message pump. Handles the WM_NCCREATE message which
78 | // is passed when the non-client area is being created and enables automatic
79 | // non-client DPI scaling so that the non-client area automatically
80 | // responds to changes in DPI. All other messages are handled by
81 | // MessageHandler.
82 | static LRESULT CALLBACK WndProc(HWND const window,
83 | UINT const message,
84 | WPARAM const wparam,
85 | LPARAM const lparam) noexcept;
86 |
87 | // Retrieves a class instance pointer for |window|
88 | static Win32Window* GetThisFromHandle(HWND const window) noexcept;
89 |
90 | // Update the window frame's theme to match the system theme.
91 | static void UpdateTheme(HWND const window);
92 |
93 | bool quit_on_close_ = false;
94 |
95 | // window handle for top level window.
96 | HWND window_handle_ = nullptr;
97 |
98 | // window handle for hosted content.
99 | HWND child_content_ = nullptr;
100 | };
101 |
102 | #endif // RUNNER_WIN32_WINDOW_H_
103 |
--------------------------------------------------------------------------------
/lib/url_launcher_utils.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 |
3 | import 'package:flutter/foundation.dart';
4 | import 'package:flutter_util_code/utils.dart';
5 | import 'package:url_launcher/url_launcher.dart';
6 | import 'package:url_launcher/url_launcher_string.dart';
7 |
8 | /// Name: URL跳转工具类
9 | /// 基于 [url_launcher](https://pub.dev/packages/url_launcher)
10 | /// *注意使用此功能需要添加权限*
11 | /// 在Android上,需要在AndroidManifest.xml中添加:
12 | /// 在iOS上,需要在Info.plist中添加:LSApplicationQueriesSchemes smstel
13 | /// Created by Fitem on 2023/6/19
14 | class UrlLauncherUtils {
15 | /// 浏览器打开url
16 | /// [url] 跳转的url https://flutter.dev
17 | /// 若不支持浏览器则返回false
18 | static Future launchInBrowser(String url) async {
19 | // 是否支持浏览器打开,支持则打开,不支持则返回false
20 | if (!await onCanLaunchUrl(url)) return false;
21 | return await launchUrlString(url, mode: LaunchMode.externalApplication);
22 | }
23 |
24 | /// 非浏览器第三方应用打开url
25 | /// [url] 跳转的url https://flutter.dev
26 | /// 若不支持非浏览器第三方应用则返回false
27 | static Future launchInNonBrowser(String url) async {
28 | // 是否支持浏览器打开,支持则打开,不支持则抛出异常
29 | if (!await onCanLaunchUrl(url)) return false;
30 | return await launchUrlString(url, mode: LaunchMode.externalNonBrowserApplication);
31 | }
32 |
33 | /// WebView打开url
34 | /// [url] 跳转的url https://flutter.dev
35 | /// 若不支持WebView则返回false
36 | static Future launchInApp(String url) async {
37 | // 是否支持浏览器打开,支持则打开,不支持则抛出异常
38 | if (!await onCanLaunchUrl(url)) return false;
39 | return await launchUrlString(url, mode: LaunchMode.inAppWebView);
40 | }
41 |
42 | /// 关闭WebView
43 | static Future onCloseInAppWebView() async {
44 | return await closeInAppWebView();
45 | }
46 |
47 | /// 打电话
48 | /// [phoneNumber] 电话号码 10086
49 | /// 若不支持打电话则返回false
50 | static Future onCall(String phoneNumber) async {
51 | Uri uri = Uri(scheme: 'tel', path: phoneNumber);
52 | if (!await onCanLaunchUrl(uri.toString())) return false;
53 | return await launchUrl(uri);
54 | }
55 |
56 | /// 发短信
57 | /// [phoneNumber] 电话号码 10086
58 | /// 若不支持发短信则返回false
59 | static Future sendSMS(String phoneNumber, {String content = ''}) async {
60 | Uri uri = Uri(scheme: 'sms', path: phoneNumber, queryParameters: {'body': content});
61 | if (!await onCanLaunchUrl(uri.toString())) return false;
62 | return await launchUrl(uri);
63 | }
64 |
65 | /// 发送邮件
66 | /// [mailAddress] 邮箱地址 smith@example.org?subject=News&body=New%20plugin
67 | /// 若不支持发邮件则返回false
68 | static Future sendEmail(
69 | String mailAddress, {
70 | String subject = '',
71 | String content = '',
72 | }) async {
73 | Uri uri = Uri(scheme: 'mailto', path: mailAddress, queryParameters: {'subject': subject, 'body': content});
74 | if (!await onCanLaunchUrl(uri.toString())) return false;
75 | return await launchUrl(uri);
76 | }
77 |
78 | /// 打开文件
79 | /// [filePath] 文件路径 /storage/emulated/0/Download/xxx.pdf
80 | /// 若不支持打开文件则返回false
81 | /// 由于Android 7.0 以上版本的限制,无法直接通过file://的方式来打开文件,需要通过FileProvider来打开
82 | static Future openFile(String filePath) async {
83 | LogUtils.println('filePath: $filePath');
84 | if (!File(filePath).existsSync()) {
85 | LogUtils.println('文件不存在');
86 | return false;
87 | }
88 | Uri uri = Uri(scheme: 'file', path: filePath);
89 | // 由于Android 7.0 以上版本的限制,无法直接通过file://的方式来打开文件,需要通过FileProvider来打开
90 | if (!kIsWeb && Platform.isAndroid && int.parse(await DeviceUtils.getSystemVersion()) >= 24) return false;
91 | if (!await onCanLaunchUrl(uri.toString())) return false;
92 | return await launchUrl(uri);
93 | }
94 |
95 | /// 是否支持该url打开
96 | /// [url] 跳转的url
97 | static Future onCanLaunchUrl(String url) async {
98 | LogUtils.println('url: $url');
99 | return await canLaunchUrlString(url);
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
37 |
38 |
39 |
40 |
43 |
49 |
50 |
51 |
52 |
53 |
63 |
65 |
71 |
72 |
73 |
74 |
80 |
82 |
88 |
89 |
90 |
91 |
93 |
94 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/example/windows/flutter/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # This file controls Flutter-level build steps. It should not be edited.
2 | cmake_minimum_required(VERSION 3.14)
3 |
4 | set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral")
5 |
6 | # Configuration provided via flutter tool.
7 | include(${EPHEMERAL_DIR}/generated_config.cmake)
8 |
9 | # TODO: Move the rest of this into files in ephemeral. See
10 | # https://github.com/flutter/flutter/issues/57146.
11 | set(WRAPPER_ROOT "${EPHEMERAL_DIR}/cpp_client_wrapper")
12 |
13 | # === Flutter Library ===
14 | set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/flutter_windows.dll")
15 |
16 | # Published to parent scope for install step.
17 | set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE)
18 | set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE)
19 | set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE)
20 | set(AOT_LIBRARY "${PROJECT_DIR}/build/windows/app.so" PARENT_SCOPE)
21 |
22 | list(APPEND FLUTTER_LIBRARY_HEADERS
23 | "flutter_export.h"
24 | "flutter_windows.h"
25 | "flutter_messenger.h"
26 | "flutter_plugin_registrar.h"
27 | "flutter_texture_registrar.h"
28 | )
29 | list(TRANSFORM FLUTTER_LIBRARY_HEADERS PREPEND "${EPHEMERAL_DIR}/")
30 | add_library(flutter INTERFACE)
31 | target_include_directories(flutter INTERFACE
32 | "${EPHEMERAL_DIR}"
33 | )
34 | target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}.lib")
35 | add_dependencies(flutter flutter_assemble)
36 |
37 | # === Wrapper ===
38 | list(APPEND CPP_WRAPPER_SOURCES_CORE
39 | "core_implementations.cc"
40 | "standard_codec.cc"
41 | )
42 | list(TRANSFORM CPP_WRAPPER_SOURCES_CORE PREPEND "${WRAPPER_ROOT}/")
43 | list(APPEND CPP_WRAPPER_SOURCES_PLUGIN
44 | "plugin_registrar.cc"
45 | )
46 | list(TRANSFORM CPP_WRAPPER_SOURCES_PLUGIN PREPEND "${WRAPPER_ROOT}/")
47 | list(APPEND CPP_WRAPPER_SOURCES_APP
48 | "flutter_engine.cc"
49 | "flutter_view_controller.cc"
50 | )
51 | list(TRANSFORM CPP_WRAPPER_SOURCES_APP PREPEND "${WRAPPER_ROOT}/")
52 |
53 | # Wrapper sources needed for a plugin.
54 | add_library(flutter_wrapper_plugin STATIC
55 | ${CPP_WRAPPER_SOURCES_CORE}
56 | ${CPP_WRAPPER_SOURCES_PLUGIN}
57 | )
58 | apply_standard_settings(flutter_wrapper_plugin)
59 | set_target_properties(flutter_wrapper_plugin PROPERTIES
60 | POSITION_INDEPENDENT_CODE ON)
61 | set_target_properties(flutter_wrapper_plugin PROPERTIES
62 | CXX_VISIBILITY_PRESET hidden)
63 | target_link_libraries(flutter_wrapper_plugin PUBLIC flutter)
64 | target_include_directories(flutter_wrapper_plugin PUBLIC
65 | "${WRAPPER_ROOT}/include"
66 | )
67 | add_dependencies(flutter_wrapper_plugin flutter_assemble)
68 |
69 | # Wrapper sources needed for the runner.
70 | add_library(flutter_wrapper_app STATIC
71 | ${CPP_WRAPPER_SOURCES_CORE}
72 | ${CPP_WRAPPER_SOURCES_APP}
73 | )
74 | apply_standard_settings(flutter_wrapper_app)
75 | target_link_libraries(flutter_wrapper_app PUBLIC flutter)
76 | target_include_directories(flutter_wrapper_app PUBLIC
77 | "${WRAPPER_ROOT}/include"
78 | )
79 | add_dependencies(flutter_wrapper_app flutter_assemble)
80 |
81 | # === Flutter tool backend ===
82 | # _phony_ is a non-existent file to force this command to run every time,
83 | # since currently there's no way to get a full input/output list from the
84 | # flutter tool.
85 | set(PHONY_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/_phony_")
86 | set_source_files_properties("${PHONY_OUTPUT}" PROPERTIES SYMBOLIC TRUE)
87 | add_custom_command(
88 | OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
89 | ${CPP_WRAPPER_SOURCES_CORE} ${CPP_WRAPPER_SOURCES_PLUGIN}
90 | ${CPP_WRAPPER_SOURCES_APP}
91 | ${PHONY_OUTPUT}
92 | COMMAND ${CMAKE_COMMAND} -E env
93 | ${FLUTTER_TOOL_ENVIRONMENT}
94 | "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.bat"
95 | windows-x64 $
96 | VERBATIM
97 | )
98 | add_custom_target(flutter_assemble DEPENDS
99 | "${FLUTTER_LIBRARY}"
100 | ${FLUTTER_LIBRARY_HEADERS}
101 | ${CPP_WRAPPER_SOURCES_CORE}
102 | ${CPP_WRAPPER_SOURCES_PLUGIN}
103 | ${CPP_WRAPPER_SOURCES_APP}
104 | )
105 |
--------------------------------------------------------------------------------
/lib/share_utils.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 | import 'dart:typed_data';
3 |
4 | import 'package:flutter_util_code/utils.dart';
5 | import 'package:share_plus/share_plus.dart';
6 |
7 | /// Name: 分享工具类
8 | /// 基于 [share_plus](https://pub.dev/packages/share_plus)
9 | /// Created by Fitem on 2023/6/28
10 | class ShareUtils {
11 | /// 分享文本
12 | /// [text]分享内容
13 | /// [subject]分享主题
14 | static Future shareText(
15 | String text, {
16 | String? subject,
17 | }) async {
18 | ShareResult result = await Share.shareWithResult(text, subject: subject);
19 | return result.status == ShareResultStatus.success;
20 | }
21 |
22 | /// 分享图片
23 | /// [path] 与 [bytes] 二选一,不符合则抛出 [FormatException] 异常
24 | /// [name]图片名称
25 | /// [path]图片路径
26 | /// [bytes]图片字节
27 | /// [text]分享内容
28 | /// [subject]分享主题
29 | static Future shareImage({
30 | required String name,
31 | String? path,
32 | Uint8List? bytes,
33 | String? text,
34 | String? subject,
35 | }) async {
36 | XFile file = await _createFile(name, path, bytes);
37 | final files = [file];
38 | ShareResult result = await Share.shareXFiles(files, text: text, subject: subject);
39 | return result.status == ShareResultStatus.success;
40 | }
41 |
42 | /// 分享多张图片
43 | /// [images]图片列表
44 | /// [text]分享内容
45 | /// [subject]分享主题
46 | static Future shareImages(
47 | List images, {
48 | String? text,
49 | String? subject,
50 | }) async {
51 | final files = [];
52 | for (var i = 0; i < images.length; i++) {
53 | files.add(await _createFile(images[i].name, images[i].path, images[i].bytes));
54 | }
55 | ShareResult result = await Share.shareXFiles(files, text: text, subject: subject);
56 | return result.status == ShareResultStatus.success;
57 | }
58 |
59 | /// 分享文件
60 | /// [path] 与 [bytes] 二选一,不符合则抛出 [FormatException] 异常
61 | /// [name]文件名称
62 | /// [path]文件路径
63 | /// [bytes]文件字节
64 | /// [text]分享内容
65 | /// [subject]分享主题
66 | static Future shareFile({
67 | required String name,
68 | String? path,
69 | Uint8List? bytes,
70 | String? text,
71 | String? subject,
72 | }) async {
73 | XFile file = await _createFile(name, path, bytes);
74 | final files = [file];
75 | ShareResult result = await Share.shareXFiles(files, text: text, subject: subject);
76 | return result.status == ShareResultStatus.success;
77 | }
78 |
79 | /// 分享多个文件
80 | /// [files]文件列表
81 | /// [text]分享内容
82 | /// [subject]分享主题
83 | static Future shareFiles(
84 | List files, {
85 | String? text,
86 | String? subject,
87 | }) async {
88 | final list = [];
89 | for (var i = 0; i < files.length; i++) {
90 | list.add(await _createFile(files[i].name, files[i].path, files[i].bytes));
91 | }
92 | ShareResult result = await Share.shareXFiles(list, text: text, subject: subject);
93 | return result.status == ShareResultStatus.success;
94 | }
95 |
96 | /// 创建XFile文件
97 | /// [path] 与 [bytes] 二选一,不符合则抛出 [FormatException] 异常
98 | /// [name]文件名称
99 | /// [path]文件路径
100 | /// [bytes]文件字节
101 | static Future _createFile(String name, String? path, Uint8List? bytes) async {
102 | if (path != null) {
103 | return XFile(path, name: name);
104 | } else if (bytes != null) {
105 | // 获取缓存目录
106 | final String tempFilePath = await PathUtils.getAppCachePath();
107 | final String path = '$tempFilePath/$name';
108 | // 写入文件
109 | final file = File(path);
110 | await file.writeAsBytes(bytes);
111 | // 根据文件路径创建XFile
112 | return XFile(path, name: name);
113 | } else {
114 | throw const FormatException('path or bytes must be not null');
115 | }
116 | }
117 | }
118 |
119 | /// 分享文件对象
120 | class ShareFile {
121 | String name; // 文件名称
122 | String? path; // 文件路径
123 | Uint8List? bytes; // 文件bytes
124 |
125 | ShareFile({
126 | required this.name,
127 | this.path,
128 | this.bytes,
129 | });
130 | }
131 |
--------------------------------------------------------------------------------
/lib/toast_utils.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:fluttertoast/fluttertoast.dart';
3 |
4 | /// Name: 吐司工具类
5 | /// 基于 [fluttertoast](https://pub.dev/packages/fluttertoast)
6 | /// Created by Fitem on 2023/6/1
7 | class ToastUtils {
8 | /// 背景色
9 | static Color toastBgColor = const Color(0x80000000);
10 |
11 | /// Text颜色
12 | static Color toastTextColor = Colors.white;
13 |
14 | /// 字体大小
15 | static double toastFontSize = 16.0;
16 |
17 | /// 初始化 Toast
18 | /// [bgColor] 背景色
19 | /// [textColor] Text颜色
20 | /// [fontSize] 字体大小
21 | static void init({Color? bgColor, Color? textColor, double? fontSize}) {
22 | toastBgColor = bgColor ?? toastBgColor;
23 | toastTextColor = textColor ?? toastTextColor;
24 | toastFontSize = fontSize ?? toastFontSize;
25 | }
26 |
27 | /// 显示中间的Toast
28 | /// [msg] 显示的内容
29 | static void showCenter(String msg) {
30 | Fluttertoast.showToast(
31 | msg: msg,
32 | toastLength: Toast.LENGTH_SHORT,
33 | gravity: ToastGravity.CENTER,
34 | backgroundColor: toastBgColor,
35 | textColor: toastTextColor,
36 | fontSize: 16.0,
37 | );
38 | }
39 |
40 | /// 显示底部的Toast
41 | /// [msg] 显示的内容
42 | static void show(String msg) {
43 | Fluttertoast.showToast(
44 | msg: msg,
45 | toastLength: Toast.LENGTH_SHORT,
46 | gravity: ToastGravity.BOTTOM,
47 | backgroundColor: toastBgColor,
48 | textColor: toastTextColor,
49 | fontSize: 16.0,
50 | );
51 | }
52 |
53 | /// 显示的Toast
54 | /// [msg] 显示的内容
55 | /// [toast] 显示的时间
56 | /// [gravity] 显示的位置
57 | /// [bgColor] 背景色
58 | /// [textColor] Text颜色
59 | /// [fontSize] 字体大小
60 | static void showToast(
61 | String msg, {
62 | FToast toast = FToast.lengthShort,
63 | FToastGravity gravity = FToastGravity.bottom,
64 | Color? bgColor,
65 | Color? textColor,
66 | double? fontSize,
67 | }) {
68 | Fluttertoast.showToast(
69 | msg: msg,
70 | toastLength: _getToastLength(toast),
71 | gravity: _getToastGravity(gravity),
72 | backgroundColor: bgColor ?? toastBgColor,
73 | textColor: textColor ?? toastTextColor,
74 | fontSize: fontSize ?? toastFontSize,
75 | );
76 | }
77 |
78 | /// 获取Toast显示时间
79 | static _getToastLength(FToast toast) {
80 | switch (toast) {
81 | case FToast.lengthShort:
82 | return Toast.LENGTH_SHORT;
83 | case FToast.lengthLong:
84 | return Toast.LENGTH_LONG;
85 | }
86 | }
87 |
88 | /// 获取Toast显示位置
89 | static _getToastGravity(FToastGravity gravity) {
90 | switch (gravity) {
91 | case FToastGravity.top:
92 | return ToastGravity.TOP;
93 | case FToastGravity.bottom:
94 | return ToastGravity.BOTTOM;
95 | case FToastGravity.center:
96 | return ToastGravity.CENTER;
97 | case FToastGravity.topLeft:
98 | return ToastGravity.TOP_LEFT;
99 | case FToastGravity.topRight:
100 | return ToastGravity.TOP_RIGHT;
101 | case FToastGravity.bottomLeft:
102 | return ToastGravity.BOTTOM_LEFT;
103 | case FToastGravity.bottomRight:
104 | return ToastGravity.BOTTOM_RIGHT;
105 | case FToastGravity.centerLeft:
106 | return ToastGravity.CENTER_LEFT;
107 | case FToastGravity.centerRight:
108 | return ToastGravity.CENTER_RIGHT;
109 | case FToastGravity.snackBar:
110 | return ToastGravity.SNACKBAR;
111 | case FToastGravity.none:
112 | return ToastGravity.NONE;
113 | }
114 | }
115 | }
116 |
117 | /// Toast显示位置
118 | enum FToastGravity {
119 | top,
120 | bottom,
121 | center,
122 | topLeft,
123 | topRight,
124 | bottomLeft,
125 | bottomRight,
126 | centerLeft,
127 | centerRight,
128 | snackBar,
129 | none
130 | }
131 |
132 | /// Toast显示时间
133 | /// 两种模式:[lengthShort] 显示时长 1秒钟、[lengthLong] 显示时长 5秒钟
134 | /// Only for Android Platform
135 | enum FToast {
136 | /// Show Short toast for 1 sec
137 | lengthShort,
138 |
139 | /// Show Long toast for 5 sec
140 | lengthLong
141 | }
--------------------------------------------------------------------------------
/example/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
37 |
38 |
39 |
40 |
43 |
49 |
50 |
51 |
52 |
53 |
63 |
65 |
71 |
72 |
73 |
74 |
80 |
82 |
88 |
89 |
90 |
91 |
93 |
94 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/example/linux/my_application.cc:
--------------------------------------------------------------------------------
1 | #include "my_application.h"
2 |
3 | #include
4 | #ifdef GDK_WINDOWING_X11
5 | #include
6 | #endif
7 |
8 | #include "flutter/generated_plugin_registrant.h"
9 |
10 | struct _MyApplication {
11 | GtkApplication parent_instance;
12 | char** dart_entrypoint_arguments;
13 | };
14 |
15 | G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION)
16 |
17 | // Implements GApplication::activate.
18 | static void my_application_activate(GApplication* application) {
19 | MyApplication* self = MY_APPLICATION(application);
20 | GtkWindow* window =
21 | GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application)));
22 |
23 | // Use a header bar when running in GNOME as this is the common style used
24 | // by applications and is the setup most users will be using (e.g. Ubuntu
25 | // desktop).
26 | // If running on X and not using GNOME then just use a traditional title bar
27 | // in case the window manager does more exotic layout, e.g. tiling.
28 | // If running on Wayland assume the header bar will work (may need changing
29 | // if future cases occur).
30 | gboolean use_header_bar = TRUE;
31 | #ifdef GDK_WINDOWING_X11
32 | GdkScreen* screen = gtk_window_get_screen(window);
33 | if (GDK_IS_X11_SCREEN(screen)) {
34 | const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen);
35 | if (g_strcmp0(wm_name, "GNOME Shell") != 0) {
36 | use_header_bar = FALSE;
37 | }
38 | }
39 | #endif
40 | if (use_header_bar) {
41 | GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new());
42 | gtk_widget_show(GTK_WIDGET(header_bar));
43 | gtk_header_bar_set_title(header_bar, "flutter_util_code_example");
44 | gtk_header_bar_set_show_close_button(header_bar, TRUE);
45 | gtk_window_set_titlebar(window, GTK_WIDGET(header_bar));
46 | } else {
47 | gtk_window_set_title(window, "flutter_util_code_example");
48 | }
49 |
50 | gtk_window_set_default_size(window, 1280, 720);
51 | gtk_widget_show(GTK_WIDGET(window));
52 |
53 | g_autoptr(FlDartProject) project = fl_dart_project_new();
54 | fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments);
55 |
56 | FlView* view = fl_view_new(project);
57 | gtk_widget_show(GTK_WIDGET(view));
58 | gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view));
59 |
60 | fl_register_plugins(FL_PLUGIN_REGISTRY(view));
61 |
62 | gtk_widget_grab_focus(GTK_WIDGET(view));
63 | }
64 |
65 | // Implements GApplication::local_command_line.
66 | static gboolean my_application_local_command_line(GApplication* application, gchar*** arguments, int* exit_status) {
67 | MyApplication* self = MY_APPLICATION(application);
68 | // Strip out the first argument as it is the binary name.
69 | self->dart_entrypoint_arguments = g_strdupv(*arguments + 1);
70 |
71 | g_autoptr(GError) error = nullptr;
72 | if (!g_application_register(application, nullptr, &error)) {
73 | g_warning("Failed to register: %s", error->message);
74 | *exit_status = 1;
75 | return TRUE;
76 | }
77 |
78 | g_application_activate(application);
79 | *exit_status = 0;
80 |
81 | return TRUE;
82 | }
83 |
84 | // Implements GObject::dispose.
85 | static void my_application_dispose(GObject* object) {
86 | MyApplication* self = MY_APPLICATION(object);
87 | g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev);
88 | G_OBJECT_CLASS(my_application_parent_class)->dispose(object);
89 | }
90 |
91 | static void my_application_class_init(MyApplicationClass* klass) {
92 | G_APPLICATION_CLASS(klass)->activate = my_application_activate;
93 | G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line;
94 | G_OBJECT_CLASS(klass)->dispose = my_application_dispose;
95 | }
96 |
97 | static void my_application_init(MyApplication* self) {}
98 |
99 | MyApplication* my_application_new() {
100 | return MY_APPLICATION(g_object_new(my_application_get_type(),
101 | "application-id", APPLICATION_ID,
102 | "flags", G_APPLICATION_NON_UNIQUE,
103 | nullptr));
104 | }
105 |
--------------------------------------------------------------------------------
/example/windows/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # Project-level configuration.
2 | cmake_minimum_required(VERSION 3.14)
3 | project(flutter_util_code_example LANGUAGES CXX)
4 |
5 | # The name of the executable created for the application. Change this to change
6 | # the on-disk name of your application.
7 | set(BINARY_NAME "flutter_util_code_example")
8 |
9 | # Explicitly opt in to modern CMake behaviors to avoid warnings with recent
10 | # versions of CMake.
11 | cmake_policy(SET CMP0063 NEW)
12 |
13 | # Define build configuration option.
14 | get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
15 | if(IS_MULTICONFIG)
16 | set(CMAKE_CONFIGURATION_TYPES "Debug;Profile;Release"
17 | CACHE STRING "" FORCE)
18 | else()
19 | if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
20 | set(CMAKE_BUILD_TYPE "Debug" CACHE
21 | STRING "Flutter build mode" FORCE)
22 | set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
23 | "Debug" "Profile" "Release")
24 | endif()
25 | endif()
26 | # Define settings for the Profile build mode.
27 | set(CMAKE_EXE_LINKER_FLAGS_PROFILE "${CMAKE_EXE_LINKER_FLAGS_RELEASE}")
28 | set(CMAKE_SHARED_LINKER_FLAGS_PROFILE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}")
29 | set(CMAKE_C_FLAGS_PROFILE "${CMAKE_C_FLAGS_RELEASE}")
30 | set(CMAKE_CXX_FLAGS_PROFILE "${CMAKE_CXX_FLAGS_RELEASE}")
31 |
32 | # Use Unicode for all projects.
33 | add_definitions(-DUNICODE -D_UNICODE)
34 |
35 | # Compilation settings that should be applied to most targets.
36 | #
37 | # Be cautious about adding new options here, as plugins use this function by
38 | # default. In most cases, you should add new options to specific targets instead
39 | # of modifying this function.
40 | function(APPLY_STANDARD_SETTINGS TARGET)
41 | target_compile_features(${TARGET} PUBLIC cxx_std_17)
42 | target_compile_options(${TARGET} PRIVATE /W4 /WX /wd"4100")
43 | target_compile_options(${TARGET} PRIVATE /EHsc)
44 | target_compile_definitions(${TARGET} PRIVATE "_HAS_EXCEPTIONS=0")
45 | target_compile_definitions(${TARGET} PRIVATE "$<$:_DEBUG>")
46 | endfunction()
47 |
48 | # Flutter library and tool build rules.
49 | set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter")
50 | add_subdirectory(${FLUTTER_MANAGED_DIR})
51 |
52 | # Application build; see runner/CMakeLists.txt.
53 | add_subdirectory("runner")
54 |
55 | # Enable the test target.
56 | set(include_flutter_util_code_tests TRUE)
57 |
58 | # Generated plugin build rules, which manage building the plugins and adding
59 | # them to the application.
60 | include(flutter/generated_plugins.cmake)
61 |
62 |
63 | # === Installation ===
64 | # Support files are copied into place next to the executable, so that it can
65 | # run in place. This is done instead of making a separate bundle (as on Linux)
66 | # so that building and running from within Visual Studio will work.
67 | set(BUILD_BUNDLE_DIR "$")
68 | # Make the "install" step default, as it's required to run.
69 | set(CMAKE_VS_INCLUDE_INSTALL_TO_DEFAULT_BUILD 1)
70 | if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
71 | set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE)
72 | endif()
73 |
74 | set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data")
75 | set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}")
76 |
77 | install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}"
78 | COMPONENT Runtime)
79 |
80 | install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
81 | COMPONENT Runtime)
82 |
83 | install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
84 | COMPONENT Runtime)
85 |
86 | if(PLUGIN_BUNDLED_LIBRARIES)
87 | install(FILES "${PLUGIN_BUNDLED_LIBRARIES}"
88 | DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
89 | COMPONENT Runtime)
90 | endif()
91 |
92 | # Fully re-copy the assets directory on each build to avoid having stale files
93 | # from a previous install.
94 | set(FLUTTER_ASSET_DIR_NAME "flutter_assets")
95 | install(CODE "
96 | file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\")
97 | " COMPONENT Runtime)
98 | install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}"
99 | DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime)
100 |
101 | # Install the AOT library on non-Debug builds only.
102 | install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
103 | CONFIGURATIONS Profile;Release
104 | COMPONENT Runtime)
105 |
--------------------------------------------------------------------------------
/lib/date_utils.dart:
--------------------------------------------------------------------------------
1 | import 'package:intl/intl.dart';
2 |
3 | /// Name: 日期时间工具类
4 | /// Created by Fitem on 2023/7/17
5 | class DateUtils {
6 | /// 时间计算
7 | static const int oneSecond = 1000;
8 | static const int oneMinute = 60 * oneSecond;
9 | static const int oneHour = 60 * oneMinute;
10 | static const int oneDay = 24 * oneHour;
11 | static const int oneWeek = 7 * oneDay;
12 | static const int oneMonth = 30 * oneDay;
13 | static const int oneYear = 365 * oneDay;
14 |
15 | /// 日期格式化
16 | static const String dateTimeFormat = '$dateFormat $timeFormat';
17 | static const String dateFormat = 'yyyy-MM-dd';
18 | static const String dateFormat2 = 'yyyy/MM/dd';
19 | static const String dateFormat3 = 'MM-dd';
20 | static const String timeFormat = 'HH:mm:ss';
21 | static const String timeFormat2 = 'HH:mm';
22 |
23 | /// 星期名称列表
24 | static const List weekList = ['周一', '周二', '周三', '周四', '周五', '周六', '周日'];
25 |
26 | /// 相差时间名称列表
27 | static const List timeRangeList = ['一分钟内', '一小时内', '一天内', '一周内', '一个月内', '一年内', '一年以上'];
28 |
29 | /// 日期时间格式化
30 | /// [timestamp] 时间戳
31 | /// [format] 格式化字符串 默认为 [dateTimeFormat]
32 | /// 默认返回:2021-07-17 15:30:00
33 | static String formatDateTime(DateTime timestamp, [String format = dateTimeFormat]) {
34 | DateFormat dateFormat = DateFormat(format);
35 | return dateFormat.format(timestamp);
36 | }
37 |
38 | /// 日期格式化
39 | /// [timestamp] 时间戳
40 | /// [format] 格式化字符串 默认为 [dateFormat]
41 | /// 默认返回:2021-07-17
42 | static String formatDate(DateTime timestamp, [String format = dateFormat]) {
43 | DateFormat dateFormat = DateFormat(format);
44 | return dateFormat.format(timestamp);
45 | }
46 |
47 | /// 时间格式化
48 | /// [timestamp] 时间戳
49 | /// [format] 格式化字符串 默认为 [timeFormat]
50 | /// 默认返回:15:30:00
51 | static String formatTime(DateTime timestamp, [String format = timeFormat]) {
52 | DateFormat dateFormat = DateFormat(format);
53 | return dateFormat.format(timestamp);
54 | }
55 |
56 | /// 时分格式化
57 | /// [timestamp] 时间戳
58 | /// [format] 格式化字符串 默认为 [timeFormat2]
59 | /// 默认返回:15:30
60 | static String formatHHmm(DateTime timestamp, [String format = timeFormat2]) {
61 | DateFormat dateFormat = DateFormat(format);
62 | return dateFormat.format(timestamp);
63 | }
64 |
65 | /// 解析日期时间
66 | /// [time] 时间字符串
67 | /// [format] 格式化字符串 默认为 [dateTimeFormat]
68 | /// [utc] 是否使用utc时间 默认为 false
69 | static DateTime parseDateTime(String time, [String format = dateTimeFormat, bool utc = false]) {
70 | DateFormat dateFormat = DateFormat(format);
71 | return dateFormat.parse(time, utc);
72 | }
73 |
74 | /// 获取星期几
75 | /// [time] 时间字符串
76 | /// 从周一开始,周日为6
77 | static int getWeekIndex(DateTime timestamp) {
78 | return timestamp.weekday - 1;
79 | }
80 |
81 | /// 获取星期名称
82 | /// [time] 时间字符串
83 | /// [weekList] 星期名称列表 默认为 [weekList]
84 | static String getWeekName(DateTime timestamp, [List weekList = weekList]) {
85 | return weekList[timestamp.weekday - 1];
86 | }
87 |
88 | /// 计算两个时间的时间差
89 | /// [start] 开始时间
90 | /// [end] 结束时间
91 | /// 返回值:毫秒数
92 | /// 若为负值,则表示 [end] 在 [start] 之前
93 | static int diff(DateTime start, DateTime end) {
94 | return end.millisecondsSinceEpoch - start.millisecondsSinceEpoch;
95 | }
96 |
97 | /// 计算两个时间的差值范围等级
98 | /// [start] 开始时间
99 | /// [end] 结束时间
100 | /// 返回值:0 - 6 对应 1分钟内、1小时内、1天内、1周内、1月内、1年内、1年以上
101 | static int diffRangeLevel(DateTime start, DateTime end) {
102 | // 相差时间,单位毫秒,取绝对值
103 | int duration = diff(start, end).abs();
104 | if (duration <= oneMinute) {
105 | return 0;
106 | } else if (duration <= oneHour) {
107 | return 1;
108 | } else if (duration <= oneDay) {
109 | return 2;
110 | } else if (duration <= oneWeek) {
111 | return 3;
112 | } else if (duration <= oneMonth) {
113 | return 4;
114 | } else if (duration <= oneYear) {
115 | return 5;
116 | } else {
117 | return 6;
118 | }
119 | }
120 |
121 | /// 相差时间范围说明
122 | /// [start] 开始时间
123 | /// [end] 结束时间
124 | /// [timeRangeList] 相差时间名称列表 默认为 [timeRangeList]
125 | static String diffRangeName(DateTime start, DateTime end, [List timeRangeList = timeRangeList]) {
126 | int rangeClass = diffRangeLevel(start, end);
127 | return timeRangeList[rangeClass];
128 | }
129 | }
130 |
131 | /// [int]转化[DateTime]工具类
132 | extension DateTimeUtils on int {
133 | /// 时间戳转日期时间
134 | /// [isUtc] 是否使用utc时间 默认为 false
135 | /// 单位:毫秒
136 | DateTime toDateTime([bool isUtc = false]) => DateTime.fromMillisecondsSinceEpoch(this, isUtc: isUtc);
137 | }
138 |
--------------------------------------------------------------------------------
/example/lib/function/encrypted_page.dart:
--------------------------------------------------------------------------------
1 | import 'package:flutter/material.dart';
2 | import 'package:flutter_util_code/utils.dart';
3 | import 'package:flutter_util_code_example/widget/display_screen.dart';
4 |
5 | /// Name: 加密页面
6 | /// Created by Fitem on 2023/6/12
7 | class EncryptPage extends StatefulWidget {
8 | const EncryptPage({super.key});
9 |
10 | @override
11 | EncryptPageState createState() => EncryptPageState();
12 | }
13 |
14 | class EncryptPageState extends State {
15 | final GlobalKey globalKey = GlobalKey();
16 | final String content = 'hello world!';
17 | final String rc4Key = 'abc123';
18 | final String aesKey = 'xsH/6p7B2xhebSoZ';
19 | final String publicKey = '''
20 | MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDMKXEQ1npgt0l5nJODHdnUMW16
21 | /HWloj3cPLvCbbEcsTTe/gGyZTvMvt2xDewRUnVqaZefn2vGlqhurkRQ7xpmo58l
22 | wb9c70d/RIZ3I+TULJH3mqZbv8nHq/BLlTL9DVqwp3G0ysdzLWHNAzAMwf7BjaNE
23 | Ro/zc4A598XePziqQwIDAQAB
24 | ''';
25 | final String privateKey = '''
26 | MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAMwpcRDWemC3SXmc
27 | k4Md2dQxbXr8daWiPdw8u8JtsRyxNN7+AbJlO8y+3bEN7BFSdWppl5+fa8aWqG6u
28 | RFDvGmajnyXBv1zvR39Ehncj5NQskfeaplu/ycer8EuVMv0NWrCncbTKx3MtYc0D
29 | MAzB/sGNo0RGj/NzgDn3xd4/OKpDAgMBAAECgYEAvWoZd1i1s3N5XLXS+gvA5Chz
30 | fW4qrGBI6kMCpBFnB8q01cptwpg/kebnAXR8N1n8i5ypyrN6p4VxgTZ3NWuQXk16
31 | G4UcZcqRciButOs0E+W4Ot5+PMLuutcsFW/uYtaTRIMWHLV0GuHJjUCbLKKJolFc
32 | thMggXOwy6EucL2NALkCQQD7koP0UiHTFyMHmdHKuAESQFU4fNzypzBlvOBBNX7T
33 | 1caLiCoRjUCDEGf8ABE4CTMeDT1SVBgLkfg0o3SFxI2vAkEAz8FQTFWerhnIGkdE
34 | bm/togRUk/LbYIg3YWMfsaDhMU3ue2h4ojXWvNduEjiLm9oX1MsmsBmZdpCRSW4/
35 | 5AeFrQJBAKQ3c+Ncaa/9fmRLyGJn0mszi22gNCpBcJo4vLpUTUHCXiRe8fcbGW10
36 | nCwnbxYBC1kmk0zWkAudcUQLHtjjAQkCQHMu+4UG504hbybaol8UYUy1V+sa93QC
37 | saml2lmSF6hNS85R8qgEb4UNb7JcdVK4TQQmidGSr9njdxmeLYAQh5UCQDlMuw0H
38 | 25UPw+9QMujcT3UTvABy0lOXRInZgEUU6YAjy0rNVUxLeNoyXlObRTlpoyVz58Er
39 | fp2bts3jaD4PsSU=
40 | ''';
41 |
42 | @override
43 | Widget build(BuildContext context) {
44 | return Scaffold(
45 | appBar: AppBar(
46 | title: const Text('加密页面'),
47 | ),
48 | body: SizedBox(
49 | width: double.infinity,
50 | height: double.infinity,
51 | child: Column(
52 | children: [
53 | ElevatedButton(onPressed: _handleMD5, child: const Text('MD5加密')),
54 | ElevatedButton(onPressed: _handleRC4, child: const Text('RC4加密')),
55 | ElevatedButton(onPressed: _handleAES, child: const Text('AES加密/解密')),
56 | ElevatedButton(onPressed: _handleRSA, child: const Text('RSA加密/解密')),
57 | ElevatedButton(onPressed: _handleSha256withRSA, child: const Text('sha256withRSA签名/验签')),
58 | ElevatedButton(onPressed: _handleMd5withRSA, child: const Text('md5withRSA签名/验签')),
59 | const Spacer(),
60 | Expanded(flex: 2, child: DisplayScreen(key: globalKey)),
61 | ],
62 | ),
63 | ),
64 | );
65 | }
66 |
67 | /// 添加内容
68 | void addContent(String content) {
69 | globalKey.currentState?.addContent(content);
70 | }
71 |
72 | _handleMD5() {
73 | addContent('''MD5加密:
74 | 原文:$content
75 | 加密:${EncryptUtils.md5Encrypt(content)}
76 | ''');
77 | }
78 |
79 | _handleRC4() {
80 | String encrypted = EncryptUtils.rc4Encrypt(content, rc4Key);
81 | addContent('''RC4加密:
82 | 原文:$content
83 | 加密:${EncryptUtils.rc4Encrypt(content, rc4Key)}
84 | 解密:${EncryptUtils.rc4Decrypt(encrypted, rc4Key)}
85 | ''');
86 | }
87 |
88 | _handleAES() {
89 | String encryptedContent = EncryptUtils.aesEncrypt(content, aesKey);
90 | addContent('''AES加密:
91 | 原文:$content
92 | 加密:$encryptedContent
93 | 解密:${EncryptUtils.aesDecrypt(encryptedContent, aesKey)}
94 | ''');
95 | }
96 |
97 | _handleRSA() {
98 | String encryptedContent = EncryptUtils.rsaEncrypt(content, publicKey);
99 | addContent('''RSA加密:
100 | 原文:$content
101 | 加密:$encryptedContent
102 | 解密:${EncryptUtils.rsaDecrypt(encryptedContent, privateKey)}
103 | ''');
104 | }
105 |
106 | void _handleSha256withRSA() {
107 | String encryptedContent = EncryptUtils.sha256withRSASign(content, privateKey);
108 | addContent('''sha256withRSA加密:
109 | 原文:$content
110 | 加密:$encryptedContent
111 | 验签:${EncryptUtils.sha256withRSAVerify(content, encryptedContent, publicKey)}
112 | ''');
113 | }
114 |
115 | Future _handleMd5withRSA() async {
116 | String encryptedContent = await EncryptUtils.md5withRSASign(content, privateKey);
117 | bool isValid = await EncryptUtils.md5withRSAVerify(content, encryptedContent, publicKey);
118 | addContent('''md5withRSA签名:
119 | 原文:$content
120 | 加密:$encryptedContent
121 | 验签:$isValid
122 | ''');
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/example/lib/function/share_page.dart:
--------------------------------------------------------------------------------
1 | import 'dart:io';
2 |
3 | import 'package:flutter/material.dart';
4 | import 'package:flutter/services.dart';
5 | import 'package:flutter_util_code/utils.dart';
6 |
7 | /// Name: 分享页面
8 | /// Created by Fitem on 2023/6/28
9 | class SharePage extends StatefulWidget {
10 | const SharePage({super.key});
11 |
12 | @override
13 | SharePageState createState() => SharePageState();
14 | }
15 |
16 | class SharePageState extends State {
17 | @override
18 | Widget build(BuildContext context) {
19 | return Scaffold(
20 | appBar: AppBar(
21 | title: const Text('分享工具类'),
22 | ),
23 | body: SizedBox(
24 | width: double.infinity,
25 | height: double.infinity,
26 | child: Column(
27 | children: [
28 | _buildButton('分享文本', () => ShareUtils.shareText('分享内容', subject: '分享主题')),
29 | _buildButton(
30 | '分享图片-path',
31 | () async {
32 | // 拷贝图片
33 | final data = await rootBundle.load('assets/flutter_logo.png');
34 | final Uint8List bytes = data.buffer.asUint8List();
35 | final String tempFilePath = await PathUtils.getAppCachePath();
36 | String filePath = '$tempFilePath/flutter_logo.png';
37 | final File imageFile = File(filePath);
38 | await imageFile.writeAsBytes(bytes);
39 | // 获取图片路径
40 | return ShareUtils.shareImage(name: 'flutter_logo.png', path: filePath);
41 | },
42 | ),
43 | _buildButton(
44 | '分享图片-bytes',
45 | () async {
46 | // 获取图片bytes
47 | final data = await rootBundle.load('assets/flutter_logo.png');
48 | final Uint8List bytes = data.buffer.asUint8List();
49 | return ShareUtils.shareImage(name: 'flutter_logo.png', bytes: bytes);
50 | },
51 | ),
52 | _buildButton(
53 | '分享多张图片',
54 | () async {
55 | // 获取多少张图片bytes
56 | final data1 = await rootBundle.load('assets/flutter_logo.png');
57 | final data2 = await rootBundle.load('assets/ic_launcher.png');
58 | final bytes1 = data1.buffer.asUint8List();
59 | final bytes2 = data2.buffer.asUint8List();
60 | ShareFile file1 = ShareFile(name: 'flutter_logo.png', bytes: bytes1);
61 | ShareFile file2 = ShareFile(name: 'ic_launcher.png', bytes: bytes2);
62 | return ShareUtils.shareImages([file1, file2]);
63 | },
64 | ),
65 | _buildButton(
66 | '分享文件-path',
67 | () async {
68 | // 拷贝文件
69 | final String tempFilePath = await PathUtils.getAppCachePath();
70 | String filePath = '$tempFilePath/temp.txt';
71 | final File testFile = File(filePath);
72 | await testFile.writeAsString('Hello, world!');
73 | return ShareUtils.shareFile(name: 'temp.txt', path: filePath);
74 | },
75 | ),
76 | _buildButton(
77 | '分享文件-bytes',
78 | () async {
79 | // 创建文件
80 | final String tempFilePath = await PathUtils.getAppCachePath();
81 | String filePath = '$tempFilePath/temp.txt';
82 | final File testFile = File(filePath);
83 | await testFile.writeAsString('Hello, world!');
84 | // 获取文件bytes
85 | Uint8List bytes = await testFile.readAsBytes();
86 | return ShareUtils.shareFile(name: 'temp.html', bytes: bytes);
87 | },
88 | ),
89 | _buildButton(
90 | '分享多个文件',
91 | () async {
92 | // 创建多个文件
93 | final String tempFilePath = await PathUtils.getAppCachePath();
94 | String filePath1 = '$tempFilePath/temp1.txt';
95 | String filePath2 = '$tempFilePath/temp2.txt';
96 | final File testFile1 = File(filePath1);
97 | final File testFile2 = File(filePath2);
98 | await testFile1.writeAsString('Hello, world!');
99 | await testFile2.writeAsString('Hello, world!');
100 | // 获取文件路径
101 | filePath1 = testFile1.absolute.path;
102 | filePath2 = testFile2.absolute.path;
103 | return ShareUtils.shareFiles([
104 | ShareFile(name: 'temp1.txt', path: filePath1),
105 | ShareFile(name: 'temp2.txt', path: filePath2),
106 | ]);
107 | },
108 | ),
109 | ],
110 | ),
111 | ),
112 | );
113 | }
114 |
115 | /// 通用按钮
116 | Widget _buildButton(String text, Future Function() onPressed) {
117 | return ElevatedButton(
118 | onPressed: () async {
119 | bool result = await onPressed();
120 | ToastUtils.showCenter(result ? '分享成功' : '分享失败');
121 | },
122 | child: Text(text));
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/example/linux/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | # Project-level configuration.
2 | cmake_minimum_required(VERSION 3.10)
3 | project(runner LANGUAGES CXX)
4 |
5 | # The name of the executable created for the application. Change this to change
6 | # the on-disk name of your application.
7 | set(BINARY_NAME "flutter_util_code_example")
8 | # The unique GTK application identifier for this application. See:
9 | # https://wiki.gnome.org/HowDoI/ChooseApplicationID
10 | set(APPLICATION_ID "com.fitem.flutter_util_code")
11 |
12 | # Explicitly opt in to modern CMake behaviors to avoid warnings with recent
13 | # versions of CMake.
14 | cmake_policy(SET CMP0063 NEW)
15 |
16 | # Load bundled libraries from the lib/ directory relative to the binary.
17 | set(CMAKE_INSTALL_RPATH "$ORIGIN/lib")
18 |
19 | # Root filesystem for cross-building.
20 | if(FLUTTER_TARGET_PLATFORM_SYSROOT)
21 | set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT})
22 | set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})
23 | set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
24 | set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
25 | set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
26 | set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
27 | endif()
28 |
29 | # Define build configuration options.
30 | if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
31 | set(CMAKE_BUILD_TYPE "Debug" CACHE
32 | STRING "Flutter build mode" FORCE)
33 | set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
34 | "Debug" "Profile" "Release")
35 | endif()
36 |
37 | # Compilation settings that should be applied to most targets.
38 | #
39 | # Be cautious about adding new options here, as plugins use this function by
40 | # default. In most cases, you should add new options to specific targets instead
41 | # of modifying this function.
42 | function(APPLY_STANDARD_SETTINGS TARGET)
43 | target_compile_features(${TARGET} PUBLIC cxx_std_14)
44 | target_compile_options(${TARGET} PRIVATE -Wall -Werror)
45 | target_compile_options(${TARGET} PRIVATE "$<$>:-O3>")
46 | target_compile_definitions(${TARGET} PRIVATE "$<$>:NDEBUG>")
47 | endfunction()
48 |
49 | # Flutter library and tool build rules.
50 | set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter")
51 | add_subdirectory(${FLUTTER_MANAGED_DIR})
52 |
53 | # System-level dependencies.
54 | find_package(PkgConfig REQUIRED)
55 | pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
56 |
57 | add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}")
58 |
59 | # Define the application target. To change its name, change BINARY_NAME above,
60 | # not the value here, or `flutter run` will no longer work.
61 | #
62 | # Any new source files that you add to the application should be added here.
63 | add_executable(${BINARY_NAME}
64 | "main.cc"
65 | "my_application.cc"
66 | "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
67 | )
68 |
69 | # Apply the standard set of build settings. This can be removed for applications
70 | # that need different build settings.
71 | apply_standard_settings(${BINARY_NAME})
72 |
73 | # Add dependency libraries. Add any application-specific dependencies here.
74 | target_link_libraries(${BINARY_NAME} PRIVATE flutter)
75 | target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK)
76 |
77 | # Run the Flutter tool portions of the build. This must not be removed.
78 | add_dependencies(${BINARY_NAME} flutter_assemble)
79 |
80 | # Only the install-generated bundle's copy of the executable will launch
81 | # correctly, since the resources must in the right relative locations. To avoid
82 | # people trying to run the unbundled copy, put it in a subdirectory instead of
83 | # the default top-level location.
84 | set_target_properties(${BINARY_NAME}
85 | PROPERTIES
86 | RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run"
87 | )
88 |
89 | # Enable the test target.
90 | set(include_flutter_util_code_tests TRUE)
91 |
92 | # Generated plugin build rules, which manage building the plugins and adding
93 | # them to the application.
94 | include(flutter/generated_plugins.cmake)
95 |
96 |
97 | # === Installation ===
98 | # By default, "installing" just makes a relocatable bundle in the build
99 | # directory.
100 | set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle")
101 | if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
102 | set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE)
103 | endif()
104 |
105 | # Start with a clean build bundle directory every time.
106 | install(CODE "
107 | file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\")
108 | " COMPONENT Runtime)
109 |
110 | set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data")
111 | set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib")
112 |
113 | install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}"
114 | COMPONENT Runtime)
115 |
116 | install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
117 | COMPONENT Runtime)
118 |
119 | install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
120 | COMPONENT Runtime)
121 |
122 | foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES})
123 | install(FILES "${bundled_library}"
124 | DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
125 | COMPONENT Runtime)
126 | endforeach(bundled_library)
127 |
128 | # Fully re-copy the assets directory on each build to avoid having stale files
129 | # from a previous install.
130 | set(FLUTTER_ASSET_DIR_NAME "flutter_assets")
131 | install(CODE "
132 | file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\")
133 | " COMPONENT Runtime)
134 | install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}"
135 | DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime)
136 |
137 | # Install the AOT library on non-Debug builds only.
138 | if(NOT CMAKE_BUILD_TYPE MATCHES "Debug")
139 | install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
140 | COMPONENT Runtime)
141 | endif()
142 |
--------------------------------------------------------------------------------