Detect Volume Button Press

Detect volume button press

Using the second method, the value of the key path should be "outputVolume". That is the property we are observing.
So change the code to,

var outputVolumeObserve: NSKeyValueObservation?
let audioSession = AVAudioSession.sharedInstance()

func listenVolumeButton() {
do {
try audioSession.setActive(true)
} catch {}

outputVolumeObserve = audioSession.observe(\.outputVolume) { (audioSession, changes) in
/// TODOs
}
}

SwiftUI: how to detect volume button pressed (hardware)?

I have had a hard time with this problem as well. I came across this project https://github.com/jpsim/JPSVolumeButtonHandler and it does the job for the most part and even hides the volume indicator when the volume buttons are pressed.

This is what I did to get it to work. I hope that it helps.

import SwiftUI
import JPSVolumeButtonHandler

struct MyView: View {

@State private var volumeHandler: JPSVolumeButtonHandler?

var body: some View {
ZStack {
Text("Hello World")
}
.onAppear {
// Setup capture of volume buttons
volumeHandler = JPSVolumeButtonHandler(up: {
// Code to run when volume button released
}, downBlock: {
// Code to run when volume button pressed
})

// Start capture of volume buttons
volumeHandler?.start(true)
}
.onDisappear {
// Stop capture of volume buttons when leaving view
volumeHandler?.start(false)
}
}

}

This is the post I used to figure it out originally: iOS. Capturing photos with volume buttons

Detect hardware volume button press when volume not changed


let volumeView = MPVolumeView(frame: CGRect.zero)
self.view.addSubview(volumeView)
NotificationCenter.default.addObserver(self, selector: #selector(volumeChanged(_:)), name: NSNotification.Name(rawValue: "AVSystemController_SystemVolumeDidChangeNotification"), object: nil)

This will get called every press regardless of volume level

@objc func volumeChanged(_ notification: NSNotification) {
if let volume = notification.userInfo!["AVSystemController_AudioVolumeNotificationParameter"] as? Float {
print("volume: \(volume)")
}
}

output:

volume: 0.8125
volume: 0.875
volume: 0.9375
volume: 1.0
volume: 1.0
volume: 1.0
volume: 1.0

Swift: Detect Volume Button Press NOT volume change events

So what I'd do is subscribe to the notification like they do in the questions you linked and then add a variable named say programmaticVolumeChange. When you change the volume programmatically set the variable to true, then in your function observeValueForKeyPath, if the variable is true don't cancel the alarm (and naturally set it to false after). That way when the user presses the volume buttons you know it wasn't your code. Maybe test the amount of time between a programmatic volume change and the function call but I think that would be fine.

Eg

var programmaticVolumeChange = false

func changeVolumeProgramatically() {

programmaticVolumeChange = true
//change volume programmatically after

}

override func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject,
change: [NSObject : AnyObject], context: UnsafeMutablePointer<Void>) {

if keyPath == "outputVolume"{

if programmaticVolumeChange {

programmaticVolumeChange = false

} else {

//handle logic for user volume button press

}

}

}

How to detect volume up and down long pressed together?

You need to detect when the both of the keys are pressed using onKeyDown callback, something like should work:

public boolean up,down;

public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN){
down = true;
} else if(keyCode == KeyEvent.KEYCODE_VOLUME_UP){
up = true;
}
if(up && down) {
// Two buttons pressed, call your function
}
return true;
}

public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN){
down = false;
} else if(keyCode == KeyEvent.KEYCODE_VOLUME_UP){
up = false;
}
return true;
}


Related Topics



Leave a reply



Submit