Skip to content

Commit

Permalink
add removeListener function and show/hide system UI for Android
Browse files Browse the repository at this point in the history
  • Loading branch information
kurenai7968 committed Jun 1, 2021
1 parent 6ce47ae commit a599a12
Show file tree
Hide file tree
Showing 11 changed files with 155 additions and 83 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,9 @@
## 2.0.1

* Fix iOS Bug

## 2.0.2

* VolumeController class change to singleton
* Add "removeListener" function
* Add show/hide volume system UI (only for android now)
60 changes: 46 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,37 @@
# volume_controller

A Flutter plugin for iOS and Android get/set/listen system volume.
A Flutter plugin for iOS and Android control system volume. \
\
**The show/hide system UI only support Android now**

## Variables

- bool showSystemUI: show or hide volume system UI \
The default value is true.
> VolumeController().showSystemUI = true
## Functions

- getVolume: get current volume from system
> VolumeController.getVolume()
> VolumeController().getVolume()
- setVolume: input a double number to set system volume. The range is [0, 1]
> await VolumeController().setVolume(double volume, {bool? showSystemUI})
- maxVolume: set the volume to max
> VolumeController.maxVolume()
> VolumeController().maxVolume({bool? showSystemUI})
- muteVolume: mute the volume
> VolumeController.muteVolume()
- setVolume: input a double number to set system volume. The range is [0, 1]
> await VolumeController.setVolume(double volume)
- volumeListener: listen system volume
> VolumeController.volumeListener.listen((volume) { // TODO });
> VolumeController().muteVolume({bool? showSystemUI})
- listener: listen system volume
> VolumeController().listener((volume) { // TODO });
- removeListener: cancel listen system volume
> VolumeController().removeListener()
## Usage

```dart
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
double _volumeListenerValue = 0;
Expand All @@ -27,10 +41,18 @@ class _MyAppState extends State<MyApp> {
@override
void initState() {
super.initState();
VolumeController.volumeListener.listen((volume) {
// Listen to system volume change
VolumeController().listener((volume) {
setState(() => _volumeListenerValue = volume);
});
VolumeController.getVolume().then((volume) => _setVolumeValue = volume);
VolumeController().getVolume().then((volume) => _setVolumeValue = volume);
}
@override
void dispose() {
VolumeController().removeListener();
super.dispose();
}
@override
Expand All @@ -52,7 +74,7 @@ class _MyAppState extends State<MyApp> {
max: 1,
onChanged: (double value) {
_setVolumeValue = value;
VolumeController.setVolume(_setVolumeValue);
VolumeController().setVolume(_setVolumeValue);
setState(() {});
},
value: _setVolumeValue,
Expand All @@ -66,21 +88,31 @@ class _MyAppState extends State<MyApp> {
Text('Volume is: $_getVolume'),
TextButton(
onPressed: () async {
_getVolume = await VolumeController.getVolume();
_getVolume = await VolumeController().getVolume();
setState(() {});
},
child: Text('Get Volume'),
),
],
),
TextButton(
onPressed: () => VolumeController.muteVolume(),
onPressed: () => VolumeController().muteVolume(),
child: Text('Mute Volume'),
),
TextButton(
onPressed: () => VolumeController.maxVolume(),
onPressed: () => VolumeController().maxVolume(),
child: Text('Max Volume'),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Show system UI:${VolumeController().showSystemUI}'),
TextButton(
onPressed: () => setState(() => VolumeController().showSystemUI = !VolumeController().showSystemUI),
child: Text('Show/Hide UI'),
)
],
),
],
),
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,9 @@ class VolumeControllerPlugin: FlutterPlugin, MethodCallHandler {
override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
when (call.method) {
"setVolume" -> {
var volume:Double? = call.argument("volume")
volumeObserver.setVolumeByPercentage(volume!!)
var volume:Double = call.argument("volume")!!
var showSystemUI:Boolean = call.argument("showSystemUI")!!
volumeObserver.setVolumeByPercentage(volume, showSystemUI)
}
"getVolume" -> result.success(volumeObserver.getVolume())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ import android.content.Context.AUDIO_SERVICE
import android.content.Intent
import android.content.IntentFilter
import android.media.AudioManager
import android.media.AudioManager.FLAG_SHOW_UI
import io.flutter.plugin.common.EventChannel
import kotlin.math.round


class VolumeObserver(private val context:Context){
private var audioManager: AudioManager = context.getSystemService(AUDIO_SERVICE) as AudioManager

fun setVolumeByPercentage(volume:Double) {
fun setVolumeByPercentage(volume:Double, showSystemUI:Boolean) {
var volumePercentage:Double = volume
var _volume:Int = 0
if (volume > 1) {
Expand All @@ -25,7 +26,7 @@ class VolumeObserver(private val context:Context){
var maxVolume:Int = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC)
_volume = (round(volumePercentage * maxVolume)).toInt()

audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, _volume, 0)
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, _volume, if (showSystemUI) FLAG_SHOW_UI else 0)
}

fun getVolume():Double {
Expand Down
31 changes: 25 additions & 6 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,18 @@ class _MyAppState extends State<MyApp> {
@override
void initState() {
super.initState();
VolumeController.volumeListener.listen((volume) {
// Listen to system volume change
VolumeController().listener((volume) {
setState(() => _volumeListenerValue = volume);
});
VolumeController.getVolume().then((volume) => _setVolumeValue = volume);

VolumeController().getVolume().then((volume) => _setVolumeValue = volume);
}

@override
void dispose() {
VolumeController().removeListener();
super.dispose();
}

@override
Expand All @@ -43,7 +51,7 @@ class _MyAppState extends State<MyApp> {
max: 1,
onChanged: (double value) {
_setVolumeValue = value;
VolumeController.setVolume(_setVolumeValue);
VolumeController().setVolume(_setVolumeValue);
setState(() {});
},
value: _setVolumeValue,
Expand All @@ -57,21 +65,32 @@ class _MyAppState extends State<MyApp> {
Text('Volume is: $_getVolume'),
TextButton(
onPressed: () async {
_getVolume = await VolumeController.getVolume();
_getVolume = await VolumeController().getVolume();
setState(() {});
},
child: Text('Get Volume'),
),
],
),
TextButton(
onPressed: () => VolumeController.muteVolume(),
onPressed: () => VolumeController().muteVolume(),
child: Text('Mute Volume'),
),
TextButton(
onPressed: () => VolumeController.maxVolume(),
onPressed: () => VolumeController().maxVolume(),
child: Text('Max Volume'),
),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Show system UI:${VolumeController().showSystemUI}'),
TextButton(
onPressed: () => setState(() => VolumeController()
.showSystemUI = !VolumeController().showSystemUI),
child: Text('Show/Hide UI'),
)
],
),
],
),
),
Expand Down
38 changes: 12 additions & 26 deletions example/pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,14 @@ packages:
name: archive
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.13"
args:
dependency: transitive
description:
name: args
url: "https://pub.dartlang.org"
source: hosted
version: "1.6.0"
version: "3.1.2"
async:
dependency: transitive
description:
name: async
url: "https://pub.dartlang.org"
source: hosted
version: "2.5.0"
version: "2.6.1"
boolean_selector:
dependency: transitive
description:
Expand Down Expand Up @@ -57,20 +50,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.15.0"
convert:
dependency: transitive
description:
name: convert
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.1"
crypto:
dependency: transitive
description:
name: crypto
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.5"
version: "3.0.1"
cupertino_icons:
dependency: "direct main"
description:
Expand All @@ -91,7 +77,7 @@ packages:
name: file
url: "https://pub.dartlang.org"
source: hosted
version: "6.0.0"
version: "6.1.0"
flutter:
dependency: "direct main"
description: flutter
Expand All @@ -116,7 +102,7 @@ packages:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.9.2+2"
version: "0.0.0"
matcher:
dependency: transitive
description:
Expand Down Expand Up @@ -151,7 +137,7 @@ packages:
name: process
url: "https://pub.dartlang.org"
source: hosted
version: "4.0.0"
version: "4.2.1"
sky_engine:
dependency: transitive
description: flutter
Expand All @@ -163,7 +149,7 @@ packages:
name: source_span
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0"
version: "1.8.1"
stack_trace:
dependency: transitive
description:
Expand Down Expand Up @@ -191,7 +177,7 @@ packages:
name: sync_http
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.0"
version: "0.3.0"
term_glyph:
dependency: transitive
description:
Expand All @@ -205,7 +191,7 @@ packages:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.19"
version: "0.3.0"
typed_data:
dependency: transitive
description:
Expand All @@ -226,21 +212,21 @@ packages:
name: vm_service
url: "https://pub.dartlang.org"
source: hosted
version: "5.5.0"
version: "6.2.0"
volume_controller:
dependency: "direct main"
description:
path: ".."
relative: true
source: path
version: "2.0.1"
version: "2.0.2"
webdriver:
dependency: transitive
description:
name: webdriver
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.2"
version: "3.0.0"
sdks:
dart: ">=2.12.0 <3.0.0"
flutter: ">=1.20.0"
4 changes: 3 additions & 1 deletion ios/Classes/SwiftVolumeControllerPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ public class SwiftVolumeControllerPlugin: NSObject, FlutterPlugin{
if (call.method == "setVolume") {
let arg = call.arguments as? [String:Any]
let volume = arg?["volume"] as? Double
volumeObserver.setVolume(volume: Float(volume!))
let showSystemUI = arg?["showSystemUI"] as? Bool

volumeObserver.setVolume(volume: Float(volume!), showSystemUI: showSystemUI!)
}
}
}
Expand Down
17 changes: 6 additions & 11 deletions ios/Classes/VolumeObserver.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,15 @@ public class VolumeObserver {
return audioSession.outputVolume
}

public func setVolume(volume:Float) {
MPVolumeView.setVolume(volume)
}
}
public func setVolume(volume:Float, showSystemUI: Bool) {
let volumeView = MPVolumeView()

extension MPVolumeView {
static func setVolume(_ volume: Float) {
let volumeView = MPVolumeView()
let slider = volumeView.subviews.first(where: { $0 is UISlider }) as? UISlider
let slider = volumeView.subviews.first(where: { $0 is UISlider }) as? UISlider

DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.01) {
slider?.value = volume
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 0.01) {
slider?.value = volume
}
}
}
}

public class VolumeListener: NSObject, FlutterStreamHandler {
Expand Down
Loading

0 comments on commit a599a12

Please sign in to comment.