Alternative for AudioManager.setRingerMode() in Android 5.0 (API 21) - android

I used AudioManager.setRingerMode() to handle the device volume in my application using:
AudioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT) to turn off vibration and sound.
AudioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE) to turn off the sound and turn on the vibration.
AudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL) to turn on the sound and turn on the vibration.
In other words, I was able to get control of the device volume and reach all "modes".
But, it's not possible to handle all modes of device volume in Android 5.0 using only the AudioManager.setRingerMode.
As per the documentation:
Setting the device to RINGER_MODE_SILENT causes the device to enter the new priority mode. The device leaves priority mode if you set it to RINGER_MODE_NORMAL or RINGER_MODE_VIBRATE.
How can I handle all modes (none, vibration in priority, sound in priority, vibration in all, sound in all) of device volume in Android 5.0?

With the new 5.0 API's there are a bunch of methods that can be used for setting the ringer/vibrate.
setVibrate (long[] pattern)
This method controls the vibration of the device. Takes a long in which the first value indicates the number of milliseconds to wait before turning on the vibrator. More details:
http://developer.android.com/reference/android/os/Vibrator.html#vibrate(long[], int)
http://developer.android.com/reference/android/app/Notification.Builder.html#setVibrate(long[])
setDefaults (int defaults)
This one sets the notifications properties i.e. SOUND,VIBRATE,ALL etc etc.
From the docs:
The value should be one or more of the following fields combined with
bitwise-or: DEFAULT_SOUND, DEFAULT_VIBRATE, DEFAULT_LIGHTS.
http://developer.android.com/reference/android/app/Notification.Builder.html#setDefaults (int defaults)
Hope this helps.

Related

How to prevent Android from automatically vibrating on MediaPlayer playback

I have an alarm clock app and some users complain phone vibrates during alarm, while vibrations should be disabled.
After some digging I have found out, that on some devices there's a system option for device to vibrate along alarm music. For example in my test Pixel 4 it is located at Settings->Sound&Vibration->Vibration&Heptics->Alarm vibration.
What this setting, enabled by default, causes, is that vibrations try to "emulate" the music played through MediaPlayer and I cannot find a way to prevent that from happening from within the app or even detect if such setting is present/enabled.
Anyone knows how to get rid of that?
Here's a sample method I used for testing:
private fun startThePlayer(context: Context, playInLoop: Boolean = true) {
try {
mediaPlayer.reset()
mediaPlayer.isLooping = playInLoop
val uri = Settings.System.DEFAULT_RINGTONE_URI
mediaPlayer.setDataSource(context, uri)
mediaPlayer.setOnPreparedListener {
mediaPlayer.start()
}
mediaPlayer.prepareAsync()
} catch (e: Exception) {
log(e.toString())
}
}
VIBRATE permission is necessary for this to work.
Effect on Pixel 4 with Android 13:
Device is vibrating, as if trying to "emulate" the music played. Vibrations strength depends on value set in device's settings, completely ignoring volume set for alarm's music, and also messing up any vibrations set directly in my app.
What's interesting, is that for some reason Android's default clock app ignores this settings and device doesn't vibrate during it's alarms.
First, I suggest that you use android's VibratorManager to control your app vibrations settings (this is how the android development team called this service.. how bizarre). Use the getDefaultVibrator and cancel methods to stop any vibrations produced by your app (official docs to the rescue)
Second, because your app is an alarm clock please consider using the setWakeMode which will allow you to keep your app running in the background regardless to the display (in order to prevent the alarm from stopping if the screen is off). Here's the method documentation and also the PowerManager flags documentation
Hope you will find the right combination to satisfy your needs

how to wake up system from sleep using gpio-keys interrupt

UPDATE : I changed the keyboard layout file (gpio-keys.kl) to the following:
key 115 POWER WAKE
key 114 POWER WAKE
As seen, I now registered the volume buttons as POWER keys in Android and it wakes up the system. However, I wish to have any generic gpio-key wake up the system. The fact that changing the key layout file as above works tells me that perhaps the issue is on the Android side and not the Linux kernel side. Not sure. Perhaps there are files in Android (policy files, etc.) where I can provide a wake capability to the gpio-key of choice, much the same way as the POWER key has this wake capability.
Please let me know your thoughts.
ORIGINAL :
As for some background, my hardware is a Samsung Galaxy S2-i777, which runs on an Exynos4210 SoC (ARM-based processor). OS is LineageOS 14.1. I'm trying to wake up my system from sleep using a gpio-keys interrupt but I have been unsuccessful.
I've configured gpio-keys in my board file (no device tree as old kernel version). A snippet of where I defined my gpio-keys is below:
struct gpio_keys_button u1_buttons[] = {
{
.code = KEY_VOLUMEUP,
.gpio = GPIO_VOL_UP,
.active_low = 1,
.type = EV_KEY,
.wakeup = 1,
.isr_hook = sec_debug_check_crash_key,
.debounce_interval = 10,
},
};
I omitted registered platform section, etc. but can show if necessary. As seen above, I set the boolean property wakeup to 1 to enable my gpio GPIO_VOL_UP to act as a wakeup source. Also as seen, it is my volume buttons that I want to use as my gpio-keys.
I also modified my key layout file (gpio-keys.kl) as seen below:
key 115 VOLUME_UP WAKE
key 114 VOLUME_DOWN WAKE
When I check my local terminal in LineageOS, I see that my gpio-keys are defined as wakeup_sources and wakeup is enabled. I also see that my volume buttons are generating interrupts (cat /proc/interrupts).
When my system goes to sleep, the volume buttons (gpio-keys) do not wake up my system. Only thing that wakes up my system is the power button (which appears to be a gpio-key as well).
What do you think the issue might be? What are the general steps necessary to waking up the system using gpio-keys interrupts? Even if it is not specific to my hardware, perhaps a general layout of these steps or certain considerations will help me since I might be missing something. Thanks!
First, I would suggest to check the console for any log messages when the Volume button is pressed in the suspend state.
Second, I would like to suggest you to probe the the HW lines to check whether an interrupt is actually generated whenever you press the Volume button when the system is in deep sleep state.
If the interrupts aren't generated, then the HW section might be disabled in the low-power mode and you wouldn't be able to wakeup the system.

