diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 0000000..92ecfa0 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,47 @@ +name: Publish package + +on: + release: + types: [published] + +jobs: + publish: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Dart SDK + uses: dart-lang/setup-dart@v1 + + - name: Install dependencies + run: dart pub get + + - name: Run tests + run: dart test + + - name: Setup pub.dev credentials + run: | + mkdir -p ${{ runner.workspace }}/.config/dart + echo "$CREDENTIAL_JSON" > ${{ runner.workspace }}/.config/dart/pub-credentials.json + if [ -n "$XDG_CONFIG_HOME" ]; then + mkdir -p $XDG_CONFIG_HOME/dart + cp ${{ runner.workspace }}/.config/dart/pub-credentials.json $XDG_CONFIG_HOME/dart/pub-credentials.json + else + mkdir -p $HOME/.config/dart + cp ${{ runner.workspace }}/.config/dart/pub-credentials.json $HOME/.config/dart/pub-credentials.json + fi + env: + CREDENTIAL_JSON: ${{ secrets.CREDENTIAL_JSON }} + XDG_CONFIG_HOME: ${{ env.XDG_CONFIG_HOME }} + + - name: Publish to pub.dev + run: dart pub publish -f + + - name: Create release branch + uses: peterjgrainger/action-create-branch@v2.2.0 + with: + branch: release/${{ github.event.release.tag_name }} + sha: '${{ github.event.pull_request.head.sha }}' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/test.yml similarity index 98% rename from .github/workflows/ci.yml rename to .github/workflows/test.yml index 383bab6..f54079c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/test.yml @@ -12,7 +12,7 @@ on: env: FLUTTER_CHANNEL: 'stable' - FLUTTER_VERSION: '3.10.2' + FLUTTER_VERSION: '3.13.4' jobs: build_example_android: diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f05172..ca03263 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 1.3.0 +* iOS: fix volume slider not shown when pressing physical buttons after `showSystemUI` is reset. +* Deprecated: `showSystemUI` setter is deprecated and migrated to `updateShowSystemUI`. + ## 1.2.7 * Fixed audio session not activated with ambient state on iOS. diff --git a/README.md b/README.md index 8608c9a..3ffff6f 100644 --- a/README.md +++ b/README.md @@ -27,9 +27,10 @@ A Flutter plugin to control system volume and listen for volume changes on diffe #### Control System UI Visibility - Set to `true` to display system volume slider when changing volume. -- This settings only works on Android and iOS. +- This setting only works on Android and iOS. +- Note: this setting doesn't control the volume slider invoked by physical buttons on Android. ```dart -FlutterVolumeController.showSystemUI = true; +await FlutterVolumeController.updateShowSystemUI(true); ``` #### Get Volume @@ -153,9 +154,13 @@ void dispose() { a rounded off value. #### Audio devices without volume control -- On desktop platforms like Windows and Linux, you may encounter PlatformExceptions if the default +- On desktop platforms like Windows and Linux, you may encounter `PlatformException` if the default audio device doesn't support volume control, like an external monitor. +#### Controlling Android volume slider UI +- Currently there is no trivial way to control the volume slider invoked by physical buttons on + Android in plugin level. You may override `FlutterActivity::onKeyDown` to customize the buttons action. + ## Having Bugs? - This package is under active development. If you find any bug, please create an issue on Github. diff --git a/example/.gitignore b/example/.gitignore index 8066995..38e3bcf 100644 --- a/example/.gitignore +++ b/example/.gitignore @@ -31,6 +31,7 @@ migrate_working_dir/ .pub-cache/ .pub/ /build/ +pubspec.lock # Web related lib/generated_plugin_registrant.dart diff --git a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index c87d15a..a6b826d 100644 --- a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ + CADisableMinimumFrameDurationOnPhone + CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleDisplayName @@ -24,6 +26,8 @@ $(FLUTTER_BUILD_NUMBER) LSRequiresIPhoneOS + UIApplicationSupportsIndirectInputEvents + UILaunchStoryboardName LaunchScreen UIMainStoryboardFile @@ -43,9 +47,5 @@ UIViewControllerBasedStatusBarAppearance - CADisableMinimumFrameDurationOnPhone - - UIApplicationSupportsIndirectInputEvents - diff --git a/example/lib/main.dart b/example/lib/main.dart index 8b8e988..fe3723e 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -68,8 +68,8 @@ class _HomeState extends State { child: ElevatedButton( child: const Text('Show or hide system ui'), onPressed: () { - FlutterVolumeController.showSystemUI = - !FlutterVolumeController.showSystemUI; + FlutterVolumeController.updateShowSystemUI( + !FlutterVolumeController.showSystemUI); _showSnackBar( 'Show system ui: ${FlutterVolumeController.showSystemUI}', ); diff --git a/example/pubspec.lock b/example/pubspec.lock deleted file mode 100644 index 5c91b5c..0000000 --- a/example/pubspec.lock +++ /dev/null @@ -1,267 +0,0 @@ -# Generated by pub -# See https://dart.dev/tools/pub/glossary#lockfile -packages: - async: - dependency: transitive - description: - name: async - sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" - url: "https://pub.dev" - source: hosted - version: "2.11.0" - boolean_selector: - dependency: transitive - description: - name: boolean_selector - sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" - url: "https://pub.dev" - source: hosted - version: "2.1.1" - characters: - dependency: transitive - description: - name: characters - sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" - url: "https://pub.dev" - source: hosted - version: "1.3.0" - clock: - dependency: transitive - description: - name: clock - sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf - url: "https://pub.dev" - source: hosted - version: "1.1.1" - collection: - dependency: transitive - description: - name: collection - sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c" - url: "https://pub.dev" - source: hosted - version: "1.17.1" - cupertino_icons: - dependency: "direct main" - description: - name: cupertino_icons - sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be - url: "https://pub.dev" - source: hosted - version: "1.0.5" - fake_async: - dependency: transitive - description: - name: fake_async - sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" - url: "https://pub.dev" - source: hosted - version: "1.3.1" - file: - dependency: transitive - description: - name: file - sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" - url: "https://pub.dev" - source: hosted - version: "6.1.4" - flutter: - dependency: "direct main" - description: flutter - source: sdk - version: "0.0.0" - flutter_driver: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - flutter_lints: - dependency: "direct dev" - description: - name: flutter_lints - sha256: aeb0b80a8b3709709c9cc496cdc027c5b3216796bc0af0ce1007eaf24464fd4c - url: "https://pub.dev" - source: hosted - version: "2.0.1" - flutter_plugin_android_lifecycle: - dependency: transitive - description: - name: flutter_plugin_android_lifecycle - sha256: c224ac897bed083dabf11f238dd11a239809b446740be0c2044608c50029ffdf - url: "https://pub.dev" - source: hosted - version: "2.0.9" - flutter_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - flutter_volume_controller: - dependency: "direct main" - description: - path: ".." - relative: true - source: path - version: "1.2.7" - fuchsia_remote_debug_protocol: - dependency: transitive - description: flutter - source: sdk - version: "0.0.0" - integration_test: - dependency: "direct dev" - description: flutter - source: sdk - version: "0.0.0" - js: - dependency: transitive - description: - name: js - sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 - url: "https://pub.dev" - source: hosted - version: "0.6.7" - lints: - dependency: transitive - description: - name: lints - sha256: "5e4a9cd06d447758280a8ac2405101e0e2094d2a1dbdd3756aec3fe7775ba593" - url: "https://pub.dev" - source: hosted - version: "2.0.1" - matcher: - dependency: transitive - description: - name: matcher - sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb" - url: "https://pub.dev" - source: hosted - version: "0.12.15" - material_color_utilities: - dependency: transitive - description: - name: material_color_utilities - sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 - url: "https://pub.dev" - source: hosted - version: "0.2.0" - meta: - dependency: transitive - description: - name: meta - sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" - url: "https://pub.dev" - source: hosted - version: "1.9.1" - path: - dependency: transitive - description: - name: path - sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" - url: "https://pub.dev" - source: hosted - version: "1.8.3" - platform: - dependency: transitive - description: - name: platform - sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76" - url: "https://pub.dev" - source: hosted - version: "3.1.0" - process: - dependency: transitive - description: - name: process - sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09" - url: "https://pub.dev" - source: hosted - version: "4.2.4" - sky_engine: - dependency: transitive - description: flutter - source: sdk - version: "0.0.99" - source_span: - dependency: transitive - description: - name: source_span - sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 - url: "https://pub.dev" - source: hosted - version: "1.9.1" - stack_trace: - dependency: transitive - description: - name: stack_trace - sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5 - url: "https://pub.dev" - source: hosted - version: "1.11.0" - stream_channel: - dependency: transitive - description: - name: stream_channel - sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8" - url: "https://pub.dev" - source: hosted - version: "2.1.1" - string_scanner: - dependency: transitive - description: - name: string_scanner - sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" - url: "https://pub.dev" - source: hosted - version: "1.2.0" - sync_http: - dependency: transitive - description: - name: sync_http - sha256: "7f0cd72eca000d2e026bcd6f990b81d0ca06022ef4e32fb257b30d3d1014a961" - url: "https://pub.dev" - source: hosted - version: "0.3.1" - term_glyph: - dependency: transitive - description: - name: term_glyph - sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 - url: "https://pub.dev" - source: hosted - version: "1.2.1" - test_api: - dependency: transitive - description: - name: test_api - sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb - url: "https://pub.dev" - source: hosted - version: "0.5.1" - vector_math: - dependency: transitive - description: - name: vector_math - sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" - url: "https://pub.dev" - source: hosted - version: "2.1.4" - vm_service: - dependency: transitive - description: - name: vm_service - sha256: f6deed8ed625c52864792459709183da231ebf66ff0cf09e69b573227c377efe - url: "https://pub.dev" - source: hosted - version: "11.3.0" - webdriver: - dependency: transitive - description: - name: webdriver - sha256: "3c923e918918feeb90c4c9fdf1fe39220fa4c0e8e2c0fffaded174498ef86c49" - url: "https://pub.dev" - source: hosted - version: "3.0.2" -sdks: - dart: ">=3.0.0-0 <4.0.0" - flutter: ">=3.0.0" diff --git a/example/pubspec.yaml b/example/pubspec.yaml index e4dabc6..ad9ec80 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -7,7 +7,7 @@ version: 1.0.0 publish_to: 'none' # Remove this line if you wish to publish to pub.dev environment: - sdk: ">=2.17.6 <3.0.0" + sdk: ">=2.17.6 <4.0.0" # Dependencies specify other packages that your package needs in order to work. # To automatically upgrade your package dependencies to the latest versions diff --git a/ios/Classes/Constants.swift b/ios/Classes/Constants.swift index 2cda469..7827246 100644 --- a/ios/Classes/Constants.swift +++ b/ios/Classes/Constants.swift @@ -15,6 +15,7 @@ struct MethodName { static let getMute = "getMute" static let setMute = "setMute" static let toggleMute = "toggleMute" + static let updateShowSystemUI = "updateShowSystemUI" } struct MethodArg { diff --git a/ios/Classes/SwiftFlutterVolumeControllerPlugin.swift b/ios/Classes/SwiftFlutterVolumeControllerPlugin.swift index c624dd6..21edd5a 100644 --- a/ios/Classes/SwiftFlutterVolumeControllerPlugin.swift +++ b/ios/Classes/SwiftFlutterVolumeControllerPlugin.swift @@ -113,6 +113,11 @@ public class SwiftFlutterVolumeControllerPlugin: NSObject, FlutterPlugin { } catch { result(FlutterError(code: ErrorCode.getIOSAudioSessionCategory, message: ErrorMessage.getIOSAudioSessionCategory, details: error.localizedDescription)) } + case MethodName.updateShowSystemUI: + let args = call.arguments as! [String: Any] + let showSystemUI = args[MethodArg.showSystemUI] as! Bool + SwiftFlutterVolumeControllerPlugin.volumeController.setShowSystemUI(showSystemUI) + result(nil) default: result(FlutterMethodNotImplemented) } diff --git a/ios/Classes/VolumeController.swift b/ios/Classes/VolumeController.swift index a45f557..dbb5de3 100644 --- a/ios/Classes/VolumeController.swift +++ b/ios/Classes/VolumeController.swift @@ -88,7 +88,7 @@ class VolumeController { try audioSession.setActive(false) } - private func setShowSystemUI(_ show: Bool) { + func setShowSystemUI(_ show: Bool) { if show { volumeView.frame = CGRect() volumeView.showsRouteButton = true diff --git a/lib/src/constants.dart b/lib/src/constants.dart index 258bcfb..3f1135b 100644 --- a/lib/src/constants.dart +++ b/lib/src/constants.dart @@ -12,6 +12,7 @@ class MethodName { static const String getMute = 'getMute'; static const String setMute = 'setMute'; static const String toggleMute = 'toggleMute'; + static const String updateShowSystemUI = 'updateShowSystemUI'; } class MethodArg { diff --git a/lib/src/flutter_volume_controller.dart b/lib/src/flutter_volume_controller.dart index f6703b5..dec4255 100644 --- a/lib/src/flutter_volume_controller.dart +++ b/lib/src/flutter_volume_controller.dart @@ -26,13 +26,40 @@ class FlutterVolumeController { /// Control system UI visibility. /// Set to `true` to display volume slider when changing volume. - /// This settings only works on Android and iOS. - static bool showSystemUI = true; + /// This setting only works on Android and iOS. + static bool _showSystemUI = true; + + static bool get showSystemUI => _showSystemUI; + + @Deprecated( + 'Migrate to [FlutterVolumeController.updateShowSystemUI] instead. ' + 'This setter was deprecated >= 1.3.0.', + ) + static set showSystemUI(bool isShown) { + _showSystemUI = isShown; + } static const AudioStream _defaultAudioStream = AudioStream.music; static const AudioSessionCategory _defaultAudioSessionCategory = AudioSessionCategory.ambient; + /// Control system UI visibility. + /// Set [isShown] to `true` to display volume slider when changing volume. + /// This setting only works on Android and iOS. + /// Note: this setting doesn't control the volume slider invoked by physical + /// buttons on Android. + static Future updateShowSystemUI(bool isShown) async { + _showSystemUI = isShown; + // iOS: needs to update MPVolumeView visibility, otherwise pressing physical buttons + // won't display volume slider after [showSystemUI] is reset to true. + if (Platform.isIOS) { + await methodChannel.invokeMethod( + MethodName.updateShowSystemUI, + {MethodArg.showSystemUI: isShown}, + ); + } + } + /// Get the current volume level. From 0.0 to 1.0. /// Use [stream] to set the audio stream type on Android. static Future getVolume({ @@ -60,7 +87,7 @@ class FlutterVolumeController { MethodArg.volume: volume, if (Platform.isAndroid || Platform.isIOS) MethodArg.showSystemUI: showSystemUI, - if (Platform.isAndroid) MethodArg.audioStream: stream.index + if (Platform.isAndroid) MethodArg.audioStream: stream.index, }, ); } @@ -81,7 +108,7 @@ class FlutterVolumeController { if (Platform.isAndroid || Platform.isIOS) MethodArg.showSystemUI: showSystemUI, if (step != null) MethodArg.step: step, - if (Platform.isAndroid) MethodArg.audioStream: stream.index + if (Platform.isAndroid) MethodArg.audioStream: stream.index, }, ); } @@ -102,7 +129,7 @@ class FlutterVolumeController { if (Platform.isAndroid || Platform.isIOS) MethodArg.showSystemUI: showSystemUI, if (step != null) MethodArg.step: step, - if (Platform.isAndroid) MethodArg.audioStream: stream.index + if (Platform.isAndroid) MethodArg.audioStream: stream.index, }, ); } @@ -138,7 +165,7 @@ class FlutterVolumeController { MethodArg.isMuted: isMuted, if (Platform.isAndroid || Platform.isIOS) MethodArg.showSystemUI: showSystemUI, - if (Platform.isAndroid) MethodArg.audioStream: stream.index + if (Platform.isAndroid) MethodArg.audioStream: stream.index, }, ); } @@ -154,7 +181,7 @@ class FlutterVolumeController { { if (Platform.isAndroid || Platform.isIOS) MethodArg.showSystemUI: showSystemUI, - if (Platform.isAndroid) MethodArg.audioStream: stream.index + if (Platform.isAndroid) MethodArg.audioStream: stream.index, }, ); } diff --git a/pubspec.yaml b/pubspec.yaml index cc549eb..9b2b421 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: flutter_volume_controller description: A Flutter plugin to control system volume and listen for volume changes on different platforms. -version: 1.2.7 +version: 1.3.0 homepage: https://github.com/yosemiteyss/flutter_volume_controller environment: