Android; detect if the Vibrate setting in the device is on or off, esp for the case when it rings but does not vibrate

孤人 提交于 2019-12-02 18:31:41

问题


App requirement: To detect when a phone is on Ringing mode with the Vibrate Setting being OFF so the problem comes down to : detect whether the Vibrate Setting is OFF or ON

Relevant information:

To start with, Vibrator has no method like isVibratorModeOn() and the Flags related to Vibrate and EXTRA_VIBRATE_... are all marked deprecated with:

This constant was deprecated in API level 16. Applications should maintain their own vibrate policy based on current ringer mode that can be queried via getRingerMode().

But under getRingerMode(), we won't exactly know if the vibrate setting is off or not with RINGER_MODE_NORMAL;

It will vibrate if the vibrate setting is on.

Now the getVibrateSetting() is also deprecated.

Code which works for detecting the RINGER_MODE on *most devices and o.s. versions including Android M on Nexus 6:

 if(audioManager.getRingerMode()!=AudioManager.RINGER_MODE_SILENT){
            if (audioManager.getStreamVolume(AudioManager.STREAM_RING) != 0) {  

*Exception: Nexus 5 - 5.1.1, probably for all Lollipop versions

I feel its very surprising if this has been missed or i've made the big(gest) silly mistake by missing something obvious. Hopefully, this isn't a waste of your time.

Here's more to explain the problem:
RINGER_MODE_SILENTscenario covered:

RINGER_MODE_VIBRATE scenario covered:

DETECTING THIS IS THE PROBLEM:

Screenshot crops from Android M, Nexus 6


回答1:


Modified solution to the one given:

Even for API < 23 and API 23 this works fine. It seems fine if you do not use deprecated methods for previous APIs. Tested on Samsung, Motorola, OnePlus, Google Pixel, Google Nexus

AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
                int mode = am.getRingerMode();

            switch (mode) {
                case AudioManager.RINGER_MODE_NORMAL:
                    if ((1 == Settings.System.getInt(getContentResolver(), Settings.System.VIBRATE_WHEN_RINGING, 0))) {
                        // code here
                        Toast.makeText(getApplicationContext(), "=== ring + vibrate mode ===", Toast.LENGTH_LONG).show();
                    } else {
                        // code here
                        Toast.makeText(getApplicationContext(), "=== ring + no vibrate mode ===", Toast.LENGTH_LONG).show();
                    }
                    break;

                case AudioManager.RINGER_MODE_SILENT:
                    // code here
                    Toast.makeText(getApplicationContext(), "=== in silent mode ===", Toast.LENGTH_LONG).show();
                    break;

                case AudioManager.RINGER_MODE_VIBRATE:
                    // code here
                    Toast.makeText(getApplicationContext(), "=== in vibrate mode ===", Toast.LENGTH_LONG).show();
                    break;
            }



回答2:


Try this,

for detect vibrate

public static boolean detectVibrate(Context context){
    boolean status = false;
    AudioManager am = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
    if(am.getRingerMode() == AudioManager.RINGER_MODE_VIBRATE){
        status = true;
    } else if (1 == Settings.System.getInt(context.getContentResolver(), "vibrate_when_ringing", 0)) //vibrate on
        status = true;
    return status;
}

check ringer is on.

public static boolean checkRingerIsOn(Context context){
    AudioManager am = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
    return am.getRingerMode() == AudioManager.RINGER_MODE_NORMAL;
}

Happy to Help you.




回答3:


Update:

the solution is a bit twisted, using a deprecated method in one of the loops, it has worked on all devices i have tested; those of companies; motorola, samsung, htc, lg, xiaomi, micromax, sony

audioManager = (AudioManager) getApplicationContext().getSystemService(Context.AUDIO_SERVICE);

if (audioManager.getRingerMode() != AudioManager.RINGER_MODE_SILENT) {
   //ensuring it is not on silent
   if (audioManager.getRingerMode() == AudioManager.RINGER_MODE_VIBRATE) {
      //  if it is on vibrate mode , esp for api 23
   } else if (audioManager.getStreamVolume(AudioManager.STREAM_RING) != 0) {
             //  else check whether the volume is not 0
             if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.LOLLIPOP_MR1) {
             if (audioManager.getVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER) == AudioManager.VIBRATE_SETTING_ON  
 || audioManager.getVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER) == AudioManager.VIBRATE_SETTING_ONLY_SILENT) { //need to add this to detect a specific scenario in xiaomi device
       // if the device o.s version is not 23 this part works
              }
            }
if ((1 == Settings.System.getInt(ApplicationController.getInstance().getContentResolver(), Settings.System.VIBRATE_WHEN_RINGING, 0))) { 
       // the constant VIBRATE_WHEN_RINGING was added in api 23
       }
}


来源:https://stackoverflow.com/questions/32709260/android-detect-if-the-vibrate-setting-in-the-device-is-on-or-off-esp-for-the-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!