拖动条SeekBar

SeekBar继承自进度条ProcessBar,有关ProcessBar的介绍见《Android开发笔记(四十九)异步任务处理AsyncTask》。SeekBar与ProcessBar的不同之处在于,SeekBar是可以拖动的,因此SeekBar可用于媒体播放的进度条,在拖动进度条后,播放器可快进或者快退到指定位置开始播放媒体;SeekBar也可用于调节铃声的音量大小、调节屏幕的亮度、调节字体的大小等等。

下面是SeekBar新增加的几个方法与事件:
setThumb : 设置当前进度位置的图标
setThumbOffset : 设置当前进度图标的偏移量
setKeyProgressIncrement : 设置使用方向键更改进度时每次的增加值

拖动条的拖动事件
监听器类名 : OnSeekBarChangeListener
设置监听器的方法 : setOnSeekBarChangeListener
监听器需要重写的方法 : 
onProgressChanged : 拖动过程中触发
onStartTrackingTouch : 开始拖动时触发
onStopTrackingTouch : 停止拖动时触发,一般在该方法中加入业务逻辑

铃声管理AudioManager

Android中有六类铃音,分别是:通话音、系统音、来电与收短信的铃声、媒体声(包括音频、视频、游戏等等)、闹钟声、通知声,管理这些铃声音量的工具是AudioManager类。

下面是六类铃声的类型说明:
STREAM_VOICE_CALL : 通话音
STREAM_SYSTEM : 系统音
STREAM_RING : 来电与收短信的铃声
STREAM_MUSIC : 媒体声(包括音频、视频、游戏等等)
STREAM_ALARM : 闹钟声
STREAM_NOTIFICATION : 通知声

下面是AudioManager的常用方法:
getStreamMaxVolume : 获取指定类型铃声的最大音量。
getStreamVolume : 获取指定类型铃声的当前音量。
getRingerMode : 获取指定类型铃声的响铃模式。RINGER_MODE_NORMAL表示正常,RINGER_MODE_SILENT表示静音,RINGER_MODE_VIBRATE表示震动
setStreamVolume : 设置指定类型铃声的当前音量。
adjustStreamVolume : 调整指定类型铃声的当前音量。第一个参数是铃声类型;第二个参数是调整方向,ADJUST_RAISE表示调大一级,ADJUST_LOWER表示调小一级,ADJUST_SAME表示保持不变;第三个参数表示调整时的附加动作,一般使用FLAG_PLAY_SOUND表示调整时提示一个铃声。
setRingerMode : 设置指定类型铃声的响铃模式。

震动器Vibrator

Vibrator用于控制手机的振动操作,它的对象需要从系统服务VIBRATOR_SERVICE中获取。震动器的使用比较简单,主要方法如下所示:
hasVibrator : 判断设备是否拥有震动器。
vibrate : 震动手机。该方法有多个重载函数,即可设定单次震动的时长,也可设置多次震动的时长,还可设置是否重复震动。
cancel : 取消震动。

震动需要在AndroidManifest.xml中加上如下权限:

    <!-- 震动 --><uses-permission android:name="android.permission.VIBRATE" />

代码示例

下面是铃声管理即设置音量的代码例子:

