Android headphone detection - java

I have an app that will speak text messages to the user. I want to make it so that when the user hits a button called "Headphones on" the app will only speak to it when headphones are detected. Is there a command that will allow me to detect if headphones are plugged in or not?

There is a broadcast made when the headphones are plugged in: http://developer.android.com/reference/android/content/Intent.html#ACTION_HEADSET_PLUG
You need to register a BroadcastReceiver to receive this and perform your required actions.

It seems in this case you just want to check if headphone are connected before to start the audio playout, so you should use audioManager.isWiredHeadsetOn() like this:
AudioManager audioManager = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
if(audioManager.isWiredHeadsetOn()) {
// Play audio...
}

Related

Audio output broadcasting and Force Routing - Android

I'm trying to build a broadcast that every time audio output route is changed it would route it to a device of choice instead (both in calls and when playing media/music).
for example: when getting a call with plugged/Bluetooth headset and then the user decides to click on the speaker icon on the phone, I need the app to route it back to the headset.
I succeeded to change the audio output on a WIRED headset with a click of a button with following code:
mAudioManager.setMode(AudioManager.MODE_IN_CALL);
mAudioManager.setSpeakerphoneOn(false);
and on a Bluetooth headset with the following (not in calls, works on media/music only):
mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
mAudioManager.startBluetoothSco();
mAudioManager.setBluetoothScoOn(true);
mAudioManager.setSpeakerphoneOn(false);
I have two problems:
When I click on the speaker icon in the call screen to stop using my Bluetooth headset and then click the button on my app to redirct the route to my Bluetooth headset with the above code it doesn't work :(
Didn't manage to find a way to broadcast audio output change in order for the above code to work automatically without a need to press my app's button. only came across the following code that only suppose to work on a Bluetooth headset and not plugged headset and it's don't even work for me on the Bluetooth headset.
private final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)) {
int state = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE, -1);
switch (state) {
case BluetoothHeadset.STATE_AUDIO_CONNECTED:
Toast.makeText(context, "Bluetooth Connected", Toast.LENGTH_SHORT).show();
case BluetoothHeadset.STATE_AUDIO_DISCONNECTED:
Toast.makeText(context, "Bluetooth Disconnected", Toast.LENGTH_SHORT).show();
mAudioManager.setMode(AudioManager.MODE_IN_CALL);
mAudioManager.startBluetoothSco();
mAudioManager.setBluetoothScoOn(true);
mAudioManager.setSpeakerphoneOn(false);
break;
}
}
}
};
Thanks so much in advance for the help!
any answer would help.

Is there possibility to "Auto-start" application when users become inactive?

I have to create an app, which detects user inactivity, and then start activity which displays some videos with WebView, and then when displaying with WebView is finished, it has to play videos from SDCard. I've already handled part with WebView and SDCard (with JavaScriptInterface etc.)
This application has to work with API 19 all the way to the newest one.
The question is - Is there a possibility to detect if user is inactive and start my application, or keep the app running in background, and then start activity in the foreground after the user becomes inactive for certain time?
I'm not trying to play ads, when user is not looking at his screen. Application is for my client, who have stores with all kind of electrical equipments, including smartphones. The goal is to play video presentations with hardware details specific for each smartphone (informations about processor, ram, camera, screen etc.).
In short: I have to make an app which is similar to "Demo Apps" created for example by Samsung (playing some kind of presentations on screen).
So far I've read and tested things like:
1) BroadcastReceiver with combination of ACTION_SCREEN_OFF / ACTION_SCREEN_ON events.
Receiver works properly, I can detect this event and then start activity, but... The screen is already off so i can't see the displayed activity - it's visible running in the foreground after unlocking the phone. Is there a way to unlock the phone when the event is received?
That's my code so far.
EventReceiver Class:
class EventReceiver: BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
StringBuilder().apply {
append("Action: ${intent.action}\n")
append("URI: ${intent.toUri(Intent.URI_INTENT_SCHEME)}\n")
toString().also { log ->
Log.d(TAG, log)
Toast.makeText(context, log, Toast.LENGTH_LONG).show()
}
}
if (intent.action == Intent.ACTION_SCREEN_OFF) {
val i = Intent(context, MainActivity::class.java)
context.startActivity(i)
}
}
}
MainActivity Class:
val br : BroadcastReceiver = EventReceiver()
val filter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION).apply {
addAction(Intent.ACTION_SCREEN_OFF)
addAction(Intent.ACTION_SCREEN_ON)
addAction(Intent.ACTION_BOOT_COMPLETED)
}
2) Foreground Services - I read that this is a great way to make some asyc stuff in the background and show notifications to user. Is there a way to start the activity with it?
3) Job Scheduler
4) Daydream / Dream Service - it actually works great with almost every API and manufacturer, but.. there's no way to set the app as Screen Saver on Huawei/Honor smartphones, at least from phone settings, I've read that this is possible with ADB etc. but this is not an option that I can use here.
It seems that none of these fullfill my expectations.

Programatically disable ALL sound and vibration in android

I want to disable ALL sound and vibration from the android device. As per the answers to similar questions, I'm currently using the following code to mute all the audio streams, set the ringer mode to silent, and to fake a voice call scenario:
AudioManager amanager=(AudioManager)getSystemService(Context.AUDIO_SERVICE);
//DOESNT DISABLE ALARM CLOCK
amanager.setStreamMute(AudioManager.STREAM_NOTIFICATION, true);
amanager.setStreamMute(AudioManager.STREAM_ALARM, true);
amanager.setStreamMute(AudioManager.STREAM_RING, true);
amanager.setStreamMute(AudioManager.STREAM_SYSTEM, true);
amanager.setStreamMute(AudioManager.STREAM_DTMF, true);
amanager.setStreamMute(AudioManager.STREAM_MUSIC, true);
amanager.setStreamMute(AudioManager.STREAM_VOICE_CALL, true);
//disables vibrate and sound of ringer
amanager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
//fakes voice call...changes alarm to single tone+vibrate
amanager.setMode(AudioManager.MODE_IN_CALL);
amanager.setStreamSolo(AudioManager.STREAM_VOICE_CALL, true);
This works for disabling music and incoming calls, but, as noted in the comments, the android's built-in alarm clock app is still able to produce sound and vibration.
Does anyone know how to truly disable ALL sound and vibrations? Or venture a guess as to why the alarm clock app seems to by bypassing the audio streams?
setStreamMute did not work for me to mute the alarm, but using setStreamVolume for STREAM_ALARM setting volume to zero did. It is necessary to restore the alarm volume afterwards.
For example like this:
AudioManager manager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
manager.setStreamVolume(AudioManager.STREAM_ALARM, 0, AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);

Observing volume changes made by apps

I have a ContentObserver registered to android.provider.Settings.System that should observe changes of any audio volume. It is notified as expected when clicking the hardware volume buttons but is not notified when I change the audio volume via AudioManager.setStreamVolume or AudioManager.adjustStreamVolume.
Here's how my ContentObserver looks like:
// this is a Service
this.getApplicationContext().getContentResolver().registerContentObserver(
android.provider.Settings.System.CONTENT_URI,
true, new ContentObserver(new Handler()) {
public void onChange(boolean selfChange) {
Log.d("ContentObserver", "got notified");
}
});
And here my call to AudioManager.adjustStreamVolume:
// this.context is the activities context
this.context.getSystemService(Context.AUDIO_SERVICE).adjustStreamVolume(
AudioManager.STREAM_RING, AudioManager.ADJUST_LOWER,
AudioManager.FLAG_SHOW_UI);
I have read this and that post and the AudioManager and Settings.System documentation and can not find a reason why the Observer is notified when changing the volume with the volume buttons but not when changing it with the AudioManager.
Thanks for the help!
The AudioManager does broadcast an intent
android.media.VOLUME_CHANGED_ACTION`
But this is not part of the official documentation. So this might change in future releases. But you could use this atleast for gingerbread devices.
you can find more about the extras in the intent from here

Disable SMS and Email Notifications in Android

Is there any way within (or non-standard way) to disable email and sms alerts / notifications when an Android application is running? I found a way to mute the phone ringer, but I want to stop the audio / vibrate alerts from occuring. I've seen some bed time clock apps that mute notifications and they work fine.
Any thoughts to how to code this?
According to the API docs:
AudioManager aM = getSystemService(Context.AUDIO_SERVICE);
aM.setRingerMode(AudioManager.RINGER_MODE_SILENT);
aM.setVibrateSetting (AudioManager.VIBRATE_TYPE_NOTIFICATION, AudioManager.VIBRATE_SETTING_OFF)
public void setRingerMode (int ringerMode)
Since: API Level 1
Sets the ringer mode.
Silent mode will mute the volume and will not vibrate. Vibrate mode will mute the volume and vibrate. Normal mode will be audible and may vibrate according to user settings.
Parameters
ringerMode The ringer mode, one of RINGER_MODE_NORMAL, RINGER_MODE_SILENT, or RINGER_MODE_VIBRATE.
public void setVibrateSetting (int vibrateType, int vibrateSetting)
Since: API Level 1
Sets the setting for when the vibrate type should vibrate.
This method should only be used by applications that replace the platform-wide management of audio settings or the main telephony application.
Parameters
vibrateType The type of vibrate. One of VIBRATE_TYPE_NOTIFICATION or VIBRATE_TYPE_RINGER.
vibrateSetting The vibrate setting, one of VIBRATE_SETTING_ON, VIBRATE_SETTING_OFF, or VIBRATE_SETTING_ONLY_SILENT.

Categories