Android ringtone multimedia volume, mute, vibration (with source code)

Introduction:

Android provides an API that can control the native system. AudioManager is used to manage volume, mode (mute, vibration, vibration plus sound, etc. modes). You can use Vibrator and HapticFeedback to manage phone vibrations. I will explain it with a case study. First, I will talk about the volume control of the system gently, and then I will talk about the sexy vibrator… Bah… it is an oscillator.

1. AudioManager (audio management)

1. How to play music

//1. Custom audio file test
 MediaPlayer player = MediaPlayer.create(getApplicationContext(), R.raw.test);

//2. System phone ringtone TYPE_RINGTONE\system notification ringtone TYPE_NOTIFICATION
Uri uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);

MediaPlayer mMediaPlayer = new MediaPlayer();
mMediaPlayer.setDataSource(PlayerService.this, uri);

---------------------------------------------- --------------
 mMediaPlayer.setLooping(true); // Set loop playback
               
 mMediaPlayer.prepare();//Prepare
               
 mMediaPlayer.start();//Play

2. Modify the volume method

First, get the audio management instance object. AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);

Then, set the volume. For example audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 30, 0);

(1) Modify the volume

adjustVolume(int direction, int flag) //Modify volume

Direction: As the name suggests, when a click event occurs, the volume increases when going up, the volume decreases when going down, and the volume remains unchanged.

  • AudioManager.ADJUST_LOWER(lower)
  • AudioManager.ADJUST_RAISE(raise)
  • AudioManager.ADJUST_SAME (locked unchanged)

(2) Modify type and volume

adjustStreamVolume(int streamType,int direction, int flag) //Modify type and volume

streamType (audio stream type): specifies the sound type, there are the following sound types:

STREAM_ALARM: mobile alarm STREAM_MUSIC: mobile music

STREAM_RING: Phone ringtone STREAM_SYSTEAM: Phone system

STREAM_DTMF: Tone STREAM_NOTIFICATION: System prompt

STREAM_VOICE_CALL:Voice call

Flag (flag): It is actually the manifestation of the volume after the click event occurs.

  • AudioManager.FLAG_SHOW_UI: The volume adjustment interface will pop up.
  • AudioManager.FLAG_ALLOW_RINGER_MODES: The lowest sound will vibrate

(3) Set the volume

setStreamVolume(int streamType, int index, int flags)//Set the volume directly

index (volume value), int type.

4. Practical small cases

Write a SeekBar control in XML

<android.support.v7.widget.AppCompatSeekBar
    android:id="@ + id/play_volume"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="50dp"/>

Code in Activiy

declare variables

private MediaPlayer player;//Test music
private int maxVolume, currentVolume;//Volume value
private AudioManager audioManager;//Audio management class
private SeekBar mView_sb_play_volume; //Control

Initialization operation

 mView_sb_play_volume = (SeekBar) findViewById(R.id.play_volume);//Sliding progress bar

        myRegisterReceiver();//Register the broadcast of synchronized updates
        player = MediaPlayer.create(getApplicationContext(), R.raw.test);//Custom audio file test
        audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);//Instance
        maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC); //Get the maximum volume of the system
        mView_sb_play_volume.setMax(maxVolume);
        currentVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC); //Get the current value
        mView_sb_play_volume.setProgress(currentVolume);

        player.setLooping(true);
        mView_sb_play_volume.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                player.pause();
            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                player.start();
            }

            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
                audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, progress, 0);
                seekBar.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
// seekBar.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
// seekBar.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);

//Constant value of HapticFeedbackConstants, there are three touch vibration methods we need to use:
// One is LONG_PRESS (long press),
//The second one is FLAG_IGNORE_VIEW_SETTING (not affected by the attribute setting of view in Xml, that is, not affected by isHapticFeedbackEnabled()),
//The third one is FLAG_IGNORE_GLOBAL_SETTING (not affected by system settings, that is, not affected by whether vibration feedback is turned on)
            }
        });

Broadcast monitoring volume changes

 //Register the broadcast received when the volume changes
    private void myRegisterReceiver(){
        MyVolumeReceiver mVolumeReceiver = new MyVolumeReceiver();
        IntentFilter filter = new IntentFilter();
        filter.addAction("android.media.VOLUME_CHANGED_ACTION") ;
        registerReceiver(mVolumeReceiver, filter);
    }

    //Interface display when processing volume changes
    private class MyVolumeReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            //If the volume changes, change the position of the seekbar
            if(intent.getAction().equals("android.media.VOLUME_CHANGED_ACTION")){
//AudioManager mAm = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
                //Current media volume
                currentVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
                mView_sb_play_volume.setProgress(currentVolume);
            }
        }
    }

2. HapticFeedback (vibration feedback)

First, explain that this vibration method does not require setting vibration permissions! ! No need to set vibration permission! ! No need to set vibration permission! ! Say important things three times.

As you can see from the above case, you can customize the trigger vibration in the SeekBar settings change monitoring. Let’s take a look at the source code explanation first.

As shown below, clicking will also trigger vibration feedback:

 click.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                v.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);

            }
        });

Now let’s go to the performHapticFeedback source code to see what is executed. View.performHapticFeedback source code:

/**
     *BZZZTT!!1!
     *
     * <p>Provide haptic feedback to the user for this view.
     *
     * <p>The framework will provide haptic feedback for some built in actions,
     * such as long presses, but you may wish to provide feedback for your
     * own widget.
     *
     * <p>The feedback will only be performed if
     * {@link #isHapticFeedbackEnabled()} is true.
     *
     * @param feedbackConstant One of the constants defined in
     * {@link HapticFeedbackConstants}
     */
    public boolean performHapticFeedback(int feedbackConstant) {
        return performHapticFeedback(feedbackConstant, 0);
    }

