iOS Code Snippet Control general audio volume

Discussion in 'iOS Code Snippets' started by JackKirk, Mar 27, 2016.

  1. JackKirk

    JackKirk Well-Known Member Licensed User

    I have to say I did a lot of head banging over this.

    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 general audio volume and includes some Objective C:
    • That originated with this post of Erel's:
    • Was extensively modified by me, using bloody-minded determination and lots of googling as a substitute for any Objective C competence, I'm particularly indebted to:
    • Required a final nudge by JanPRO:
    • Allows you to change the general audio volume (0 = mute, 1= full).
    • Theoretically(**) allows you to get the current general audio volume.
    • Hides the stupid "general audio volume HUD" (the little grey square with a speaker icon in it) that would otherwise appear.
    The Objective C comes wrapped in a simple B4I example whose usage is pretty self evident when you copy the snippet into a new B4I project then compile and run it.
    Code:
    'Code module
    #Region  Project Attributes
        
    #ApplicationLabel: Control General Audio 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 xTTS As TTS
        
    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)

        
    'Initialize TTS
        xTTS.Initialize("")

        Audiovolume_hide

    End Sub

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

        Page1.RootPanel.RemoveAllViews

        label1.Initialize(
    "")
        Page1.RootPanel.AddView(label1, 
    00, Page1.RootPanel.Width, Page1.RootPanel.Height)
        label1.Multiline = 
    True
        label1.Text = 
    "Tap screen to change volume" & CRLF & "Volume set at: " & volume_value & CRLF & "Volume reported: " & Audiovolume_get

    End Sub

    Private Sub Page1_Click

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

        Audiovolume_set(volume_value)

        label1.Text = 
    "Tap screen to change volume" & CRLF & "Volume set at: " & volume_value & CRLF & "Volume reported: " & Audiovolume_get

        
    'Speak away
        xTTS.Stop
        xTTS.Speak(
    "testing testing 1 2 3 4 5 6 7 8 9 10"True)

    End Sub

    Private Sub Application_Background

    End Sub

    Sub Audiovolume_hide
        
    Dim no As NativeObject = Me
        no.RunMethod(
    "audiovol_hide"Null)
    End Sub

    Sub Audiovolume_get As Float
        
    Dim no As NativeObject = Me
        
    Return no.RunMethod("audiovol_get"Null).AsNumber
    End Sub

    Sub Audiovolume_set(volumevalue As Float)
        
    Dim no As NativeObject = Me
        no.RunMethod(
    "audiovol_set:"Array(volumevalue))
    End Sub

    #If OBJC
    @import MediaPlayer;
    - (void) audiovol_hide
    {
        //following hides "general audio volume HUD" - see:
        //http://stackoverflow.com/questions/7430985/hide-grey-volume-overlay-when-using-mpvolumeview
        MPVolumeView *volumeView = [[MPVolumeView alloc] initWithFrame:CGRectMake(-2000., -2000., 0.f, 0.f)];
        NSArray *windows = [UIApplication sharedApplication].windows;
        volumeView.alpha = 0.1f;
        volumeView.userInteractionEnabled = NO;
        if (windows.count > 0) {
            [[windows objectAtIndex:0] addSubview:volumeView];
        }
    }
    - (float) audiovol_get
    {
        MPVolumeView *volumeView = [[MPVolumeView alloc] init];
        //find general audio volumeViewSlider
        UISlider* volumeViewSlider = nil;
        for (UIView *view in [volumeView subviews]){
            if ([view.class.description isEqualToString:@"MPVolumeSlider"]){
                volumeViewSlider = (UISlider*)view;
                break;
            }
        }
        // get general audio volume here:
        static float volval = .123;
        // if comment next line out then this method returns .123 - proving that next
        // line actually always returns 0 (at least in iOS 9.3)
        volval = [volumeViewSlider value];
        return volval;
    }
    - (void) audiovol_set: (float) volval
    {
        MPVolumeView *volumeView = [[MPVolumeView alloc] init];
        //find general audio volumeViewSlider
        UISlider* volumeViewSlider = nil;
        for (UIView *view in [volumeView subviews]){
            if ([view.class.description isEqualToString:@"MPVolumeSlider"]){
                volumeViewSlider = (UISlider*)view;
                break;
            }
        }
        // set general audio volume here:
        [volumeViewSlider setValue:volval animated:YES];
        [volumeViewSlider sendActionsForControlEvents:UIControlEventTouchUpInside];
    }
    #End If
    A few notes:

    (1) Re getting the current general audio volume:​

    Above I say "Theoretically(**) ..." - if you look closely at the code at the bottom of the - (float) audiovol_get Objective C method you will see that I could only ever get a value of 0 returned.

    I could only test on my iPhone 4s running iOS 9.3 and there are some google hits that suggest that [volumeViewSlider value] is broken in iOS 9, for example:

    http://stackoverflow.com/questions/35214008/how-to-change-the-volume-in-ios9

    I would be really interested to know if getting the current general audio volume with this snippet works in earlier iOS releases.
    (2) This only gives control of general audio volume - for control of ringer volume look at the sister snippet here:

    Any and all comments welcome...
     

    Attached Files:

    Last edited: Mar 28, 2016
    moster67 and Filippo like this.
  2. salvadoro

    salvadoro Member Licensed User

    Hi,

    For newer versions of iOS you need to add a delay

    Code:
    - (void) audiovol_set: (float) volval 

    {

        MPVolumeView *volumeView = [[MPVolumeView alloc] init];

        //find general audio volumeViewSlider

        UISlider* volumeViewSlider = nil;

        
    for (UIView *view in [volumeView subviews]){

            
    if ([view.class.description isEqualToString:@"MPVolumeSlider"]){

                volumeViewSlider = (UISlider*)
    view;

                break;

            
    }

        }

        // set general audio volume here:

          //[volumeViewSlider setValue:volval animated:YES];

        //[volumeViewSlider sendActionsForControlEvents:UIControlEventTouchUpInside];

       

        // For newer version we need to add a delay

        // How to change volume programmatically on iOS 11.4

        // https://stackoverflow.com/questions/50737943/how-to-change-volume-programmatically-on-ios-11-4/50740074

        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

            [volumeViewSlider setValue:volval animated:YES];

            [volumeViewSlider sendActionsForControlEvents:UIControlEventTouchUpInside];

          });

       

    }
     
    moster67 likes this.
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice