簡(jiǎn)述:
自己遇到的需求:在自己app?中,全局監(jiān)聽音量變化,就是用戶按設(shè)備的加減聲音鍵,然后將音量變化展示到界面上(一個(gè)seekbar)。
正文:
1:監(jiān)聽系統(tǒng)音量變化(廣播)
因?yàn)樵O(shè)備是安卓11的,記得好像安卓版本高于8.0?不允許靜態(tài)廣播監(jiān)聽系統(tǒng)廣播,沒(méi)辦法,只能動(dòng)態(tài)注冊(cè)。上代碼吧:
廣播類:
public class MediaButtonIntentRecieverextends BroadcastReceiver{
? ? private static final StringTAG = MediaButtonIntentReciever.class.getSimpleName();
? ? private AudioManagermAudioManager;
? ? private PopupWindowmPopupWindow;
? ? private int mMediaMaxVolume;
? ? private int mMediaVolume;
? ? private SeekBarmCar_volume;
? ? private CountDownTimercountDownTimer;
? ? public MediaButtonIntentReciever() {
}
? ? @Override
? ? public void onReceive(Context context, Intent intent) {
? ? ? ? if (intent !=null) {
? ? ? ? ? ? if (intent.getAction().equals("android.media.VOLUME_CHANGED_ACTION")) {
? ? ? ? ? ? ? ? //監(jiān)聽音量
? ? ? ? ? ? ? ? InitVolume(context);
? ? ? ? ? ? }
? ? ? ? }
? ? }
? ? //監(jiān)聽音量
? ? private void InitVolume(Context context) {
? ? ? ? //獲取音量管理器
? ? ? ? if (mAudioManager ==null) {
? ? ? ? ? ? mAudioManager =(AudioManager) context.getSystemService(Service.AUDIO_SERVICE);
? ? ? ? }
? ? ? ? //當(dāng)前音量
? ? ? ? mMediaVolume =mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
? ? ? ? //最大音量
? ? ? ? mMediaMaxVolume =mAudioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC);
? ? ? ? LogUtil.e("===當(dāng)前音量:" +mMediaVolume);
? ? ? ? startPopupWindow(context);
? ? }
? ? private void startPopupWindow(Context context) {
? ? ? ? View inflate = LayoutInflater.from(context).inflate(R.layout.volume_popup, null);
? ? ? ? if (mPopupWindow ==null) {
? ? ? ? ? ? mPopupWindow =new PopupWindow(inflate, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
? ? ? ? }
? ? ? ? mPopupWindow.setBackgroundDrawable(null);
? ? ? ? mPopupWindow.setOutsideTouchable(true);
? ? ? ? //主界面linealayout的id,并給自己定義的popwindow xml文件backgrount? ? android:background="#33000000"
? ? ? ? mPopupWindow.showAtLocation(new View(context), Gravity.TOP, Gravity.CENTER_HORIZONTAL, Gravity.TOP);
? ? ? ? init();
? ? ? ? inflate.setOnClickListener(new View.OnClickListener() {
? ? ? ? ? ? @Override
? ? ? ? ? ? public void onClick(View v) {
? ? ? ? ? ? ? ? mPopupWindow.dismiss();
? ? ? ? ? ? ? ? countDownTimer.cancel();
? ? ? ? ? ? }
? ? ? ? });
? ? ? ? if (mCar_volume ==null) {
? ? ? ? ? ? mCar_volume = inflate.findViewById(R.id.car_volume);
? ? ? ? }
? ? ? ? //seekbar設(shè)置最大值為最大音量
? ? ? ? mCar_volume.setMax(mMediaMaxVolume);
? ? ? ? mCar_volume.setOnTouchListener(new View.OnTouchListener() {
? ? ? ? ? ? @Override
? ? ? ? ? ? public boolean onTouch(View v, MotionEvent event) {
? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? }
? ? ? ? });
? ? ? ? mCar_volume.setProgress(mMediaVolume);
? ? }
? ? //seekbar設(shè)置當(dāng)前進(jìn)度為當(dāng)前音量
? ? private void setView() {
? ? ? ? LogUtil.e("===音量改變:" +mMediaVolume);
? ? ? ? mCar_volume.setProgress(mMediaVolume);
? ? }
? ? private void init() {
? ? ? ? //重新計(jì)時(shí)
? ? ? ? if (countDownTimer !=null) {
? ? ? ? ? ? countDownTimer.cancel();
? ? ? ? }
? ? ? ? //初始化CountTimer,設(shè)置倒計(jì)時(shí)時(shí)間
? ? ? ? countDownTimer =new CountDownTimer(5000, 1000) {
? ? ? ? ? ? @Override
? ? ? ? ? ? public void onTick(long l) {
//? ? ? ? ? ? ? ? onActivityTick(l);
? ? ? ? ? ? ? ? LogUtil.e("音量彈窗倒計(jì)時(shí)--------" + l);
? ? ? ? ? ? }
? ? ? ? ? ? @Override
? ? ? ? ? ? public void onFinish() {
? ? ? ? ? ? ? ? //長(zhǎng)時(shí)間未操作 啟動(dòng)廣告頁(yè)
//? ? ? ? ? ? ? ? onActivityFinish();
? ? ? ? ? ? ? ? mPopupWindow.dismiss();
? ? ? ? ? ? ? ? countDownTimer.cancel();
? ? ? ? ? ? }
? ? ? ? };
? ? ? ? new Handler(getMainLooper()).post(new Runnable() {
? ? ? ? ? ? @Override
? ? ? ? ? ? public void run() {
? ? ? ? ? ? ? ? countDownTimer.start();
? ? ? ? ? ? }
? ? ? ? });
? ? }
? ? private void timeStart() {
}
}
broadcastreceiver中代碼有點(diǎn)亂,懶得改了,著急總結(jié)完下班 -.- !?有注釋,相信差不多都能看懂
可以在onReceive回調(diào)中,進(jìn)行處理自己想要的。我這邊是彈出一個(gè)popupwindow,里面有一個(gè)seekbar,根據(jù)音量調(diào)節(jié),seekbar進(jìn)行滑動(dòng)。
還有一個(gè)五秒消失seekbar,當(dāng)音量發(fā)生改變,倒計(jì)時(shí)重新計(jì)時(shí)。
? ? 清單文件:
? ??<receiver
????android:name=".receiver.MediaButtonIntentReciever"
? ? android:permission="android.permission.RECEIVE_VOLUME_CHANGED_ACTION"
? ? android:enabled="true"
? ? android:exported="true">
? ? <intent-filter>
? ? ? ? <action android:name="android.media.VOLUME_CHANGED_ACTION" />
? ? </intent-filter>
</receiver>
首先在清單文件注冊(cè)。
因?yàn)槭侨直O(jiān)聽的,所以我這邊是直接在base層的activity中,進(jìn)行注冊(cè)廣播。
下面分別是注冊(cè)廣播代碼和銷毀廣播代碼:
private void initBroatCastReceiver() {
? ? mIntentFilter =new IntentFilter();
? ? mIntentFilter.addAction("android.media.VOLUME_CHANGED_ACTION");
? ? mReciever =new MediaButtonIntentReciever();
? ? registerReceiver(mReciever, mIntentFilter);
? ? LogUtil.e("=====注冊(cè)廣播");
}
private void onDestoryRevicer() {
? ? unregisterReceiver(mReciever);
? ? LogUtil.e("=====銷毀廣播");
}

因?yàn)槭侨值?,所以寫在了baseActivity中,之后在baseActivity中的onStart和onPase回調(diào)中分別調(diào)用注冊(cè)和注銷廣播方法。?
有一個(gè)問(wèn)題,就是系統(tǒng)自己的音量調(diào)節(jié)提示框也會(huì)展示,所以還需要在baseActivity中,添加一段代碼:
//調(diào)節(jié)音量時(shí),不展示系統(tǒng)音量進(jìn)度條
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
? ? if (mAudioManager ==null) {
? ? ? ? mAudioManager =(AudioManager) this.getSystemService(Service.AUDIO_SERVICE);
? ? }
? ? //小聲鍵
? ? if (event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_DOWN) {
? ? ? ? mAudioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_LOWER, 0);
return true;
? ? } else if (event.getKeyCode() == KeyEvent.KEYCODE_VOLUME_UP) {
? ? ? ? //大聲鍵
? ? ? ? mAudioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_RAISE, 0);
return true;
? ? }
? ? return super.dispatchKeyEvent( event);
}
這樣就能做到,app中調(diào)大調(diào)小音量,系統(tǒng)的音量提示框不展示,自己的seekbar展示音量提醒。?
沒(méi)法加效果視頻 - - !??