利用MediaPlayer来实现Notification通知铃声
来源:互联网 发布:python fix 编辑:程序博客网 时间:2024/05/06 13:53
最近一直有收到客户反馈,通知铃声不响,这让我很郁闷啊,因为那块地方是我来公司前的大神写的,看了一下他是用noticication设置的铃声,我以前的时候发现qq好像并不是用noticication来设置的,因为我在调音量的时候发现他调用的媒体的声音!
于是呼,我就百度有没有用媒体做铃声提示的,果然有!
首先,整理一下Notification的功能与用法
Notification是显示在手机状态栏的通知——手机状态栏位于手机屏幕的最上方,那里一般显示了手机当前的网络状态、电池状态、时间等。Notification所代表的是一种具有全局效果的通知,程序一般通过NotificationManger服务来发送Notification。
Android3.0增加Notification.Builder类,通过该类允许开发者更轻松地创建Notification对象。Notification.Builder提供了如下常用方法。
setDefaults():设置通知LED灯、音乐、震动等。
setAutoCancel():设置点击通知后,让通知自动取消。
setContentTitle():设置通知栏标题。
setContentText():设置通知内容。
setSmallIcon():设置通知图标。
setLargeIcon():设置通知大图标。
setTick():设置通知在状态栏的提示文本。
setContentIntent():设置点击通知后将要启动的程序组件对应的 PendingIntent。
发送Notification很简单,按如下步骤即可。
1、调用getSystemService(NOTIFICATION_SERVICE)方法获取系统的NotificationManger服务。
2、通过构造器创建一个Notification对象。
3、为Notification设置各种属性。
4、通过NotificationManger发送Notification。
此外,setDefaults()方法为Notification设置了声音提示、振动提示、闪光灯等。该属性支持如下属性值。
DEFAULT_SOUND:设置使用默认声音。
DEFAULT_VIBRATE:设置默认振动。
DEFAULT_LIGHTS:设置使用默认闪光灯。
ALL:设置使用默认声音、振动、闪光灯。
如果不想默认设置,也可以使用如下代码:
//设置自定义声音
setSound(Uri.parse(“file:///sdcard/click.mp3”));
//设置自定义振动,实现效果:延迟0ms,然后振动50ms,在延迟100ms,接着在振动150ms。
setVibrate(new long[]{0, 50, 100, 150});
注意:需要添加权限
android.permission.FLASHLIGHT //闪光灯
android.permission.VIBRATE //振动
在写demo前,还需要了解一下PendingIntent这个东东。
pendingIntent字面意义:等待的,未决定的Intent。
pendingIntent对象,使用方法类的静态方法 :
getActivity(Context, int, Intent, int)——->跳转到一个activity组件
getBroadcast(Context, int, Intent, int)——>打开一个广播组件
getService(Context, int, Intent, int)——–>打开一个服务组件。
pendingIntent是一种特殊的Intent。主要的区别在于Intent的执行立刻的,而pendingIntent的执行不是立刻的。pendingIntent执行的操作实质上是参数传进来的Intent的操作,但是使用pendingIntent的目的在于它所包含的Intent的操作的执行是需要满足某些条件的。
intent英文意思是意图,pending表示即将发生或来临的事情。
PendingIntent这个类用于处理即将发生的事情。比如在通知Notification中用于跳转页面,但不是马上跳转。
PendingIntent用于描述Intent及其最终的行为.
你可以通过getActivity(Context context, int requestCode, Intent intent, int flags)系列方法从系统取得一个用于启动一个Activity的PendingIntent对象,
可以通过getService(Context context, int requestCode, Intent intent, int flags)方法从系统取得一个用于启动一个Service的PendingIntent对象
可以通过getBroadcast(Context context, int requestCode, Intent intent, int flags)方法从系统取得一个用于向BroadcastReceiver的Intent广播的PendingIntent对象
返回的PendingIntent可以递交给别的应用程序,然后继续处理。这里的话你可以稍后才处理PendingIntent中描述的Intent及其最终行为。
当你把PendingIntent递交给别的程序进行处理时,PendingIntent仍然拥有PendingIntent原程序所拥有的权限(with the same permissions and identity).当你从系统取得一个PendingIntent时,一定要非常小心才行。比如,通常,如果Intent目的地是你自己的component(Activity/Service/BroadcastReceiver)的话,你最好采用在Intent中显示指定目的component名字的方式,以确保Intent最终能发到目的,否则Intent最后可能不知道发到哪里了。一个PendingIntent就是Android系统中的一个token(节点,这个应该是Linux或C\C++用语)的一个对象引用,它描述了一些将用于retrieve的数据(这里,这些数据描述了Intent及其最终的行为)。
这就意味着即使PendingIntent原进程结束了的话, PendingIntent本身仍然还存在,可在其他进程(PendingIntent被递交到的其他程序)中继续使用.如果我在从系统中提取一个PendingIntent的,而系统中有一个和你描述的PendingIntent对等的PendingInent, 那么系统会直接返回和该PendingIntent其实是同一token的PendingIntent,而不是一个新的token和PendingIntent。然而你在从提取PendingIntent时,通过FLAG_CANCEL_CURRENT参数,让这个老PendingIntent的先cancel()掉,这样得到的pendingInten和其token的就是新的了。
通过FLAG_UPDATE_CURRENT参数的话,可以让新的Intent会更新之前PendingIntent中的Intent对象数据,例如更新Intent中的Extras。另外,我们也可以在PendingIntent的原进程中调用PendingIntent的cancel ()把其从系统中移除掉。
package com.nicole.test.notifictiontest;import android.app.Notification;import android.app.NotificationManager;import android.app.PendingIntent;import android.content.Context;import android.content.Intent;import android.net.Uri;/** * Created by Nicole on 2016/10/23. */public class NotificationUtil { private NotificationManager notificationManager; private Context context; public NotificationUtil(Context context){ this.context = context; notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); } public NotificationManager getNotificationManager(){ return notificationManager; } public Notification getNotification(){ Intent intent = new Intent(context, SecondActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0); Notification notification = new Notification.Builder(context) .setAutoCancel(true) .setTicker("有新消息") .setSmallIcon(R.mipmap.ic_launcher) .setContentTitle("一条新通知") .setContentText("~~~~~~~") .setVibrate(new long[]{0, 50, 100, 150})// .setDefaults(Notification.DEFAULT_LIGHTS|Notification.DEFAULT_SOUND) .setSound(Uri.parse("android.resource://" + MyApplication.getInstance().getPackageName() + "/" + R.raw.message)) .setWhen(System.currentTimeMillis()) .setContentIntent(pendingIntent) .build(); return notification; }}
测试下来结果总结一下,设置了Notification.DEFAULT_LIGHTS,闪光灯好像毫无反应啊!这是为啥。。。我不造。。。然后同时设置了Notification.DEFAULT_SOUND和自定义setSound,系统只会响默认的,要自定义setSound,那就不要setDefaults(Notification.DEFAULT_SOUND)。
接下来利用MediaPlayer来实现通知铃声
首先,先来了解一下MediaPlayer是怎么用的。使用MediaPlayer播放音频十分简单,当程序控制MediaPlayer对象装载音频完成之后,程序可以调用MediaPlayer的如下三个方法进行播放控制。
start():开始或恢复播放
stop():停止播放
pause():暂停播放
为了让MediaPlayer来装在制定音频文件,MediaPlayer提供了如下简单的静态方法。
static MediaPlayer creat(Context context, Uri uri):从指定Uri来装载音频文件,并返回新创建的MediaPlayer对象。
static MediaPlayer creat(Context context, int resid):从resid资源ID对应的资源文件中装载音频文件,并返回新创建的MediaPlayer对象。
上面这两个方法用起来非常方便,但这两个方法每次都会返回新创建的MediaPlayer对象,如果程序需要使用MediaPlayer循环播放多个音频文件,使用MediaPlayer的静态create方法就不太合适了,此时可通过MediaPlayer的setDataSource()方法来装载指定的音频文件。
MediaPlayer提供了如下方法来指定装载相应的音频文件。
setDataSource(String path):指定装载path路径所代表的文件。
setDataSource(FileDescriptor fd, long offset, long length):指定装载fd所代表的文件中从offset开始,长度为length的文件内容。
setDataSource(FileDescriptor fd):指定装载fd所代表的文件。
setDataSource(Context context, Uri uri):指定装载uri所代表的文件。
执行上面所示的setDataSource()方法之后,MediaPlayer并未真正去装载那些音频文件,还需要调用MediaPlayer的prepare()方法去准备音频,所谓“准备”,就是让MediaPlayer真正去装载音频文件。
因此,使用已有的MediaPlayer对象装载“下一首”歌曲的代码模块:
player.reset();player.setDataSource(“…”);player.prepare();player.start();
除此之外,MediaPlayer还提供了一些绑定事件监听器的方法,用于监听MediaPlayer播放过程中所发生的特定事件,绑定事件监听器的方法如下。
setOnCompletionListener(MediaPlayer.OnCompletionListener listener):为MediaPlayer的播放完成事件绑定事件监听器。
setOnErrorListener(MediaPlayer.OnErrorListener listener):为MediaPlayer的播放错误事件绑定事件监听器。
setOnPreparedListener(MediaPlayer.OnPreparedListener listener):当MediaPlayer调用prepare()方法时触发该监听器。
setOnSeekCompleteListener(MediaPlayer.OnSeekCompleteListener listener):当MediaPlayer调用seek()方法时触发该监听器。
接下来是我写的一个demo:
package com.nicole.test.notifictiontest;import android.app.Notification;import android.app.NotificationManager;import android.app.PendingIntent;import android.content.Context;import android.content.Intent;import android.media.AudioManager;import android.media.MediaPlayer;import android.net.Uri;/** * Created by Nicole on 2016/10/23. */public class NotificationUtil { private NotificationManager notificationManager; private static Context context; private static MediaPlayer player ; public NotificationUtil(Context context){ this.context = context; notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); } public NotificationManager getNotificationManager(){ return notificationManager; } public Notification getNotification(){ Intent intent = new Intent(context, SecondActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0); Notification notification = new Notification.Builder(context)// .setAutoCancel(true) .setTicker("有新消息") .setSmallIcon(R.mipmap.ic_launcher) .setContentTitle("一条新通知") .setContentText("~~~~~~~") .setVibrate(new long[]{1500, 500, 1500, 500}) .setWhen(System.currentTimeMillis()) .setContentIntent(pendingIntent) .setPriority(Notification.PRIORITY_MAX) .build(); // 声音一直响到用户相应,就是通知会一直响起,直到你触碰通知栏的时间就会停止 // 创建后在状态栏中通知的内容 notification.flags |= Notification.FLAG_INSISTENT; return notification; } public void voice(){ if(!Config.voiceIsRunning){ Config.voiceIsRunning = true; } else { return; } try { Uri alert = Uri.parse("android.resource://" + MyApplication.getInstance().getPackageName() + "/" + R.raw.message); player = new MediaPlayer(); player.setDataSource(context, alert); if (player.isPlaying()) { player.reset(); // 到初始化状态,这里需要判断是否正在响铃,如果直接在开启一次会出现2个铃声一直循环响起,您不信可以尝试 } else if (!player.isPlaying()) { ring(); } } catch (Exception e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } } private MediaPlayer ring() throws Exception { final AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); if (audioManager.getStreamVolume(AudioManager.STREAM_NOTIFICATION) != 0) { player.setAudioStreamType(AudioManager.STREAM_NOTIFICATION); player.setLooping(true); player.prepare(); player.start(); } return player; } public void cancelNotification(){ notificationManager.cancel(MyApplication.NOTIFICATION_ID); if(player!=null && player.isPlaying()){ player.stop(); player.release(); } Config.voiceIsRunning = false; }}
主要代码就是这样的,现在我把这两种通知做在两个按钮上,在托人在那些收到通知没声音的手机上试试看,是两个都不行呢,还是用MediaPlayer的可以,坐等中。。。
我滴个天。。。测下来都会响,那些说收到通知没声音的人!竟然又说法了!泪流满面的我! _ ( :3 」 ) _
- 利用MediaPlayer来实现Notification通知铃声
- 利用android的"通知Notification"来实现msn的登录状态
- 实现应用专属通知铃声
- Notification实现消息通知
- Notification实现状态通知栏
- Android-Notification (通知实现)
- Android-Notification (通知实现)
- window.Notification实现桌面通知
- 通知栏通知:Notification的实现
- Notification消息通知 通知栏的实现
- 实现手机来电铃声,通知铃声、警告铃声等音频定制化功能(一,添加扫描分区myimage)
- 实现手机来电铃声,通知铃声、警告铃声等音频定制化功能(三,多媒体扫描结果定制处理)
- 利用i/o流来合成自己喜欢的铃声
- Android实现推送PushService通知Notification
- Notification通知实现自定义和带进度条
- Android--PendingIntent 实现发送通知notification
- Notification(通知栏)的实现
- android:Notification实现状态栏的通知
- Java二进制兼容性
- 【J2EE核心开发学习笔记 011】Struts2常用开发技能
- 在android中读取联系人信息的程序,包括读取联系人姓名、手机号码和邮箱
- mybatis配置
- 使用百度地图API获取经纬度
- 利用MediaPlayer来实现Notification通知铃声
- 二维数组作为函数参数传递(C++)
- JavaWeb 发送 激活邮件功能
- 课堂笔记2
- Leetcode||8.String to Integer (atoi)
- 去天瑞地安面试了 这是我整个的面试流程
- 计算机视觉相关领域网站链接(转)
- C语言unsigned char、char与int之间的转换
- Gradle详解