/* * Copyright (C) 2010 beworx.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.bwx.bequick.handlers; import android.app.Activity; import android.app.AlertDialog; import android.app.Dialog; import android.content.DialogInterface; import android.content.Intent; import android.content.DialogInterface.OnCancelListener; import android.content.DialogInterface.OnClickListener; import android.media.AudioManager; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.SeekBar; import android.widget.TextView; import android.widget.Toast; import android.widget.SeekBar.OnSeekBarChangeListener; import com.bwx.bequick.Constants; import com.bwx.bequick.MainSettingsActivity; import com.bwx.bequick.R; import com.bwx.bequick.fwk.Setting; import com.bwx.bequick.fwk.SettingHandler; public class VolumeSettingHandler extends SettingHandler implements OnSeekBarChangeListener, OnClickListener, OnCancelListener { //private static final String TAG = "VolumeSettingHandler"; private static final int BUTTON_CANCEL = -2; private int mIdCounter; private static final int[] STREAM_TYPES = { AudioManager.STREAM_RING, AudioManager.STREAM_NOTIFICATION, AudioManager.STREAM_MUSIC, AudioManager.STREAM_ALARM, AudioManager.STREAM_VOICE_CALL, AudioManager.STREAM_SYSTEM }; private static final int[] STRING_IDS = { R.string.txt_volume_ringer, R.string.txt_volume_notification, R.string.txt_volume_media, R.string.txt_volume_alarm, R.string.txt_volume_voice_call, R.string.txt_volume_system }; private TextView[] mValueViews; private SeekBar[] mSeekBars; private int[] mVolumes; private Dialog mDialog; /** * <li> Ringer volume * <li> Music volume * <li> in-call voice volume * <li> notification volume * <li> alarm volume * @param setting */ public VolumeSettingHandler(Setting setting) { super(setting); } @Override public void activate(MainSettingsActivity activity) throws Exception { mActivity = activity; //Log.d(TAG, "activate: " + activity); } @Override public void deactivate() { //Log.d(TAG, "deactivate"); if (mDialog != null) { mDialog.dismiss(); mDialog = null; } } @Override public void onSelected(int buttonIndex) { mDialog = createDialog(); prepareDialog(); mDialog.show(); } @Override public void onSwitched(boolean isSwitched) { // do nothing } @Override public void onValueChanged(int value) { // do nothing } public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { if (fromUser) { final AudioManager manager = (AudioManager) mActivity.getSystemService(Activity.AUDIO_SERVICE); final int index = (Integer) seekBar.getTag(); final int streamType = STREAM_TYPES[index]; // update view final TextView valueView = mValueViews[index]; valueView.setText(progress + "/" + manager.getStreamMaxVolume(streamType)); //Log.d(TAG, "onProgressChanged: index: " + index + ", value: " + progress + ", seekbar: " + seekBar); } } public void onStartTrackingTouch(SeekBar seekBar) { // do nothing } public void onStopTrackingTouch(SeekBar seekBar) { // do nothing } public void onCancel(DialogInterface dialog) { mDialog.hide(); } public void onClick(DialogInterface dialog, int whichButton) { if (BUTTON_CANCEL == whichButton) { return; // stop on cancel } Activity activity = mActivity; // cache final AudioManager manager = (AudioManager) activity.getSystemService(Activity.AUDIO_SERVICE); final int[] volumes = mVolumes; final SeekBar[] seekBars = mSeekBars; final int[] streamTypes = STREAM_TYPES; // apply changes final int length = seekBars.length; boolean prevChanged = false; for (int i = 0; i<length; i++) { // get control int value = seekBars[i].getProgress(); boolean isNotification = i == 1; boolean changed = value != volumes[i] || (isNotification && prevChanged); if (changed) { manager.setStreamVolume(streamTypes[i], value, 0); //Log.d(TAG, "updating index: " + i + ", value: " + value); } if (isNotification) { // if notification change updated volume as well we should return volume back (2.0 behavior) int ringerVolumeDesired = seekBars[0].getProgress(); int ringerVolumeActual = manager.getStreamVolume(streamTypes[0]); if (ringerVolumeDesired != ringerVolumeActual) { manager.setStreamVolume(streamTypes[0], ringerVolumeDesired, 0); //Log.d(TAG, "changing ringer volume to desired value: " + + value); } } prevChanged = changed; } // check if we have to switch silent / not silen mode int ringerVolume = manager.getStreamVolume(AudioManager.STREAM_RING); int notifVolume = manager.getStreamVolume(AudioManager.STREAM_NOTIFICATION); int ringerMode = manager.getRingerMode(); if (ringerVolume > 0 && ringerMode == AudioManager.RINGER_MODE_SILENT) { Toast.makeText(activity, activity.getString(R.string.msg_not_silent_warning, ringerVolume), Toast.LENGTH_LONG).show(); } else if (ringerVolume == 0 && ringerMode == AudioManager.RINGER_MODE_NORMAL) { Toast.makeText(activity, R.string.msg_zero_ringer_warning, Toast.LENGTH_LONG).show(); } else if (notifVolume == 0 && ringerMode == AudioManager.RINGER_MODE_NORMAL) { Toast.makeText(activity, R.string.msg_zero_notification_warning, Toast.LENGTH_LONG).show(); } // send internal volume changed notification activity.sendBroadcast(new Intent(Constants.ACTION_VOLUME_UPDATED)); } public boolean prepareDialog() { // local cache final AudioManager manager = (AudioManager) mActivity.getSystemService(Activity.AUDIO_SERVICE); final SeekBar[] seekBars = mSeekBars; final TextView[] valueViews = mValueViews; final int[] volumes = mVolumes; final int length = seekBars.length; final int[] streamTypes = STREAM_TYPES; for (int i=0; i<length; i++) { // get value and max value int volume = manager.getStreamVolume(streamTypes[i]); int max = manager.getStreamMaxVolume(streamTypes[i]); // update values final TextView valueView = valueViews[i]; valueView.setText(volume + "/" + max); // update seekbar SeekBar seekBar = seekBars[i]; seekBar.setMax(max); seekBar.setProgress(volume); volumes[i] = volume; // store initial volume //Log.d(TAG, "prepare: index: " + i + ", value: " + volume + ", max: " + max + ", seekbar: " + seekBar); } return true; } private Dialog createDialog() { if (mDialog != null) return mDialog; Activity activity = mActivity; // load main view final LayoutInflater factory = LayoutInflater.from(activity); final View dialog = factory.inflate(R.layout.settings_volume_streams, null); final ViewGroup parent = (ViewGroup) dialog.findViewById(R.id.placeholder); // local cache final int[] stringIds = STRING_IDS; final int length = stringIds.length; final SeekBar[] seekBars = mSeekBars = new SeekBar[length]; final TextView[] valueViews = mValueViews = new TextView[length]; mVolumes = new int[length]; // add controls for all stream for (int i=0; i<length; i++) { View control = factory.inflate(R.layout.row_volume, null); // init text TextView text = (TextView) control.findViewById(R.id.text); text.setText(stringIds[i]); // init values valueViews[i] = (TextView) control.findViewById(R.id.value); // init seekbars SeekBar seekBar = (SeekBar) control.findViewById(R.id.seekbar); seekBar.setOnSeekBarChangeListener(this); seekBar.setId(mIdCounter++); // workaround for seekbar id bug seekBar.setTag(i); seekBars[i] = seekBar; // add to parent parent.addView(control); //Log.d(TAG, "create: index: " + i + ", seekbar: " + seekBar); } AlertDialog d = new AlertDialog.Builder(activity) .setIcon(R.drawable.ic_dialog_menu_generic) .setTitle(R.string.txt_volume) .setView(dialog) .setPositiveButton(R.string.btn_set, this) .setNegativeButton(R.string.btn_calcel, this) .create(); d.setOnCancelListener(this); return d; } }