├── bin └── .gitkeep ├── etc └── .gitkeep ├── tool └── .gitkeep ├── VERSION ├── lib ├── src │ ├── .gitkeep │ ├── os │ │ ├── exceptions.dart │ │ ├── vibrator.dart │ │ ├── vibration_effect.dart │ │ ├── build.dart │ │ ├── parcelable.dart │ │ ├── system_clock.dart │ │ ├── hardware_properties_manager.dart │ │ ├── stat_fs.dart │ │ ├── bundle.dart │ │ ├── power_manager.dart │ │ └── process.dart │ ├── app │ │ ├── alarm_manager.dart │ │ ├── search_manager.dart │ │ ├── keyguard_manager.dart │ │ ├── activity.dart │ │ ├── wallpaper_info.dart │ │ ├── notification_manager.dart │ │ ├── wallpaper_manager.dart │ │ ├── notification_builder.dart │ │ ├── activity_manager.dart │ │ ├── pending_intent.dart │ │ ├── exceptions.dart │ │ ├── download_manager.dart │ │ ├── wallpaper_colors.dart │ │ └── notification_action.dart │ ├── hardware │ │ ├── sensor_event_listener.dart │ │ └── sensor_event.dart │ ├── content │ │ ├── exceptions.dart │ │ ├── intent_filter.dart │ │ ├── content_values.dart │ │ ├── component_name.dart │ │ ├── intent.dart │ │ └── shared_preferences.dart │ ├── bluetooth │ │ ├── bluetooth_manager.dart │ │ └── bluetooth_le_scanner.dart │ ├── database │ │ ├── exceptions.dart │ │ ├── matrix_cursor.dart │ │ └── database_utils.dart │ ├── graphics │ │ ├── point.dart │ │ ├── pointf.dart │ │ └── bitmap.dart │ └── media │ │ ├── face_detector.dart │ │ └── face.dart ├── android_net.dart ├── android_speech.dart ├── android_security.dart ├── android_provider.dart ├── android_nfc.dart ├── android_view.dart ├── android_telephony.dart ├── android_location.dart ├── android_media.dart ├── android_graphics.dart ├── android_hardware.dart ├── android_database.dart ├── android_content.dart ├── android_bluetooth.dart ├── android.dart ├── android_os.dart └── android_app.dart ├── doc └── .gitignore ├── ios ├── Assets │ └── .gitkeep ├── Classes │ ├── FlutterAndroidPlugin.h │ ├── SwiftFlutterAndroidPlugin.swift │ └── FlutterAndroidPlugin.m ├── .gitignore └── flutter_android.podspec ├── TODO.md ├── CREDITS.md ├── AUTHORS ├── .test_config ├── android ├── settings.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── .gitignore ├── gradle.properties ├── src │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── com │ │ └── github │ │ └── drydart │ │ └── flutter_android │ │ ├── BluetoothDeviceHandler.java │ │ ├── BluetoothAdapterHandler.java │ │ ├── BluetoothHeadsetHandler.java │ │ ├── BluetoothManagerHandler.java │ │ ├── BluetoothLeScannerHandler.java │ │ ├── AndroidHandler.java │ │ ├── ActivityManagerHandler.java │ │ ├── SharedPreferencesHandler.java │ │ ├── LocationHandler.java │ │ ├── EnvironmentHandler.java │ │ ├── SensorEventStream.java │ │ ├── ContextHandler.java │ │ ├── FlutterMethodCallHandler.java │ │ ├── FlutterAndroidPlugin.java │ │ ├── FaceDetectorHandler.java │ │ ├── IntentHandler.java │ │ └── SensorManagerHandler.java ├── build.gradle └── gradlew.bat ├── example ├── 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 │ ├── Podfile.lock │ ├── .gitignore │ └── Podfile ├── flutter_01.png ├── flutter_02.png ├── images │ └── einstein.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 │ │ │ │ │ └── values │ │ │ │ │ │ └── styles.xml │ │ │ │ ├── java │ │ │ │ │ └── com │ │ │ │ │ │ └── github │ │ │ │ │ │ └── drydart │ │ │ │ │ │ └── flutter_android │ │ │ │ │ │ └── example │ │ │ │ │ │ └── MainActivity.java │ │ │ │ └── AndroidManifest.xml │ │ │ ├── debug │ │ │ │ └── AndroidManifest.xml │ │ │ └── profile │ │ │ │ └── AndroidManifest.xml │ │ └── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ ├── .gitignore │ ├── settings.gradle │ └── build.gradle ├── .metadata ├── README.md ├── .gitignore ├── lib │ ├── demos │ │ ├── bluetooth_scanner.dart │ │ ├── heartrate_monitor.dart │ │ └── face_detector.dart │ ├── main.dart │ ├── library_tab.dart │ ├── class_tab.dart │ ├── main_screen.dart │ ├── demo_tab.dart │ └── method_tab.dart ├── test │ └── widget_test.dart └── pubspec.yaml ├── Makefile ├── analysis_options.yaml ├── test ├── android_test.dart ├── android_app_test.dart ├── android_net_test.dart ├── android_nfc_test.dart ├── android_media_test.dart ├── android_view_test.dart ├── android_speech_test.dart ├── android_graphics_test.dart ├── android_hardware_test.dart ├── android_location_test.dart ├── android_provider_test.dart ├── android_security_test.dart ├── android_bluetooth_test.dart ├── android_telephony_test.dart ├── android_os_test.dart ├── android_database_test.dart └── android_content_test.dart ├── .metadata ├── .github ├── linters │ ├── analysis_options.yaml │ └── .markdown-lint.yml ├── dependabot.yml └── workflows │ ├── gitstamp.yaml │ └── linter.yaml ├── .gitignore ├── pubspec.yaml └── UNLICENSE /bin/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /etc/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tool/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /VERSION: -------------------------------------------------------------------------------- 1 | 0.8.0 2 | -------------------------------------------------------------------------------- /lib/src/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /doc/.gitignore: -------------------------------------------------------------------------------- 1 | api 2 | -------------------------------------------------------------------------------- /ios/Assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | To-Dos 2 | ====== 3 | -------------------------------------------------------------------------------- /CREDITS.md: -------------------------------------------------------------------------------- 1 | Credits 2 | ======= 3 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | * Arto Bendiken 2 | -------------------------------------------------------------------------------- /.test_config: -------------------------------------------------------------------------------- 1 | { 2 | "test_package": true 3 | } 4 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'flutter_android' 2 | -------------------------------------------------------------------------------- /example/ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /example/flutter_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drydart/flutter_android/HEAD/example/flutter_01.png -------------------------------------------------------------------------------- /example/flutter_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drydart/flutter_android/HEAD/example/flutter_02.png -------------------------------------------------------------------------------- /example/images/einstein.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drydart/flutter_android/HEAD/example/images/einstein.png -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drydart/flutter_android/HEAD/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /ios/Classes/FlutterAndroidPlugin.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface FlutterAndroidPlugin : NSObject 4 | @end 5 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | -------------------------------------------------------------------------------- /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.enableR8=true 3 | android.useAndroidX=true 4 | android.enableJetifier=true 5 | -------------------------------------------------------------------------------- /example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.enableR8=true 3 | android.useAndroidX=true 4 | android.enableJetifier=true 5 | -------------------------------------------------------------------------------- /example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | FLUTTER ?= flutter 2 | PANDOC ?= pandoc 3 | PUB ?= pub 4 | 5 | check: 6 | $(FLUTTER) test 7 | 8 | .PHONY: check 9 | .SECONDARY: 10 | .SUFFIXES: 11 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drydart/flutter_android/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/drydart/flutter_android/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/drydart/flutter_android/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/drydart/flutter_android/HEAD/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /lib/src/os/exceptions.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | //import 'package:flutter/services.dart' show PlatformException; 4 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drydart/flutter_android/HEAD/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drydart/flutter_android/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drydart/flutter_android/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/drydart/flutter_android/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drydart/flutter_android/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/drydart/flutter_android/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/drydart/flutter_android/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/drydart/flutter_android/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/drydart/flutter_android/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/drydart/flutter_android/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/drydart/flutter_android/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/drydart/flutter_android/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/drydart/flutter_android/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/drydart/flutter_android/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/drydart/flutter_android/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/drydart/flutter_android/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/drydart/flutter_android/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/drydart/flutter_android/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/drydart/flutter_android/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /lib/android_net.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | /// Classes that help with network access. 4 | /// 5 | /// See: https://developer.android.com/reference/android/net/package-summary 6 | library android_net; 7 | -------------------------------------------------------------------------------- /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-5.6.2-all.zip 6 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # See: https://dart.dev/guides/language/analysis-options 2 | --- 3 | include: package:pedantic/analysis_options.1.9.0.yaml 4 | analyzer: 5 | exclude: 6 | - example/**.dart 7 | linter: 8 | rules: 9 | prefer_single_quotes: false 10 | -------------------------------------------------------------------------------- /lib/src/app/alarm_manager.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | /// Provides access to the system alarm services. 4 | /// 5 | /// See: https://developer.android.com/reference/android/app/AlarmManager 6 | class AlarmManager {} 7 | -------------------------------------------------------------------------------- /lib/src/app/search_manager.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | /// Provides access to the system search services. 4 | /// 5 | /// See: https://developer.android.com/reference/android/app/SearchManager 6 | class SearchManager {} 7 | -------------------------------------------------------------------------------- /lib/android_speech.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | /// Provides access to the speech recognition service. 4 | /// 5 | /// See: https://developer.android.com/reference/android/speech/package-summary 6 | library android_speech; 7 | -------------------------------------------------------------------------------- /lib/src/app/keyguard_manager.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | /// Can be used to lock and unlock the keyboard. 4 | /// 5 | /// See: https://developer.android.com/reference/android/app/KeyguardManager 6 | class KeyguardManager {} 7 | -------------------------------------------------------------------------------- /lib/src/app/activity.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | /// An activity is a single, focused thing that the user can do. 4 | /// 5 | /// See: https://developer.android.com/reference/android/app/Activity 6 | abstract class Activity {} 7 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip 7 | -------------------------------------------------------------------------------- /lib/android_security.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | /// Provides access to a few facilities of the Android security subsystems. 4 | /// 5 | /// See: https://developer.android.com/reference/android/security/package-summary 6 | library android_security; 7 | -------------------------------------------------------------------------------- /test/android_test.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'package:flutter_test/flutter_test.dart'; 4 | 5 | //import 'package:flutter_android/android.dart'; 6 | 7 | void main() { 8 | group('android', () { 9 | // TODO 10 | }); 11 | } 12 | -------------------------------------------------------------------------------- /test/android_app_test.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'package:flutter_test/flutter_test.dart'; 4 | 5 | //import 'package:flutter_android/android_app.dart'; 6 | 7 | void main() { 8 | group('android_app', () { 9 | // TODO 10 | }); 11 | } 12 | -------------------------------------------------------------------------------- /test/android_net_test.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'package:flutter_test/flutter_test.dart'; 4 | 5 | //import 'package:flutter_android/android_net.dart'; 6 | 7 | void main() { 8 | group('android_net', () { 9 | // TODO 10 | }); 11 | } 12 | -------------------------------------------------------------------------------- /test/android_nfc_test.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'package:flutter_test/flutter_test.dart'; 4 | 5 | //import 'package:flutter_android/android_nfc.dart'; 6 | 7 | void main() { 8 | group('android_nfc', () { 9 | // TODO 10 | }); 11 | } 12 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /test/android_media_test.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'package:flutter_test/flutter_test.dart'; 4 | 5 | //import 'package:flutter_android/android_media.dart'; 6 | 7 | void main() { 8 | group('android_media', () { 9 | // TODO 10 | }); 11 | } 12 | -------------------------------------------------------------------------------- /test/android_view_test.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'package:flutter_test/flutter_test.dart'; 4 | 5 | //import 'package:flutter_android/android_view.dart'; 6 | 7 | void main() { 8 | group('android_view', () { 9 | // TODO 10 | }); 11 | } 12 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /lib/android_provider.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | /// Provides convenience classes to access the content providers supplied by 4 | /// Android. 5 | /// 6 | /// See: https://developer.android.com/reference/android/provider/package-summary 7 | library android_provider; 8 | -------------------------------------------------------------------------------- /lib/src/os/vibrator.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | /// Operates the vibrator on the device. 4 | /// 5 | /// If your process exits, any vibration you started will stop. 6 | /// 7 | /// See: https://developer.android.com/reference/android/os/Vibrator 8 | class Vibrator {} 9 | -------------------------------------------------------------------------------- /test/android_speech_test.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'package:flutter_test/flutter_test.dart'; 4 | 5 | //import 'package:flutter_android/android_speech.dart'; 6 | 7 | void main() { 8 | group('android_speech', () { 9 | // TODO 10 | }); 11 | } 12 | -------------------------------------------------------------------------------- /test/android_graphics_test.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'package:flutter_test/flutter_test.dart'; 4 | 5 | //import 'package:flutter_android/android_graphics.dart'; 6 | 7 | void main() { 8 | group('android_graphics', () { 9 | // TODO 10 | }); 11 | } 12 | -------------------------------------------------------------------------------- /test/android_hardware_test.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'package:flutter_test/flutter_test.dart'; 4 | 5 | //import 'package:flutter_android/android_hardware.dart'; 6 | 7 | void main() { 8 | group('android_hardware', () { 9 | // TODO 10 | }); 11 | } 12 | -------------------------------------------------------------------------------- /test/android_location_test.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'package:flutter_test/flutter_test.dart'; 4 | 5 | //import 'package:flutter_android/android_location.dart'; 6 | 7 | void main() { 8 | group('android_location', () { 9 | // TODO 10 | }); 11 | } 12 | -------------------------------------------------------------------------------- /test/android_provider_test.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'package:flutter_test/flutter_test.dart'; 4 | 5 | //import 'package:flutter_android/android_provider.dart'; 6 | 7 | void main() { 8 | group('android_provider', () { 9 | // TODO 10 | }); 11 | } 12 | -------------------------------------------------------------------------------- /test/android_security_test.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'package:flutter_test/flutter_test.dart'; 4 | 5 | //import 'package:flutter_android/android_security.dart'; 6 | 7 | void main() { 8 | group('android_security', () { 9 | // TODO 10 | }); 11 | } 12 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /test/android_bluetooth_test.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'package:flutter_test/flutter_test.dart'; 4 | 5 | //import 'package:flutter_android/android_bluetooth.dart'; 6 | 7 | void main() { 8 | group('android_bluetooth', () { 9 | // TODO 10 | }); 11 | } 12 | -------------------------------------------------------------------------------- /test/android_telephony_test.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'package:flutter_test/flutter_test.dart'; 4 | 5 | //import 'package:flutter_android/android_telephony.dart'; 6 | 7 | void main() { 8 | group('android_telephony', () { 9 | // TODO 10 | }); 11 | } 12 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /lib/android_nfc.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | /// Provides access to Near Field Communication (NFC) functionality, allowing 4 | /// applications to read NDEF message in NFC tags. 5 | /// 6 | /// See: https://developer.android.com/reference/android/nfc/package-summary 7 | library android_nfc; 8 | -------------------------------------------------------------------------------- /lib/android_view.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | /// Provides classes that expose basic user interface classes that handle screen 4 | /// layout and interaction with the user. 5 | /// 6 | /// See: https://developer.android.com/reference/android/view/package-summary 7 | library android_view; 8 | -------------------------------------------------------------------------------- /.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 and should not be manually edited. 5 | 6 | version: 7 | revision: e606910f28be51c8151f6169072afe3b3a8b3c5e 8 | channel: beta 9 | 10 | project_type: plugin 11 | -------------------------------------------------------------------------------- /example/android/app/src/main/java/com/github/drydart/flutter_android/example/MainActivity.java: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | package com.github.drydart.flutter_android.example; 4 | 5 | import io.flutter.embedding.android.FlutterActivity; 6 | 7 | public class MainActivity extends FlutterActivity { 8 | } 9 | -------------------------------------------------------------------------------- /example/.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 and should not be manually edited. 5 | 6 | version: 7 | revision: e606910f28be51c8151f6169072afe3b3a8b3c5e 8 | channel: beta 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /lib/src/hardware/sensor_event_listener.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | /// Used for receiving notifications from the [SensorManager] when there is new 4 | /// sensor data. 5 | /// 6 | /// See: https://developer.android.com/reference/android/hardware/SensorEventListener 7 | abstract class SensorEventListener {} 8 | -------------------------------------------------------------------------------- /.github/linters/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | # See: https://dart.dev/guides/language/analysis-options 2 | # See: https://github.com/github/super-linter/blob/master/TEMPLATES/analysis_options.yaml 3 | --- 4 | include: package:pedantic/analysis_options.1.9.0.yaml 5 | analyzer: 6 | exclude: 7 | - example/**.dart 8 | linter: 9 | rules: 10 | prefer_single_quotes: false 11 | -------------------------------------------------------------------------------- /lib/src/app/wallpaper_info.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import '../os/parcelable.dart' show Parcelable; 4 | 5 | /// Used to specify meta information of a wallpaper service. 6 | /// 7 | /// See: https://developer.android.com/reference/android/app/WallpaperInfo 8 | abstract class WallpaperInfo implements Parcelable {} 9 | -------------------------------------------------------------------------------- /lib/src/app/notification_manager.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | /// Notifies the user of events that happen. 4 | /// 5 | /// This is how you tell the user that something has happened in the background. 6 | /// 7 | /// See: https://developer.android.com/reference/android/app/NotificationManager 8 | class NotificationManager {} 9 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # flutter_android_example 2 | 3 | Demonstrates how to use the flutter_android plugin. 4 | 5 | ## Screenshot 6 | 7 | Screenshot 1 8 | 9 | Screenshot 2 10 | -------------------------------------------------------------------------------- /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. 6 | -------------------------------------------------------------------------------- /lib/android_telephony.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | /// Provides APIs for monitoring the basic phone information, such as the 4 | /// network type and connection state, plus utilities for manipulating phone 5 | /// number strings. 6 | /// 7 | /// See: https://developer.android.com/reference/android/telephony/package-summary 8 | library android_telephony; 9 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /lib/src/app/wallpaper_manager.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | /// Provides access to the system wallpaper. 4 | /// 5 | /// With this class, you can get the current wallpaper, get the desired 6 | /// dimensions for the wallpaper, set the wallpaper, and more. 7 | /// 8 | /// See: https://developer.android.com/reference/android/app/WallpaperManager 9 | class WallpaperManager {} 10 | -------------------------------------------------------------------------------- /lib/android_location.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | /// Contains the framework API classes that define Android location-based and 4 | /// related services. 5 | /// 6 | /// See: https://developer.android.com/reference/android/location/package-summary 7 | /// 8 | /// {@canonicalFor location.Location} 9 | library android_location; 10 | 11 | export 'src/location/location.dart' show Location; 12 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # See: https://docs.github.com/en/github/administering-a-repository/customizing-dependency-updates 2 | # See: https://docs.github.com/en/github/administering-a-repository/configuration-options-for-dependency-updates 3 | --- 4 | version: 2 5 | updates: 6 | - package-ecosystem: github-actions 7 | directory: / 8 | schedule: 9 | interval: daily 10 | reviewers: 11 | - artob 12 | assignees: 13 | - artob 14 | -------------------------------------------------------------------------------- /lib/src/app/notification_builder.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | /// Builder class for [Notification] objects. 4 | /// 5 | /// Provides a convenient way to set the various fields of a [Notification] and 6 | /// generate content views using the platform's notification layout template. 7 | /// 8 | /// See: https://developer.android.com/reference/android/app/Notification.Builder 9 | abstract class NotificationBuilder {} 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # macOS 2 | .DS_Store 3 | 4 | # Editor backup files 5 | *~ 6 | 7 | # Pandoc outputs 8 | *.html 9 | 10 | # Dart artifacts 11 | .dart_tool/ 12 | .packages 13 | .pub/ 14 | build/ 15 | pubspec.lock 16 | 17 | # VS Code artifacts 18 | .vscode/ 19 | android/.classpath 20 | android/.project 21 | android/.settings/ 22 | example/android/.project 23 | example/android/.settings/ 24 | example/android/app/.classpath 25 | example/android/app/.project 26 | example/android/app/.settings/ 27 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /lib/android_media.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | /// Provides classes that manage various media interfaces in audio and video. 4 | /// 5 | /// See: https://developer.android.com/reference/android/media/package-summary 6 | /// 7 | /// {@canonicalFor face.Face} 8 | /// {@canonicalFor face_detector.FaceDetector} 9 | library android_media; 10 | 11 | export 'src/media/face.dart' show Face; 12 | export 'src/media/face_detector.dart' show FaceDetector; 13 | -------------------------------------------------------------------------------- /lib/src/content/exceptions.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'package:flutter/services.dart' show PlatformException; 4 | 5 | /// Thrown when a call to `Context.startActivity(Intent)` or one of its variants 6 | /// fails because an `Activity` can not be found to execute the given [Intent]. 7 | /// 8 | /// See: https://developer.android.com/reference/android/content/ActivityNotFoundException 9 | class ActivityNotFoundException extends PlatformException {} 10 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /.github/workflows/gitstamp.yaml: -------------------------------------------------------------------------------- 1 | # See: https://github.com/artob/gitstamp-action 2 | --- 3 | name: Gitstamp 4 | on: 5 | push: 6 | branches: 7 | - master 8 | jobs: 9 | gitstamp: 10 | runs-on: ubuntu-latest 11 | name: Timestamp commit with Gitstamp 12 | steps: 13 | - name: Clone repository 14 | uses: actions/checkout@v2 15 | - name: Submit Gitstamp transaction 16 | uses: artob/gitstamp-action@v1 17 | with: 18 | wallet-key: ${{ secrets.GITSTAMP_KEYFILE }} 19 | commit-link: true 20 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .vagrant/ 3 | .sconsign.dblite 4 | .svn/ 5 | 6 | .DS_Store 7 | *.swp 8 | profile 9 | 10 | DerivedData/ 11 | build/ 12 | GeneratedPluginRegistrant.h 13 | GeneratedPluginRegistrant.m 14 | 15 | .generated/ 16 | 17 | *.pbxuser 18 | *.mode1v3 19 | *.mode2v3 20 | *.perspectivev3 21 | 22 | !default.pbxuser 23 | !default.mode1v3 24 | !default.mode2v3 25 | !default.perspectivev3 26 | 27 | xcuserdata 28 | 29 | *.moved-aside 30 | 31 | *.pyc 32 | *sync/ 33 | Icon? 34 | .tags* 35 | 36 | /Flutter/Generated.xcconfig 37 | /Flutter/flutter_export_environment.sh -------------------------------------------------------------------------------- /test/android_os_test.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'package:flutter_test/flutter_test.dart'; 4 | 5 | import 'package:flutter_android/android_os.dart'; 6 | 7 | void main() { 8 | group('android_os', () { 9 | group('Parcel', () { 10 | test(".obtain()", () { 11 | expect(Parcel.obtain(), isNot(equals(null))); 12 | }); 13 | test("#writeValue()", () { 14 | // TODO 15 | }); 16 | }); 17 | group('Parcelable', () { 18 | // TODO 19 | }); 20 | }); 21 | } 22 | -------------------------------------------------------------------------------- /example/ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Flutter (1.0.0) 3 | - url_launcher (0.0.1): 4 | - Flutter 5 | 6 | DEPENDENCIES: 7 | - Flutter (from `Flutter`) 8 | - url_launcher (from `.symlinks/plugins/url_launcher/ios`) 9 | 10 | EXTERNAL SOURCES: 11 | Flutter: 12 | :path: Flutter 13 | url_launcher: 14 | :path: ".symlinks/plugins/url_launcher/ios" 15 | 16 | SPEC CHECKSUMS: 17 | Flutter: 0e3d915762c693b495b44d77113d4970485de6ec 18 | url_launcher: 6fef411d543ceb26efce54b05a0a40bfd74cbbef 19 | 20 | PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c 21 | 22 | COCOAPODS: 1.9.1 23 | -------------------------------------------------------------------------------- /ios/Classes/SwiftFlutterAndroidPlugin.swift: -------------------------------------------------------------------------------- 1 | import Flutter 2 | import UIKit 3 | 4 | public class SwiftFlutterAndroidPlugin: NSObject, FlutterPlugin { 5 | public static func register(with registrar: FlutterPluginRegistrar) { 6 | let channel = FlutterMethodChannel(name: "flutter_android", binaryMessenger: registrar.messenger()) 7 | let instance = SwiftFlutterAndroidPlugin() 8 | registrar.addMethodCallDelegate(instance, channel: channel) 9 | } 10 | 11 | public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { 12 | result("iOS " + UIDevice.current.systemVersion) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | google() 4 | jcenter() 5 | } 6 | 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:3.5.0' 9 | } 10 | } 11 | 12 | allprojects { 13 | repositories { 14 | google() 15 | jcenter() 16 | } 17 | } 18 | 19 | rootProject.buildDir = '../build' 20 | subprojects { 21 | project.buildDir = "${rootProject.buildDir}/${project.name}" 22 | } 23 | subprojects { 24 | project.evaluationDependsOn(':app') 25 | } 26 | 27 | task clean(type: Delete) { 28 | delete rootProject.buildDir 29 | } 30 | -------------------------------------------------------------------------------- /lib/src/content/intent_filter.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import '../os/parcelable.dart' show Parcelable; 4 | 5 | /// Structured description of [Intent] values to be matched. 6 | /// 7 | /// An [IntentFilter] can match against actions, categories, and data (either 8 | /// via its type, scheme, and/or path) in an Intent. It also includes a 9 | /// "priority" value which is used to order multiple matching filters. 10 | /// 11 | /// See: https://developer.android.com/reference/android/content/IntentFilter 12 | abstract class IntentFilter implements Parcelable {} 13 | -------------------------------------------------------------------------------- /lib/src/bluetooth/bluetooth_manager.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | //import 'package:flutter/services.dart' show MethodChannel; 4 | 5 | //import 'bluetooth_adapter.dart' show BluetoothAdapter; 6 | 7 | /// High level manager used to obtain an instance of a [BluetoothAdapter] and to 8 | /// conduct overall Bluetooth management. 9 | /// 10 | /// See: https://developer.android.com/reference/android/bluetooth/BluetoothManager 11 | abstract class BluetoothManager { 12 | //static const MethodChannel _channel = 13 | // MethodChannel('flutter_android/BluetoothManager'); 14 | } 15 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | group 'com.github.drydart.flutter_android' 2 | version '1.0' 3 | 4 | buildscript { 5 | repositories { 6 | google() 7 | jcenter() 8 | } 9 | 10 | dependencies { 11 | classpath 'com.android.tools.build:gradle:3.5.0' 12 | } 13 | } 14 | 15 | rootProject.allprojects { 16 | repositories { 17 | google() 18 | jcenter() 19 | } 20 | } 21 | 22 | apply plugin: 'com.android.library' 23 | 24 | android { 25 | compileSdkVersion 28 26 | 27 | defaultConfig { 28 | minSdkVersion 16 29 | } 30 | lintOptions { 31 | disable 'InvalidPackage' 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /lib/android_graphics.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | /// Provides low level graphics tools such as canvases, color filters, points, 4 | /// and rectangles that let you handle drawing to the screen directly. 5 | /// 6 | /// See: https://developer.android.com/reference/android/graphics/package-summary 7 | /// 8 | /// {@canonicalFor bitmap.Bitmap} 9 | /// {@canonicalFor point.Point} 10 | /// {@canonicalFor pointf.PointF} 11 | library android_graphics; 12 | 13 | export 'src/graphics/bitmap.dart' show Bitmap; 14 | export 'src/graphics/point.dart' show Point; 15 | export 'src/graphics/pointf.dart' show PointF; 16 | -------------------------------------------------------------------------------- /ios/Classes/FlutterAndroidPlugin.m: -------------------------------------------------------------------------------- 1 | #import "FlutterAndroidPlugin.h" 2 | #if __has_include() 3 | #import 4 | #else 5 | // Support project import fallback if the generated compatibility header 6 | // is not copied when this plugin is created as a library. 7 | // https://forums.swift.org/t/swift-static-libraries-dont-copy-generated-objective-c-header/19816 8 | #import "flutter_android-Swift.h" 9 | #endif 10 | 11 | @implementation FlutterAndroidPlugin 12 | + (void)registerWithRegistrar:(NSObject*)registrar { 13 | [SwiftFlutterAndroidPlugin registerWithRegistrar:registrar]; 14 | } 15 | @end 16 | -------------------------------------------------------------------------------- /example/ios/.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.mode2v3 3 | *.moved-aside 4 | *.pbxuser 5 | *.perspectivev3 6 | **/*sync/ 7 | .sconsign.dblite 8 | .tags* 9 | **/.vagrant/ 10 | **/DerivedData/ 11 | Icon? 12 | **/Pods/ 13 | **/.symlinks/ 14 | profile 15 | xcuserdata 16 | **/.generated/ 17 | Flutter/App.framework 18 | Flutter/Flutter.framework 19 | Flutter/Flutter.podspec 20 | Flutter/Generated.xcconfig 21 | Flutter/app.flx 22 | Flutter/app.zip 23 | Flutter/flutter_assets/ 24 | Flutter/flutter_export_environment.sh 25 | ServiceDefinitions.json 26 | Runner/GeneratedPluginRegistrant.* 27 | 28 | # Exceptions to above rules. 29 | !default.mode1v3 30 | !default.mode2v3 31 | !default.pbxuser 32 | !default.perspectivev3 33 | -------------------------------------------------------------------------------- /.github/linters/.markdown-lint.yml: -------------------------------------------------------------------------------- 1 | # See: https://github.com/github/super-linter/blob/master/docs/disabling-linters.md#markdown 2 | # See: https://github.com/github/super-linter/blob/master/TEMPLATES/.markdown-lint.yml 3 | --- 4 | MD013: false # line-length 5 | MD014: false # commands-show-output 6 | MD022: # blanks-around-headings 7 | lines_above: 1 8 | lines_below: 0 9 | MD024: # no-duplicate-heading 10 | siblings_only: true 11 | MD026: # no-trailing-punctuation 12 | punctuation: ".,;:!。,;:" 13 | MD033: false # no-inline-html 14 | MD044: # proper-names 15 | names: 16 | - JavaScript 17 | code_blocks: false 18 | MD046: # code-block-style 19 | style: consistent 20 | MD048: # code-fence-style 21 | style: backtick 22 | -------------------------------------------------------------------------------- /lib/src/database/exceptions.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'package:flutter/services.dart' show PlatformException; 4 | 5 | /// An exception indicating that a cursor is out of bounds. 6 | /// 7 | /// See: https://developer.android.com/reference/android/database/CursorIndexOutOfBoundsException 8 | class CursorIndexOutOfBoundsException extends PlatformException { 9 | final int index; 10 | 11 | final int size; 12 | 13 | CursorIndexOutOfBoundsException(this.index, this.size); 14 | } 15 | 16 | /// An exception that indicates there was an error with SQL parsing or 17 | /// execution. 18 | /// 19 | /// See: https://developer.android.com/reference/android/database/SQLException 20 | class SQLException extends PlatformException {} 21 | -------------------------------------------------------------------------------- /lib/android_hardware.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | /// Provides support for hardware features, such as the camera and other 4 | /// sensors. 5 | /// 6 | /// See: https://developer.android.com/reference/android/hardware/package-summary 7 | /// 8 | /// {@canonicalFor sensor.Sensor} 9 | /// {@canonicalFor sensor_event.SensorEvent} 10 | /// {@canonicalFor sensor_event_listener.SensorEventListener} 11 | /// {@canonicalFor sensor_manager.SensorManager} 12 | library android_hardware; 13 | 14 | export 'src/hardware/sensor.dart' show Sensor; 15 | export 'src/hardware/sensor_event.dart' show SensorEvent; 16 | export 'src/hardware/sensor_event_listener.dart' show SensorEventListener; 17 | export 'src/hardware/sensor_manager.dart' show SensorManager; 18 | -------------------------------------------------------------------------------- /lib/android_database.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | /// Contains classes to explore data returned through a content provider. 4 | /// 5 | /// See: https://developer.android.com/reference/android/database/package-summary 6 | /// 7 | /// {@canonicalFor cursor.Cursor} 8 | /// {@canonicalFor database_utils.DatabaseUtils} 9 | /// {@canonicalFor exceptions.CursorIndexOutOfBoundsException} 10 | /// {@canonicalFor exceptions.SQLException} 11 | /// {@canonicalFor matrix_cursor.MatrixCursor} 12 | library android_database; 13 | 14 | export 'src/database/cursor.dart' show Cursor; 15 | export 'src/database/database_utils.dart' show DatabaseUtils; 16 | export 'src/database/exceptions.dart' 17 | show CursorIndexOutOfBoundsException, SQLException; 18 | export 'src/database/matrix_cursor.dart' show MatrixCursor; 19 | -------------------------------------------------------------------------------- /lib/src/graphics/point.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'dart:math' as math; 4 | 5 | import '../os/parcel.dart' show Parcel; 6 | import '../os/parcelable.dart' show Parcelable; 7 | 8 | /// [Point] holds two integer coordinates. 9 | /// 10 | /// See: https://developer.android.com/reference/android/graphics/Point 11 | /// See: https://github.com/aosp-mirror/platform_frameworks_base/blob/master/graphics/java/android/graphics/Point.java 12 | class Point extends math.Point with Parcelable { 13 | Point([final int x = 0, final int y = 0]) : super(x, y); 14 | 15 | @override 16 | String get parcelableCreator => "android.graphics.Point"; 17 | 18 | @override 19 | void writeToParcel(final Parcel parcel, [final int flags = 0]) { 20 | parcel.writeInt(x); 21 | parcel.writeInt(y); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/src/graphics/pointf.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'dart:math' as math; 4 | 5 | import '../os/parcel.dart' show Parcel; 6 | import '../os/parcelable.dart' show Parcelable; 7 | 8 | /// [PointF] holds two float coordinates. 9 | /// 10 | /// See: https://developer.android.com/reference/android/graphics/PointF 11 | /// See: https://github.com/aosp-mirror/platform_frameworks_base/blob/master/graphics/java/android/graphics/PointF.java 12 | class PointF extends math.Point with Parcelable { 13 | PointF([final double x = 0, final double y = 0]) : super(x, y); 14 | 15 | @override 16 | String get parcelableCreator => "android.graphics.PointF"; 17 | 18 | @override 19 | void writeToParcel(final Parcel parcel, [final int flags = 0]) { 20 | parcel.writeFloat(x); 21 | parcel.writeFloat(y); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/src/os/vibration_effect.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'parcelable.dart' show Parcelable; 4 | 5 | /// Describes a haptic effect to be performed by a [Vibrator]. 6 | /// 7 | /// These effects may be any number of things, from single shot vibrations to 8 | /// complex waveforms. 9 | /// 10 | /// See: https://developer.android.com/reference/android/os/VibrationEffect 11 | abstract class VibrationEffect implements Parcelable { 12 | /// The default vibration strength of the device. 13 | /// 14 | /// See: https://developer.android.com/reference/android/os/VibrationEffect#DEFAULT_AMPLITUDE 15 | static const int DEFAULT_AMPLITUDE = -1; 16 | 17 | /// See: https://developer.android.com/reference/android/os/VibrationEffect#CREATOR 18 | //static const Parcelable.Creator CREATOR = null; // TODO 19 | } 20 | -------------------------------------------------------------------------------- /example/.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 | **/ios/Flutter/.last_build_id 26 | .dart_tool/ 27 | .flutter-plugins 28 | .flutter-plugins-dependencies 29 | .packages 30 | .pub-cache/ 31 | .pub/ 32 | /build/ 33 | 34 | # Web related 35 | lib/generated_plugin_registrant.dart 36 | 37 | # Symbolication related 38 | app.*.symbols 39 | 40 | # Obfuscation related 41 | app.*.map.json 42 | 43 | # Exceptions to above rules. 44 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 45 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | # See: https://dart.dev/tools/pub/pubspec 2 | name: flutter_android 3 | version: 0.8.0 4 | description: >- 5 | A Flutter plugin for Android platform-specific APIs, to reduce duplication 6 | of effort by centralizing Android bindings in a single package. 7 | homepage: https://github.com/drydart/flutter_android 8 | repository: https://github.com/drydart/flutter_android 9 | issue_tracker: https://github.com/drydart/flutter_android/issues 10 | documentation: 11 | dependencies: 12 | flutter: 13 | sdk: flutter 14 | typed_data: ^1.2.0 15 | dev_dependencies: 16 | flutter_test: 17 | sdk: flutter 18 | pedantic: ^1.9.0 19 | dependency_overrides: 20 | environment: 21 | sdk: ">=2.8.0 <3.0.0" 22 | flutter: ">=1.17.0 <2.0.0" 23 | executables: 24 | flutter: 25 | plugin: 26 | platforms: 27 | android: 28 | package: com.github.drydart.flutter_android 29 | pluginClass: FlutterAndroidPlugin 30 | -------------------------------------------------------------------------------- /example/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 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 | 8.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /lib/src/app/activity_manager.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'dart:async' show Future; 4 | import 'dart:io' show Platform; 5 | 6 | import 'package:flutter/services.dart' show MethodChannel; 7 | 8 | /// Gives information about, and interacts with, activities, services, and the 9 | /// containing process. 10 | /// 11 | /// See: https://developer.android.com/reference/android/app/ActivityManager 12 | class ActivityManager { 13 | static const MethodChannel _channel = 14 | MethodChannel('flutter_android/ActivityManager'); 15 | 16 | /// Returns `true` if device is running in a test harness. 17 | /// 18 | /// See: https://developer.android.com/reference/android/app/ActivityManager#isRunningInTestHarness() 19 | static Future get isRunningInTestHarness async { 20 | assert(Platform.isAndroid); 21 | return await _channel.invokeMethod('isRunningInTestHarness') as bool; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ios/flutter_android.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. 3 | # Run `pod lib lint flutter_android.podspec' to validate before publishing. 4 | # 5 | Pod::Spec.new do |s| 6 | s.name = 'flutter_android' 7 | s.version = '0.0.1' 8 | s.summary = 'A new flutter plugin project.' 9 | s.description = <<-DESC 10 | A new flutter plugin project. 11 | DESC 12 | s.homepage = 'http://example.com' 13 | s.license = { :file => '../LICENSE' } 14 | s.author = { 'Your Company' => 'email@example.com' } 15 | s.source = { :path => '.' } 16 | s.source_files = 'Classes/**/*' 17 | s.dependency 'Flutter' 18 | s.platform = :ios, '8.0' 19 | 20 | # Flutter.framework does not contain a i386 slice. Only x86_64 simulators are supported. 21 | s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' } 22 | s.swift_version = '5.0' 23 | end 24 | -------------------------------------------------------------------------------- /.github/workflows/linter.yaml: -------------------------------------------------------------------------------- 1 | # See: https://github.com/github/super-linter 2 | --- 3 | name: Linter 4 | on: 5 | push: 6 | branches: [master] 7 | paths: 8 | - '**.dart' 9 | - '**.md' 10 | - '**.yaml' 11 | - '**.yml' 12 | pull_request: 13 | branches: [master] 14 | paths: 15 | - '**.dart' 16 | - '**.md' 17 | - '**.yaml' 18 | - '**.yml' 19 | jobs: 20 | lint: 21 | name: Lint codebase 22 | runs-on: ubuntu-18.04 23 | steps: 24 | - name: Clone repository 25 | uses: actions/checkout@v2 26 | - name: Lint Markdown and YAML files 27 | uses: docker://github/super-linter:v3.4.0 28 | env: 29 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 30 | VALIDATE_MD: true 31 | VALIDATE_YAML: true 32 | - name: Lint Dart source code 33 | uses: docker://github/super-linter:v3.4.0 34 | env: 35 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 36 | VALIDATE_DART: true 37 | DISABLE_ERRORS: true 38 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /lib/src/app/pending_intent.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | /// A description of an [Intent] and target action to perform with it. 4 | /// 5 | /// See: https://developer.android.com/reference/android/app/PendingIntent 6 | abstract class PendingIntent { 7 | /// See: https://developer.android.com/reference/android/app/PendingIntent#FLAG_CANCEL_CURRENT 8 | static const int FLAG_CANCEL_CURRENT = 0x10000000; 9 | 10 | /// See: https://developer.android.com/reference/android/app/PendingIntent#FLAG_IMMUTABLE 11 | static const int FLAG_IMMUTABLE = 0x04000000; 12 | 13 | /// See: https://developer.android.com/reference/android/app/PendingIntent#FLAG_NO_CREATE 14 | static const int FLAG_NO_CREATE = 0x20000000; 15 | 16 | /// See: https://developer.android.com/reference/android/app/PendingIntent#FLAG_ONE_SHOT 17 | static const int FLAG_ONE_SHOT = 0x40000000; 18 | 19 | /// See: https://developer.android.com/reference/android/app/PendingIntent#FLAG_UPDATE_CURRENT 20 | static const int FLAG_UPDATE_CURRENT = 0x08000000; 21 | } 22 | -------------------------------------------------------------------------------- /lib/android_content.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | /// Contains classes for accessing and publishing data on a device. 4 | /// 5 | /// See: https://developer.android.com/reference/android/content/package-summary 6 | /// 7 | /// {@canonicalFor component_name.ComponentName} 8 | /// {@canonicalFor content_values.ContentValues} 9 | /// {@canonicalFor context.Context} 10 | /// {@canonicalFor exceptions.ActivityNotFoundException} 11 | /// {@canonicalFor intent.Intent} 12 | /// {@canonicalFor intent_filter.IntentFilter} 13 | /// {@canonicalFor shared_preferences.SharedPreferences} 14 | library android_content; 15 | 16 | export 'src/content/component_name.dart' show ComponentName; 17 | export 'src/content/content_values.dart' show ContentValues; 18 | export 'src/content/context.dart' show Context; 19 | export 'src/content/exceptions.dart' show ActivityNotFoundException; 20 | export 'src/content/intent.dart' show Intent; 21 | export 'src/content/intent_filter.dart' show IntentFilter; 22 | export 'src/content/shared_preferences.dart' show SharedPreferences; 23 | -------------------------------------------------------------------------------- /android/src/main/java/com/github/drydart/flutter_android/BluetoothDeviceHandler.java: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | package com.github.drydart.flutter_android; 4 | 5 | import androidx.annotation.NonNull; 6 | 7 | import io.flutter.embedding.engine.plugins.FlutterPlugin; 8 | import io.flutter.plugin.common.MethodCall; 9 | import io.flutter.plugin.common.MethodChannel.Result; 10 | 11 | /** BluetoothDeviceHandler */ 12 | @SuppressWarnings("unchecked") 13 | class BluetoothDeviceHandler extends FlutterMethodCallHandler { 14 | static final String CHANNEL = "flutter_android/BluetoothDevice"; 15 | 16 | BluetoothDeviceHandler(final @NonNull FlutterPlugin.FlutterPluginBinding binding) { 17 | super(binding); 18 | } 19 | 20 | @Override 21 | public void onMethodCall(final MethodCall call, final Result result) { 22 | assert(call != null); 23 | assert(result != null); 24 | 25 | assert(call.method != null); 26 | switch (call.method) { 27 | // TODO 28 | 29 | default: { 30 | result.notImplemented(); 31 | } 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /android/src/main/java/com/github/drydart/flutter_android/BluetoothAdapterHandler.java: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | package com.github.drydart.flutter_android; 4 | 5 | import androidx.annotation.NonNull; 6 | 7 | import io.flutter.embedding.engine.plugins.FlutterPlugin; 8 | import io.flutter.plugin.common.MethodCall; 9 | import io.flutter.plugin.common.MethodChannel.Result; 10 | 11 | /** BluetoothAdapterHandler */ 12 | @SuppressWarnings("unchecked") 13 | class BluetoothAdapterHandler extends FlutterMethodCallHandler { 14 | static final String CHANNEL = "flutter_android/BluetoothAdapter"; 15 | 16 | BluetoothAdapterHandler(final @NonNull FlutterPlugin.FlutterPluginBinding binding) { 17 | super(binding); 18 | } 19 | 20 | @Override 21 | public void onMethodCall(final MethodCall call, final Result result) { 22 | assert(call != null); 23 | assert(result != null); 24 | 25 | assert(call.method != null); 26 | switch (call.method) { 27 | // TODO 28 | 29 | default: { 30 | result.notImplemented(); 31 | } 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /android/src/main/java/com/github/drydart/flutter_android/BluetoothHeadsetHandler.java: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | package com.github.drydart.flutter_android; 4 | 5 | import androidx.annotation.NonNull; 6 | 7 | import io.flutter.embedding.engine.plugins.FlutterPlugin; 8 | import io.flutter.plugin.common.MethodCall; 9 | import io.flutter.plugin.common.MethodChannel.Result; 10 | 11 | /** BluetoothHeadsetHandler */ 12 | @SuppressWarnings("unchecked") 13 | class BluetoothHeadsetHandler extends FlutterMethodCallHandler { 14 | static final String CHANNEL = "flutter_android/BluetoothHeadset"; 15 | 16 | BluetoothHeadsetHandler(final @NonNull FlutterPlugin.FlutterPluginBinding binding) { 17 | super(binding); 18 | } 19 | 20 | @Override 21 | public void onMethodCall(final MethodCall call, final Result result) { 22 | assert(call != null); 23 | assert(result != null); 24 | 25 | assert(call.method != null); 26 | switch (call.method) { 27 | // TODO 28 | 29 | default: { 30 | result.notImplemented(); 31 | } 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /android/src/main/java/com/github/drydart/flutter_android/BluetoothManagerHandler.java: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | package com.github.drydart.flutter_android; 4 | 5 | import androidx.annotation.NonNull; 6 | 7 | import io.flutter.embedding.engine.plugins.FlutterPlugin; 8 | import io.flutter.plugin.common.MethodCall; 9 | import io.flutter.plugin.common.MethodChannel.Result; 10 | 11 | /** BluetoothManagerHandler */ 12 | @SuppressWarnings("unchecked") 13 | class BluetoothManagerHandler extends FlutterMethodCallHandler { 14 | static final String CHANNEL = "flutter_android/BluetoothManager"; 15 | 16 | BluetoothManagerHandler(final @NonNull FlutterPlugin.FlutterPluginBinding binding) { 17 | super(binding); 18 | } 19 | 20 | @Override 21 | public void onMethodCall(final MethodCall call, final Result result) { 22 | assert(call != null); 23 | assert(result != null); 24 | 25 | assert(call.method != null); 26 | switch (call.method) { 27 | // TODO 28 | 29 | default: { 30 | result.notImplemented(); 31 | } 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /example/lib/demos/bluetooth_scanner.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | //import 'package:flutter_android/android_bluetooth.dart'; 6 | 7 | //////////////////////////////////////////////////////////////////////////////// 8 | 9 | class BluetoothScannerDemo extends StatefulWidget { 10 | @override 11 | State createState() => _BluetoothScannerState(); 12 | } 13 | 14 | //////////////////////////////////////////////////////////////////////////////// 15 | 16 | class _BluetoothScannerState extends State { 17 | @override 18 | void initState() { 19 | super.initState(); 20 | _initPlatformState(); 21 | } 22 | 23 | @override 24 | Widget build(final BuildContext context) { 25 | return Scaffold( 26 | appBar: AppBar( 27 | title: Text("Bluetooth Scanner"), 28 | ), 29 | body: Center( 30 | child: Text("To be implemented"), // TODO 31 | ), 32 | ); 33 | } 34 | 35 | Future _initPlatformState() async { 36 | // TODO 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /example/lib/demos/heartrate_monitor.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | //import 'package:flutter_android/android_hardware.dart'; 6 | 7 | //////////////////////////////////////////////////////////////////////////////// 8 | 9 | class HeartrateMonitorDemo extends StatefulWidget { 10 | @override 11 | State createState() => _HeartrateMonitorState(); 12 | } 13 | 14 | //////////////////////////////////////////////////////////////////////////////// 15 | 16 | class _HeartrateMonitorState extends State { 17 | @override 18 | void initState() { 19 | super.initState(); 20 | _initPlatformState(); 21 | } 22 | 23 | @override 24 | Widget build(final BuildContext context) { 25 | return Scaffold( 26 | appBar: AppBar( 27 | title: Text("Heart-Rate Monitor"), 28 | ), 29 | body: Center( 30 | child: Text("To be implemented"), // TODO 31 | ), 32 | ); 33 | } 34 | 35 | Future _initPlatformState() async { 36 | // TODO 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /android/src/main/java/com/github/drydart/flutter_android/BluetoothLeScannerHandler.java: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | package com.github.drydart.flutter_android; 4 | 5 | import androidx.annotation.NonNull; 6 | 7 | import io.flutter.embedding.engine.plugins.FlutterPlugin; 8 | import io.flutter.plugin.common.MethodCall; 9 | import io.flutter.plugin.common.MethodChannel.Result; 10 | 11 | /** BluetoothLeScannerHandler */ 12 | @SuppressWarnings("unchecked") 13 | class BluetoothLeScannerHandler extends FlutterMethodCallHandler { 14 | static final String CHANNEL = "flutter_android/BluetoothLeScanner"; 15 | 16 | BluetoothLeScannerHandler(final @NonNull FlutterPlugin.FlutterPluginBinding binding) { 17 | super(binding); 18 | } 19 | 20 | @Override 21 | public void onMethodCall(final MethodCall call, final Result result) { 22 | assert(call != null); 23 | assert(result != null); 24 | 25 | assert(call.method != null); 26 | switch (call.method) { 27 | // TODO 28 | 29 | default: { 30 | result.notImplemented(); 31 | } 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /example/test/widget_test.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | // This is a basic Flutter widget test. 4 | // 5 | // To perform an interaction with a widget in your test, use the WidgetTester 6 | // utility that Flutter provides. For example, you can send tap and scroll 7 | // gestures. You can also use WidgetTester to find child widgets in the widget 8 | // tree, read text, and verify that the values of widget properties are correct. 9 | 10 | import 'package:flutter/material.dart'; 11 | import 'package:flutter_test/flutter_test.dart'; 12 | 13 | import 'package:flutter_android_example/main.dart' show App; 14 | 15 | void main() { 16 | testWidgets("Verify Android platform version", 17 | (final WidgetTester tester) async { 18 | // Build our app and trigger a frame. 19 | await tester.pumpWidget(App()); 20 | 21 | // Verify that platform version is retrieved. 22 | expect( 23 | find.byWidgetPredicate( 24 | (Widget widget) => 25 | widget is Text && widget.data.startsWith('Running on:'), 26 | ), 27 | findsOneWidget, 28 | ); 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /example/lib/main.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | import 'main_screen.dart'; 6 | 7 | //////////////////////////////////////////////////////////////////////////////// 8 | 9 | void main() => runApp(App()); 10 | 11 | //////////////////////////////////////////////////////////////////////////////// 12 | 13 | class App extends StatefulWidget { 14 | @override 15 | State createState() => _AppState(); 16 | } 17 | 18 | //////////////////////////////////////////////////////////////////////////////// 19 | 20 | class _AppState extends State { 21 | @override 22 | void initState() { 23 | super.initState(); 24 | } 25 | 26 | @override 27 | void dispose() { 28 | super.dispose(); 29 | } 30 | 31 | @override 32 | Widget build(final BuildContext context) { 33 | return MaterialApp( 34 | color: Colors.grey, 35 | theme: ThemeData( 36 | primaryColor: Colors.black, 37 | brightness: Brightness.dark, 38 | ), 39 | home: MainScreen(), 40 | routes: {}, 41 | ); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /lib/android_bluetooth.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | /// Provides classes that manage Bluetooth functionality, such as scanning for 4 | /// devices, connecting with devices, and managing data transfer between 5 | /// devices. 6 | /// 7 | /// See: https://developer.android.com/reference/android/bluetooth/package-summary 8 | /// See: https://developer.android.com/reference/android/bluetooth/le/package-summary 9 | /// 10 | /// {@canonicalFor bluetooth_adapter.BluetoothAdapter} 11 | /// {@canonicalFor bluetooth_device.BluetoothDevice} 12 | /// {@canonicalFor bluetooth_headset.BluetoothHeadset} 13 | /// {@canonicalFor bluetooth_le_scanner.BluetoothLeScanner} 14 | /// {@canonicalFor bluetooth_manager.BluetoothManager} 15 | library android_bluetooth; 16 | 17 | export 'src/bluetooth/bluetooth_adapter.dart' show BluetoothAdapter; 18 | export 'src/bluetooth/bluetooth_device.dart' show BluetoothDevice; 19 | export 'src/bluetooth/bluetooth_headset.dart' show BluetoothHeadset; 20 | export 'src/bluetooth/bluetooth_le_scanner.dart' show BluetoothLeScanner; 21 | export 'src/bluetooth/bluetooth_manager.dart' show BluetoothManager; 22 | -------------------------------------------------------------------------------- /android/src/main/java/com/github/drydart/flutter_android/AndroidHandler.java: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | package com.github.drydart.flutter_android; 4 | 5 | import androidx.annotation.NonNull; 6 | 7 | import io.flutter.embedding.engine.plugins.FlutterPlugin; 8 | import io.flutter.plugin.common.MethodCall; 9 | import io.flutter.plugin.common.MethodChannel.Result; 10 | 11 | /** AndroidHandler */ 12 | class AndroidHandler extends FlutterMethodCallHandler { 13 | static final String CHANNEL = "flutter_android/Android"; 14 | 15 | AndroidHandler(final @NonNull FlutterPlugin.FlutterPluginBinding binding) { 16 | super(binding); 17 | } 18 | 19 | @Override 20 | public void onMethodCall(final MethodCall call, final Result result) { 21 | assert(call != null); 22 | assert(result != null); 23 | 24 | assert(call.method != null); 25 | switch (call.method) { 26 | case "getPlatformVersion": { 27 | result.success("Android " + android.os.Build.VERSION.RELEASE); 28 | break; 29 | } 30 | default: { 31 | result.notImplemented(); 32 | } 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /lib/src/os/build.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'dart:io' show Platform; 4 | 5 | /// Information about the current build, extracted from system properties. 6 | /// 7 | /// See: https://developer.android.com/reference/android/os/Build 8 | abstract class Build { 9 | /// Value used for when a build property is unknown. 10 | /// 11 | /// See: https://developer.android.com/reference/android/os/Build#UNKNOWN 12 | static const String UNKNOWN = "unknown"; 13 | 14 | /// Returns the version string for the radio firmware. 15 | /// 16 | /// May return `null` (if, for instance, the radio is not currently on). 17 | /// 18 | /// See: https://developer.android.com/reference/android/os/Build#getRadioVersion() 19 | static Future get radioVersion { 20 | assert(Platform.isAndroid); 21 | return null; // TODO 22 | } 23 | 24 | /// Gets the hardware serial number, if available. 25 | /// 26 | /// See: https://developer.android.com/reference/android/os/Build#getSerial() 27 | static Future get serial { 28 | assert(Platform.isAndroid); 29 | return null; // TODO 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /lib/src/content/content_values.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import '../os/parcel.dart' show Parcel; 4 | import '../os/parcelable.dart' show Parcelable; 5 | 6 | /// This class is used to store a set of values that the [ContentResolver] can 7 | /// process. 8 | /// 9 | /// See: https://developer.android.com/reference/android/content/ContentValues 10 | /// See: https://github.com/aosp-mirror/platform_frameworks_base/blob/master/core/java/android/content/ContentValues.java 11 | class ContentValues with Parcelable { 12 | final Map map = const {}; 13 | 14 | /// Creates an empty set of values using the default initial size. 15 | /// 16 | /// See: https://developer.android.com/reference/android/content/ContentValues#ContentValues() 17 | ContentValues(); // FIXME: https://github.com/dart-lang/sdk/issues/40982 18 | 19 | @override 20 | String get parcelableCreator => "android.content.ContentValues"; 21 | 22 | @override 23 | void writeToParcel(final Parcel parcel, [final int flags = 0]) { 24 | parcel.writeInt(map.length); 25 | parcel.writeArrayMap(map); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /lib/android.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | /// Android bindings for Flutter. 4 | library android; 5 | 6 | import 'dart:async' show Future; 7 | import 'dart:io' show Platform; 8 | 9 | import 'package:flutter/services.dart' show MethodChannel; 10 | 11 | export 'android_app.dart'; 12 | export 'android_bluetooth.dart'; 13 | export 'android_content.dart'; 14 | export 'android_database.dart'; 15 | export 'android_graphics.dart'; 16 | export 'android_hardware.dart'; 17 | export 'android_location.dart'; 18 | export 'android_media.dart'; 19 | export 'android_net.dart'; 20 | export 'android_nfc.dart'; 21 | export 'android_os.dart'; 22 | export 'android_provider.dart'; 23 | export 'android_security.dart'; 24 | export 'android_speech.dart'; 25 | export 'android_telephony.dart'; 26 | export 'android_view.dart'; 27 | 28 | /// Android metadata. 29 | abstract class Android { 30 | static const MethodChannel _channel = 31 | MethodChannel('flutter_android/Android'); 32 | 33 | /// Returns the Android platform version. 34 | static Future get platformVersion async { 35 | assert(Platform.isAndroid); 36 | return await _channel.invokeMethod('getPlatformVersion'); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /android/src/main/java/com/github/drydart/flutter_android/ActivityManagerHandler.java: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | package com.github.drydart.flutter_android; 4 | 5 | import android.app.ActivityManager; 6 | import androidx.annotation.NonNull; 7 | 8 | import io.flutter.embedding.engine.plugins.FlutterPlugin; 9 | import io.flutter.plugin.common.MethodCall; 10 | import io.flutter.plugin.common.MethodChannel.Result; 11 | 12 | /** ActivityManagerHandler */ 13 | class ActivityManagerHandler extends FlutterMethodCallHandler { 14 | static final String CHANNEL = "flutter_android/ActivityManager"; 15 | 16 | ActivityManagerHandler(final @NonNull FlutterPlugin.FlutterPluginBinding binding) { 17 | super(binding); 18 | } 19 | 20 | @Override 21 | public void onMethodCall(final MethodCall call, final Result result) { 22 | assert(call != null); 23 | assert(result != null); 24 | 25 | assert(call.method != null); 26 | switch (call.method) { 27 | case "isRunningInTestHarness": { 28 | result.success(ActivityManager.isRunningInTestHarness()); 29 | break; 30 | } 31 | default: { 32 | result.notImplemented(); 33 | } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /UNLICENSE: -------------------------------------------------------------------------------- 1 | This is free and unencumbered software released into the public domain. 2 | 3 | Anyone is free to copy, modify, publish, use, compile, sell, or 4 | distribute this software, either in source code form or as a compiled 5 | binary, for any purpose, commercial or non-commercial, and by any 6 | means. 7 | 8 | In jurisdictions that recognize copyright laws, the author or authors 9 | of this software dedicate any and all copyright interest in the 10 | software to the public domain. We make this dedication for the benefit 11 | of the public at large and to the detriment of our heirs and 12 | successors. We intend this dedication to be an overt act of 13 | relinquishment in perpetuity of all present and future rights to this 14 | software under copyright law. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | 24 | For more information, please refer to 25 | -------------------------------------------------------------------------------- /lib/src/app/exceptions.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'package:flutter/services.dart' show PlatformException; 4 | 5 | import '../os/parcel.dart' show Parcel; 6 | import '../os/parcelable.dart' show Parcelable; 7 | 8 | /// Thrown when authentication is needed from the end user before viewing the 9 | /// content. 10 | /// 11 | /// This exception is only appropriate where there is a concrete action the user 12 | /// can take to authorize and make forward progress, such as confirming or 13 | /// entering authentication credentials, or granting access via other means. 14 | /// 15 | /// See: https://developer.android.com/reference/android/app/AuthenticationRequiredException 16 | /// See: https://github.com/aosp-mirror/platform_frameworks_base/blob/master/core/java/android/app/AuthenticationRequiredException.java 17 | class AuthenticationRequiredException extends PlatformException 18 | with Parcelable { 19 | @override 20 | String get parcelableCreator => "android.app.AuthenticationRequiredException"; 21 | 22 | @override 23 | void writeToParcel(final Parcel parcel, [final int flags = 0]) { 24 | throw UnimplementedError(); // TODO: https://github.com/aosp-mirror/platform_frameworks_base/blob/master/core/java/android/app/AuthenticationRequiredException.java#L79 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /lib/src/hardware/sensor_event.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'sensor.dart' show Sensor; 4 | 5 | /// Represents a [Sensor] event and holds information such as the sensor's type, 6 | /// the time-stamp, accuracy and of course the sensor's data. 7 | /// 8 | /// See: https://developer.android.com/reference/android/hardware/SensorEvent 9 | class SensorEvent { 10 | /// The accuracy of this event. 11 | /// 12 | /// See: https://developer.android.com/reference/android/hardware/SensorEvent#accuracy 13 | final int accuracy; 14 | 15 | /// The sensor that generated this event. 16 | /// 17 | /// See: https://developer.android.com/reference/android/hardware/SensorEvent#sensor 18 | final Sensor sensor; 19 | 20 | /// The time in nanoseconds at which the event happened. 21 | /// 22 | /// See: https://developer.android.com/reference/android/hardware/SensorEvent#timestamp 23 | final int timestamp; 24 | 25 | /// The length and contents of the values array depends on which sensor type 26 | /// is being monitored. 27 | /// 28 | /// See: https://developer.android.com/reference/android/hardware/SensorEvent#values 29 | final List values; 30 | 31 | const SensorEvent({ 32 | this.accuracy, 33 | this.sensor, 34 | this.timestamp, 35 | this.values, 36 | }); 37 | } 38 | -------------------------------------------------------------------------------- /lib/src/os/parcelable.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'parcel.dart' show Parcel; 4 | 5 | /// Interface for classes whose instances can be written to and restored from a 6 | /// [Parcel]. 7 | /// 8 | /// See: https://developer.android.com/reference/android/os/Parcelable 9 | mixin Parcelable { 10 | /// Descriptor bit used with `describeContents()`: indicates that the 11 | /// `Parcelable` object's flattened representation includes a file 12 | /// descriptor. 13 | /// 14 | /// See: https://developer.android.com/reference/android/os/Parcelable#CONTENTS_FILE_DESCRIPTOR 15 | static const int CONTENTS_FILE_DESCRIPTOR = 1; 16 | 17 | /// Flag for use with `writeToParcel`. 18 | /// 19 | /// See: https://developer.android.com/reference/android/os/Parcelable#PARCELABLE_WRITE_RETURN_VALUE 20 | static const int PARCELABLE_WRITE_RETURN_VALUE = 1; 21 | 22 | String get parcelableCreator; 23 | 24 | /// Describe any special objects contained in this instance's marshaled representation. 25 | /// 26 | /// See: https://developer.android.com/reference/android/os/Parcelable#describeContents() 27 | int describeContents() { 28 | return 0; 29 | } 30 | 31 | /// Flatten this object in to a [Parcel]. 32 | /// 33 | /// See: https://developer.android.com/reference/android/os/Parcelable#writeToParcel(android.os.Parcel,%20int) 34 | void writeToParcel(Parcel parcel, [int flags = 0]); 35 | } 36 | -------------------------------------------------------------------------------- /lib/src/bluetooth/bluetooth_le_scanner.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | //import 'package:flutter/services.dart' show MethodChannel; 4 | 5 | /// This class provides methods to perform scan related operations for Bluetooth 6 | /// LE devices. 7 | /// 8 | /// See: https://developer.android.com/reference/android/bluetooth/le/BluetoothLeScanner 9 | abstract class BluetoothLeScanner { 10 | //static const MethodChannel _channel = 11 | // MethodChannel('flutter_android/BluetoothLeScanner'); 12 | 13 | /// Extra containing a list of ScanResults. 14 | /// 15 | /// See: https://developer.android.com/reference/android/bluetooth/le/BluetoothLeScanner#EXTRA_LIST_SCAN_RESULT 16 | static const String EXTRA_LIST_SCAN_RESULT = 17 | "android.bluetooth.le.extra.LIST_SCAN_RESULT"; 18 | 19 | /// Optional extra indicating the error code, if any. 20 | /// 21 | /// See: https://developer.android.com/reference/android/bluetooth/le/BluetoothLeScanner#EXTRA_ERROR_CODE 22 | static const String EXTRA_ERROR_CODE = 23 | "android.bluetooth.le.extra.ERROR_CODE"; 24 | 25 | /// Optional extra indicating the callback type, which will be one of CALLBACK_TYPE_* constants in `ScanSettings`. 26 | /// 27 | /// See: https://developer.android.com/reference/android/bluetooth/le/BluetoothLeScanner#EXTRA_CALLBACK_TYPE 28 | static const String EXTRA_CALLBACK_TYPE = 29 | "android.bluetooth.le.extra.CALLBACK_TYPE"; 30 | } 31 | -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '9.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 | end 36 | 37 | post_install do |installer| 38 | installer.pods_project.targets.each do |target| 39 | flutter_additional_ios_build_settings(target) 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /android/src/main/java/com/github/drydart/flutter_android/SharedPreferencesHandler.java: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | package com.github.drydart.flutter_android; 4 | 5 | import android.content.Context; 6 | import android.content.SharedPreferences; 7 | import androidx.annotation.NonNull; 8 | 9 | import io.flutter.embedding.engine.plugins.FlutterPlugin; 10 | import io.flutter.plugin.common.MethodCall; 11 | import io.flutter.plugin.common.MethodChannel.Result; 12 | 13 | /** SharedPreferencesHandler */ 14 | class SharedPreferencesHandler extends FlutterMethodCallHandler { 15 | static final String CHANNEL = "flutter_android/SharedPreferences"; 16 | 17 | SharedPreferencesHandler(final @NonNull FlutterPlugin.FlutterPluginBinding binding) { 18 | super(binding); 19 | } 20 | 21 | @Override 22 | public void onMethodCall(final MethodCall call, final Result result) { 23 | assert(call != null); 24 | assert(result != null); 25 | 26 | final Context context = this.binding.getApplicationContext(); 27 | assert(context != null); 28 | 29 | assert(call.method != null); 30 | switch (call.method) { 31 | case "getAll": { 32 | final String name = getRequiredArgument(call, "name"); 33 | final int mode = getRequiredArgument(call, "mode"); 34 | final SharedPreferences prefs = context.getSharedPreferences(name, mode); 35 | result.success(prefs.getAll()); 36 | break; 37 | } 38 | default: { 39 | result.notImplemented(); 40 | } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /lib/src/app/download_manager.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'dart:async' show Future; 4 | import 'dart:io' show Platform; 5 | 6 | import 'package:flutter/services.dart' show MethodChannel; 7 | 8 | /// The download manager is a system service that handles long-running HTTP 9 | /// downloads. 10 | /// 11 | /// See: https://developer.android.com/reference/android/app/DownloadManager 12 | class DownloadManager { 13 | static const MethodChannel _channel = 14 | MethodChannel('flutter_android/DownloadManager'); 15 | 16 | /// Returns maximum size, in bytes, of downloads that may go over a mobile 17 | /// connection; or `null` if there's no limit. 18 | /// 19 | /// See: https://developer.android.com/reference/android/app/DownloadManager#getMaxBytesOverMobile(android.content.Context) 20 | static Future get maxBytesOverMobile async { 21 | assert(Platform.isAndroid); 22 | return await _channel.invokeMethod('getMaxBytesOverMobile') 23 | as int; // TODO: implement backend 24 | } 25 | 26 | /// Returns recommended maximum size, in bytes, of downloads that may go over 27 | /// a mobile connection; or `null` if there's no recommended limit. The user 28 | /// will have the option to bypass this limit. 29 | /// 30 | /// See: https://developer.android.com/reference/android/app/DownloadManager#getRecommendedMaxBytesOverMobile(android.content.Context) 31 | static Future get recommendedMaxBytesOverMobile async { 32 | assert(Platform.isAndroid); 33 | return await _channel.invokeMethod('getRecommendedMaxBytesOverMobile') 34 | as int; // TODO: implement backend 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /android/src/main/java/com/github/drydart/flutter_android/LocationHandler.java: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | package com.github.drydart.flutter_android; 4 | 5 | import android.location.Location; 6 | import androidx.annotation.NonNull; 7 | 8 | import io.flutter.embedding.engine.plugins.FlutterPlugin; 9 | import io.flutter.plugin.common.MethodCall; 10 | import io.flutter.plugin.common.MethodChannel.Result; 11 | 12 | /** LocationHandler */ 13 | @SuppressWarnings("unchecked") 14 | class LocationHandler extends FlutterMethodCallHandler { 15 | static final String CHANNEL = "flutter_android/Location"; 16 | 17 | LocationHandler(final @NonNull FlutterPlugin.FlutterPluginBinding binding) { 18 | super(binding); 19 | } 20 | 21 | @Override 22 | public void onMethodCall(final MethodCall call, final Result result) { 23 | assert(call != null); 24 | assert(result != null); 25 | 26 | assert(call.method != null); 27 | switch (call.method) { 28 | case "distanceBetween": { 29 | final double startLatitude = getRequiredArgument(call, "startLatitude"); 30 | final double startLongitude = getRequiredArgument(call, "startLongitude"); 31 | final double endLatitude = getRequiredArgument(call, "endLatitude"); 32 | final double endLongitude = getRequiredArgument(call, "endLongitude"); 33 | final float[] distance = new float[1]; 34 | Location.distanceBetween(startLatitude, startLongitude, endLatitude, endLongitude, distance); 35 | result.success((double)distance[0]); 36 | break; 37 | } 38 | 39 | default: { 40 | result.notImplemented(); 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /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/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | flutter_android_example 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /test/android_database_test.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'package:flutter_test/flutter_test.dart'; 4 | 5 | import 'package:flutter_android/android_database.dart'; 6 | 7 | void main() { 8 | group('android_database.DatabaseUtils', () { 9 | test('DatabaseUtils.dumpCurrentRowToString', () { 10 | // TODO 11 | }); 12 | test('DatabaseUtils.dumpCurrentRowToStringBuffer', () { 13 | // TODO 14 | }); 15 | test('DatabaseUtils.dumpCursorToString', () { 16 | // TODO 17 | }); 18 | }); 19 | 20 | group('android_database.MatrixCursor', () { 21 | test('MatrixCursor.empty', () { 22 | final Cursor cursor = MatrixCursor.empty(); 23 | expect(cursor, isEmpty); 24 | expect(cursor.position, equals(-1)); 25 | expect(cursor.isBeforeFirst, isTrue); 26 | for (var row in cursor) {} // ignore: unused_local_variable 27 | expect(cursor.position, equals(0)); 28 | expect(cursor.isAfterLast, isTrue); 29 | }); 30 | test('MatrixCursor.from', () { 31 | final Cursor cursor = MatrixCursor.from( 32 | columns: ['a', 'b', 'c'], 33 | rows: >[ 34 | [1, 2, 3], 35 | [4, 5, 6], 36 | [7, 8, 9] 37 | ], 38 | ); 39 | expect(cursor, isNotEmpty); 40 | expect(cursor.position, equals(-1)); 41 | expect(cursor.isBeforeFirst, isTrue); 42 | for (var row in cursor) { 43 | expect(row, hasLength(3)); 44 | expect(row.keys, contains('a')); 45 | expect(row.keys, contains('b')); 46 | expect(row.keys, contains('c')); 47 | } 48 | expect(cursor.position, equals(3)); 49 | expect(cursor.isAfterLast, isTrue); 50 | }); 51 | }); 52 | } 53 | -------------------------------------------------------------------------------- /lib/android_os.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | /// Provides basic operating system services, message passing, and 4 | /// inter-process communication on the device. 5 | /// 6 | /// See: https://developer.android.com/reference/android/os/package-summary 7 | /// 8 | /// {@canonicalFor battery_manager.BatteryManager} 9 | /// {@canonicalFor build.Build} 10 | /// {@canonicalFor bundle.Bundle} 11 | /// {@canonicalFor environment.Environment} 12 | /// {@canonicalFor hardware_properties_manager.HardwarePropertiesManager} 13 | /// {@canonicalFor parcel.Parcel} 14 | /// {@canonicalFor parcelable.Parcelable} 15 | /// {@canonicalFor power_manager.PowerManager} 16 | /// {@canonicalFor process.Process} 17 | /// {@canonicalFor stat_fs.StatFs} 18 | /// {@canonicalFor system_clock.SystemClock} 19 | /// {@canonicalFor user_manager.UserManager} 20 | /// {@canonicalFor vibration_effect.VibrationEffect} 21 | /// {@canonicalFor vibrator.Vibrator} 22 | library android_os; 23 | 24 | export 'src/os/battery_manager.dart' show BatteryManager; 25 | export 'src/os/build.dart' show Build; 26 | export 'src/os/bundle.dart' show Bundle; 27 | export 'src/os/environment.dart' show Environment; 28 | export 'src/os/exceptions.dart'; 29 | export 'src/os/hardware_properties_manager.dart' show HardwarePropertiesManager; 30 | export 'src/os/parcel.dart' show Parcel; 31 | export 'src/os/parcelable.dart' show Parcelable; 32 | export 'src/os/power_manager.dart' show PowerManager; 33 | export 'src/os/process.dart' show Process; 34 | export 'src/os/stat_fs.dart' show StatFs; 35 | export 'src/os/system_clock.dart' show SystemClock; 36 | export 'src/os/user_manager.dart' show UserManager; 37 | export 'src/os/vibration_effect.dart' show VibrationEffect; 38 | export 'src/os/vibrator.dart' show Vibrator; 39 | -------------------------------------------------------------------------------- /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 from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 26 | 27 | android { 28 | compileSdkVersion 28 29 | 30 | lintOptions { 31 | disable 'InvalidPackage' 32 | } 33 | 34 | defaultConfig { 35 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 36 | applicationId "com.github.drydart.flutter_android.example" 37 | minSdkVersion 16 38 | targetSdkVersion 28 39 | versionCode flutterVersionCode.toInteger() 40 | versionName flutterVersionName 41 | } 42 | 43 | buildTypes { 44 | release { 45 | // TODO: Add your own signing config for the release build. 46 | // Signing with the debug keys for now, so `flutter run --release` works. 47 | signingConfig signingConfigs.debug 48 | } 49 | } 50 | } 51 | 52 | flutter { 53 | source '../..' 54 | } 55 | -------------------------------------------------------------------------------- /lib/src/content/component_name.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import '../os/parcel.dart' show Parcel; 4 | import '../os/parcelable.dart' show Parcelable; 5 | 6 | /// Identifier for a specific application component that is available. 7 | /// 8 | /// See: https://developer.android.com/reference/android/content/ComponentName 9 | /// See: https://github.com/aosp-mirror/platform_frameworks_base/blob/master/core/java/android/content/ComponentName.java 10 | class ComponentName with Parcelable { 11 | /// The package name of this component. 12 | /// 13 | /// See: https://developer.android.com/reference/android/content/ComponentName#getPackageName() 14 | final String packageName; 15 | 16 | /// The class name of this component. 17 | /// 18 | /// See: https://developer.android.com/reference/android/content/ComponentName#getClassName() 19 | final String className; 20 | 21 | /// Creates a new component identifier. 22 | /// 23 | /// See: https://developer.android.com/reference/android/content/ComponentName#ComponentName(java.lang.String,%20java.lang.String) 24 | ComponentName(this.packageName, this.className) 25 | : assert(packageName != null), 26 | assert(className != null); 27 | 28 | /// Return a string that unambiguously describes both the package and class 29 | /// names contained in the [ComponentName]. 30 | /// 31 | /// See: https://developer.android.com/reference/android/content/ComponentName#flattenToString() 32 | String flattenToString() { 33 | return [packageName, className].join("/"); 34 | } 35 | 36 | @override 37 | String get parcelableCreator => "android.content.ComponentName"; 38 | 39 | @override 40 | void writeToParcel(final Parcel parcel, [final int flags = 0]) { 41 | parcel.writeString(packageName); 42 | parcel.writeString(className); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /lib/src/os/system_clock.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | /// Core timekeeping facilities. 4 | /// 5 | /// See: https://developer.android.com/reference/android/os/SystemClock 6 | abstract class SystemClock { 7 | /// Returns milliseconds running in the current thread. 8 | /// 9 | /// See: https://developer.android.com/reference/android/os/SystemClock#currentThreadTimeMillis() 10 | int get currentThreadTimeMillis { 11 | return null; // TODO 12 | } 13 | 14 | /// Returns milliseconds since boot, including time spent in sleep. 15 | /// 16 | /// See: https://developer.android.com/reference/android/os/SystemClock#elapsedRealtime() 17 | int get elapsedRealtime { 18 | return null; // TODO 19 | } 20 | 21 | /// Returns nanoseconds since boot, including time spent in sleep. 22 | /// 23 | /// See: https://developer.android.com/reference/android/os/SystemClock#elapsedRealtimeNanos() 24 | int get elapsedRealtimeNanos { 25 | return null; // TODO 26 | } 27 | 28 | /// Sets the current wall time, in milliseconds. 29 | /// 30 | /// Requires the calling process to have appropriate permissions. 31 | /// 32 | /// See: https://developer.android.com/reference/android/os/SystemClock#setCurrentTimeMillis(long) 33 | set currentThreadTimeMillis(final int millis) { 34 | return null; // TODO 35 | } 36 | 37 | /// Waits a given number of milliseconds (of [uptimeMillis]) before returning. 38 | /// 39 | /// See: https://developer.android.com/reference/android/os/SystemClock#sleep(long) 40 | void sleep(final int ms) { 41 | return null; // TODO 42 | } 43 | 44 | /// Returns milliseconds since boot, not counting time spent in deep sleep. 45 | /// 46 | /// See: https://developer.android.com/reference/android/os/SystemClock#uptimeMillis() 47 | int get uptimeMillis { 48 | return null; // TODO 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /example/lib/library_tab.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'dart:async'; 4 | import 'package:flutter/material.dart'; 5 | import 'package:url_launcher/url_launcher.dart' show launch; 6 | 7 | import 'src/metadata.dart' show metadata; 8 | 9 | //////////////////////////////////////////////////////////////////////////////// 10 | 11 | class LibraryTab extends StatefulWidget { 12 | @override 13 | State createState() => _LibraryTabState(); 14 | } 15 | 16 | //////////////////////////////////////////////////////////////////////////////// 17 | 18 | class _LibraryTabState extends State { 19 | @override 20 | void initState() { 21 | super.initState(); 22 | _initPlatformState(); 23 | } 24 | 25 | @override 26 | Widget build(final BuildContext context) { 27 | final libraryNames = metadata.keys.toList(); 28 | return ListView.separated( 29 | padding: EdgeInsets.all(8.0), 30 | itemCount: libraryNames.length, 31 | itemBuilder: (final BuildContext context, final int index) { 32 | final libraryName = libraryNames[index]; 33 | return GestureDetector( 34 | onTap: () => launch(_getURL(libraryName)), 35 | child: ListTile( 36 | leading: Icon(Icons.info), 37 | title: Text(libraryName), 38 | subtitle: Text(""), // TODO 39 | //trailing: Icon(Icons.info, color: Theme.of(context).disabledColor), 40 | ), 41 | ); 42 | }, 43 | separatorBuilder: (final BuildContext context, final int index) { 44 | return Divider(); 45 | }, 46 | ); 47 | } 48 | 49 | String _getURL(final String libraryName) { 50 | return "https://pub.dev/documentation/flutter_android/latest/$libraryName/$libraryName-library.html"; 51 | } 52 | 53 | Future _initPlatformState() async { 54 | // TODO 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /lib/src/app/wallpaper_colors.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'dart:ui' show Color; 4 | 5 | import '../os/parcel.dart' show Parcel; 6 | import '../os/parcelable.dart' show Parcelable; 7 | 8 | /// Provides information about the colors of a wallpaper. 9 | /// 10 | /// Exposes the 3 most visually representative colors of a wallpaper. 11 | /// 12 | /// See: https://developer.android.com/reference/android/app/WallpaperColors 13 | /// See: https://github.com/aosp-mirror/platform_frameworks_base/blob/master/core/java/android/app/WallpaperColors.java 14 | class WallpaperColors with Parcelable { 15 | /// The most visually representative color of the wallpaper. 16 | /// 17 | /// See: https://developer.android.com/reference/android/app/WallpaperColors#getPrimaryColor() 18 | final Color primaryColor; 19 | 20 | /// The second most preeminent color of the wallpaper. 21 | /// 22 | /// See: https://developer.android.com/reference/android/app/WallpaperColors#getSecondaryColor() 23 | final Color secondaryColor; 24 | 25 | /// The third most preeminent color of the wallpaper. 26 | /// 27 | /// See: https://developer.android.com/reference/android/app/WallpaperColors#getTertiaryColor() 28 | final Color tertiaryColor; 29 | 30 | /// Constructs a new object from three colors. 31 | /// 32 | /// See: https://developer.android.com/reference/android/app/WallpaperColors#WallpaperColors(android.graphics.Color,%20android.graphics.Color,%20android.graphics.Color) 33 | WallpaperColors(this.primaryColor, this.secondaryColor, this.tertiaryColor); 34 | 35 | @override 36 | String get parcelableCreator => "android.app.WallpaperColors"; 37 | 38 | @override 39 | void writeToParcel(final Parcel parcel, [final int flags = 0]) { 40 | throw UnimplementedError(); // TODO: https://github.com/aosp-mirror/platform_frameworks_base/blob/master/core/java/android/app/WallpaperColors.java#L281 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /lib/src/graphics/bitmap.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'dart:ui' show Image; 4 | 5 | import 'package:flutter/painting.dart' show AssetImage; 6 | 7 | import '../os/parcel.dart' show Parcel; 8 | import '../os/parcelable.dart' show Parcelable; 9 | 10 | /// Bitmap image. 11 | /// 12 | /// See: https://developer.android.com/reference/android/graphics/Bitmap 13 | /// See: https://github.com/aosp-mirror/platform_frameworks_base/blob/master/graphics/java/android/graphics/Bitmap.java 14 | abstract class Bitmap with Parcelable { 15 | static Bitmap fromImage(final Image image) { 16 | return _ImageBitmap(image); 17 | } 18 | 19 | static Bitmap fromAssetImage(final AssetImage asset) { 20 | return _AssetBitmap(asset); 21 | } 22 | 23 | String get assetName => null; 24 | 25 | /// The bitmap's height. 26 | int get height; 27 | 28 | /// The bitmap's width. 29 | int get width; 30 | 31 | /// Returns the bitmap's height. 32 | int getHeight() => height; 33 | 34 | /// Returns the bitmap's width. 35 | int getWidth() => width; 36 | 37 | /// Creates an image from this bitmap. 38 | Image toImage(); 39 | 40 | @override 41 | String get parcelableCreator => "android.graphics.Bitmap"; 42 | 43 | @override 44 | void writeToParcel(final Parcel parcel, [final int flags = 0]) { 45 | throw UnimplementedError(); // TODO 46 | } 47 | } 48 | 49 | class _ImageBitmap extends Bitmap { 50 | final Image image; 51 | 52 | _ImageBitmap(this.image) : assert(image != null); 53 | 54 | @override 55 | int get height => image.height; 56 | 57 | @override 58 | int get width => image.width; 59 | 60 | @override 61 | Image toImage() => image; 62 | } 63 | 64 | class _AssetBitmap extends Bitmap { 65 | final AssetImage asset; 66 | 67 | _AssetBitmap(this.asset) : assert(asset != null); 68 | 69 | @override 70 | String get assetName => asset.assetName; 71 | 72 | @override 73 | int get height => null; // TODO 74 | 75 | @override 76 | int get width => null; // TODO 77 | 78 | @override 79 | Image toImage() => null; // TODO 80 | } 81 | -------------------------------------------------------------------------------- /lib/android_app.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | /// Contains high-level classes encapsulating the overall Android application 4 | /// model. 5 | /// 6 | /// See: https://developer.android.com/reference/android/app/package-summary 7 | /// 8 | /// {@canonicalFor activity.Activity} 9 | /// {@canonicalFor activity_manager.ActivityManager} 10 | /// {@canonicalFor alarm_manager.AlarmManager} 11 | /// {@canonicalFor download_manager.DownloadManager} 12 | /// {@canonicalFor exceptions.AuthenticationRequiredException} 13 | /// {@canonicalFor keyguard_manager.KeyguardManager} 14 | /// {@canonicalFor notification.Notification} 15 | /// {@canonicalFor notification_action.NotificationAction} 16 | /// {@canonicalFor notification_builder.NotificationBuilder} 17 | /// {@canonicalFor notification_manager.NotificationManager} 18 | /// {@canonicalFor pending_intent.PendingIntent} 19 | /// {@canonicalFor search_manager.SearchManager} 20 | /// {@canonicalFor wallpaper_colors.WallpaperColors} 21 | /// {@canonicalFor wallpaper_info.WallpaperInfo} 22 | /// {@canonicalFor wallpaper_manager.WallpaperManager} 23 | library android_app; 24 | 25 | export 'src/app/activity.dart' show Activity; 26 | export 'src/app/activity_manager.dart' show ActivityManager; 27 | export 'src/app/alarm_manager.dart' show AlarmManager; 28 | export 'src/app/download_manager.dart' show DownloadManager; 29 | export 'src/app/exceptions.dart' show AuthenticationRequiredException; 30 | export 'src/app/keyguard_manager.dart' show KeyguardManager; 31 | export 'src/app/notification.dart' show Notification; 32 | export 'src/app/notification_action.dart' show NotificationAction; 33 | export 'src/app/notification_builder.dart' show NotificationBuilder; 34 | export 'src/app/notification_manager.dart' show NotificationManager; 35 | export 'src/app/pending_intent.dart' show PendingIntent; 36 | export 'src/app/search_manager.dart' show SearchManager; 37 | export 'src/app/wallpaper_colors.dart' show WallpaperColors; 38 | export 'src/app/wallpaper_info.dart' show WallpaperInfo; 39 | export 'src/app/wallpaper_manager.dart' show WallpaperManager; 40 | -------------------------------------------------------------------------------- /android/src/main/java/com/github/drydart/flutter_android/EnvironmentHandler.java: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | package com.github.drydart.flutter_android; 4 | 5 | import android.os.Environment; 6 | import androidx.annotation.NonNull; 7 | 8 | import io.flutter.embedding.engine.plugins.FlutterPlugin; 9 | import io.flutter.plugin.common.MethodCall; 10 | import io.flutter.plugin.common.MethodChannel.Result; 11 | 12 | /** EnvironmentHandler */ 13 | class EnvironmentHandler extends FlutterMethodCallHandler { 14 | static final String CHANNEL = "flutter_android/Environment"; 15 | 16 | EnvironmentHandler(final @NonNull FlutterPlugin.FlutterPluginBinding binding) { 17 | super(binding); 18 | } 19 | 20 | @Override 21 | public void onMethodCall(final MethodCall call, final Result result) { 22 | assert(call != null); 23 | assert(result != null); 24 | 25 | final Environment env = new Environment(); 26 | assert(env != null); 27 | 28 | assert(call.method != null); 29 | switch (call.method) { 30 | case "getDataDirectory": { 31 | result.success(env.getDataDirectory().toString()); 32 | break; 33 | } 34 | case "getDownloadCacheDirectory": { 35 | result.success(env.getDownloadCacheDirectory().toString()); 36 | break; 37 | } 38 | case "getExternalStorageDirectory": { 39 | result.success(env.getExternalStorageDirectory().toString()); 40 | break; 41 | } 42 | case "getExternalStorageState": { 43 | result.success(env.getExternalStorageState().toString()); 44 | break; 45 | } 46 | case "getRootDirectory": { 47 | result.success(env.getRootDirectory().toString()); 48 | break; 49 | } 50 | case "isExternalStorageEmulated": { 51 | result.success(env.isExternalStorageEmulated()); 52 | break; 53 | } 54 | case "isExternalStorageRemovable": { 55 | result.success(env.isExternalStorageRemovable()); 56 | break; 57 | } 58 | default: { 59 | result.notImplemented(); 60 | } 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /example/lib/class_tab.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'dart:async'; 4 | import 'package:flutter/material.dart'; 5 | import 'package:url_launcher/url_launcher.dart' show launch; 6 | 7 | import 'src/metadata.dart' show metadata; 8 | 9 | //////////////////////////////////////////////////////////////////////////////// 10 | 11 | class ClassTab extends StatefulWidget { 12 | @override 13 | State createState() => _ClassTabState(); 14 | } 15 | 16 | //////////////////////////////////////////////////////////////////////////////// 17 | 18 | class _ClassTabState extends State { 19 | final List> _classes = []; 20 | 21 | @override 22 | void initState() { 23 | super.initState(); 24 | metadata.forEach((libraryName, classInfos) { 25 | for (final classInfo in classInfos) { 26 | _classes.add(MapEntry(libraryName, classInfo.name)); 27 | } 28 | }); 29 | _initPlatformState(); 30 | } 31 | 32 | @override 33 | Widget build(final BuildContext context) { 34 | return ListView.separated( 35 | padding: EdgeInsets.all(8.0), 36 | itemCount: _classes.length, 37 | itemBuilder: (final BuildContext context, final int index) { 38 | final classEntry = _classes[index]; 39 | return GestureDetector( 40 | onTap: () => launch(_getURL(classEntry.key, classEntry.value)), 41 | child: ListTile( 42 | leading: Icon(Icons.info), 43 | title: Text(classEntry.value), 44 | subtitle: Text("${classEntry.key}.${classEntry.value}"), 45 | //trailing: Icon(Icons.info, color: Theme.of(context).disabledColor), 46 | ), 47 | ); 48 | }, 49 | separatorBuilder: (final BuildContext context, final int index) { 50 | return Divider(); 51 | }, 52 | ); 53 | } 54 | 55 | String _getURL(final String libraryName, final String className) { 56 | return "https://pub.dev/documentation/flutter_android/latest/$libraryName/$className-class.html"; 57 | } 58 | 59 | Future _initPlatformState() async { 60 | // TODO 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /android/src/main/java/com/github/drydart/flutter_android/SensorEventStream.java: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | package com.github.drydart.flutter_android; 4 | 5 | import android.hardware.Sensor; 6 | import android.hardware.SensorEvent; 7 | import android.hardware.SensorEventListener; 8 | import android.hardware.SensorManager; 9 | import io.flutter.plugin.common.EventChannel; 10 | 11 | /** SensorEventStream */ 12 | class SensorEventStream implements EventChannel.StreamHandler { 13 | private final SensorManager sensorManager; 14 | private final Sensor sensor; 15 | private final int samplingPeriodUs; 16 | private final int maxReportLatencyUs; 17 | private SensorEventListener sensorEventListener; 18 | 19 | SensorEventStream(final SensorManager sensorManager, 20 | final Sensor sensor, 21 | final int samplingPeriodUs, 22 | final int maxReportLatencyUs) { 23 | this.sensorManager = sensorManager; 24 | this.sensor = sensor; 25 | this.samplingPeriodUs = samplingPeriodUs; 26 | this.maxReportLatencyUs = maxReportLatencyUs; 27 | } 28 | 29 | @Override 30 | public void onListen(final Object _arguments, final EventChannel.EventSink events) { 31 | this.sensorEventListener = createSensorEventListener(events); 32 | this.sensorManager.registerListener(this.sensorEventListener, 33 | this.sensor, this.samplingPeriodUs, this.maxReportLatencyUs); 34 | } 35 | 36 | @Override 37 | public void onCancel(final Object _arguments) { 38 | this.sensorManager.unregisterListener(this.sensorEventListener); 39 | this.sensorEventListener = null; 40 | } 41 | 42 | SensorEventListener createSensorEventListener(final EventChannel.EventSink events) { 43 | return new SensorEventListener() { 44 | @Override 45 | public void onAccuracyChanged(final Sensor sensor, final int accuracy) {} 46 | 47 | @Override 48 | public void onSensorChanged(final SensorEvent event) { 49 | double[] sensorValues = new double[event.values.length]; 50 | for (int i = 0; i < event.values.length; i++) { 51 | sensorValues[i] = event.values[i]; 52 | } 53 | events.success(sensorValues); 54 | } 55 | }; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /example/lib/main_screen.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | import 'class_tab.dart'; 6 | import 'demo_tab.dart'; 7 | import 'library_tab.dart'; 8 | import 'method_tab.dart'; 9 | import 'property_tab.dart'; 10 | 11 | //////////////////////////////////////////////////////////////////////////////// 12 | 13 | class MainScreen extends StatefulWidget { 14 | @override 15 | State createState() => _MainScreenState(); 16 | } 17 | 18 | //////////////////////////////////////////////////////////////////////////////// 19 | 20 | class _MainScreenState extends State { 21 | final List _tabs; 22 | int _tabIndex = 0; 23 | 24 | _MainScreenState() 25 | : _tabs = [ 26 | DemoTab(), 27 | PropertyTab(), 28 | MethodTab(), 29 | ClassTab(), 30 | LibraryTab(), 31 | ], 32 | super(); 33 | 34 | @override 35 | void initState() { 36 | super.initState(); 37 | } 38 | 39 | @override 40 | Widget build(final BuildContext context) { 41 | return Scaffold( 42 | appBar: AppBar( 43 | title: Text("Flutter Android Bindings"), 44 | ), 45 | body: _tabs[_tabIndex], 46 | bottomNavigationBar: BottomNavigationBar( 47 | type: BottomNavigationBarType.fixed, 48 | onTap: _onTabTapped, 49 | currentIndex: _tabIndex, 50 | items: [ 51 | BottomNavigationBarItem( 52 | icon: Icon(Icons.slideshow), 53 | title: Text("Demos"), 54 | ), 55 | BottomNavigationBarItem( 56 | icon: Icon(Icons.info), 57 | title: Text("Properties"), 58 | ), 59 | BottomNavigationBarItem( 60 | icon: Icon(Icons.scatter_plot), 61 | title: Text("Methods"), 62 | ), 63 | BottomNavigationBarItem( 64 | icon: Icon(Icons.category), 65 | title: Text("Classes"), 66 | ), 67 | BottomNavigationBarItem( 68 | icon: Icon(Icons.local_library), 69 | title: Text("Libraries"), 70 | ), 71 | ], 72 | ), 73 | ); 74 | } 75 | 76 | void _onTabTapped(final int index) { 77 | setState(() { 78 | _tabIndex = index; 79 | }); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /lib/src/os/hardware_properties_manager.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | /// Provides a mechanism of accessing hardware state of a device: CPU, GPU and 4 | /// battery temperatures, CPU usage per core, fan speed, etc. 5 | /// 6 | /// See: https://developer.android.com/reference/android/os/HardwarePropertiesManager 7 | class HardwarePropertiesManager { 8 | /// Temperature of CPUs in Celsius. 9 | /// 10 | /// See: https://developer.android.com/reference/android/os/HardwarePropertiesManager#DEVICE_TEMPERATURE_CPU 11 | static const int DEVICE_TEMPERATURE_CPU = 0; 12 | 13 | /// Temperature of GPUs in Celsius. 14 | /// 15 | /// See: https://developer.android.com/reference/android/os/HardwarePropertiesManager#DEVICE_TEMPERATURE_GPU 16 | static const int DEVICE_TEMPERATURE_GPU = 1; 17 | 18 | /// Temperature of battery in Celsius. 19 | /// 20 | /// See: https://developer.android.com/reference/android/os/HardwarePropertiesManager#DEVICE_TEMPERATURE_BATTERY 21 | static const int DEVICE_TEMPERATURE_BATTERY = 2; 22 | 23 | /// Temperature of device skin in Celsius. 24 | /// 25 | /// See: https://developer.android.com/reference/android/os/HardwarePropertiesManager#DEVICE_TEMPERATURE_SKIN 26 | static const int DEVICE_TEMPERATURE_SKIN = 3; 27 | 28 | /// Get current temperature. 29 | /// 30 | /// See: https://developer.android.com/reference/android/os/HardwarePropertiesManager#TEMPERATURE_CURRENT 31 | static const int TEMPERATURE_CURRENT = 0; 32 | 33 | /// Get throttling temperature threshold. 34 | /// 35 | /// See: https://developer.android.com/reference/android/os/HardwarePropertiesManager#TEMPERATURE_THROTTLING 36 | static const int TEMPERATURE_THROTTLING = 1; 37 | 38 | /// Get shutdown temperature threshold. 39 | /// 40 | /// See: https://developer.android.com/reference/android/os/HardwarePropertiesManager#TEMPERATURE_SHUTDOWN 41 | static const int TEMPERATURE_SHUTDOWN = 2; 42 | 43 | /// Get throttling temperature threshold above which minimum clockrates for VR mode will not be met. 44 | /// 45 | /// See: https://developer.android.com/reference/android/os/HardwarePropertiesManager#TEMPERATURE_THROTTLING_BELOW_VR_MIN 46 | static const int TEMPERATURE_THROTTLING_BELOW_VR_MIN = 3; 47 | 48 | /// Undefined temperature constant. 49 | /// 50 | /// See: https://developer.android.com/reference/android/os/HardwarePropertiesManager#UNDEFINED_TEMPERATURE 51 | static const double UNDEFINED_TEMPERATURE = -3.4028235E38; 52 | } 53 | -------------------------------------------------------------------------------- /android/src/main/java/com/github/drydart/flutter_android/ContextHandler.java: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | package com.github.drydart.flutter_android; 4 | 5 | import android.content.Context; 6 | import androidx.annotation.NonNull; 7 | 8 | import io.flutter.embedding.engine.plugins.FlutterPlugin; 9 | import io.flutter.plugin.common.MethodCall; 10 | import io.flutter.plugin.common.MethodChannel.Result; 11 | 12 | /** ContextHandler */ 13 | class ContextHandler extends FlutterMethodCallHandler { 14 | static final String CHANNEL = "flutter_android/Context"; 15 | 16 | ContextHandler(final @NonNull FlutterPlugin.FlutterPluginBinding binding) { 17 | super(binding); 18 | } 19 | 20 | @Override 21 | public void onMethodCall(final MethodCall call, final Result result) { 22 | assert(call != null); 23 | assert(result != null); 24 | 25 | final Context context = this.binding.getApplicationContext(); 26 | assert(context != null); 27 | 28 | assert(call.method != null); 29 | switch (call.method) { 30 | case "getCacheDir": { 31 | result.success(context.getCacheDir().toString()); 32 | break; 33 | } 34 | case "getCodeCacheDir": { 35 | result.success(context.getCodeCacheDir().toString()); 36 | break; 37 | } 38 | case "getDataDir": { 39 | result.success(context.getDataDir().toString()); 40 | break; 41 | } 42 | case "getExternalCacheDir": { 43 | result.success(context.getExternalCacheDir().toString()); 44 | break; 45 | } 46 | case "getExternalFilesDir": { 47 | result.success(context.getExternalFilesDir(null).toString()); 48 | break; 49 | } 50 | case "getFilesDir": { 51 | result.success(context.getFilesDir().toString()); 52 | break; 53 | } 54 | case "getNoBackupFilesDir": { 55 | result.success(context.getNoBackupFilesDir().toString()); 56 | break; 57 | } 58 | case "getPackageCodePath": { 59 | result.success(context.getPackageCodePath().toString()); 60 | break; 61 | } 62 | case "getPackageName": { 63 | result.success(context.getPackageName().toString()); 64 | break; 65 | } 66 | case "getPackageResourcePath": { 67 | result.success(context.getPackageResourcePath().toString()); 68 | break; 69 | } 70 | default: { 71 | result.notImplemented(); 72 | } 73 | } 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 | -------------------------------------------------------------------------------- /lib/src/media/face_detector.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'dart:io' show Platform; 4 | 5 | import 'package:flutter/services.dart' show MethodChannel; 6 | import 'package:flutter/foundation.dart' show required; 7 | 8 | import '../graphics/bitmap.dart' show Bitmap; 9 | import '../graphics/pointf.dart' show PointF; 10 | import 'face.dart' show Face; 11 | 12 | /// Identifies the faces of people in a [Bitmap] graphic object. 13 | /// 14 | /// See: https://developer.android.com/reference/android/media/FaceDetector 15 | class FaceDetector { 16 | static const MethodChannel _channel = 17 | MethodChannel('flutter_android/FaceDetector'); 18 | 19 | /// The width of the images to be analyzed. 20 | final int width; 21 | 22 | /// The height of the images to be analyzed. 23 | final int height; 24 | 25 | /// The maximum number of faces to identify. 26 | final int maxFaces; 27 | 28 | /// Creates a FaceDetector, configured with the size of the images to be 29 | /// analyzed and the maximum number of faces that can be detected. 30 | /// 31 | /// These parameters cannot be changed once the object is constructed. 32 | /// Note that the width of the image must be even. 33 | /// 34 | /// See: https://developer.android.com/reference/android/media/FaceDetector#FaceDetector(int,%20int,%20int) 35 | FaceDetector({@required this.width, @required this.height, this.maxFaces = 1}) 36 | : assert(width != null && width > 0 && width % 2 == 0), 37 | assert(height != null && height > 0); 38 | 39 | /// Finds all the faces found in a given [Bitmap]. 40 | /// 41 | /// Returns an array of [Face] for each face found. 42 | /// 43 | /// See: https://developer.android.com/reference/android/media/FaceDetector#findFaces(android.graphics.Bitmap,%20android.media.FaceDetector.Face[]) 44 | Future> findFaces(final Bitmap bitmap) async { 45 | assert(Platform.isAndroid); 46 | final request = { 47 | 'width': width, 48 | 'height': height, 49 | 'maxFaces': maxFaces, 50 | 'bitmapName': bitmap.assetName, // TODO: support dynamic images as well 51 | }; 52 | final response = await _channel.invokeMethod('findFaces', request); 53 | return response.cast>().map((final List input) { 54 | final result = input.cast(); 55 | return Face( 56 | confidence: result[0], 57 | midPoint: PointF(result[1], result[2]), 58 | eyesDistance: result[3], 59 | poseX: result[4], 60 | poseY: result[5], 61 | poseZ: result[6], 62 | ); 63 | }).toList(); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /lib/src/os/stat_fs.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | /// Retrieve overall information about the space on a filesystem. 4 | /// 5 | /// This is a wrapper for Unix `statvfs()`. 6 | /// 7 | /// See: https://developer.android.com/reference/android/os/StatFs 8 | class StatFs { 9 | /// The filesystem path being examined. 10 | final String path; 11 | 12 | /// Construct a new `StatFs` for looking at the stats of the filesystem at 13 | /// path. 14 | /// 15 | /// Upon construction, the stat of the file system will be performed, and the 16 | /// values retrieved available from the methods on this class. 17 | /// 18 | /// See: https://developer.android.com/reference/android/os/StatFs#StatFs(java.lang.String) 19 | StatFs(this.path); 20 | 21 | /// The number of blocks that are free on the file system and available to 22 | /// applications. 23 | /// 24 | /// See: https://developer.android.com/reference/android/os/StatFs#getAvailableBlocksLong() 25 | int get availableBlocks { 26 | return null; // TODO 27 | } 28 | 29 | /// The number of bytes that are free on the file system and available to 30 | /// applications. 31 | /// 32 | /// See: https://developer.android.com/reference/android/os/StatFs#getAvailableBytes() 33 | int get availableBytes { 34 | return null; // TODO 35 | } 36 | 37 | /// The total number of blocks on the file system. 38 | /// 39 | /// See: https://developer.android.com/reference/android/os/StatFs#getBlockCountLong() 40 | int get blockCount { 41 | return null; // TODO 42 | } 43 | 44 | /// The size, in bytes, of a block on the file system. 45 | /// 46 | /// See: https://developer.android.com/reference/android/os/StatFs#getBlockSizeLong() 47 | int get blockSize { 48 | return null; // TODO 49 | } 50 | 51 | /// The total number of blocks that are free on the file system, including 52 | /// reserved blocks (that are not available to normal applications). 53 | /// 54 | /// See: https://developer.android.com/reference/android/os/StatFs#getFreeBlocksLong() 55 | int get freeBlocks { 56 | return null; // TODO 57 | } 58 | 59 | /// The number of bytes that are free on the file system, including reserved 60 | /// blocks (that are not available to normal applications). 61 | /// 62 | /// See: https://developer.android.com/reference/android/os/StatFs#getFreeBytes() 63 | int get freeBytes { 64 | return null; // TODO 65 | } 66 | 67 | /// The total number of bytes supported by the file system. 68 | /// 69 | /// See: https://developer.android.com/reference/android/os/StatFs#getTotalBytes() 70 | int get totalBytes { 71 | return null; // TODO 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_android_example 2 | description: Demonstrates how to use the flutter_android plugin. 3 | 4 | # The following line prevents the package from being accidentally published to 5 | # pub.dev using `pub publish`. This is preferred for private packages. 6 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev 7 | 8 | environment: 9 | sdk: ">=2.8.0 <3.0.0" 10 | 11 | dependencies: 12 | flutter: 13 | sdk: flutter 14 | 15 | flutter_android: 16 | # When depending on this package from a real application you should use: 17 | # flutter_android: ^x.y.z 18 | # See https://dart.dev/tools/pub/dependencies#version-constraints 19 | # The example app is bundled with the plugin so we use a path dependency on 20 | # the parent directory to use the current plugin's version. 21 | path: ../ 22 | 23 | # The following adds the Cupertino Icons font to your application. 24 | # Use with the CupertinoIcons class for iOS style icons. 25 | cupertino_icons: ^0.1.3 26 | 27 | url_launcher: ^5.5.0 28 | 29 | dev_dependencies: 30 | flutter_test: 31 | sdk: flutter 32 | 33 | # For information on the generic Dart part of this file, see the 34 | # following page: https://dart.dev/tools/pub/pubspec 35 | 36 | # The following section is specific to Flutter. 37 | flutter: 38 | 39 | # The following line ensures that the Material Icons font is 40 | # included with your application, so that you can use the icons in 41 | # the material Icons class. 42 | uses-material-design: true 43 | 44 | # To add assets to your application, add an assets section, like this: 45 | assets: 46 | - images/ 47 | 48 | # An image asset can refer to one or more resolution-specific "variants", see 49 | # https://flutter.dev/assets-and-images/#resolution-aware. 50 | 51 | # For details regarding adding assets from package dependencies, see 52 | # https://flutter.dev/assets-and-images/#from-packages 53 | 54 | # To add custom fonts to your application, add a fonts section here, 55 | # in this "flutter" section. Each entry in this list should have a 56 | # "family" key with the font family name, and a "fonts" key with a 57 | # list giving the asset and other descriptors for the font. For 58 | # example: 59 | # fonts: 60 | # - family: Schyler 61 | # fonts: 62 | # - asset: fonts/Schyler-Regular.ttf 63 | # - asset: fonts/Schyler-Italic.ttf 64 | # style: italic 65 | # - family: Trajan Pro 66 | # fonts: 67 | # - asset: fonts/TrajanPro.ttf 68 | # - asset: fonts/TrajanPro_Bold.ttf 69 | # weight: 700 70 | # 71 | # For details regarding fonts from package dependencies, 72 | # see https://flutter.dev/custom-fonts/#from-packages 73 | -------------------------------------------------------------------------------- /android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /android/src/main/java/com/github/drydart/flutter_android/FlutterMethodCallHandler.java: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | package com.github.drydart.flutter_android; 4 | 5 | import android.content.res.AssetFileDescriptor; 6 | import android.content.res.AssetManager; 7 | import android.graphics.Bitmap; 8 | import android.graphics.BitmapFactory; 9 | import androidx.annotation.NonNull; 10 | 11 | import io.flutter.embedding.engine.plugins.FlutterPlugin; 12 | import io.flutter.plugin.common.MethodCall; 13 | import io.flutter.plugin.common.MethodChannel.MethodCallHandler; 14 | import java.io.InputStream; 15 | import java.io.IOException; 16 | 17 | /** FlutterMethodCallHandler */ 18 | @SuppressWarnings("unchecked") 19 | abstract class FlutterMethodCallHandler implements MethodCallHandler { 20 | final protected FlutterPlugin.FlutterPluginBinding binding; 21 | 22 | FlutterMethodCallHandler(final @NonNull FlutterPlugin.FlutterPluginBinding binding) { 23 | this.binding = binding; 24 | } 25 | 26 | AssetManager 27 | getAssets() { 28 | return this.binding.getApplicationContext().getAssets(); 29 | } 30 | 31 | AssetFileDescriptor 32 | openAsset(final @NonNull String assetName) throws IOException { 33 | final String assetKey = this.binding.getFlutterAssets().getAssetFilePathByName(assetName); 34 | return getAssets().openFd(assetKey); 35 | } 36 | 37 | Bitmap 38 | loadBitmap(final String assetName) throws IOException { 39 | return loadBitmap(assetName, null); 40 | } 41 | 42 | Bitmap 43 | loadBitmap(final String assetName, 44 | final BitmapFactory.Options options) throws IOException { 45 | final InputStream stream = openAsset(assetName).createInputStream(); 46 | return BitmapFactory.decodeStream(stream, null, options); 47 | } 48 | 49 | static T 50 | getRequiredArgument(final MethodCall call, 51 | final String name) { 52 | assert(call != null); 53 | assert(name != null); 54 | 55 | if (!call.hasArgument(name)) { 56 | throw new AssertionError(); 57 | } 58 | final T arg = call.argument(name); 59 | if (arg == null) { 60 | throw new AssertionError(); 61 | } 62 | return arg; 63 | } 64 | 65 | static T 66 | getOptionalArgument(final MethodCall call, 67 | final String name) { 68 | return getOptionalArgument(call, name, (T)null); 69 | } 70 | 71 | static T 72 | getOptionalArgument(final MethodCall call, 73 | final String name, 74 | final T defaultValue) { 75 | assert(call != null); 76 | assert(name != null); 77 | 78 | return call.hasArgument(name) && call.argument(name) != null ? 79 | (T)call.argument(name) : defaultValue; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /lib/src/database/matrix_cursor.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'dart:async' show Future; 4 | 5 | import 'package:flutter/foundation.dart' show required; 6 | 7 | import 'cursor.dart' show Cursor; 8 | import 'exceptions.dart' show CursorIndexOutOfBoundsException; 9 | 10 | /// A mutable cursor implementation backed by an array of objects. Use 11 | /// [addRow()] to add rows. Automatically expands internal capacity as needed. 12 | /// 13 | /// See: https://developer.android.com/reference/android/database/MatrixCursor 14 | class MatrixCursor extends Cursor { 15 | bool _isClosed = false; 16 | List _columns = const []; 17 | List> _rows = >[]; 18 | int _rowIndex = -1; 19 | 20 | /// Constructs an empty cursor. 21 | MatrixCursor.empty(); 22 | 23 | /// Constructs a cursor from the provided column/row data. 24 | MatrixCursor.from( 25 | {@required List columns, @required List> rows}) 26 | : assert(columns != null), 27 | assert(rows != null), 28 | _columns = List.unmodifiable(columns), 29 | _rows = rows; 30 | 31 | @override 32 | Future close() { 33 | _isClosed = true; 34 | _columns = null; 35 | _rows = null; 36 | _rowIndex = -1; 37 | return Future.value(); 38 | } 39 | 40 | @override 41 | dynamic get(final int columnIndex) { 42 | assert(!_isClosed); 43 | if (_rowIndex < 0 || _rowIndex >= _rows?.length ?? 0) { 44 | throw CursorIndexOutOfBoundsException(_rowIndex, _rows.length); 45 | } 46 | if (columnIndex < 0 || columnIndex >= _columns?.length ?? 0) { 47 | throw CursorIndexOutOfBoundsException(columnIndex, _columns.length); 48 | } 49 | assert(_rows != null); 50 | return _rows[_rowIndex][columnIndex]; 51 | } 52 | 53 | @override 54 | List getColumnNames() => _columns ?? []; 55 | 56 | @override 57 | int getCount() => _rows?.length ?? 0; 58 | 59 | @override 60 | int getPosition() => _rowIndex; 61 | 62 | @override 63 | bool get isClosed => _isClosed; 64 | 65 | @override 66 | bool moveToPosition(final int position) { 67 | assert(!_isClosed); 68 | if (position >= -1 && position <= _rows?.length ?? 0) { 69 | _rowIndex = position; 70 | return true; // request accepted 71 | } 72 | return false; // request rejected 73 | } 74 | 75 | /// Adds a new row to the end with the given column values. 76 | /// 77 | /// See: https://developer.android.com/reference/android/database/MatrixCursor#addRow(java.lang.Object[]) 78 | void addRow(final List columnValues) { 79 | assert(!_isClosed); 80 | if (columnValues.length != _columns?.length ?? 0) { 81 | throw ArgumentError(); 82 | } 83 | assert(_rows != null); 84 | _rows.add(columnValues); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /example/lib/demo_tab.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'dart:async'; 4 | import 'package:flutter/material.dart'; 5 | 6 | import 'demos/bluetooth_scanner.dart' show BluetoothScannerDemo; 7 | import 'demos/face_detector.dart' show FaceDetectorDemo; 8 | import 'demos/heartrate_monitor.dart' show HeartrateMonitorDemo; 9 | 10 | //////////////////////////////////////////////////////////////////////////////// 11 | 12 | class DemoDescription { 13 | final String title; 14 | final String subtitle; 15 | final WidgetBuilder widget; 16 | 17 | const DemoDescription({this.title, this.subtitle, this.widget}); 18 | } 19 | 20 | //////////////////////////////////////////////////////////////////////////////// 21 | 22 | final Map demos = { 23 | 'bluetooth_scanner': DemoDescription( 24 | title: "Bluetooth scanning", 25 | subtitle: "Using android_bluetooth.BluetoothLeScanner.", 26 | widget: (context) => BluetoothScannerDemo(), 27 | ), 28 | 'face_detector': DemoDescription( 29 | title: "Face detection", 30 | subtitle: "Using android_media.FaceDetector.", 31 | widget: (context) => FaceDetectorDemo(), 32 | ), 33 | 'heartrate_monitor': DemoDescription( 34 | title: "Heart-rate monitoring", 35 | subtitle: "Using android_hardware.SensorManager.", 36 | widget: (context) => HeartrateMonitorDemo(), 37 | ), 38 | }; 39 | 40 | //////////////////////////////////////////////////////////////////////////////// 41 | 42 | class DemoTab extends StatefulWidget { 43 | @override 44 | State createState() => _DemoTabState(); 45 | } 46 | 47 | //////////////////////////////////////////////////////////////////////////////// 48 | 49 | class _DemoTabState extends State { 50 | @override 51 | void initState() { 52 | super.initState(); 53 | _initPlatformState(); 54 | } 55 | 56 | @override 57 | Widget build(final BuildContext context) { 58 | final demoKeys = demos.keys.toList(); 59 | return ListView.separated( 60 | padding: EdgeInsets.all(8.0), 61 | itemCount: demoKeys.length, 62 | itemBuilder: (final BuildContext context, final int index) { 63 | final demoKey = demoKeys[index]; 64 | final demo = demos[demoKey]; 65 | return GestureDetector( 66 | onTap: () { 67 | Navigator.of(context).push(MaterialPageRoute( 68 | builder: demo.widget, 69 | )); 70 | }, 71 | child: ListTile( 72 | leading: Icon(Icons.play_circle_outline), 73 | title: Text(demo.title), 74 | subtitle: Text(demo.subtitle), 75 | ), 76 | ); 77 | }, 78 | separatorBuilder: (final BuildContext context, final int index) { 79 | return Divider(); 80 | }, 81 | ); 82 | } 83 | 84 | Future _initPlatformState() async { 85 | // TODO 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /lib/src/media/face.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import '../graphics/pointf.dart' show PointF; 4 | 5 | /// A [Face] contains all the information identifying the location of a face in 6 | /// a bitmap. 7 | /// 8 | /// See: https://developer.android.com/reference/android/media/FaceDetector.Face 9 | class Face { 10 | /// The minimum confidence factor of good face recognition. 11 | /// 12 | /// See: https://developer.android.com/reference/android/media/FaceDetector.Face#CONFIDENCE_THRESHOLD 13 | static const double CONFIDENCE_THRESHOLD = 0.4; 14 | 15 | /// The X-axis Euler angle of a face. 16 | /// 17 | /// See: https://developer.android.com/reference/android/media/FaceDetector.Face#EULER_X 18 | static const int EULER_X = 0; 19 | 20 | /// The Y-axis Euler angle of a face. 21 | /// 22 | /// See: https://developer.android.com/reference/android/media/FaceDetector.Face#EULER_Y 23 | static const int EULER_Y = 1; 24 | 25 | /// The Z-axis Euler angle of a face. 26 | /// 27 | /// See: https://developer.android.com/reference/android/media/FaceDetector.Face#EULER_Z 28 | static const int EULER_Z = 2; 29 | 30 | /// A confidence factor between 0 and 1. 31 | /// 32 | /// This indicates how certain what has been found is actually a face. 33 | /// A confidence factor above 0.3 is usually good enough. 34 | /// 35 | /// See: https://developer.android.com/reference/android/media/FaceDetector.Face#confidence() 36 | final double confidence; 37 | 38 | /// The distance between the eyes. 39 | /// 40 | /// See: https://developer.android.com/reference/android/media/FaceDetector.Face#eyesDistance() 41 | final double eyesDistance; 42 | 43 | /// The position of the mid-point between the eyes. 44 | /// 45 | /// See: https://developer.android.com/reference/android/media/FaceDetector.Face#getMidPoint(android.graphics.PointF) 46 | final PointF midPoint; 47 | 48 | /// The Euler angle of the face, around the X axis. 49 | final double poseX; 50 | 51 | /// The Euler angle of the face, around the Y axis. 52 | final double poseY; 53 | 54 | /// The Euler angle of the face, around the Z axis. 55 | final double poseZ; 56 | 57 | Face({ 58 | this.confidence, 59 | this.eyesDistance, 60 | this.midPoint, 61 | this.poseX, 62 | this.poseY, 63 | this.poseZ, 64 | }); 65 | 66 | /// Returns the face's pose. That is, the rotations around either the X, Y or 67 | /// Z axis (the positions in 3-dimensional Euclidean space). 68 | /// 69 | /// See: https://developer.android.com/reference/android/media/FaceDetector.Face#pose(int) 70 | double pose(final int euler) { 71 | switch (euler) { 72 | case EULER_X: 73 | return poseX; 74 | case EULER_Y: 75 | return poseY; 76 | case EULER_Z: 77 | return poseZ; 78 | default: 79 | assert(false, "unreachable"); 80 | return null; // unreachable 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /example/lib/demos/face_detector.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'package:flutter/material.dart'; 4 | 5 | import 'package:flutter_android/android_graphics.dart' show Bitmap; 6 | import 'package:flutter_android/android_media.dart' show Face, FaceDetector; 7 | 8 | //////////////////////////////////////////////////////////////////////////////// 9 | 10 | class FaceDetectorDemo extends StatefulWidget { 11 | @override 12 | State createState() => _FaceDetectorState(); 13 | } 14 | 15 | //////////////////////////////////////////////////////////////////////////////// 16 | 17 | class _FaceDetectorState extends State { 18 | static const photo = AssetImage('images/einstein.png'); 19 | 20 | final Image _image = Image(image: photo); 21 | FaceDetector _detector; 22 | List _faces = []; 23 | 24 | @override 25 | void initState() { 26 | super.initState(); 27 | _initPlatformState(); 28 | } 29 | 30 | @override 31 | Widget build(final BuildContext context) { 32 | return Scaffold( 33 | appBar: AppBar( 34 | title: Text("Face Detector"), 35 | ), 36 | body: Center( 37 | child: CustomPaint( 38 | child: _image, 39 | foregroundPainter: _FaceDetectorPainter(faces: _faces), 40 | ), 41 | ), 42 | ); 43 | } 44 | 45 | Future _initPlatformState() async { 46 | _detector = FaceDetector(width: 280, height: 396, maxFaces: 1); 47 | final faces = await _detector.findFaces(Bitmap.fromAssetImage(photo)); 48 | setState(() { 49 | _faces = faces; 50 | }); 51 | } 52 | } 53 | 54 | //////////////////////////////////////////////////////////////////////////////// 55 | 56 | class _FaceDetectorPainter extends CustomPainter { 57 | final List faces; 58 | 59 | _FaceDetectorPainter({this.faces}); 60 | 61 | @override 62 | void paint(final Canvas canvas, final Size size) { 63 | const eyeRadius = 12.0; 64 | final line = Paint() 65 | ..color = Colors.blue 66 | ..strokeCap = StrokeCap.round 67 | ..style = PaintingStyle.stroke 68 | ..strokeWidth = 2; 69 | 70 | for (final face in faces) { 71 | if (face.confidence < Face.CONFIDENCE_THRESHOLD) continue; 72 | 73 | final midPoint = Offset(face.midPoint.x, face.midPoint.y); 74 | final leftEye = midPoint.translate(-(face.eyesDistance / 2), 0); 75 | final rightEye = midPoint.translate((face.eyesDistance / 2), 0); 76 | final noseBridge = Path() 77 | ..moveTo(leftEye.dx + eyeRadius, leftEye.dy) 78 | ..quadraticBezierTo(midPoint.dx, midPoint.dy - eyeRadius, 79 | rightEye.dx - eyeRadius, rightEye.dy); 80 | canvas.drawCircle(leftEye, eyeRadius, line); 81 | canvas.drawCircle(rightEye, eyeRadius, line); 82 | canvas.drawPath(noseBridge, line); 83 | } 84 | } 85 | 86 | @override 87 | bool shouldRepaint(_FaceDetectorPainter oldDelegate) => false; 88 | } 89 | -------------------------------------------------------------------------------- /android/src/main/java/com/github/drydart/flutter_android/FlutterAndroidPlugin.java: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | package com.github.drydart.flutter_android; 4 | 5 | import androidx.annotation.NonNull; 6 | 7 | import io.flutter.embedding.engine.plugins.FlutterPlugin; 8 | import io.flutter.plugin.common.BinaryMessenger; 9 | import io.flutter.plugin.common.MethodCall; 10 | import io.flutter.plugin.common.MethodChannel; 11 | import io.flutter.plugin.common.MethodChannel.MethodCallHandler; 12 | import io.flutter.plugin.common.MethodChannel.Result; 13 | 14 | /** FlutterAndroidPlugin */ 15 | public class FlutterAndroidPlugin implements FlutterPlugin { 16 | 17 | /** Plugin registration. */ 18 | @Override 19 | public void onAttachedToEngine(final @NonNull FlutterPlugin.FlutterPluginBinding binding) { 20 | assert(binding != null); 21 | 22 | final BinaryMessenger messenger = binding.getBinaryMessenger(); 23 | assert(messenger != null); 24 | 25 | (new MethodChannel(messenger, ActivityManagerHandler.CHANNEL)) 26 | .setMethodCallHandler(new ActivityManagerHandler(binding)); 27 | 28 | (new MethodChannel(messenger, AndroidHandler.CHANNEL)) 29 | .setMethodCallHandler(new AndroidHandler(binding)); 30 | 31 | (new MethodChannel(messenger, BluetoothAdapterHandler.CHANNEL)) 32 | .setMethodCallHandler(new BluetoothAdapterHandler(binding)); 33 | 34 | (new MethodChannel(messenger, BluetoothDeviceHandler.CHANNEL)) 35 | .setMethodCallHandler(new BluetoothDeviceHandler(binding)); 36 | 37 | (new MethodChannel(messenger, BluetoothHeadsetHandler.CHANNEL)) 38 | .setMethodCallHandler(new BluetoothHeadsetHandler(binding)); 39 | 40 | (new MethodChannel(messenger, BluetoothLeScannerHandler.CHANNEL)) 41 | .setMethodCallHandler(new BluetoothLeScannerHandler(binding)); 42 | 43 | (new MethodChannel(messenger, BluetoothManagerHandler.CHANNEL)) 44 | .setMethodCallHandler(new BluetoothManagerHandler(binding)); 45 | 46 | (new MethodChannel(messenger, ContextHandler.CHANNEL)) 47 | .setMethodCallHandler(new ContextHandler(binding)); 48 | 49 | (new MethodChannel(messenger, EnvironmentHandler.CHANNEL)) 50 | .setMethodCallHandler(new EnvironmentHandler(binding)); 51 | 52 | (new MethodChannel(messenger, FaceDetectorHandler.CHANNEL)) 53 | .setMethodCallHandler(new FaceDetectorHandler(binding)); 54 | 55 | (new MethodChannel(messenger, IntentHandler.CHANNEL)) 56 | .setMethodCallHandler(new IntentHandler(binding)); 57 | 58 | (new MethodChannel(messenger, LocationHandler.CHANNEL)) 59 | .setMethodCallHandler(new LocationHandler(binding)); 60 | 61 | (new MethodChannel(messenger, SensorManagerHandler.CHANNEL)) 62 | .setMethodCallHandler(new SensorManagerHandler(binding)); 63 | 64 | (new MethodChannel(messenger, SharedPreferencesHandler.CHANNEL)) 65 | .setMethodCallHandler(new SharedPreferencesHandler(binding)); 66 | } 67 | 68 | @Override 69 | public void onDetachedFromEngine(final @NonNull FlutterPlugin.FlutterPluginBinding binding) { 70 | assert(binding != null); 71 | 72 | // TODO: channel.setMethodCallHandler(null); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /lib/src/app/notification_action.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'package:flutter/widgets.dart' show Icon; 4 | 5 | import 'pending_intent.dart' show PendingIntent; 6 | 7 | /// Structure to encapsulate a named action that can be shown as part of a 8 | /// notification. 9 | /// 10 | /// It must include an icon, a label, and a [PendingIntent] to be fired when the 11 | /// action is selected by the user. 12 | /// 13 | /// See: https://developer.android.com/reference/android/app/Notification.Action 14 | class NotificationAction { 15 | /// See: https://developer.android.com/reference/android/app/Notification.Action#SEMANTIC_ACTION_ARCHIVE 16 | static const int SEMANTIC_ACTION_ARCHIVE = 5; 17 | 18 | /// See: https://developer.android.com/reference/android/app/Notification.Action#SEMANTIC_ACTION_CALL 19 | static const int SEMANTIC_ACTION_CALL = 10; 20 | 21 | /// See: https://developer.android.com/reference/android/app/Notification.Action#SEMANTIC_ACTION_DELETE 22 | static const int SEMANTIC_ACTION_DELETE = 4; 23 | 24 | /// See: https://developer.android.com/reference/android/app/Notification.Action#SEMANTIC_ACTION_MARK_AS_READ 25 | static const int SEMANTIC_ACTION_MARK_AS_READ = 2; 26 | 27 | /// See: https://developer.android.com/reference/android/app/Notification.Action#SEMANTIC_ACTION_MARK_AS_UNREAD 28 | static const int SEMANTIC_ACTION_MARK_AS_UNREAD = 3; 29 | 30 | /// See: https://developer.android.com/reference/android/app/Notification.Action#SEMANTIC_ACTION_MUTE 31 | static const int SEMANTIC_ACTION_MUTE = 6; 32 | 33 | /// See: https://developer.android.com/reference/android/app/Notification.Action#SEMANTIC_ACTION_NONE 34 | static const int SEMANTIC_ACTION_NONE = 0; 35 | 36 | /// See: https://developer.android.com/reference/android/app/Notification.Action#SEMANTIC_ACTION_REPLY 37 | static const int SEMANTIC_ACTION_REPLY = 1; 38 | 39 | /// See: https://developer.android.com/reference/android/app/Notification.Action#SEMANTIC_ACTION_THUMBS_DOWN 40 | static const int SEMANTIC_ACTION_THUMBS_DOWN = 9; 41 | 42 | /// See: https://developer.android.com/reference/android/app/Notification.Action#SEMANTIC_ACTION_THUMBS_UP 43 | static const int SEMANTIC_ACTION_THUMBS_UP = 8; 44 | 45 | /// See: https://developer.android.com/reference/android/app/Notification.Action#SEMANTIC_ACTION_UNMUTE 46 | static const int SEMANTIC_ACTION_UNMUTE = 7; 47 | 48 | /// Intent to send when the user invokes this action. 49 | /// 50 | /// May be null, in which case the action may be rendered in a disabled 51 | /// presentation by the system UI. 52 | /// 53 | /// See: https://developer.android.com/reference/android/app/Notification.Action#actionIntent 54 | final PendingIntent intent; 55 | 56 | /// Small icon representing the action. 57 | /// 58 | /// See: https://developer.android.com/reference/android/app/Notification.Action#icon 59 | final Icon icon; 60 | 61 | /// Title of the action. 62 | /// 63 | /// See: https://developer.android.com/reference/android/app/Notification.Action#title 64 | final String title; 65 | 66 | NotificationAction({ 67 | this.intent, 68 | this.icon, 69 | this.title, 70 | }); 71 | } 72 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /android/src/main/java/com/github/drydart/flutter_android/FaceDetectorHandler.java: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | package com.github.drydart.flutter_android; 4 | 5 | import android.graphics.Bitmap; 6 | import android.graphics.BitmapFactory; 7 | import android.graphics.PointF; 8 | import android.media.FaceDetector; 9 | import androidx.annotation.NonNull; 10 | 11 | import io.flutter.embedding.engine.plugins.FlutterPlugin; 12 | import io.flutter.plugin.common.MethodCall; 13 | import io.flutter.plugin.common.MethodChannel.Result; 14 | import java.io.IOException; 15 | import java.util.ArrayList; 16 | import java.util.Arrays; 17 | import java.util.List; 18 | 19 | /** FaceDetectorHandler */ 20 | @SuppressWarnings("unchecked") 21 | class FaceDetectorHandler extends FlutterMethodCallHandler { 22 | static final String CHANNEL = "flutter_android/FaceDetector"; 23 | 24 | final BitmapFactory.Options options; 25 | 26 | FaceDetectorHandler(final @NonNull FlutterPlugin.FlutterPluginBinding binding) { 27 | super(binding); 28 | options = new BitmapFactory.Options(); 29 | options.inPreferredConfig = Bitmap.Config.RGB_565; 30 | } 31 | 32 | @Override 33 | public void onMethodCall(final MethodCall call, final Result result) { 34 | assert(call != null); 35 | assert(result != null); 36 | 37 | assert(call.method != null); 38 | switch (call.method) { 39 | 40 | case "findFaces": { 41 | final int width = getRequiredArgument(call, "width"); 42 | final int height = getRequiredArgument(call, "height"); 43 | final int maxFaces = getRequiredArgument(call, "maxFaces"); 44 | final String bitmapName = getRequiredArgument(call, "bitmapName"); 45 | try { 46 | final Bitmap bitmap = loadBitmap(bitmapName, options); 47 | assert(bitmap != null); 48 | assert(bitmap.getWidth() == width); 49 | assert(bitmap.getHeight() == height); 50 | 51 | final FaceDetector.Face[] faces = findFaces(width, height, maxFaces, bitmap); 52 | 53 | final PointF midPoint = new PointF(); 54 | final List> response = new ArrayList(faces.length); 55 | for (final FaceDetector.Face face : faces) { 56 | face.getMidPoint(midPoint); 57 | response.add(Arrays.asList( 58 | (double)face.confidence(), 59 | (double)midPoint.x, 60 | (double)midPoint.y, 61 | (double)face.eyesDistance(), 62 | (double)face.pose(FaceDetector.Face.EULER_X), 63 | (double)face.pose(FaceDetector.Face.EULER_Y), 64 | (double)face.pose(FaceDetector.Face.EULER_Z) 65 | )); 66 | } 67 | result.success(response); 68 | } 69 | catch (final IOException error) { 70 | result.error("IOException", error.getMessage(), error.toString()); 71 | } 72 | break; 73 | } 74 | default: { 75 | result.notImplemented(); 76 | } 77 | } 78 | } 79 | 80 | FaceDetector.Face[] 81 | findFaces(final int width, 82 | final int height, 83 | final int maxFaces, 84 | final Bitmap bitmap) { 85 | 86 | final FaceDetector.Face[] faces = new FaceDetector.Face[maxFaces]; 87 | final FaceDetector detector = new FaceDetector(width, height, maxFaces); 88 | final int foundFaces = detector.findFaces(bitmap, faces); 89 | return Arrays.copyOf(faces, foundFaces); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /lib/src/content/intent.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'dart:async' show Future; 4 | import 'dart:io' show Platform; 5 | 6 | import 'package:flutter/services.dart' show MethodChannel; 7 | 8 | import '../os/bundle.dart' show Bundle; 9 | import '../os/parcel.dart' show Parcel; 10 | import '../os/parcelable.dart' show Parcelable; 11 | import 'component_name.dart'; 12 | 13 | /// An intent is an abstract description of an operation to be performed. 14 | /// 15 | /// An [Intent] provides a facility for performing late runtime binding between 16 | /// the code in different applications. Its most significant use is in the 17 | /// launching of activities, where it can be thought of as the glue between 18 | /// activities. It is basically a passive data structure holding an abstract 19 | /// description of an action to be performed. 20 | /// 21 | /// See: https://developer.android.com/reference/android/content/Intent 22 | /// See: https://github.com/aosp-mirror/platform_frameworks_base/blob/master/core/java/android/content/Intent.java 23 | class Intent with Parcelable { 24 | static const MethodChannel _channel = MethodChannel('flutter_android/Intent'); 25 | 26 | /// The general action to be performed. 27 | final String action; 28 | 29 | /// The data to operate on, such as a person record in the contacts database. 30 | final Uri data; 31 | 32 | /// Gives additional information about the action to execute. 33 | final List categories; 34 | 35 | /// Specifies an explicit type (a MIME type) of the intent data. 36 | final String type; 37 | 38 | /// Specifies an explicit name of a component class to use for the intent. 39 | final ComponentName component; 40 | 41 | /// This is a [Bundle] of any additional information. 42 | final Bundle extras; 43 | 44 | /// Flags used on this [Intent]. 45 | /// 46 | /// See: https://developer.android.com/reference/android/content/Intent#flags 47 | final int flags; 48 | 49 | /// Specifies the application package name this intent is limited to. 50 | final String package; 51 | 52 | Intent({ 53 | this.action, 54 | this.data, 55 | this.categories, 56 | this.type, 57 | this.component, 58 | this.extras, 59 | this.flags, 60 | this.package, 61 | }); 62 | 63 | /// Gives additional information about the action to execute. 64 | /// 65 | /// If this intent has multiple categories, returns the first of them. 66 | String get category => categories.isNotEmpty ? categories.first : null; 67 | 68 | /// Launches a new activity. 69 | /// 70 | /// See: https://developer.android.com/reference/android/content/Context#startActivity(android.content.Intent) 71 | Future startActivity() async { 72 | assert(Platform.isAndroid); 73 | final request = { 74 | 'action': action, 75 | 'data': data?.toString(), 76 | 'categories': categories, 77 | 'type': type, 78 | 'component': component?.flattenToString(), 79 | 'extras': extras?.mappings, 80 | 'flags': flags, 81 | 'package': package, 82 | }; 83 | return await _channel.invokeMethod('startActivity', request) as bool; 84 | } 85 | 86 | @override 87 | String get parcelableCreator => "android.content.Intent"; 88 | 89 | @override 90 | void writeToParcel(final Parcel parcel, [final int flags = 0]) { 91 | throw UnimplementedError(); // TODO: https://github.com/aosp-mirror/platform_frameworks_base/blob/master/core/java/android/content/Intent.java#L10650 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /test/android_content_test.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'package:flutter_test/flutter_test.dart'; 4 | 5 | import 'package:flutter_android/android_app.dart'; 6 | import 'package:flutter_android/android_content.dart' show Context; 7 | import 'package:flutter_android/android_os.dart'; 8 | 9 | void main() { 10 | group('android_content', () { 11 | test("Context.getSystemService('') returns null", () { 12 | expect(Context.getSystemService(''), equals(null)); 13 | }); 14 | test( 15 | "Context.getSystemService(Context.ACTIVITY_SERVICE) returns a ActivityManager", 16 | () { 17 | expect(Context.getSystemService(Context.ACTIVITY_SERVICE), 18 | isInstanceOf()); 19 | }); 20 | test( 21 | "Context.getSystemService(Context.ALARM_SERVICE) returns a AlarmManager", 22 | () { 23 | expect(Context.getSystemService(Context.ALARM_SERVICE), 24 | isInstanceOf()); 25 | }); 26 | test( 27 | "Context.getSystemService(Context.BATTERY_SERVICE) returns a BatteryManager", 28 | () { 29 | expect(Context.getSystemService(Context.BATTERY_SERVICE), 30 | isInstanceOf()); 31 | }); 32 | test( 33 | "Context.getSystemService(Context.DOWNLOAD_SERVICE) returns a DownloadManager", 34 | () { 35 | expect(Context.getSystemService(Context.DOWNLOAD_SERVICE), 36 | isInstanceOf()); 37 | }); 38 | test( 39 | "Context.getSystemService(Context.HARDWARE_PROPERTIES_SERVICE) returns a HardwarePropertiesManager", 40 | () { 41 | expect(Context.getSystemService(Context.HARDWARE_PROPERTIES_SERVICE), 42 | isInstanceOf()); 43 | }); 44 | test( 45 | "Context.getSystemService(Context.KEYGUARD_SERVICE) returns a KeyguardManager", 46 | () { 47 | expect(Context.getSystemService(Context.KEYGUARD_SERVICE), 48 | isInstanceOf()); 49 | }); 50 | test( 51 | "Context.getSystemService(Context.NOTIFICATION_SERVICE) returns a NotificationManager", 52 | () { 53 | expect(Context.getSystemService(Context.NOTIFICATION_SERVICE), 54 | isInstanceOf()); 55 | }); 56 | test( 57 | "Context.getSystemService(Context.POWER_SERVICE) returns a PowerManager", 58 | () { 59 | expect(Context.getSystemService(Context.POWER_SERVICE), 60 | isInstanceOf()); 61 | }); 62 | test( 63 | "Context.getSystemService(Context.SEARCH_SERVICE) returns a SearchManager", 64 | () { 65 | expect(Context.getSystemService(Context.SEARCH_SERVICE), 66 | isInstanceOf()); 67 | }); 68 | test("Context.getSystemService(Context.USER_SERVICE) returns a UserManager", 69 | () { 70 | expect(Context.getSystemService(Context.USER_SERVICE), 71 | isInstanceOf()); 72 | }); 73 | test( 74 | "Context.getSystemService(Context.VIBRATOR_SERVICE) returns a Vibrator", 75 | () { 76 | expect(Context.getSystemService(Context.VIBRATOR_SERVICE), 77 | isInstanceOf()); 78 | }); 79 | test( 80 | "Context.getSystemService(Context.WALLPAPER_SERVICE) returns a WallpaperManager", 81 | () { 82 | expect(Context.getSystemService(Context.WALLPAPER_SERVICE), 83 | isInstanceOf()); 84 | }); 85 | }); 86 | } 87 | -------------------------------------------------------------------------------- /lib/src/os/bundle.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'parcel.dart' show Parcel; 4 | import 'parcelable.dart' show Parcelable; 5 | 6 | /// A mapping from [String] keys to various [Parcelable] values. 7 | /// 8 | /// See: https://developer.android.com/reference/android/os/Bundle 9 | /// See: https://github.com/aosp-mirror/platform_frameworks_base/blob/master/core/java/android/os/Bundle.java 10 | class Bundle with Parcelable { 11 | /// The canonical empty bundle. 12 | /// 13 | /// See: https://developer.android.com/reference/android/os/Bundle#EMPTY 14 | /// 15 | // ignore: non_constant_identifier_names 16 | static final Bundle EMPTY = Bundle(); 17 | 18 | /// See: https://developer.android.com/reference/android/os/Bundle#CREATOR 19 | //static const Parcelable.Creator CREATOR = null; // TODO 20 | 21 | final Map mappings = Map.identity(); 22 | 23 | /// Constructs a new, empty [Bundle]. 24 | /// 25 | /// See: https://developer.android.com/reference/android/os/Bundle#Bundle() 26 | Bundle(); 27 | 28 | /// Returns whether the mapping of this [Bundle] is empty. 29 | /// 30 | /// See: https://developer.android.com/reference/android/os/BaseBundle#isEmpty() 31 | bool get isEmpty => mappings.isEmpty; 32 | 33 | /// Reports whether the bundle contains any parcelled file descriptors. 34 | /// 35 | /// See: https://developer.android.com/reference/android/os/Bundle#hasFileDescriptors() 36 | bool get hasFileDescriptors => false; 37 | 38 | /// Returns the number of mappings contained in this [Bundle]. 39 | /// 40 | /// See: https://developer.android.com/reference/android/os/BaseBundle#size() 41 | int get size => mappings.length; 42 | 43 | /// Removes all elements from the mapping of this [Bundle]. 44 | /// 45 | /// See: https://developer.android.com/reference/android/os/Bundle#clear() 46 | void clear() => mappings.clear(); 47 | 48 | /// Removes any entry with the given key from the mapping of this [Bundle]. 49 | /// 50 | /// See: https://developer.android.com/reference/android/os/Bundle#remove(java.lang.String) 51 | void remove(final String key) => mappings.remove(key); 52 | 53 | /// Returns whether the given key is contained in the mapping of this [Bundle]. 54 | /// 55 | /// See: https://developer.android.com/reference/android/os/BaseBundle#containsKey(java.lang.String) 56 | bool containsKey(final String key) => mappings.containsKey(key); 57 | 58 | /// Returns the entry with the given key as an object. 59 | /// 60 | /// See: https://developer.android.com/reference/android/os/BaseBundle#get(java.lang.String) 61 | dynamic get(final String key) => mappings[key]; 62 | 63 | /// Returns the entry with the given key. 64 | /// 65 | /// See: https://developer.android.com/reference/android/os/BaseBundle#getString(java.lang.String) 66 | String getString(final String key) => get(key); 67 | 68 | /// Inserts a string value into the mapping of this [Bundle], replacing any 69 | /// existing value for the given key. 70 | /// 71 | /// See: https://developer.android.com/reference/android/os/BaseBundle#putString(java.lang.String,%20java.lang.String) 72 | void putString(final String key, final String value) => mappings[key] = value; 73 | 74 | @override 75 | String get parcelableCreator => "android.os.Bundle"; 76 | 77 | @override 78 | void writeToParcel(final Parcel parcel, [final int flags = 0]) { 79 | throw UnimplementedError(); // TODO: https://github.com/aosp-mirror/platform_frameworks_base/blob/master/core/java/android/os/BaseBundle.java#L1556 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /lib/src/os/power_manager.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | /// This class gives you control of the power state of the device. 4 | /// 5 | /// See: https://developer.android.com/reference/android/os/PowerManager 6 | class PowerManager { 7 | /// Wake lock level: Ensures that the CPU is running; the screen and keyboard backlight will be allowed to go off. 8 | /// 9 | /// See: https://developer.android.com/reference/android/os/PowerManager#PARTIAL_WAKE_LOCK 10 | static const int PARTIAL_WAKE_LOCK = 1; 11 | 12 | /// Wake lock level: Turns the screen off when the proximity sensor activates. 13 | /// 14 | /// See: https://developer.android.com/reference/android/os/PowerManager#PROXIMITY_SCREEN_OFF_WAKE_LOCK 15 | static const int PROXIMITY_SCREEN_OFF_WAKE_LOCK = 32; 16 | 17 | /// Wake lock flag: Turn the screen on when the wake lock is acquired. 18 | /// 19 | /// See: https://developer.android.com/reference/android/os/PowerManager#ACQUIRE_CAUSES_WAKEUP 20 | static const int ACQUIRE_CAUSES_WAKEUP = 268435456; 21 | 22 | /// Wake lock flag: When this wake lock is released, poke the user activity timer so the screen stays on for a little longer. 23 | /// 24 | /// See: https://developer.android.com/reference/android/os/PowerManager#ON_AFTER_RELEASE 25 | static const int ON_AFTER_RELEASE = 536870912; 26 | 27 | /// Flag for `WakeLock#release WakeLock.release(int)`: Defer releasing a `PROXIMITY_SCREEN_OFF_WAKE_LOCK` wake lock until the proximity sensor indicates that an object is not in close proximity. 28 | /// 29 | /// See: https://developer.android.com/reference/android/os/PowerManager#RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY 30 | static const int RELEASE_FLAG_WAIT_FOR_NO_PROXIMITY = 1; 31 | 32 | /// Either the location providers shouldn't be affected by battery saver, or battery saver is off. 33 | /// 34 | /// See: https://developer.android.com/reference/android/os/PowerManager#LOCATION_MODE_NO_CHANGE 35 | static const int LOCATION_MODE_NO_CHANGE = 0; 36 | 37 | /// In this mode, the GPS based location provider should be disabled when battery saver is on and the device is non-interactive. 38 | /// 39 | /// See: https://developer.android.com/reference/android/os/PowerManager#LOCATION_MODE_GPS_DISABLED_WHEN_SCREEN_OFF 40 | static const int LOCATION_MODE_GPS_DISABLED_WHEN_SCREEN_OFF = 1; 41 | 42 | /// All location providers should be disabled when battery saver is on and the device is non-interactive. 43 | /// 44 | /// See: https://developer.android.com/reference/android/os/PowerManager#LOCATION_MODE_ALL_DISABLED_WHEN_SCREEN_OFF 45 | static const int LOCATION_MODE_ALL_DISABLED_WHEN_SCREEN_OFF = 2; 46 | 47 | /// In this mode, all the location providers will be kept available, but location fixes should only be provided to foreground apps. 48 | /// 49 | /// See: https://developer.android.com/reference/android/os/PowerManager#LOCATION_MODE_FOREGROUND_ONLY 50 | static const int LOCATION_MODE_FOREGROUND_ONLY = 3; 51 | 52 | /// Intent that is broadcast when the state of `isPowerSaveMode()` changes. 53 | /// 54 | /// See: https://developer.android.com/reference/android/os/PowerManager#ACTION_POWER_SAVE_MODE_CHANGED 55 | static const String ACTION_POWER_SAVE_MODE_CHANGED = 56 | "android.os.action.POWER_SAVE_MODE_CHANGED"; 57 | 58 | /// Intent that is broadcast when the state of `isDeviceIdleMode()` changes. 59 | /// 60 | /// See: https://developer.android.com/reference/android/os/PowerManager#ACTION_DEVICE_IDLE_MODE_CHANGED 61 | static const String ACTION_DEVICE_IDLE_MODE_CHANGED = 62 | "android.os.action.DEVICE_IDLE_MODE_CHANGED"; 63 | } 64 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /android/src/main/java/com/github/drydart/flutter_android/IntentHandler.java: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | package com.github.drydart.flutter_android; 4 | 5 | import android.content.ActivityNotFoundException; 6 | import android.content.ComponentName; 7 | import android.content.Context; 8 | import android.content.Intent; 9 | import android.net.Uri; 10 | import androidx.annotation.NonNull; 11 | import java.io.Serializable; 12 | import java.util.List; 13 | import java.util.Map; 14 | 15 | import io.flutter.embedding.engine.plugins.FlutterPlugin; 16 | import io.flutter.plugin.common.MethodCall; 17 | import io.flutter.plugin.common.MethodChannel.Result; 18 | 19 | /** IntentHandler */ 20 | class IntentHandler extends FlutterMethodCallHandler { 21 | static final String CHANNEL = "flutter_android/Intent"; 22 | 23 | IntentHandler(final @NonNull FlutterPlugin.FlutterPluginBinding binding) { 24 | super(binding); 25 | } 26 | 27 | @Override 28 | public void onMethodCall(final MethodCall call, final Result result) { 29 | assert(call != null); 30 | assert(result != null); 31 | 32 | final Context context = this.binding.getApplicationContext(); 33 | assert(context != null); 34 | 35 | assert(call.method != null); 36 | switch (call.method) { 37 | case "startActivity": { 38 | final String action = getOptionalArgument(call, "action"); 39 | final String data = getOptionalArgument(call, "data"); 40 | final List categories = getOptionalArgument(call, "categories"); 41 | final String type = getOptionalArgument(call, "type"); 42 | final String component = getOptionalArgument(call, "component"); 43 | final Map extras = getOptionalArgument(call, "extras"); 44 | final Integer flags = getOptionalArgument(call, "flags"); 45 | final String packageName = getOptionalArgument(call, "package"); 46 | 47 | final Intent intent = new Intent(); 48 | if (action != null && !action.isEmpty()) { 49 | intent.setAction(action); 50 | } 51 | if (data != null && type != null) { 52 | intent.setDataAndTypeAndNormalize(Uri.parse(data), type); 53 | } 54 | else if (data != null && type == null) { 55 | intent.setDataAndNormalize(Uri.parse(data)); 56 | } 57 | else if (data == null && type != null) { 58 | intent.setTypeAndNormalize(type); 59 | } 60 | if (categories != null) { 61 | for (final String category : categories) { 62 | if (!category.isEmpty()) { 63 | intent.addCategory(category); 64 | } 65 | } 66 | } 67 | if (component != null && !component.isEmpty()) { 68 | intent.setComponent(ComponentName.unflattenFromString(component)); 69 | } 70 | if (extras != null) { 71 | for (Map.Entry entry : extras.entrySet()) { 72 | if (entry.getValue() instanceof Serializable) { 73 | intent.putExtra(entry.getKey(), (Serializable)entry.getValue()); 74 | } 75 | } 76 | } 77 | if (flags != null) { 78 | intent.addFlags(flags); 79 | } 80 | if (packageName != null && !packageName.isEmpty()) { 81 | intent.setPackage(packageName); 82 | } 83 | try { 84 | context.startActivity(intent); 85 | result.success(true); 86 | } 87 | catch (final ActivityNotFoundException error) { 88 | result.success(false); 89 | } 90 | break; 91 | } 92 | default: { 93 | result.notImplemented(); 94 | } 95 | } 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /android/src/main/java/com/github/drydart/flutter_android/SensorManagerHandler.java: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | package com.github.drydart.flutter_android; 4 | 5 | import android.content.Context; 6 | import android.hardware.Sensor; 7 | import android.hardware.SensorManager; 8 | import androidx.annotation.NonNull; 9 | 10 | import io.flutter.embedding.engine.plugins.FlutterPlugin; 11 | import io.flutter.plugin.common.EventChannel; 12 | import io.flutter.plugin.common.MethodCall; 13 | import io.flutter.plugin.common.MethodChannel.Result; 14 | import java.util.HashMap; 15 | import java.util.Map; 16 | 17 | /** SensorManagerHandler */ 18 | @SuppressWarnings("unchecked") 19 | class SensorManagerHandler extends FlutterMethodCallHandler { 20 | static final String CHANNEL = "flutter_android/SensorManager"; 21 | 22 | private final Map sensors = new HashMap<>(); 23 | private final Map channels = new HashMap<>(); 24 | 25 | SensorManagerHandler(final @NonNull FlutterPlugin.FlutterPluginBinding binding) { 26 | super(binding); 27 | } 28 | 29 | @Override 30 | public void onMethodCall(final MethodCall call, final Result result) { 31 | assert(call != null); 32 | assert(result != null); 33 | 34 | assert(call.method != null); 35 | switch (call.method) { 36 | /* Static methods */ 37 | 38 | case "getDefaultSensor": { 39 | final int sensorType = getRequiredArgument(call, "type"); 40 | final int sensorKey = sensorType; // for now 41 | if (this.sensors.containsKey(sensorKey)) { 42 | result.success(sensorKey); 43 | break; 44 | } 45 | final Context context = this.binding.getApplicationContext(); 46 | final SensorManager sensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE); 47 | final Sensor sensor = sensorManager.getDefaultSensor(sensorType); 48 | if (sensor == null) { 49 | result.success(null); 50 | break; 51 | } 52 | this.sensors.put(sensorKey, sensor); 53 | result.success(sensorType); 54 | break; 55 | } 56 | 57 | /* Instance methods */ 58 | 59 | case "registerListener": { 60 | final int sensorKey = getRequiredArgument(call, "key"); 61 | if (this.channels.containsKey(sensorKey)) { 62 | final String channelID = String.valueOf(sensorKey); 63 | result.success(channelID); // already registered 64 | break; 65 | } 66 | if (!this.sensors.containsKey(sensorKey)) { 67 | result.success(null); // invalid sensor key 68 | break; 69 | } 70 | final int samplingPeriodUs = getOptionalArgument(call, "samplingPeriodUs", SensorManager.SENSOR_DELAY_NORMAL); 71 | final int maxReportLatencyUs = getOptionalArgument(call, "maxReportLatencyUs", 0); 72 | final Context context = this.binding.getApplicationContext(); 73 | final SensorManager sensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE); 74 | final Sensor sensor = this.sensors.get(sensorKey); 75 | final String channelID = String.valueOf(sensorKey); 76 | final EventChannel channel = new EventChannel(this.binding.getBinaryMessenger(), String.format("%s/%d", CHANNEL, sensorKey)); 77 | channel.setStreamHandler(new SensorEventStream(sensorManager, sensor, samplingPeriodUs, maxReportLatencyUs)); 78 | this.channels.put(sensorKey, channel); 79 | result.success(channelID); 80 | break; 81 | } 82 | 83 | case "unregisterListener": { 84 | // TODO 85 | break; 86 | } 87 | 88 | default: { 89 | result.notImplemented(); 90 | } 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /lib/src/database/database_utils.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'dart:async' show Future; 4 | import 'dart:io' show Platform; 5 | 6 | import 'cursor.dart' show Cursor; 7 | 8 | /// Static utility methods for dealing with databases and [Cursor]s. 9 | /// 10 | /// See: https://developer.android.com/reference/android/database/DatabaseUtils 11 | abstract class DatabaseUtils { 12 | /// Prints the contents of a [Cursor]'s current row to standard output. 13 | /// 14 | /// See: https://developer.android.com/reference/android/database/DatabaseUtils#dumpCurrentRow(android.database.Cursor) 15 | static Future dumpCurrentRow(final Cursor cursor) async { 16 | assert(Platform.isAndroid); 17 | 18 | print(await dumpCurrentRowToString(cursor)); 19 | } 20 | 21 | /// Prints the contents of a [Cursor]'s current row to a string. 22 | /// 23 | /// See: https://developer.android.com/reference/android/database/DatabaseUtils#dumpCurrentRowToString(android.database.Cursor) 24 | static Future dumpCurrentRowToString(final Cursor cursor) async { 25 | assert(Platform.isAndroid); 26 | 27 | final buffer = StringBuffer(); 28 | await dumpCurrentRowToStringBuffer(cursor, buffer); 29 | return buffer.toString(); 30 | } 31 | 32 | /// Prints the contents of a [Cursor]'s current row to a string buffer. 33 | /// 34 | /// See: https://developer.android.com/reference/android/database/DatabaseUtils#dumpCurrentRowToString(android.database.Cursor) 35 | static Future dumpCurrentRowToStringBuffer( 36 | final Cursor cursor, final StringBuffer buffer) async { 37 | assert(Platform.isAndroid); 38 | 39 | buffer.write("["); 40 | for (var columnIndex = 0; 41 | columnIndex < cursor.getColumnCount(); 42 | columnIndex++) { 43 | if (columnIndex > 0) buffer.write(", "); 44 | switch (cursor.getType(columnIndex)) { 45 | case Cursor.FIELD_TYPE_NULL: 46 | buffer.write("null"); 47 | break; 48 | case Cursor.FIELD_TYPE_INTEGER: 49 | buffer.write(cursor.getLong(columnIndex)); 50 | break; 51 | case Cursor.FIELD_TYPE_FLOAT: 52 | buffer.write(cursor.getDouble(columnIndex)); 53 | break; 54 | case Cursor.FIELD_TYPE_STRING: 55 | buffer.write(cursor.getString(columnIndex)); 56 | break; 57 | case Cursor.FIELD_TYPE_BLOB: 58 | buffer.write(cursor.getBlob(columnIndex)); 59 | break; 60 | default: 61 | assert(false); // unreachable 62 | throw AssertionError(); 63 | } 64 | } 65 | buffer.write("]"); 66 | } 67 | 68 | /// Prints the contents of a [Cursor] to standard output. 69 | /// 70 | /// The position is restored after printing. 71 | /// 72 | /// See: https://developer.android.com/reference/android/database/DatabaseUtils#dumpCursor(android.database.Cursor) 73 | static Future dumpCursor(final Cursor cursor) async { 74 | assert(Platform.isAndroid); 75 | 76 | final position = cursor.getPosition(); 77 | while (cursor.moveToNext()) { 78 | print(await dumpCurrentRowToString(cursor)); 79 | } 80 | cursor.moveToPosition(position); 81 | } 82 | 83 | /// Prints the contents of a [Cursor] to a string. 84 | /// 85 | /// The position is restored after printing. 86 | /// 87 | /// See: https://developer.android.com/reference/android/database/DatabaseUtils#dumpCursorToString(android.database.Cursor) 88 | static Future dumpCursorToString(final Cursor cursor) async { 89 | assert(Platform.isAndroid); 90 | 91 | final buffer = StringBuffer(); 92 | 93 | final position = cursor.getPosition(); 94 | while (cursor.moveToNext()) { 95 | await dumpCurrentRowToStringBuffer(cursor, buffer); 96 | buffer.writeln(); 97 | } 98 | cursor.moveToPosition(position); 99 | 100 | return buffer.toString(); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 29 | 34 | 41 | 45 | 49 | 54 | 58 | 59 | 60 | 61 | 62 | 63 | 65 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /lib/src/content/shared_preferences.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'dart:async' show Future; 4 | import 'dart:io' show Platform; 5 | 6 | import 'package:flutter/services.dart' show MethodChannel; 7 | 8 | /// Interface for accessing and modifying preference data. 9 | /// 10 | /// For any particular set of preferences, there is a single instance of this 11 | /// class that all clients share. 12 | /// 13 | /// See: https://developer.android.com/reference/android/content/SharedPreferences 14 | abstract class SharedPreferences { 15 | /// See [Context.getSharedPreferences]. 16 | static Future open(final String name, 17 | [final int mode = 0]) async { 18 | return _SharedPreferences(name, mode).load(); 19 | } 20 | 21 | /// Retrieves a value from the preferences. 22 | /// 23 | /// See: https://developer.android.com/reference/android/content/SharedPreferences#getBoolean(java.lang.String,%20boolean) 24 | T get(String key, [T defaultValue]); 25 | 26 | /// Checks whether the preferences contains a preference. 27 | /// 28 | /// See: https://developer.android.com/reference/android/content/SharedPreferences#contains(java.lang.String) 29 | bool contains(String key) => get(key) != null; 30 | 31 | /// Retrieves all values from the preferences. 32 | /// 33 | /// See: https://developer.android.com/reference/android/content/SharedPreferences#getAll() 34 | Map getAll(); 35 | 36 | /// Retrieves a boolean value from the preferences. 37 | /// 38 | /// See: https://developer.android.com/reference/android/content/SharedPreferences#getBoolean(java.lang.String,%20boolean) 39 | bool getBoolean(String key, [bool defaultValue]) => get(key, defaultValue); 40 | 41 | /// Retrieves a float value from the preferences. 42 | /// 43 | /// See: https://developer.android.com/reference/android/content/SharedPreferences#getFloat(java.lang.String,%20float) 44 | double getFloat(String key, [double defaultValue]) => get(key, defaultValue); 45 | 46 | /// Retrieves an int value from the preferences. 47 | /// 48 | /// See: https://developer.android.com/reference/android/content/SharedPreferences#getInt(java.lang.String,%20int) 49 | int getInt(String key, [int defaultValue]) => get(key, defaultValue); 50 | 51 | /// Retrieves a long value from the preferences. 52 | /// 53 | /// See: https://developer.android.com/reference/android/content/SharedPreferences#getLong(java.lang.String,%20long) 54 | int getLong(String key, [int defaultValue]) => get(key, defaultValue); 55 | 56 | /// Retrieves a string value from the preferences. 57 | /// 58 | /// See: https://developer.android.com/reference/android/content/SharedPreferences#getString(java.lang.String,%20java.lang.String) 59 | String getString(String key, [String defaultValue]) => get(key, defaultValue); 60 | 61 | /// Retrieves a set of string values from the preferences. 62 | /// 63 | /// See: https://developer.android.com/reference/android/content/SharedPreferences#getStringSet(java.lang.String,%20java.util.Set%3Cjava.lang.String%3E) 64 | Set getStringSet(String key, [Set defaultValue]) => 65 | get(key, defaultValue); 66 | } 67 | 68 | class _SharedPreferences extends SharedPreferences { 69 | static const MethodChannel _channel = 70 | MethodChannel('flutter_android/SharedPreferences'); 71 | 72 | final String name; 73 | final int mode; 74 | Map _cache; 75 | 76 | _SharedPreferences(this.name, this.mode); 77 | 78 | Future load() async { 79 | assert(Platform.isAndroid); 80 | final request = {'name': name, 'mode': mode}; 81 | _cache = (await _channel.invokeMethod('getAll', request) 82 | as Map) 83 | .cast(); 84 | return this; 85 | } 86 | 87 | @override 88 | T get(String key, [T defaultValue]) { 89 | return _cache[key] ?? defaultValue; 90 | } 91 | 92 | @override 93 | Map getAll() { 94 | return Map.unmodifiable(_cache); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /example/lib/method_tab.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'dart:async'; 4 | import 'package:flutter/material.dart'; 5 | import 'package:flutter/services.dart' show PlatformException; 6 | import 'package:url_launcher/url_launcher.dart' show launch; 7 | 8 | //import 'src/metadata.dart' show metadata; 9 | 10 | //////////////////////////////////////////////////////////////////////////////// 11 | 12 | typedef MethodCallback = Future Function(); 13 | 14 | final Map methods = { 15 | // TODO 16 | }; 17 | 18 | //////////////////////////////////////////////////////////////////////////////// 19 | 20 | class MethodTab extends StatefulWidget { 21 | @override 22 | State createState() => _MethodTabState(); 23 | } 24 | 25 | //////////////////////////////////////////////////////////////////////////////// 26 | 27 | class _MethodTabState extends State { 28 | Map> _results = >{}; 29 | 30 | @override 31 | void initState() { 32 | super.initState(); 33 | _initPlatformState(); 34 | } 35 | 36 | @override 37 | Widget build(final BuildContext context) { 38 | final methodKeys = methods.keys.toList(); 39 | return ListView.separated( 40 | padding: EdgeInsets.all(8.0), 41 | itemCount: methodKeys.length, 42 | itemBuilder: (final BuildContext context, final int index) { 43 | final methodKey = methodKeys[index]; 44 | return GestureDetector( 45 | onTap: () => launch(_getURL(methodKey)), 46 | child: ListTile( 47 | leading: Icon(Icons.info), 48 | title: Text(_getTitle(methodKey)), 49 | subtitle: FutureBuilder( 50 | future: _results[methodKey], 51 | builder: (final BuildContext context, 52 | final AsyncSnapshot snapshot) { 53 | switch (snapshot.connectionState) { 54 | case ConnectionState.done: 55 | return snapshot.hasError 56 | ? Text(snapshot.error) 57 | : Text(snapshot.data.toString()); 58 | case ConnectionState.none: 59 | case ConnectionState.active: 60 | case ConnectionState.waiting: 61 | default: 62 | return Text("Unknown"); 63 | } 64 | }, 65 | ), 66 | //trailing: Icon(Icons.info, color: Theme.of(context).disabledColor), 67 | ), 68 | ); 69 | }, 70 | separatorBuilder: (final BuildContext context, final int index) { 71 | return Divider(); 72 | }, 73 | ); 74 | } 75 | 76 | String _getTitle(final String qualifiedMethodName) { 77 | final methodInfo = qualifiedMethodName.split("."); 78 | return [methodInfo[1], methodInfo[2]].join("."); 79 | } 80 | 81 | String _getURL(final String qualifiedMethodName) { 82 | final methodInfo = qualifiedMethodName.split("."); 83 | final libraryName = methodInfo[0]; 84 | final className = methodInfo[1]; 85 | final methodName = methodInfo[2]; 86 | return "https://pub.dev/documentation/flutter_android/latest/$libraryName/$className/$methodName.html"; 87 | } 88 | 89 | // Platform messages are asynchronous, so we initialize in an async method. 90 | Future _initPlatformState() async { 91 | final results = >{}; 92 | 93 | // Platform messages may fail, so we use a try/catch PlatformException. 94 | try { 95 | methods.forEach((k, v) { 96 | results[k] = Future.value(""); //v(); 97 | }); 98 | } on PlatformException { 99 | // TODO: improve error handling 100 | } 101 | 102 | // If the widget was removed from the tree while the asynchronous platform 103 | // message was in flight, we want to discard the reply rather than calling 104 | // setState to update our non-existent appearance. 105 | if (!mounted) return; 106 | 107 | setState(() { 108 | _results = results; 109 | }); 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /lib/src/os/process.dart: -------------------------------------------------------------------------------- 1 | /* This is free and unencumbered software released into the public domain. */ 2 | 3 | import 'dart:async' show Future; 4 | 5 | /// Tools for managing OS processes. 6 | /// 7 | /// See: https://developer.android.com/reference/android/os/Process 8 | abstract class Process { 9 | /// Defines the UID/GID under which system code runs. 10 | /// 11 | /// See: https://developer.android.com/reference/android/os/Process#SYSTEM_UID 12 | static const int SYSTEM_UID = 1000; 13 | 14 | /// Defines the UID/GID under which the telephony code runs. 15 | /// 16 | /// See: https://developer.android.com/reference/android/os/Process#PHONE_UID 17 | static const int PHONE_UID = 1001; 18 | 19 | /// Defines the start of a range of UIDs (and GIDs), going from this number to 20 | /// `LAST_APPLICATION_UID` that are reserved for assigning to applications. 21 | /// 22 | /// See: https://developer.android.com/reference/android/os/Process#FIRST_APPLICATION_UID 23 | static const int FIRST_APPLICATION_UID = 10000; 24 | 25 | /// Last of application-specific UIDs starting at `FIRST_APPLICATION_UID`. 26 | /// 27 | /// See: https://developer.android.com/reference/android/os/Process#LAST_APPLICATION_UID 28 | static const int LAST_APPLICATION_UID = 19999; 29 | 30 | /// Standard priority of application threads. 31 | /// 32 | /// See: https://developer.android.com/reference/android/os/Process#THREAD_PRIORITY_DEFAULT 33 | static const int THREAD_PRIORITY_DEFAULT = 0; 34 | 35 | /// Lowest available thread priority. 36 | /// 37 | /// See: https://developer.android.com/reference/android/os/Process#THREAD_PRIORITY_LOWEST 38 | static const int THREAD_PRIORITY_LOWEST = 19; 39 | 40 | /// Standard priority background threads. 41 | /// 42 | /// See: https://developer.android.com/reference/android/os/Process#THREAD_PRIORITY_BACKGROUND 43 | static const int THREAD_PRIORITY_BACKGROUND = 10; 44 | 45 | /// Standard priority of threads that are currently running a user interface that the user is interacting with. 46 | /// 47 | /// See: https://developer.android.com/reference/android/os/Process#THREAD_PRIORITY_FOREGROUND 48 | static const int THREAD_PRIORITY_FOREGROUND = -2; 49 | 50 | /// Standard priority of system display threads, involved in updating the user interface. 51 | /// 52 | /// See: https://developer.android.com/reference/android/os/Process#THREAD_PRIORITY_DISPLAY 53 | static const int THREAD_PRIORITY_DISPLAY = -4; 54 | 55 | /// Standard priority of the most important display threads, for compositing the screen and retrieving input events. 56 | /// 57 | /// See: https://developer.android.com/reference/android/os/Process#THREAD_PRIORITY_URGENT_DISPLAY 58 | static const int THREAD_PRIORITY_URGENT_DISPLAY = -8; 59 | 60 | /// Standard priority of video threads. 61 | /// 62 | /// See: https://developer.android.com/reference/android/os/Process#THREAD_PRIORITY_VIDEO 63 | static const int THREAD_PRIORITY_VIDEO = -10; 64 | 65 | /// Standard priority of audio threads. 66 | /// 67 | /// See: https://developer.android.com/reference/android/os/Process#THREAD_PRIORITY_AUDIO 68 | static const int THREAD_PRIORITY_AUDIO = -16; 69 | 70 | /// Standard priority of the most important audio threads. 71 | /// 72 | /// See: https://developer.android.com/reference/android/os/Process#THREAD_PRIORITY_URGENT_AUDIO 73 | static const int THREAD_PRIORITY_URGENT_AUDIO = -19; 74 | 75 | /// Minimum increment to make a priority more favorable. 76 | /// 77 | /// See: https://developer.android.com/reference/android/os/Process#THREAD_PRIORITY_MORE_FAVORABLE 78 | static const int THREAD_PRIORITY_MORE_FAVORABLE = -1; 79 | 80 | /// Minimum increment to make a priority less favorable. 81 | /// 82 | /// See: https://developer.android.com/reference/android/os/Process#THREAD_PRIORITY_LESS_FAVORABLE 83 | static const int THREAD_PRIORITY_LESS_FAVORABLE = 1; 84 | 85 | /// See: https://developer.android.com/reference/android/os/Process#SIGNAL_QUIT 86 | static const int SIGNAL_QUIT = 3; 87 | 88 | /// See: https://developer.android.com/reference/android/os/Process#SIGNAL_KILL 89 | static const int SIGNAL_KILL = 9; 90 | 91 | /// See: https://developer.android.com/reference/android/os/Process#SIGNAL_USR1 92 | static const int SIGNAL_USR1 = 10; 93 | 94 | /// Returns whether the current process is a 64-bit runtime. 95 | /// 96 | /// See: https://developer.android.com/reference/android/os/Process#is64Bit() 97 | static Future get is64Bit { 98 | return null; // TODO 99 | } 100 | 101 | /// Returns whether the current process is in an isolated sandbox. 102 | /// 103 | /// See: https://developer.android.com/reference/android/os/Process#isIsolated() 104 | static Future get isIsolated { 105 | return null; // TODO 106 | } 107 | } 108 | --------------------------------------------------------------------------------