iOS 7:不推荐使用 MPMusicPlayerController 音量。现在如何更改设备音量?
Posted
技术标签:
【中文标题】iOS 7:不推荐使用 MPMusicPlayerController 音量。现在如何更改设备音量?【英文标题】:iOS 7: MPMusicPlayerController volume deprecated. How to change device volume now? 【发布时间】:2013-10-07 06:58:40 【问题描述】:MPMusicPlayerController setVolume 为deprecated since ios 7
还有其他方法可以改变系统音乐音量吗?最好没有用户交互。 它的重要功能:自动增加 AppStore 中任何闹钟的音量。
【问题讨论】:
我也依赖此功能,因为我的用户希望能够设置和保存我的应用打开的音量。从开发人员的控制中移除这似乎是一件奇怪的事情。 有AVAudioPlayer:***.com/questions/5222464/…。我的问题是它是否可以播放 iPod 库中的歌曲。 同意,Apple 弃用了这些方法而没有提供适当的替代品,这很奇怪。 我注意到在 iOS 8.3 中,我的应用程序中的 MPMusicPlayerController 音量滑块根本不显示。它在早期的 iOS 版本中显示。没有对应用程序进行任何更改。有人在他们的应用中遇到过这个问题吗? @kzia 请为此问题创建单独的问题 【参考方案1】:要准确回答您的问题: 是的,还有其他方法可以在无需用户交互的情况下更改系统音量。
直到最近,我一直认为只有使用 私有 API 才能以编程方式使用 MPVolumeView 更改音量。但我刚刚验证,改变 volumeSlider 的值和伪造滑块的 touchUP 事件是有效的:
MPVolumeView* volumeView = [[MPVolumeView alloc] init];
//find the volumeSlider
UISlider* volumeViewSlider = nil;
for (UIView *view in [volumeView subviews])
if ([view.class.description isEqualToString:@"MPVolumeSlider"])
volumeViewSlider = (UISlider*)view;
break;
[volumeViewSlider setValue:1.0f animated:YES];
[volumeViewSlider sendActionsForControlEvents:UIControlEventTouchUpInside];
(当slider收到touchUP事件时,会调用自己的_commitVolumeChange
方法,改变系统音量)
【讨论】:
对不起,如果我很愚蠢。我正在尝试将您的代码粘贴到我的 js 函数中。 Dreamweaver 向我抛出了一个红色的语法箭头。这是js代码还是别的什么? @Garavani 这是一个objective-c代码。而且跟js集成也不是那么简单。请在类似这样的教程中在线查找更多信息 - bignerdranch.com/blog/javascriptcore-example 这段代码,如所写,将引入一个问题:存储到“volumeView”中的对象的潜在泄漏 解决方法:Potential leak of an object stored into 'volumeView'
将 volumeView 移动到这样的属性中:@property (nonatomic, retain) MPVolumeView* volumeView;
然后从循环中以这种方式访问它:for (UIView *view in [self.volumeView subviews])
@ambientlight 我知道它不直接使用私有 API,但伪装用户交互作为触发私有 API _commitVolumeChange
的解决方法对我来说似乎有点冒险。还是)感谢你的建议! :)【参考方案2】:
在 Apple 认为适合撤销此决定之前,我发现了两种补救措施:
继续使用 volume 属性,在 iOS 7.0.2 下仍然可以使用 使用 AVAudioSession.outputVolume 在您的应用唤醒时读取音量,如果音量低于(或高于)用户指定的值,则会弹出包含 MPVolumeView 的警报。至少您的用户知道他们的闹钟(或其他)会安静地播放并有机会调整音量。或者,您可以非常清楚地显示音量级别,这样他们就不会感到意外。【讨论】:
只应使用第二个选项 >= iOS 7.0。谢谢! :) 从 iOS 10 开始,你仍然可以使用 volume 属性!【参考方案3】:这样做:
let masterVolumeSlider: MPVolumeView = MPVolumeView()
if let view = masterVolumeSlider.subviews.first as? UISlider
view.value = 1.0
【讨论】:
还需要一个“导入媒体播放器”masterVolumeSlider.alpha = 0.01; self.view.addSubview(masterVolumeSlider)
还允许我在不显示操作系统音量计的情况下减少它
我最喜欢这个答案,因为它很优雅并且不需要使用内部类名。它似乎很可能在未来不会中断。【参考方案4】:
@Hurden,我写了一个 Swift 代码来实现 MPVolumeSlider:
for view in mpVolumeView.subviews
let uiview: UIView = view as UIView
//println("\(uiview.description)")
if uiview.description.rangesOfString("MPVolumeSlider").first != nil
mpVolumeSilder = (uiview as UISlider)
currentDeviceVolume = mpVolumeSilder!.value
return
func rangeOfString 扩展字符串可以在这里找到Swift: A pure Swift method for returning ranges of a String instance (Xcode 6 Beta 5)
并使用这段代码让手势和mpvolumeslider一起工作
@IBAction func handlePan(recognizer: UIPanGestureRecognizer)
let translation = recognizer.translationInView(self.view)
let dx = (translation.x-lastTranslationX)
let volumeChanged = Float(dx / mpVolumeView.frame.width)
currentDeviceVolume = currentDeviceVolume + Float(volumeChanged)
if currentDeviceVolume > 1
currentDeviceVolume = 1
else if currentDeviceVolume < 0
currentDeviceVolume = 0
mpVolumeSilder!.value = currentDeviceVolume
if recognizer.state == .Changed
lastTranslationX = translation.x
if recognizer.state == .Ended || recognizer.state == .Began
lastTranslationX = 0
【讨论】:
【参考方案5】:显然有一种改变系统音量的方法根本不显示任何内容。
最棒的是它适用于 iOS 11。
我是这样实现的:
1) 在所需的 ViewController 中创建两个变量
let volumeView = MPVolumeView()
var slider: UISlider?
2) 将下面的代码添加到您的 viewDidLoad 中
volumeView.alpha = 0.01
self.view.addSubview(volumeView)
if let view = volumeView.subviews.first as? UISlider
slider = view
3) 随时更改音量
slider?.value = 0.4
【讨论】:
【参考方案6】:Swift 版本:
// Outlet added in Storyboard (Add UIView then set class to MPVolumeView)
@IBOutlet weak var mpVolumeView: MPVolumeView!
// Get volume slider within MPVolumeView
for subview in self.mpVolumeView.subviews
if (subview as UIView).description.rangeOfString("MPVolumeSlider") != nil
// Set volume
let volumeSlider = subview as UISlider
volumeSlider.value = 1
// Works with or without the following line:
// volumeSlider.sendActionsForControlEvents(UIControlEvents.TouchUpInside)
break
【讨论】:
【参考方案7】:这个解决方案有点紧张,我觉得官方 API 不存在有点奇怪,但这是我根据环境光的帖子构建的 Swift 解决方案
var _volumeView = MPVolumeView()
var _volumeSlider : UISlider? = nil
self.view.addSubview(_volumeView)
_volumeView.hidden = true
var i = 0
while i < _volumeView.subviews.count
if let _r = _volumeView.subviews[i] as? UISlider
_volumeSlider = _r
break
++i
【讨论】:
【参考方案8】:let masterVolumeSlider : MPVolumeView = MPVolumeView()
if let view = masterVolumeSlider.subviews.first as? UISlider
view.value = fVolume!
view.sendActionsForControlEvents(UIControlEvents.TouchUpInside)
【讨论】:
以上是关于iOS 7:不推荐使用 MPMusicPlayerController 音量。现在如何更改设备音量?的主要内容,如果未能解决你的问题,请参考以下文章
iOS 7:不推荐使用 MPMusicPlayerController 音量。现在如何更改设备音量?
Swift - 坐标不可用:从 iOS 7 开始不推荐使用 API
iOS 7 及更高版本 (8.4) 中不推荐使用 SegmentedControlStyle | Xcode 6.4
帮我选择合适的 iPhone 音频类 - MPMoviePlayer vs AVAudioPlayer vs MPMusicPlayer