Android 铃声多媒体音量、静音、震动(附源码)
导读:
Android提供了可以进行对原生系统进行控制API。AudioManager用来对音量、模式(静音,震动,震动加声音等模式)等进行管理。可以用Vibrator、HapticFeedback进行管理手机震动。本人带着案例进行讲解,先温柔点讲控制系统音量,再说撩人的震动棒...呸..是振荡器。
一、AudioManager (音频管理)
1、音乐的播放方式
//1、自定义音频文件testMediaPlayer player = MediaPlayer.create(getApplicationContext(), R.raw.test);//2、系统电话铃声TYPE_RINGTONE\系统通知铃声TYPE_NOTIFICATION
Uri uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE); MediaPlayer mMediaPlayer = new MediaPlayer();
mMediaPlayer.setDataSource(PlayerService.this, uri);———————————————————————————————————————————————————————————————— mMediaPlayer.setLooping(true); // 设置循环播放mMediaPlayer.prepare();//准备mMediaPlayer.start();//播放
2、修改音量方式
首先,拿到音频管理实例对象。 AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
然后,设置音量。例如 audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 30, 0);
(1)修改音量
adjustVolume(int direction , int flag) //修改音量
direction(方向):顾名思义,就是点击事件发生,往上增加音量,往下减少音量,和保持音量不变。
- AudioManager.ADJUST_LOWER(降低)
- AudioManager.ADJUST_RAISE(升高)
- AudioManager.ADJUST_SAME(锁定不变)
(2) 修改类型、音量
adjustStreamVolume(int streamType ,int direction , int flag) //修改类型、音量
streamType(音频流类型):即指定声音类型,有下述几种声音类型:
STREAM_ALARM:手机闹铃 STREAM_MUSIC:手机音乐STREAM_RING:电话铃声 STREAM_SYSTEAM:手机系统STREAM_DTMF:音调 STREAM_NOTIFICATION:系统提示STREAM_VOICE_CALL:语音电话
flag(标志):其实是点击事件发生后,音量的表现形式。
- AudioManager.FLAG_SHOW_UI :会弹出调节音量的界面
- AudioManager.FLAG_ALLOW_RINGER_MODES :最低声音会振动
(3)设置音量大小
setStreamVolume(int streamType, int index, int flags)//直接设置音量大小
index(音量的值) ,int类型。
4、实用小案例
XML 写一个SeekBar控件
<android.support.v7.widget.AppCompatSeekBarandroid:id="@+id/play_volume"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="50dp"/>
Activiy中的代码
声明变量
private MediaPlayer player;//测试音乐
private int maxVolume, currentVolume;//音量值
private AudioManager audioManager;//音频管理类
private SeekBar mView_sb_play_volume; //控件
初始化操作
mView_sb_play_volume = (SeekBar) findViewById(R.id.play_volume);//滑动进度条myRegisterReceiver();//注册同步更新的广播player = MediaPlayer.create(getApplicationContext(), R.raw.test);//自定义音频文件testaudioManager = (AudioManager) getSystemService(AUDIO_SERVICE);//实例maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC); //获取系统最大音量mView_sb_play_volume.setMax(maxVolume);currentVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC); //获取当前值mView_sb_play_volume.setProgress(currentVolume);player.setLooping(true);mView_sb_play_volume.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {@Overridepublic void onStopTrackingTouch(SeekBar seekBar) {player.pause();}@Overridepublic void onStartTrackingTouch(SeekBar seekBar) {player.start();}@Overridepublic void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, progress, 0);seekBar.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
// seekBar.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);
// seekBar.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);//HapticFeedbackConstants的常量值,我们要用到的有三个触摸震动方式:
// 一个是LONG_PRESS(长按),
// 第二个是FLAG_IGNORE_VIEW_SETTING(不受Xml里view的属性设置影响,即不受isHapticFeedbackEnabled()的影响),
// 第三个是FLAG_IGNORE_GLOBAL_SETTING(不受系统设置的影响,即不受是否开启震动反馈的影响)}});
广播监听音量变化
//注册当音量发生变化时接收的广播private void myRegisterReceiver(){MyVolumeReceiver mVolumeReceiver = new MyVolumeReceiver() ;IntentFilter filter = new IntentFilter() ;filter.addAction("android.media.VOLUME_CHANGED_ACTION") ;registerReceiver(mVolumeReceiver, filter) ;}//处理音量变化时的界面显示private class MyVolumeReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {//如果音量发生变化则更改seekbar的位置if(intent.getAction().equals("android.media.VOLUME_CHANGED_ACTION")){
//AudioManager mAm = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE); // 当前的媒体音量currentVolume = audioManager.getStreamVolume(AudioManager.STREAM_MUSIC) ;mView_sb_play_volume.setProgress(currentVolume) ;}}}
二、HapticFeedback(震动反馈)
首先,说明该震动方式不需要设置震动权限!!不需要设置震动权限!!不需要设置震动权限!!重要的事情说三遍。
从上面案例中所见,在SeekBar设置改变监听里自定义触发震动,下面先看一下源码讲解。
如下文所示,点击也会触发震动反馈了:
click.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {v.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);}});
现在我们就去performHapticFeedback源码看下,都执行了什么。View.performHapticFeedback源码:
/*** BZZZTT!!1!** <p>Provide haptic feedback to the user for this view.** <p>The framework will provide haptic feedback for some built in actions,* such as long presses, but you may wish to provide feedback for your* own widget.** <p>The feedback will only be performed if* {@link #isHapticFeedbackEnabled()} is true.** @param feedbackConstant One of the constants defined in* {@link HapticFeedbackConstants}*/public boolean performHapticFeedback(int feedbackConstant) {return performHapticFeedback(feedbackConstant, 0);}
这里解释三个知识点:
1、只有在isHapticFeedbackEnabled()为true的情况下,才会触发震动。之后会解释在为false的情况下,为何不会触发震动。
在xml里,可以通过android:hapticFeedbackEnabled=”false|true”来进行设置
在java代码里,可以通过view.setHapticFeedbackEnabled(boolean)来设置,不过默认是true哦。
2、HapticFeedbackConstants的常量值,我们要用到的有三个:
- LONG_PRESS(长按);
- FLAG_IGNORE_VIEW_SETTING(不受view的设置影响,即不受isHapticFeedbackEnabled()的影响);
- FLAG_IGNORE_GLOBAL_SETTING(不受系统设置的影响,即不受是否开启震动反馈的影响);
3、最终是返回的performHapticFeedback(int feedbackConstant, int flags)这个方法。
View.performHapticFeedback(int feedbackConstant, int flags)源码:
/*** BZZZTT!!1!** <p>Like {@link #performHapticFeedback(int)}, with additional options.** @param feedbackConstant One of the constants defined in* {@link HapticFeedbackConstants}* @param flags Additional flags as per {@link HapticFeedbackConstants}.*/public boolean performHapticFeedback(int feedbackConstant, int flags) {if (mAttachInfo == null) {return false;}//noinspection SimplifiableIfStatementif ((flags & HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING) == 0&& !isHapticFeedbackEnabled()) {return false;}return mAttachInfo.mRootCallbacks.performHapticFeedback(feedbackConstant,(flags & HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING) != 0);}
看第15行的if语句,当flags=0时,flags & HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING为0,又isHapticFeedbackEnabled()为false,整个条件为真,所以会执行17行,直接return。这也是为什么performHapticFeedback(int feedbackConstant)方法一定要在isHapticFeedbackEnabled()为ture的情况下才会触发震动。 在这里说一下,&是按位与,返回数值,&&逻辑与,返回布尔值。 第19-20行,就是触发底层震动的代码了,之后代码不做分析。
案例:
在单击事件,会触发震动:
click.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {v.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);//长按}});
如果xml加上 android:hapticFeedbackEnabled=”false”这句话,单击事件没有震动效果了。如下所示:
<Buttonandroid:layout_width="wrap_content"android:id="@+id/click"android:layout_height="wrap_content"android:hapticFeedbackEnabled="false"android:text="make" />
如果这时,想让其震动,可以用如下方法来做:
click.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {v.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,HapticFeedbackConstants.FLAG_IGNORE_VIEW_SETTING);//忽略view属性设置}});
还记得本篇文章之前,说去设置里打开触摸时震动的开关吗,其实,用户不打开,照样可以让其震动,只需要用如下的方法:
click.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {v.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS,HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);}});
三、Vibrator(振荡器)
震动的系统权限
<uses-permission android:name="android.permission.VIBRATE"/>
获取实例:
Vibrator vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);
两种震动方式:
1、按照指定的模式去震动:
vibrator.vibrate(new long[]{100,1000,1000,1000}, -1);
数组参数意义:
- 第一个参数为等待指定时间后开始震动,震动时间为第二个参数; 后边的参数依次为等待震动和震动的时间;
- 第二个参数为重复次数,-1为不重复,0为一直震动;
2、指定震动的时间,数据类型long,单位为毫秒,一毫秒为1/1000秒
vibrator.vibrate(2000);
取消震动:
注意:震动为一直震动的话,如果不取消震动,就算退出,也会一直震动
vibrator.cancel();
案例:
XML
<Buttonandroid:id="@+id/vibrator1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="35dp"android:text="震动模式一间断性"/><Buttonandroid:id="@+id/vibrator2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="20dp"android:text="震动模式二独立性"/>
Activity
private Button vibrator1,vibrator2;//控件
private Vibrator vibrator;//震动
vibrator1 = (Button) findViewById(R.id.vibrator1);vibrator2 =(Button)findViewById(R.id.vibrator2);vibrator1.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);vibrator.vibrate(new long[]{100,1000,1000,1000}, -1);//按照指定的模式去震动。数组参数意义:// 第一个参数为等待指定时间后开始震动,震动时间为第二个参数; 后边的参数依次为等待震动和震动的时间;// 第二个参数为重复次数,-1为不重复,0为一直震动;}});vibrator2.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {vibrator = (Vibrator) getSystemService(VIBRATOR_SERVICE);vibrator.vibrate(2000);//震动指定时间 ,数据类型long,单位为毫秒,一毫秒为1/1000秒}});
// vibrator.cancel();//取消震动,立即停止震动震动为一直震动的话,如果不取消震动,就算退出,也会一直震动
源码:安卓系统音频震动demohttp://download.csdn.net/download/csdn_aiyang/9970166
加群一起学习,我们不是一个人战斗:
Android 铃声多媒体音量、静音、震动(附源码)相关推荐
- Android使用GridView实现俄罗斯方块(附源码)(三)
GitHub地址: https://github.com/weijifen/AndroidTetris 移动方向 移动方向包括左移,右移和下移. 移动方块实际是对position向量做改变,改变之后使 ...
- 暑期Android游戏开发——小兔子跳铃铛(附源码)
暑期Android游戏开发--小兔子跳铃铛(附源码) 一. 背景说明 我在南京的一所高校学习软件工程.学院里每年会举行一次"创新杯"软件比赛,鼓励同学自主学习和创新.我和几个好兄弟 ...
- Android 实现播放网络视频 内容附源码下载链接
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...
- 基于Android的健身系统-计算机毕设 附源码90470
基于Android的健身系统 目 录 摘要 1 1 绪论 1 1.1 课题研究的背景与意义 1 1.2研究的目的与研究内容 1 1.3本文主要工作 1 2基于Android的手机健身系统系统分析 3 ...
- android媒体焦点音量压低/暂停逻辑源码简析
客户端通过AudioManager的调用requestAudioFocus请求焦点的过程中,其他媒体客户端会因媒体焦点丢失进行媒体压低或暂停,下面从framework层简单分析其过程. 首先调用Aud ...
- Android小项目之---选择对话框(附源码)
还记得早先我们做的记算器的例子吗?当中的验证判断用到了对话框,今天我们来做一个不一样的对话框,要做的这个小例子是一个可供选择效果的对话框即层层迭迭的Alert Dialog:界面方面我们摆放一个But ...
- Android串口编程--开关灯Demo(附源码)
1.项目简述 第二次玩硬件了,第一次是通过局域网控制门的开关,这次是通过ZB(大概就是这么叫,具体名字不清楚)控制灯的开关,感觉控制硬件也就是给硬件发个byte数组而已. 这里有个框架usb-seri ...
- Android串口通信实例分析【附源码】
Android 串口通信实例分析,用的时开源的android-serialport-api 这个是用android ndk实现的串口通信,我把他做了一个简化,适合于一般的程序的串口通信移植,欢迎拍砖- ...
- 几款不错的Android开源APP效果展示(附源码地址)
在逛gitHub时,发现了很多不错的Android开源模板,做一次搬运工,大家有需要的可以点链接进去学习一下. 1,很炫酷的activity跳转动画效果 gitHub地址:https://gith ...
最新文章
- 卡耐基梅隆大学计算机工程录取率,卡内基梅隆大学2020新生数据出炉!计算机学院录取率堪比藤校...
- html5 直接获取当前位置,HTML5调用百度地图API获取当前位置并直接导航目的地的方法...
- python2中的unicode_在python2中的编码
- 如何进行现场演示(二)
- linux加大ram 内核需要,Linux 5.1内核发布:io_uring接口+支持持久性内存用作RAM
- 【渝粤题库】广东开放大学 Linux 形成性考核
- Mysql写入数据时,adapter 日志报ES连接错误
- 通过JQUERY获取SELECT OPTION中选中的值
- Google 的三篇论文
- C++笔记---函数声明(prototype)
- 如何整理MacOS的菜单栏图标
- 常见文本相似度计算方法简介
- 支持USB Video Class的摄像头
- JavaScript 计算时间差
- Win12爆料,微软Windows 12计划3月份开始开发
- 小米忙着营销,麻烦带上技术!
- 编写windows版ANE
- uni-app 157发布朋友圈-批量上传图片
- 用JavaScript移动对象
- 原来漏斗分析应该这样用!
热门文章
- 苹果电脑在哪里改计算机id,如何在mac上切换apple id和icloud账号密码-mac上切换apple id和icloud账号密码教程 - 河东软件园...
- 在Linux下安装MySQL(详细)
- bnd.bnd属性文件格式
- 宽动态范围的高端电流 检测:三种解决方案
- Vue父子组件生命周期的先后顺序
- linux启动失败故障分析修复
- USB无线网卡导致耳机电流声很大
- 图像视频编辑工具箱MMEditing使用示例:图像生成(generation)
- AGC007 A - Shik and Stone(模拟)
- RobotStudio 机器人工具坐标的创建