实现自定义音量盘

来源:互联网 发布:php curl 跳转页面 编辑:程序博客网 时间:2024/05/18 02:52

思路:监听音量的上下按键,显示自定义的音量键盘,然后通过异步线程调整声音的大小,因为这是一个耗时的过程,

/** * 音量显示面板 * */public class VolumePanel extends Handler implements OnKeyListener, OnSeekBarChangeListener {    /**     * 日志标签     */    public static final String TAG = VolumePanel.class.getSimpleName();    /**     * 面板自动关闭延迟时间({@value} ms)     */    public static final long DIALOG_DISMISS_DELAY = 5 * 1000;    /**     * 显示面板消息     */    public static final int MSG_SHOW = 0;    /**     * 关闭面板消息     */    public static final int MSG_DISMISS = 1;    /**     * 弹出框     */    private Dialog mDialog;    /**     * 弹出框视图     */    private View mView;    /**     * 进度条视图     */    private SeekBar mSeekbarView;    /**     * 面板     */    private ViewGroup mPanel;    /**     * 用于放置音量显示条的视图     */    private ViewGroup mSliderGroup;    /**     * 音量显示条视图     */    private ViewGroup mGroupView;    /**     * 音量条前面的图标     */    private ImageView mStreamIcon;    /**     * Android上下文     */    private Context mContext;    /**     * 音量进度     */    private int mProgress;    /**     * 声音流枚举     *      *     */    private enum StreamResources {        RingerStream(AudioManager.STREAM_RING, R.string.volume_icon_description_ringer, R.drawable.ic_audio_ring_notif,                R.drawable.ic_audio_ring_notif_mute, false), VoiceStream(AudioManager.STREAM_VOICE_CALL,        `R.string.volume_icon_description_incall, R.drawable.ic_audio_phone, R.drawable.ic_audio_phone, false), MediaStream(                AudioManager.STREAM_MUSIC, R.string.volume_icon_description_media, R.drawable.ic_audio_vol,                R.drawable.ic_audio_vol_mute, true);        int streamType;        int descRes;        int iconRes;        int iconMuteRes;        // RING, VOICE_CALL & BLUETOOTH_SCO are hidden unless explicitly        // requested        boolean show;        /**         * 声音流枚举         *          * @param streamType         *            声音流类型         * @param descRes         *            声音流描述         * @param iconRes         *            声音流图标         * @param iconMuteRes         *            声音流静音图标         * @param show         *            是否显示         */        StreamResources(int streamType, int descRes, int iconRes, int iconMuteRes, boolean show) {            this.streamType = streamType;            this.descRes = descRes;            this.iconRes = iconRes;            this.iconMuteRes = iconMuteRes;            this.show = show;        }    };    /**     * 声音流列表     */    private final StreamResources[] STREAMS = { StreamResources.RingerStream, StreamResources.VoiceStream,            StreamResources.MediaStream };    /**     * 当前的流     */    private StreamResources currentStream;    /**     * 构造方法     *      * @param context     *            Android上下文,必须是Application     * @param itemOnly     *            只显示音量进度条     */    public VolumePanel(Context context, boolean itemOnly) {        super(context.getMainLooper());        LayoutInflater inflater = LayoutInflater.from(context);        // 初始化音量进度条        mGroupView = (ViewGroup) inflater.inflate(R.layout.volume_adjust_item, null);        mSeekbarView = (SeekBar) mGroupView.findViewById(R.id.seekbar);        mSeekbarView.setOnSeekBarChangeListener(this);        mStreamIcon = (ImageView) mGroupView.findViewById(R.id.stream_icon);        if (itemOnly) {            mView = mGroupView;        } else {            // 初始化音量面板            mView = inflater.inflate(R.layout.volume_adjust, null);            mPanel = (ViewGroup) mView.findViewById(R.id.visible_panel);            mSliderGroup = (ViewGroup) mView.findViewById(R.id.slider_group);            mSliderGroup.addView(mGroupView);        }        // 初始化弹出框        mDialog = new Dialog(context) {            @Override            public boolean onTouchEvent(MotionEvent event) {                if (event.getAction() == MotionEvent.ACTION_OUTSIDE) {                    dismiss();                    return true;                }                return super.onTouchEvent(event);            }        };        mDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);        mDialog.setContentView(mView);        // 初始化窗口        Window window = mDialog.getWindow();        window.setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);        window.setGravity(Gravity.TOP);        LayoutParams lp = window.getAttributes();        lp.token = null;        // Offset from the top        lp.y = context.getResources().getDimensionPixelOffset(R.dimen.volume_panel_top);        lp.width = LayoutParams.WRAP_CONTENT;        lp.height = LayoutParams.WRAP_CONTENT;        window.setAttributes(lp);        window.addFlags(LayoutParams.FLAG_NOT_FOCUSABLE | LayoutParams.FLAG_NOT_TOUCH_MODAL                | LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);        mDialog.setOnKeyListener(this);        // 保存Android上下文        mContext = context;    }    /**     * 显示面板     */    public void show() {        Log.i(TAG, "show volume panel");        sendEmptyMessage(MSG_SHOW);    }    /**     * 关闭面板     */    public void dismiss() {        Log.i(TAG, "dismiss volume panel");        sendEmptyMessage(MSG_DISMISS);    }    @Override    public void handleMessage(Message msg) {        // 获取音频管理器        AudioManager manager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);        switch (msg.what) {        // 显示面板        case MSG_SHOW:            // 获取调整的声音模式            int stream = RtpStreamReceiver.getjStream();            // 判断是否在振铃,如果振铃则调整振铃音量            Ringtone ringtone = JAudioLauncher.oRingtone;            if (ringtone != null && ringtone.isPlaying()) {                stream = ringtone.getStreamType();            }            // 获取音量最大值            int max = manager.getStreamMaxVolume(stream);            // 最大声音和音量面板不匹配时重新设置            if (max != mSeekbarView.getMax()) {                mSeekbarView.setMax(max);            }            // 获取音量,设置进度            int volume = manager.getStreamVolume(stream);            Log.d(TAG, "volume : " + volume);            mProgress = volume;            mSeekbarView.setProgress(volume);            // 获取流信息,设置进度条            for (StreamResources streamResources : STREAMS) {                if (streamResources.streamType == stream) {                    // 设置音量图标                    if (volume == 0) {                        mStreamIcon.setImageResource(streamResources.iconMuteRes);                    } else {                        mStreamIcon.setImageResource(streamResources.iconRes);                    }                    streamResources.show = true;                    currentStream = streamResources;                    break;                }                currentStream = null;                streamResources.show = false;            }            // 显示面板            mDialog.show();            // 移除关闭消息            removeMessages(MSG_DISMISS);            // 设置关闭消息,延迟DIALOG_DISMISS_DELAY            sendEmptyMessageDelayed(MSG_DISMISS, DIALOG_DISMISS_DELAY);            break;        // 关闭面板        case MSG_DISMISS:            // 移除关闭消息            removeMessages(MSG_DISMISS);            // 如果显示,则关闭            if (mDialog.isShowing()) {                mDialog.dismiss();            }            break;        }        super.handleMessage(msg);    }    @Override    public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {        // 监听按键,继续调用调整声音方法        if (event.getAction() == KeyEvent.ACTION_DOWN) {            if (keyCode == KeyEvent.KEYCODE_VOLUME_UP || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {                JAudioLauncher.adjust(keyCode, true, mContext);                return true;            }        }        return false;    }    @Override    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {    }    @Override    public void onStartTrackingTouch(SeekBar seekBar) {        mProgress = seekBar.getProgress();    }    @Override    public void onStopTrackingTouch(SeekBar seekBar) {        int progress = seekBar.getProgress();        if (mProgress != progress && currentStream != null) {            RtpStreamReceiver.setStreamVolume(currentStream.streamType, progress, AudioManager.FLAG_PLAY_SOUND                    | AudioManager.FLAG_VIBRATE, mContext);        }    }} 自定义的音量键盘布局
  <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="80dip"android:orientation="horizontal"android:layout_marginTop="8dip"android:layout_marginBottom="8dip"android:gravity="left|center_vertical"><ImageView    android:id="@+id/stream_icon"    android:layout_width="wrap_content"    android:layout_height="wrap_content"    android:padding="16dip"    android:background="?android:attr/selectableItemBackground"    /><SeekBar    style="?android:attr/seekBarStyle"    android:id="@+id/seekbar"    android:layout_width="300dp"    android:layout_height="wrap_content"    android:layout_weight="1"    android:padding="16dip"    android:layout_marginRight="16dip" /> </LinearLayout>
///修改声音的方法
    static void setStreamVolume(final int stream,         final int vol, final int flags,  final Context context) {if (setVolumeService != null) {  // 使用线程池调整声音  setVolumeService.execute(new Runnable() {    public void run() {      if (debug) {        Log.d(TAG, "setStreamVolume : (stream : " + stream + ", vol : " + vol + ", flags : "            + flags + ")");      }               AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);      am.setStreamVolume(stream, vol, flags);  });} else {  Log.w(TAG, "setStreamVolume setVolumeService is null");   }    }

//开启一个异步线程

 /**   * 用于设置音量大小操作的线程池   */  static ExecutorService setVolumeService = Executors.newSingleThreadExecutor(new ThreadFactory() {    @Override    public Thread newThread(Runnable r) {      return new Thread(r, "setStreamVolume");    }  });
原创粉丝点击