views:

1011

answers:

4

Is there any way to subscribe to volume buttons press evens?

+3  A: 

After the recent rejections from Apple

Do not use this. Apple now uses some patch which would reject your app straightaway if it uses any of the private APIs - though should note here that quite some apps on the App Store use this already and are still there!

The only way to do this now is to have an AVAudioPlayer prepared to play but not playing ([player prepareToPlay]). This seems to take care of adjusting the app's volume according to the rocker buttons.

There's no other published way currently to handle this.

PLEASE READ THE ABOVE NOTE

Yes, Use the MPVolumeView

MPVolumeView *volume = [[[MPVolumeView alloc] initWithFrame:CGRectMake(18.0, 340.0, 284.0, 23.0)] autorelease];
  [[self view] addSubview:volume];

  [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(volumeChanged:) 
                                        name:@"AVSystemController_SystemVolumeDidChangeNotification" 
                                        object:nil];    
  for (UIView *view in [volume subviews]){
    if ([[[view class] description] isEqualToString:@"MPVolumeSlider"]) {
      volumeViewSlider = view;  //volumeViewSlider is a UIView * object
    }
  }
  [volumeViewSlider _updateVolumeFromAVSystemController];

-(IBAction)volumeChanged:(id)sender{
  [volumeViewSlider _updateVolumeFromAVSystemController];
}

This will give you a slider (same as one used in ipod) whose value will change acc to volume of the phone

You will get a compile-time warning that view may not respond to _updateVolumeFromAVSystemControl, but just ignore it.

lostInTransit
yeah, i was thinking about listening to VolumeChanged but i wonder if it will still receive a message when no actual VolumeChange occurs (for example volume is at max and i'm increasing it)?
COTOHA
you can try the code on a device and see if the event is received.
lostInTransit
You can't ship an app with this code, it uses a private API. That's what the compile time warning is about, and the underscore prefix is a giveaway too.
duncanwilcox
A: 

If you are willing to dip into the private API, I have a patch to Wolf3d that adds exactly the functionality you are looking for. It uses the private AVSystemController class and some hidden methods on UIApplication

rpetrich
A: 

DO NOT USE THIS TECHNIQUE!

Apple is now denying any app that uses a private API. _updateVolumeFromAVSystemController counts as a private API.

I have now had apps denied because I used this method.

--Batgar

Batgar
A: 

If you just want to get the notifications, I think it is like this:

Please correct me if I am wrong, but I don't believe this uses any internal API.

[[NSNotificationCenter defaultCenter] addObserver:self
        selector:@selector(volumeChanged:) 
        name:@"AVSystemController_SystemVolumeDidChangeNotification" 
        object:nil];

Details of this event are here: http://www.cocoadev.com/index.pl?AVSystemController

The other replies here seem to be based on this hack: http://blog.stormyprods.com/2008/09/proper-usage-of-mpvolumeview-class.html which was a workaround for a now-fixed bug.

But I'm pretty sure if all you want to do is GET the notification, and not SET the system volume, you can just use the notification center like with any other event!!

Will

William Denniss