iOS Code Snippet Control ringer volume

It appears that iPhones have 2 sets of audio, each with their own volume:
  • "General audio" - music, TTS etc
  • "Ringer" or "ringtones/alerts" - incoming phone call, SMS arrivals, other notifications AND pseudo camera shutter sound.
This link makes a reasonably good stab at explaining it all:

http://artoftheiphone.com/2012/02/1...ume-controls-for-ringtones-and-general-audio/

The following code snippet allows you to control the ringer volume and includes some Objective C:
  • That I managed to scrounge off the web, principally from:
  • Allows you to change the ringer volume (0 = mute, 1= full).
  • Hides the stupid "ringer volume HUD" (the little grey square with a speaker icon in it) that would otherwise appear.
The Objective C comes wrapped in a reasonably simple B4I example that uses the Camera object to supply a test "ringer" (aka "system", "device", "alert", ...) sound - actually the pseudo camera shutter sound.

Example usage is pretty self evident when you copy the snippet into a new B4I project then compile and run it.
B4X:
'Code module
#Region  Project Attributes
    #ApplicationLabel: Control Ringer Volume
    #Version: 1.0.0
    'Orientation possible values: Portrait, LandscapeLeft, LandscapeRight and PortraitUpsideDown
    #iPhoneOrientations: Portrait, LandscapeLeft, LandscapeRight
    #iPadOrientations: Portrait, LandscapeLeft, LandscapeRight, PortraitUpsideDown
    #Target: iPhone, iPad
    #MinVersion: 7
#End Region

Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'Public variables can be accessed from all modules.
    Public App As Application
    Public NavControl As NavigationController
    Private Page1 As Page

    Private button1 As Button
    Private cam As Camera
    Private vv As VideoView
    Private label1 As Label
    Private volume_value As Float

End Sub

Private Sub Application_Start (Nav As NavigationController)
    NavControl = Nav
    Page1.Initialize("Page1")
    Page1.Title = "Page 1"
    Page1.RootPanel.Color = Colors.White
    NavControl.ShowPage(Page1)

    Ringervolume_hide

End Sub

Private Sub Page1_Resize(Width As Int, Height As Int)

    Page1.RootPanel.RemoveAllViews

    button1.Initialize("button1", button1.STYLE_SYSTEM)
    Page1.RootPanel.AddView(button1, 0, 0, Page1.RootPanel.Width, 100)
    button1.Text = "CLICK HERE FOR CAMERA"

    Ringervolume_set(volume_value)

    label1.Initialize("")
    Page1.RootPanel.AddView(label1, 0, 100, Page1.RootPanel.Width, Page1.RootPanel.Height - 100)
    label1.Multiline = True
    label1.Text = "Tap screen to change volume" & CRLF & "Volume set at: " & volume_value & CRLF & CRLF & "To test:"    & CRLF & "(1) Tap [CLICK HERE FOR CAMERA]"    & CRLF & "(2) Tap round button - note shutter sound" & CRLF & "(3) Tap [Retake] then [Cancel] to return"

    cam.Initialize("cam", Page1)
    button1.Enabled = cam.IsSupported
    vv.Initialize("vv")
    Page1.RootPanel.AddView(vv.View, 100, 100, 100, 100)
    vv.View.Visible = False

End Sub

Private Sub Page1_Click

    volume_value = volume_value - .25
    If volume_value < 0 Then volume_value = 1

    Ringervolume_set(volume_value)

    label1.Text = "Tap screen to change volume" & CRLF & "Volume set at: " & volume_value & CRLF & CRLF & "To test:"    & CRLF & "(1) Tap [CLICK HERE FOR CAMERA]"    & CRLF & "(2) Tap round button - note shutter sound" & CRLF & "(3) Tap [Retake] then [Cancel] to return"

End Sub

Private Sub Application_Background

End Sub

Private Sub button1_Click
    cam.TakePicture
End Sub

Sub Ringervolume_hide
    Dim no As NativeObject = Me
    no.RunMethod("ringervol_hide", Null)
End Sub

Sub Ringervolume_set(volumevalue As Float)
    Dim no As NativeObject = Me
    no.RunMethod("ringervol_set:", Array(volumevalue))
End Sub

#If OBJC
- (void) ringervol_hide
{
    //following hides "ringer/alert volume HUD" - see:
    //http://stackoverflow.com/questions/26302218/hide-volume-hud-in-ios-8
    NSString *str1 = @"etSystemV";
    NSString *str2 = @"eHUDEnabled";
    NSString *selectorString = [NSString stringWithFormat:@"s%@olum%@:forAudioCategory:", str1, str2];
    SEL selector = NSSelectorFromString(selectorString);
    if ([[UIApplication sharedApplication] respondsToSelector:selector]) {
        NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:
                                   [UIApplication instanceMethodSignatureForSelector:selector]];
        [invocation setTarget:[UIApplication sharedApplication]];
        [invocation setSelector:selector];
        bool visible = false;
        [invocation setArgument:&visible atIndex:2];
        NSString *soundcategory = @"Ringtone";
        [invocation setArgument:&soundcategory atIndex:3];
        [invocation invoke];
    }
}
- (void) ringervol_set: (float) volval
{
    //following changes ringer/alert volume - see:
    //http://stackoverflow.com/questions/6284402/how-to-disable-ios-system-sounds?answertab=votes#tab-top
    Class avSystemControllerClass = NSClassFromString(@"AVSystemController");
    id avSystemControllerInstance = [avSystemControllerClass performSelector:@selector(sharedAVSystemController)];
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:
                               [avSystemControllerClass instanceMethodSignatureForSelector:
                               @selector(setVolumeTo:forCategory:)]];
    [invocation setTarget:avSystemControllerInstance];
    [invocation setSelector:@selector(setVolumeTo:forCategory:)];
    [invocation setArgument:&volval atIndex:2];
    NSString *soundCategory = @"Ringtone";
    [invocation setArgument:&soundCategory atIndex:3];
    [invocation invoke];
}
#End If
A few notes:

(1) Re getting the current ringer volume - I haven't tried - I suspect it can be done by copying and modifying the - (void) ringervol_set: (float) volval Objective C method.

(2) You can not set the ringer volume to absolute 0 - if you try it will reset itself to about 0.1 - this is identical behaviour to when you manually minimize ringer volume with the volume up/down buttons on the top left of the phone.​

(3) This only gives control of ringer volume - for control of general audio volume look at the sister snippet here:​

Any and all comments welcome...
 

Attachments

  • Control Ringer Volume.zip
    2 KB · Views: 235
Last edited:
Top