import com.example.exmring.R;import android.app.Activity;
import android.content.Context;
import android.media.AudioManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;public class RingActivity extends Activity implements OnSeekBarChangeListener, OnClickListener {private static final String TAG = "RingActivity";private SeekBar sb_voice, sb_system, sb_ring, sb_music, sb_alarm, sb_notify;private ImageView iv_voice_add, iv_system_add, iv_ring_add, iv_music_add, iv_alarm_add, iv_notify_add;private ImageView iv_voice_del, iv_system_del, iv_ring_del, iv_music_del, iv_alarm_del, iv_notify_del;private int[] mStreamType = {AudioManager.STREAM_VOICE_CALL, AudioManager.STREAM_SYSTEM,AudioManager.STREAM_RING, AudioManager.STREAM_MUSIC,AudioManager.STREAM_ALARM, AudioManager.STREAM_NOTIFICATION};private int[] mMaxVolume = {0, 0, 0, 0, 0, 0};private int[] mNowVolume = {0, 0, 0, 0, 0, 0};private SeekBar[] mSeekBar = {sb_voice, sb_system, sb_ring,sb_music, sb_alarm, sb_notify};private int[] mStreamRes = {R.id.sb_voice, R.id.sb_system, R.id.sb_ring,R.id.sb_music, R.id.sb_alarm, R.id.sb_notify};private ImageView[] mAddView = {iv_voice_add, iv_system_add, iv_ring_add,iv_music_add, iv_alarm_add, iv_notify_add};private int[] mAddRes = {R.id.iv_voice_add, R.id.iv_system_add, R.id.iv_ring_add,R.id.iv_music_add, R.id.iv_alarm_add, R.id.iv_notify_add};private ImageView[] mDelView = {iv_voice_del, iv_system_del, iv_ring_del,iv_music_del, iv_alarm_del, iv_notify_del};private int[] mDelRes = {R.id.iv_voice_del, R.id.iv_system_del, R.id.iv_ring_del,R.id.iv_music_del, R.id.iv_alarm_del, R.id.iv_notify_del};private int SEEK_BAR=1, ADD_VIEW=2, DEL_VIEW=3;private AudioManager mAudioMgr;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_ring);for (int i=0; i<mStreamType.length; i++) {mSeekBar[i] = (SeekBar) findViewById(mStreamRes[i]);mAddView[i] = (ImageView) findViewById(mAddRes[i]);mDelView[i] = (ImageView) findViewById(mDelRes[i]);}setStreamVolume();for (int i=0; i<mStreamType.length; i++) {mSeekBar[i].setOnSeekBarChangeListener(this);mAddView[i].setOnClickListener(this);mDelView[i].setOnClickListener(this);}}void setStreamVolume() {mAudioMgr = (AudioManager) getSystemService(Context.AUDIO_SERVICE);for (int i=0; i<mStreamType.length; i++) {int type = mStreamType[i];mMaxVolume[i] = mAudioMgr.getStreamMaxVolume(type);mNowVolume[i] = mAudioMgr.getStreamVolume(type);mSeekBar[i].setProgress(100 * mNowVolume[i]/mMaxVolume[i]);}}@Overridepublic void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {}@Overridepublic void onStartTrackingTouch(SeekBar seekBar) {}@Overridepublic void onStopTrackingTouch(SeekBar seekBar) {Log.d(TAG, "当前进度为:"+seekBar.getProgress()+", 最大进度为"+seekBar.getMax());int index = getArrayIndex(seekBar.getId(), SEEK_BAR);int type = mStreamType[index];int volume = mMaxVolume[index] * seekBar.getProgress()/seekBar.getMax();Log.d(TAG, "volume="+volume+", last volume="+mNowVolume[index]+", max volume="+mMaxVolume[index]);if (volume != mNowVolume[index]) {mNowVolume[index] = volume;seekBar.setProgress(100 * mNowVolume[index]/mMaxVolume[index]);}mAudioMgr.setStreamVolume(type, volume, AudioManager.FLAG_PLAY_SOUND);}@Overridepublic void onClick(View v) {int add_index = getArrayIndex(v.getId(), ADD_VIEW);int del_index = getArrayIndex(v.getId(), DEL_VIEW);if (add_index != -1) {SeekBar seekBar = mSeekBar[add_index];if (mNowVolume[add_index] < mMaxVolume[add_index]) {mNowVolume[add_index] = mNowVolume[add_index]+1;seekBar.setProgress(100 * mNowVolume[add_index]/mMaxVolume[add_index]);mAudioMgr.adjustStreamVolume(mStreamType[add_index], AudioManager.ADJUST_RAISE, AudioManager.FLAG_PLAY_SOUND);}} else if (del_index != -1) {SeekBar seekBar = mSeekBar[del_index];if (mNowVolume[del_index] > 0) {mNowVolume[del_index] = mNowVolume[del_index]-1;seekBar.setProgress(100 * mNowVolume[del_index]/mMaxVolume[del_index]);mAudioMgr.adjustStreamVolume(mStreamType[del_index], AudioManager.ADJUST_LOWER, AudioManager.FLAG_PLAY_SOUND);}}}private int getArrayIndex(int resid, int type) {int index = -1;if (type == SEEK_BAR) {for (int i=0; i<mSeekBar.length; i++) {if (mSeekBar[i].getId() == resid) {index = i;break;}}} else if (type == ADD_VIEW) {for (int i=0; i<mAddView.length; i++) {if (mAddView[i].getId() == resid) {index = i;break;}}} else if (type == DEL_VIEW) {for (int i=0; i<mDelView.length; i++) {if (mDelView[i].getId() == resid) {index = i;break;}}}return index;}}

下面是设备震动的代码例子:

import com.example.exmring.R;import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Vibrator;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
import android.widget.Toast;public class ShakeActivity extends Activity implements OnCheckedChangeListener, OnClickListener {private static final String TAG = "ShakeActivity";private EditText et_duration;private CheckBox ck_repeat;private Button btn_begin, btn_end;private Vibrator mVibrator;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_shake);et_duration = (EditText) findViewById(R.id.et_duration);ck_repeat = (CheckBox) findViewById(R.id.ck_repeat);btn_begin = (Button) findViewById(R.id.btn_begin);btn_end = (Button) findViewById(R.id.btn_end);ck_repeat.setOnCheckedChangeListener(this);btn_begin.setOnClickListener(this);btn_end.setOnClickListener(this);mVibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);}@Overridepublic void onClick(View v) {if (v.getId() == R.id.btn_begin) {if (mVibrator.hasVibrator() != true) {Toast.makeText(this, "当前设备未找到震动器", Toast.LENGTH_LONG).show();} else {long duration = Integer.parseInt(et_duration.getText().toString());if (ck_repeat.isChecked() != true) {mVibrator.vibrate(duration);} else {long[] pattern = {duration, duration};mVibrator.vibrate(pattern, 0);}}} else if (v.getId() == R.id.btn_end) {mVibrator.cancel();}}@Overridepublic void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {}}

点击下载本文用到的铃声与震动操作的工程代码

点此查看Android开发笔记的完整目录

Android开发笔记(五十八)铃声与震动相关推荐

  1. Android开发笔记(十八)书籍翻页动画PageAnimation

    前面几节的动画都算简单,本文就介绍一个复杂点的动画--书籍翻页动画.Android有自带的翻页动画ViewPager,不过ViewPager只实现了平移效果.即便使用补间组合动画或者属性动画,也只是把 ...

  2. Android开发笔记(十五)淡入淡出动画TransitionDrawable

    说到淡入淡出动画,可能大家会想到补间动画里面的AlphaAnimation,不过这个深浅动画只能对透明度做渐变效果,也就是只能对一个图形做深浅的颜色变换.如果我们想要从A图片逐渐变为B图片,也就是要实 ...

  3. Android开发笔记(十四)圆弧进度动画CircleAnimation

    一个好看的APP,都有不少精致的动画效果.熟练运用各种动画技术,可让我们的APP灼灼生辉.Android在技术上把动画分为了三类,分别是帧动画FrameAnimation.补间动画TweenAnima ...

  4. Android开发笔记(九十八)往图片添加部件

    添加圆角 添加圆角的功能,要用到Canvas类的drawRoundRect方法,即把画布裁剪成指定的圆角矩形. 下面是给图片添加圆角的效果截图: 下面是给图片添加圆角的代码片段: public sta ...

  5. Android开发笔记(十九)底部标签栏TabBar

    底部标签页实现思路 现在的APP,大多在页面底部显示标签栏Tabbar,用于切换不同栏目的页面.Tabbar起源于iOS,iOS的Tabbar自动位于页面下方,可是Android搬过来的时候做了改动, ...

  6. Android开发笔记(十六)秋千摇摆动画SwingAnimation

    上节博主介绍了AlphaAnimation和淡入淡出动画的使用,其实AlphaAnimation只是四种补间动画中的一种.那么为了加深对其他补间动画的理解,我想说说旋转动画RotateAnimatio ...

  7. Android开发笔记(十二)测量尺寸与下拉刷新

    尺寸测量的配置 控件宽和高的设置方式 大家知道,自定义视图的目的就是要在屏幕上显示期望的图案,那在绘制图案之前,我们得先知道这个图案的尺寸(如宽多少高多少). 一般在xml中给控件的宽和高有三种赋值方 ...

  8. Android开发笔记(一百八十七)利用估值器实现弹幕动画

    如今上网看电影电视越发流行了,追剧的时候经常看到视频上方数行评论向左边飘去,犹如子弹那样飞快掠过,这些评论文字因此得名"弹幕".弹幕评论由正在观看的网友们即兴发表,故而连绵不绝从画 ...

  9. Android开发笔记(十)常用的图片加工操作

    APP开发自然少不了各种图片的加工处理,虽然说加工图片是美工干的活,但是码农会些简单的操作总归是好事.一些简单的加工如缩放.旋转.裁剪.格式转换,使用ACDSee就够用了,不过有些稍微复杂的操作得借助 ...

  10. Xamarin.Android开发实践(十八)

    Xamarin.Android之SlidingMenu 一.前言 有位网友在评论中希望能够出个在Xamarin.Android下实现SlidingMenu效果的随笔,刚好昨天在观看官网示例项目的时候也 ...

最新文章

  1. Gallery简单应用
  2. 【Python】对self和_init_的理解
  3. VS 2017 安装测试
  4. wxpython制作表格界面_[Python] wxPython 菜单栏控件学习总结(原创)
  5. [学习笔记]c#Primer中文版-类设计、static成员、const和readonly数据成员
  6. Jw-alipay 1.0.0版本发布,开源支付窗管理平台
  7. 7-1 水文数据校验及处理 (50 分)
  8. GCF(1)---How to modify PICS according to FGI bits UE reported
  9. Vue学习笔记(二) —— 组件开发
  10. angular实例模态【modal】
  11. mysql frm 没有myd_MySQL表只对应一个.frm文件,没有.MYD 和.MYI文件
  12. 《大数据分析原理与实践》一一导读
  13. jqueryAjax的使用
  14. 【每日算法Day 72】谷歌面试题:又双叒叕是位运算,最详细的自动机推导过程...
  15. json数据交互——@RequestBody与@ResponseBody
  16. 细说 AppCompat 主题引发的坑:You need to use a Theme.AppCompat theme with this activity!
  17. Scipy安装遇到的问题
  18. 我的前端成长之路-写给在迷茫路上的人
  19. 超详细且简单的Qt Designer设置界面背景图
  20. ids for this class must be manually assigned before calling save(): com.jia.enity.Book;

热门文章

  1. 直观理解:为什么A为 n 阶满秩方阵时,Ax=0 只有零解?
  2. Vue 中是如何解析 template 字符串为 VNode 的?
  3. Java自动化测试框架-07 - TestNG之Factory篇 - (详细教程)
  4. python没有return语句的函数将返回_为什么Python没有return返回值
  5. WEB小知识学习集锦
  6. android camera 降低帧率_深入理解Camera 硬件抽象层
  7. java随机生成车牌_JDBC:随机生成车牌号,批量插入数据库
  8. html中div流光边框,CSS3 迷你的圆形流光边界
  9. 支持同步的php目录,php – rsync同步省略目录
  10. 调用远程接口上传文件