导读:

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 铃声多媒体音量、静音、震动(附源码)相关推荐

  1. Android使用GridView实现俄罗斯方块(附源码)(三)

    GitHub地址: https://github.com/weijifen/AndroidTetris 移动方向 移动方向包括左移,右移和下移. 移动方块实际是对position向量做改变,改变之后使 ...

  2. 暑期Android游戏开发——小兔子跳铃铛(附源码)

    暑期Android游戏开发--小兔子跳铃铛(附源码) 一. 背景说明 我在南京的一所高校学习软件工程.学院里每年会举行一次"创新杯"软件比赛,鼓励同学自主学习和创新.我和几个好兄弟 ...

  3. Android 实现播放网络视频 内容附源码下载链接

    <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...

  4. 基于Android的健身系统-计算机毕设 附源码90470

    基于Android的健身系统 目  录 摘要 1 1 绪论 1 1.1 课题研究的背景与意义 1 1.2研究的目的与研究内容 1 1.3本文主要工作 1 2基于Android的手机健身系统系统分析 3 ...

  5. android媒体焦点音量压低/暂停逻辑源码简析

    客户端通过AudioManager的调用requestAudioFocus请求焦点的过程中,其他媒体客户端会因媒体焦点丢失进行媒体压低或暂停,下面从framework层简单分析其过程. 首先调用Aud ...

  6. Android小项目之---选择对话框(附源码)

    还记得早先我们做的记算器的例子吗?当中的验证判断用到了对话框,今天我们来做一个不一样的对话框,要做的这个小例子是一个可供选择效果的对话框即层层迭迭的Alert Dialog:界面方面我们摆放一个But ...

  7. Android串口编程--开关灯Demo(附源码)

    1.项目简述 第二次玩硬件了,第一次是通过局域网控制门的开关,这次是通过ZB(大概就是这么叫,具体名字不清楚)控制灯的开关,感觉控制硬件也就是给硬件发个byte数组而已. 这里有个框架usb-seri ...

  8. Android串口通信实例分析【附源码】

    Android 串口通信实例分析,用的时开源的android-serialport-api 这个是用android ndk实现的串口通信,我把他做了一个简化,适合于一般的程序的串口通信移植,欢迎拍砖- ...

  9. 几款不错的Android开源APP效果展示(附源码地址)

    在逛gitHub时,发现了很多不错的Android开源模板,做一次搬运工,大家有需要的可以点链接进去学习一下. 1,很炫酷的activity跳转动画效果   gitHub地址:https://gith ...

最新文章

  1. 卡耐基梅隆大学计算机工程录取率,卡内基梅隆大学2020新生数据出炉!计算机学院录取率堪比藤校...
  2. html5 直接获取当前位置,HTML5调用百度地图API获取当前位置并直接导航目的地的方法...
  3. python2中的unicode_在python2中的编码
  4. 如何进行现场演示(二)
  5. linux加大ram 内核需要,Linux 5.1内核发布:io_uring接口+支持持久性内存用作RAM
  6. 【渝粤题库】广东开放大学 Linux 形成性考核
  7. Mysql写入数据时,adapter 日志报ES连接错误
  8. 通过JQUERY获取SELECT OPTION中选中的值
  9. Google 的三篇论文
  10. C++笔记---函数声明(prototype)
  11. 如何整理MacOS的菜单栏图标
  12. 常见文本相似度计算方法简介
  13. 支持USB Video Class的摄像头
  14. JavaScript 计算时间差
  15. Win12爆料,微软Windows 12计划3月份开始开发
  16. 小米忙着营销,麻烦带上技术!
  17. 编写windows版ANE
  18. uni-app 157发布朋友圈-批量上传图片
  19. 用JavaScript移动对象
  20. 原来漏斗分析应该这样用!

热门文章

  1. 苹果电脑在哪里改计算机id,如何在mac上切换apple id和icloud账号密码-mac上切换apple id和icloud账号密码教程 - 河东软件园...
  2. 在Linux下安装MySQL(详细)
  3. bnd.bnd属性文件格式
  4. 宽动态范围的高端电流 检测:三种解决方案
  5. Vue父子组件生命周期的先后顺序
  6. linux启动失败故障分析修复
  7. USB无线网卡导致耳机电流声很大
  8. 图像视频编辑工具箱MMEditing使用示例:图像生成(generation)
  9. AGC007 A - Shik and Stone(模拟)
  10. RobotStudio 机器人工具坐标的创建