Change or get current vibration intensity or make forceful vibration

I've a diagnostic app which currently tests vibration including other kind of tests as well. In case of vibration, it vibrates and asks user to input the count of vibration. Here is the code snippet I've been using,
vibrator = (Vibrator) getContext().getSystemService(Context.VIBRATOR_SERVICE);
vibrator.vibrate(vibrationPattern, -1);
Now, I got a complain that it's not been vibrating, The reason was Vibration intensity was set to 0 in settings of his device.
Please help me how I can overcome this, I've two options,
1. Request user to increase vibration intensity.
Is it possible to get how much vibration intensity is set in settings and redirect user to the belonging page?
2. Make a forceful vibration somehow.
Is it possible to vibrate going beyond the vibration intensity settings?
I've tried many possible ways but couldn't get through it. Any help will be appreciated.
You can control the pattern and length of the vibration, but I don't think you can change its intensity.
This would remain limitation, you may like to redirect user to sound settings if the required feature didn't worked for him/her with an explaination message.
Intent intent = new Intent(Settings.ACTION_SOUND_SETTINGS);
startActivity(intent);
For complete Settings Intents
Hope it helps.

Programmatically muting a call in Android

I am revisiting an old question posted (in early 2014 mind) here:
What permissions are needed to programmatically mute a phone call, from a background app?
How to Mute Phone Call Stream (uplink) while calling on Android
How to mute audio speaker in android
How does setMicrophoneMute() work?
For a recent project, I am building an app that can mute an existing call and get an audio recording from the user. I know that audio-recording in-call works, that's no problem (recording only the user mic). Now i can also reduce the volume programmatically, which i did using the code On my Github, Here
Specifically, I am using the AudioManager class to set the volume to 0 and also muting as a backup, but doesn't work.. I am wondering whether this is a Samsung specific issue or not..
mgr.setStreamVolume(stream, progress, AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
mgr.adjustVolume(AudioManager.ADJUST_MUTE, AudioManager.FLAG_VIBRATE);
boolean a = mgr.isVolumeFixed();
Log.d("MUTING", "Volume fixed: "+a);
boolean streamMuteStatus = mgr.isStreamMute(stream);
Log.d("MUTING", "Stream Mute Status: "+streamMuteStatus);
I am printing out the boolean variables above for testing purposes, but both print out 'False'.
But the Samsung S5 device is not allowing me to set the volume to 0 at all. This is true even when adjusting the in-call volume using the volume slider.. The slider does not physically move to the leftmost position on the seekbar. See figure below for the leftmost position i can drag to:
Anyone have any ideas about how i can mute the incoming call stream?

How can I access the audio 'Priority Mode' on a device running Android 5.0?

Android 5.0 includes a new way to control which apps are allowed to make noise on your device: when you press the volume button, the popup now lets you to choose None (completely silent), Priority (only priority notifications make sound), or All (everything is allowed to make noise.)
I would like my app to be able to query the device to find out which of these three modes is currently active, and also I would like to be able to change these modes (without requiring the device to be rooted). Does anyone know how to do this?
So far, all I can find is a brief reference on this changelog:
Setting the device to RINGER_MODE_SILENT causes the device to enter the new priority mode. The device leaves priority mode if you set it to RINGER_MODE_NORMAL or RINGER_MODE_VIBRATE.
This works as described, which allows me a very limited ability to change "priority mode" by modifying the ringer mode in AudioManager. That's not enough, though, as I need to be able to know exactly which of the three priority mode settings is currently active, and it would also be nice if I could change them more precisely than AudioManager allows.
I've found a solution, but this requires root to change, because this setting is in Settings.Global.
Name of setting is "zen_mode".
Values are:
ZENMODE_ALL = 0;
ZENMODE_PRIORITY = 1;
ZENMODE_NONE = 2;
EDIT: I've found another solution. Check NotificationListenerService.requestInterruptionFilter(int interruptionFilter). https://developer.android.com/reference/android/service/notification/NotificationListenerService.html
Implementation example: https://github.com/kpbird/NotificationListenerService-Example

Categories

Resources