Three knowledge points are explained here:

1. Vibration will be triggered only when isHapticFeedbackEnabled() is true. Later, we will explain why the vibration will not be triggered when it is false.

In xml, you can set it through android:hapticFeedbackEnabled=”false|true”

In java code, it can be set through view.setHapticFeedbackEnabled(boolean), but the default is true.

2. There are three constant values we need to use for HapticFeedbackConstants:

  • LONG_PRESS (long press);
  • FLAG_IGNORE_VIEW_SETTING (not affected by view settings, that is, not affected by isHapticFeedbackEnabled());
  • FLAG_IGNORE_GLOBAL_SETTING (not affected by system settings, that is, not affected by whether vibration feedback is turned on);

3. Finally, the performHapticFeedback(int feedbackConstant, int flags) method is returned.

View.performHapticFeedback(int feedbackConstant, int flags) source code:

/**
     *BZZZTT!!1!
     *
     * <p>Like {@link #performHapticFeedback(int)}, with additional options.
     *
     * @param feedbackConstant One of the constants defined in
     * {@link HapticFeedbackConstants}
     * @param flags Additional flags as per {@link HapticFeedbackConstants}.
     */
    public boolean performHapticFeedback(int feedbackConstant, int flags) {
        if (mAttachInfo == null) {
            return false;
        }
        //noinspection SimplifiableIfStatement
        if ((flags & amp; HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING) == 0
                 & amp; & amp; !isHapticFeedbackEnabled()) {
            return false;
        }
        return mAttachInfo.mRootCallbacks.performHapticFeedback(feedbackConstant,
                (flags & amp; HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING) != 0);
    }

Look at the if statement on line 15. When flags=0, flags & amp; HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING is 0, and isHapticFeedbackEnabled() is false. The entire condition is true, so line 17 will be executed and return directly. This is why the performHapticFeedback(int feedbackConstant) method must trigger vibration when isHapticFeedbackEnabled() is true. Let me talk here, & amp; is a bitwise AND and returns a numerical value, & amp; & amp; is a logical AND and returns a Boolean value. Lines 19-20 are the codes that trigger the underlying vibration. The subsequent code will not be analyzed.

Case:

On a click event, a vibration will be triggered:

click.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                v.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);//Long press
            }
        });

If the sentence android:hapticFeedbackEnabled=”false” is added to the xml, the click event will have no vibration effect. As follows:

<Button
        android:layout_width="wrap_content"
        android:id="@ + id/click"
        android:layout_height="wrap_content"
        android:hapticFeedbackEnabled="false"
        android:text="make" />

If you want it to vibrate at this time, you can do it as follows:

click.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                v.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS
,HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);//Ignore view attribute settings
            }
        });

Remember before this article, I talked about turning on the vibration on touch switch in the settings. In fact, the user can still make it vibrate without turning it on. Just use the following method:

click.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                v.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS
,HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
            }
        });

3. Vibrator (oscillator)

Vibrate system permissions

Get an instance:

 Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);

Two vibration modes:

1. Vibrate according to the specified mode:

 vibrator.vibrate(new long[]{100,1000,1000,1000}, -1);

Array parameter meaning:

  • The first parameter is to wait for the specified time before starting to vibrate, and the vibration time is the second parameter; the following parameters are the waiting time for vibration and the time to vibrate;
  • The second parameter is the number of repetitions, -1 means no repetition, 0 means constant vibration;

2. Specify the vibration time, the data type is long, the unit is milliseconds, one millisecond is 1/1000 seconds

vibrator.vibrate(2000);

Cancel vibration:

Note: If the vibration is to vibrate all the time, if you do not cancel the vibration, it will still vibrate even if you exit.

vibrator.cancel();

Case:

XML

<Button
    android:id="@ + id/vibrator1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="35dp"
    android:text="Vibrate mode is intermittent"/>


<Button
    android:id="@ + id/vibrator2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="20dp"
    android:text="Vibrate mode two independence"/>

Activity

private Button vibrator1,vibrator2;//Control
private Vibrator vibrator;//vibration
vibrator1 = (Button) findViewById(R.id.vibrator1);
 vibrator2 =(Button)findViewById(R.id.vibrator2);
 vibrator1.setOnClickListener(new View.OnClickListener() {
     @Override
     public void onClick(View view) {
         vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
         vibrator.vibrate(new long[]{100,1000,1000,1000}, -1);
         //Vibrate according to the specified mode. Array parameter meaning:
         // The first parameter is to wait for the specified time before starting to vibrate, and the vibration time is the second parameter; the following parameters are the waiting time for vibration and the time to vibrate;
         //The second parameter is the number of repetitions, -1 means no repetition, 0 means constant vibration;
     }
 });
 vibrator2.setOnClickListener(new View.OnClickListener() {
     @Override
     public void onClick(View view) {
         vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
         vibrator.vibrate(2000);//Vibration specified time, data type long, unit is millisecond, one millisecond is 1/1000 second
     }
 });
//vibrator.cancel();//Cancel the vibration and stop vibrating immediately. If the vibration is to vibrate all the time, if you do not cancel the vibration, it will continue to vibrate even if you exit

Source code: Android system audio vibration demohttp://download.csdn.net/download/csdn_aiyang/9970166

Join a group to learn together, we are not fighting alone: