Read out Alarm volume - android

I try to read out the Alarm volume the following way, but I always get wrong values. The ringer volume is always correct!!
That happens on every Smartphone, HTC, Samsung, Sony and even on the virtual device. What could be the problem?
private AudioManager amanager;
#Override
public void onCreate(Bundle savedInstanceState)
{
amanager = (AudioManager) this.getSystemService(Context.AUDIO_SERVICE);
}
int volume = 3;
int alarm = 3;
try{
volume = amanager.getStreamVolume(amanager.getStreamVolume(AudioManager.STREAM_RING));
alarm = amanager.getStreamVolume(amanager.getStreamVolume(AudioManager.STREAM_ALARM));
Log.i("!!!!!!!!!!", "Activity!!, Volume ringer: " + volume + " Vol Alarm: " + alarm);
}catch(IllegalArgumentException e){}

I was getting wrong values for the ringer volume. The method getStreamVolume (int streamType) gets an int and returns int. When you write:
alarm = amanager.getStreamVolume(amanager.getStreamVolume(AudioManager.STREAM_ALARM));
you're actually getting the volume of the alarm (lets say it is X), and then passing to alarm the value alarm = amanager.getStreamVolume(X);
so the result is unexpected.
change the values of volume and alarm to -
volume = amanager.getStreamVolume(AudioManager.STREAM_RING);
alarm = amanager.getStreamVolume(AudioManager.STREAM_ALARM);

Related

Leveraging Sensor batching

I'm trying to utilize the max fifo size of Accelerometer on Nexus 6
SensorManager sensorManager =
(SensorManager) getSystemService(Context.SENSOR_SERVICE);
Sensor sensor = sensorManager.getDefaultSensor(typeAccelerometer);
Log.e("test",
"Max delay: " + sensor.getMaxDelay() + " - Fifo count" + sensor.getFifoReservedEventCount()); // prints 1000000 (1 second) - Fifo count 10000
// Register the listener for this sensor in batch mode.
// Following code reports every 190ms when screen is ON, and every 10 seconds when screen is OFF. I always want every 10 seconds.
final boolean batchMode = sensorManager.registerListener(
mListener, sensor, 1000000 /* 1 second */, 10000000 /* 10 seconds */);
private final SensorEventListener mListener = new SensorEventListener() {
long lastTimeStamp;
#Override
public void onSensorChanged(SensorEvent event) {
long current = System.currentTimeMillis();
long time = current - lastTimeStamp;
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
Log.e("test",
"New ACCELERO "+ " -> "+ time + "ms -> " + (int)event.values[0] + " -> "+ (int)event.values[1] +" -> "+ (int)event.values[2]);
lastTimeStamp = current;
}
}
#Override
public void onAccuracyChanged(Sensor s, int accuracy) {
}
};
When Screen is ON, I get the events every 190ms. However, when screen is off, it obeys 10 seconds.
How do I utilize the full batching FIFO (with delayed listeners) when screen is ON, for minimal CPU impact.
Code above is fine. On Nexus 6, accelerometer doesnt batch as long as screen is ON. All other sensors do fine.
sensor.getFifoReservedEventCount() returns the amount of values it can store, i dont think its time in ms
Beware of the third argument to registerListener. It is not in seconds like you wrote:
final boolean batchMode = sensorManager.registerListener(
mListener, sensor, 1000000 /* WRONG */, 10000000);
It should be one of the following constants:
SENSOR_DELAY_NORMAL
SENSOR_DELAY_UI
SENSOR_DELAY_GAME
SENSOR_DELAY_FASTEST.
Source: https://developer.android.com/reference/android/hardware/SensorManager.html#registerListener(android.hardware.SensorEventListener,%20android.hardware.Sensor,%20int,%20int)

How to get song duration from currently playing track on other music player

I need to get the song details of the current track playing on another app. I am able to get the following details except duration through the bundle extras. Anybody please suggest me how to get the duration
String artist = intent.getStringExtra("artist");
String album = intent.getStringExtra("album");
String track = intent.getStringExtra("track");
String time = intent.getStringExtra("duration");
Yes we can get the song duration of current track which is playing on another app.I found the solution.
long milliseconds=intent.getLongExtra(MediaStore.Audio.AudioColumns.DURATION, 0);
It is working fine now :)
If the other app is also handling by you, you can set the data of duration with your Intent and can access the value from Intent in your activity.
MediaMetadataRetriever metaRetriever = new MediaMetadataRetriever();
metaRetriever.setDataSource(filePath);
String songDuration =
metaRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_DURATION);
long duration = Long.parseLong(songDuration );
String seconds = String.valueOf((duration % 60000) / 1000);
String minutes = String.valueOf(duration / 60000);
Sting time = "";
time = minutes + ":" + seconds;
// close object
metaRetriever.release();

Issue with the sound volumes in button press:

I'm developing currently an IME, and I have sound for button click. I have an option in the preferences screen to change the volume of the sounds. The SeekBar values are going from 0.0 to 1.0. Now I try to let the user to configure the volume of the buttons in the preferences screen and later I get this value and save it as mSoundVol parameter. So for the sound of the click I wrote the following method:
float soundVolume;
int maxVolume, sound;
switch (primaryCode) {
case Keyboard.KEYCODE_DELETE:
maxVolume = mAudioManager.getStreamMaxVolume(mAudioManager.FX_KEYPRESS_DELETE);
sound = mAudioManager.FX_KEYPRESS_DELETE;
Log.d(TAG+ "-volume", "chosen sound: mAudioManager.FX_KEYPRESS_DELETE");
break;
case ASCII_ENTER:
maxVolume = mAudioManager.getStreamMaxVolume(mAudioManager.FX_KEYPRESS_RETURN);
sound = mAudioManager.FX_KEYPRESS_RETURN;
Log.d(TAG+ "-volume", "chosen sound: mAudioManager.FX_KEYPRESS_RETURN");
break;
case ASCII_SPACE:
maxVolume = mAudioManager.getStreamMaxVolume(mAudioManager.FX_KEYPRESS_SPACEBAR);
sound = mAudioManager.FX_KEYPRESS_SPACEBAR;
Log.d(TAG+ "-volume", "chosen sound: mAudioManager.FX_KEYPRESS_SPACEBAR");
break;
default:
maxVolume = mAudioManager.getStreamMaxVolume(mAudioManager.FX_KEYPRESS_STANDARD);
sound = mAudioManager.FX_KEYPRESS_STANDARD;
Log.d(TAG + "-volume", "chosen sound: mAudioManager.FX_KEYPRESS_STANDARD");
}
soundVolume = maxVolume * mSoundVol;
Log.d(TAG+ "-volume", "current max volume: " + maxVolume + " current volume setting: " +mSoundVol * 100 +"%" + " volume result: " + soundVolume);
mAudioManager.playSoundEffect(sound, soundVolume);
But for some reason this does not change the volume of the sound for the user.
Can some one tell me what am I doing wrong with the AudioManager here?
Thanks.
your need to use this method for a more accurate result
AudioManager audioManager =
(AudioManager)getSystemService(Context.AUDIO_SERVICE);
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC,
[int value],
[if desired a flag]);
EDIT
Take this FLAg as example
AudioManager.FLAG_PLAY_SOUND
This means that whenever the user press the volume Button a bip will be outputed
EDIT 2
here is an implementation of the code
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC,
AudioManager.getStreamMaxVolume(),
AudioManager.FLAG_PLAY_SOUND);
The solution in my case was this:
float soundVolume;
int maxVolume, sound;
switch (primaryCode) {
case Keyboard.KEYCODE_DELETE:
sound = mAudioManager.FX_KEYPRESS_DELETE;
break;
case ASCII_ENTER:
sound = mAudioManager.FX_KEYPRESS_RETURN;
break;
case ASCII_SPACE:
sound = mAudioManager.FX_KEYPRESS_SPACEBAR;
break;
default:
sound = mAudioManager.FX_KEYPRESS_STANDARD;
break;
}
maxVolume = mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
soundVolume = maxVolume * mSoundVol;
mAudioManager.setStreamVolume(AudioManager.STREAM_SYSTEM , (int)(soundVolume * 1.5) , 0);
mAudioManager.playSoundEffect(sound);
The important thing was to pass 0 as the last parameter of the setStreamVolume method, that way this action only changes the volume without playing any other sound of showing the volume UI.

Widgets, AlarmManager and KitKat API19

Since API19 (KitKat), AlarmManager broadcasts are not acted on immediately, but batched together. The documentation says that it should act immediately in KitKat if the app is targeted to API 18 or less, but this doesnt seem to work.
Example, my clock widget is targeted to API 18 but it doesnt update when required on KitKat emulator (i dont have a device to test on). I read online that many people report their old clock widgets no longer updating on their KitKat devices.
The AlarmManager doc suggests this is to avoid wakeups, but it affects my RTC alarm also.
The docs suggest setExact, but this is only for API19+. Is there a way to trigger updates that will be processed immediately on API8+ including API19? Or is it better to add a separate AlarmManager for API19+?What could be a good solution for getting widgets to update properly on API19+ and still work properly on older devices?
One strategy that has a single solution for both pre-API19 and API19+ that works for me: replace AlarmManager's setRepeating() broadcast with a new set()/setExact() created each time the widgets are updated.This strategy allows continued use of AlarmManager's RTC alarm type, which doesnt trigger while the phone is asleep. It causes the widget to update at the intended time on any API and keeps my widget as power efficient as it was using setRepeating().Instead of creating a setRepeating() alarm in the onEnabled method in the "widget manager" class... Create a set() for API18 or less, or setExact() for API19+ in the "Update Widget" class, after the widget update code is run. Everytime the widget is updated, a new alarm is set for whatever time is next required.Here is a section of code (incomplete) from within onStartCommand() in the "updateservice" class, that is called by both onEnabled() and the broadcast receiver class.
public int onStartCommand(Intent intent, int flags, int startId) {
Log.w(LOG, "UpdateService.onStartCommand activated");
// reset the time dependent millis addition
long alarmAddMillis = 0;
// get time instance and values
Calendar rightNow = Calendar.getInstance();
int thisMin = rightNow.get(Calendar.MINUTE);
int thisHour = rightNow.get(Calendar.HOUR);
// set correct hour values to update widget
nextHour = thisHour + 1;
if (thisHour == 0) {thisHour = 12;}
if (nextHour == 13) {nextHour = 1;}
// set text values based on minutes
// set the values for the next alarm time
if (thisMin >= 0 && thisMin <= 6) {
clockH = thisHour; nextAlarmMin = 8; alarmAddMillis = 0;}
if (thisMin >= 7 && thisMin <= 21) {
clockH = thisHour; nextAlarmMin = 22; alarmAddMillis = 0;}
if (thisMin >= 21 && thisMin <= 35) {
clockH = thisHour; nextAlarmMin = 37; alarmAddMillis = 0;}
if (thisMin >= 36 && thisMin <= 50) {
clockH = nextHour; nextAlarmMin = 52; alarmAddMillis = 0;}
if (thisMin >= 51 && thisMin <= 59) {
clockH = nextHour; nextAlarmMin = 8; alarmAddMillis = 3600000;}
----CODE FOR UPDATING THE WIDGETS GOES IN HERE----
// cancel any unsent alarm
if (alarmManager != null){
alarmManager.cancel(pendingIntent);
Log.w(LOG, "UpdateService.onStartCommand unsent alarm canceled");}
// SET UP THE NEXT ALARM
// set the time using values set above
Calendar nextAlarm = Calendar.getInstance();
// add one hour of millis if its for the next hour
nextAlarm.setTimeInMillis(System.currentTimeMillis() + alarmAddMillis);
// set the correct minute
nextAlarm.set(Calendar.MINUTE, nextAlarmMin);
nextAlarm.set(Calendar.SECOND, 0);
nextAlarm.set(Calendar.MILLISECOND, 0);
// request the alarm
alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent usIntent = new Intent(this, AlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(this, 0, usIntent, 0);
// ACCOUNT FOR DIFFERENT APIs HERE...
// use onExact for API19+
int currentApiVersion = android.os.Build.VERSION.SDK_INT;
if (currentApiVersion <= 18) {
alarmManager.set(AlarmManager.RTC, nextAlarm.getTimeInMillis(), pendingIntent);
Log.w(LOG, "FuzzyTimeWidget.onEnabled pre-kitkat AlarmManager requested");
}else{
alarmManager.setExact(AlarmManager.RTC, nextAlarm.getTimeInMillis(), pendingIntent);
Log.w(LOG, "FuzzyTimeWidget.onEnabled API19+ AlarmManager requested");
}
The only code required to manage the different API's is at the point of setting the alarm. Just choosing set() or setExact(). All the other code is for any API. In my case, I use nextAlarmMin to set the exact time for the next Alarm, which goes off 4 times per hour at 8, 22, 37, 52.For widgets that update every minute, I'm not sure how this strategy would be for the battery life.

android.media.AudioManager.setStreamVolume(int streamType, int index, int flags)

I am trying to change volume of notifications, but not ringer.
However, when I use this function notification and ringer volume are changed.
Example code:
AudioManager mAudioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
int volNot = mAudioManager.getStreamVolume(STREAM_NOTIFICATION);
int volRing = mAudioManager.getStreamVolume(STREAM_RING);
Log.d(volNot + "," + volRing, "not, ringer");
mAudioManager.setStreamVolume(STREAM_NOTIFICATION, 1, 0);
volNot = mAudioManager.getStreamVolume(STREAM_NOTIFICATION);
volRing = mAudioManager.getStreamVolume(STREAM_RING);
Log.d(volNot + "," + volRing, "not, ringer");
For result setStreamVolume(STREAM_NOTIFICATION, 1, 0) changes value of notifications(STREAM_NOTIFICATION) to 1, but it also changes value of ringer(STREAM_RING) to 1.
This is because the phone has a setting in sounds---> volume in which there is a tick box which is checked, uncheck it and try your code again, this setting says that the ringer volume will be your notification volume and visa-verse.
Since ICS (Android 4.0), Ringer and Notification shares volume stream in official Android ROMS. Before this, user could choose to split the streams.

Categories

Resources