Android之Notification制作多媒体控制器

    上一篇讲述了Notification的基础用法,本篇将介绍,自定义通知栏,并利用讲到的内容,实现一个简单的音乐播发器。


 1.自定义通知的实现;


  Notification有一个contentView属性,该属性接受的对象是RemoteView对象,用它即可实现自定义布局.


  获取RemoteView对象的方法:


<span style="font-size:14px;">RemoteView remoteViews = new RemoteViews(getPackageName(),R.layout.notify_view);</span>

2.添加通知栏响应事件


 

Intent buttonplayIntent = new Intent("play");PendingIntent pendplayButtonIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, buttonplayIntent, 0);mRemoteViews.setOnClickPendingIntent(R.id.play, pendplayButtonIntent);

 其中关于PendingIntent


 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及其最终行为。


3.完整的创建自定义通知方法:


 

Notification mNotification;RemoteViews mRemoteViews;NotificationManager notificationManager;public void createNotifiView() {notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);mNotification = new Notification(R.drawable.ic_launcher, "MusicDemo",System.currentTimeMillis());mNotification.flags |= Notification.FLAG_ONGOING_EVENT;Intent intent = new Intent(Intent.ACTION_MAIN);intent.setClass(getApplicationContext(), MainActivity.class);PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent,PendingIntent.FLAG_CANCEL_CURRENT);mNotification.contentIntent = pendingIntent;if (mRemoteViews == null) {mRemoteViews = new RemoteViews(getPackageName(),R.layout.notify_view);}Intent buttoncloseIntent = new Intent("close");PendingIntent pendcloseButtonIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, buttoncloseIntent, 0);mRemoteViews.setOnClickPendingIntent(R.id.close, pendcloseButtonIntent);Intent buttonplayIntent = new Intent("play");PendingIntent pendplayButtonIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, buttonplayIntent, 0);mRemoteViews.setOnClickPendingIntent(R.id.play, pendplayButtonIntent);//Intent buttonnextIntent = new Intent("next");PendingIntent pendnextButtonIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, buttonnextIntent, 0);mRemoteViews.setOnClickPendingIntent(R.id.next, pendnextButtonIntent);Intent buttonprewtIntent = new Intent("prew");PendingIntent pendprewButtonIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, buttonprewtIntent, 0);mRemoteViews.setOnClickPendingIntent(R.id.prew, pendprewButtonIntent);mRemoteViews.setTextViewText(R.id.songName, "歌曲名");if (!MainActivity.isPlay) {mRemoteViews.setImageViewResource(R.id.play,R.drawable.statusbar_btn_play);mRemoteViews.setOnClickPendingIntent(R.id.play,pendplayButtonIntent);} else {mRemoteViews.setImageViewResource(R.id.play,R.drawable.statusbar_btn_pause);mRemoteViews.setOnClickPendingIntent(R.id.play,pendplayButtonIntent);}mNotification.contentView = mRemoteViews;notificationManager.notify(0, mNotification);}

因为这里用了getBroadCast()获取PendingIntent,所以该Intent是通过发送广播来告知通知栏控件发生了触发事件。


所以,需要在响应界面过滤action,注册响应广播。

先给出通知布局文件notifiy_view:


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"tools:ignore="ContentDescription" ><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="64dp"android:orientation="vertical" ><ImageViewandroid:id="@+id/icon_pic"android:layout_width="60dp"android:layout_height="60dp"android:layout_centerVertical="true" /><ImageButtonandroid:id="@+id/close"android:layout_width="30dp"android:layout_height="30dp"android:layout_alignParentRight="true"android:layout_alignParentTop="true"android:layout_marginRight="10dp"android:layout_marginTop="10dp"android:background="@drawable/status_bg"android:src="@drawable/statusbar_close" /><TextViewandroid:id="@+id/songName"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="10dp"android:layout_marginRight="5dp"android:layout_marginTop="10dp"android:layout_toLeftOf="@+id/close"android:layout_toRightOf="@+id/icon_pic"android:ellipsize="end"android:singleLine="true"android:text="歌名"android:textSize="15dp" /><ImageButtonandroid:id="@+id/prew"android:layout_width="30dp"android:layout_height="30dp"android:layout_alignParentBottom="true"android:layout_centerInParent="true"android:background="@drawable/status_bg"android:src="@drawable/statusbar_btn_prev" /><ImageButtonandroid:id="@+id/play"android:layout_width="30dp"android:layout_height="30dp"android:layout_alignTop="@+id/prew"android:layout_marginLeft="10dp"android:layout_toRightOf="@+id/prew"android:background="@drawable/status_bg"android:src="@drawable/statusbar_btn_play" /><ImageButtonandroid:id="@+id/next"android:layout_width="30dp"android:layout_height="30dp"android:layout_alignTop="@+id/prew"android:layout_marginLeft="10dp"android:layout_toRightOf="@+id/play"android:background="@drawable/status_bg"android:src="@drawable/statusbar_btn_next" /></RelativeLayout></LinearLayout>

我将会把项目放在CSDN上,大家可以下载,获取相应的资源文件



在这个小项目中,我将播放的service做为的是后台服务,然后广播也提出来了,作为一个公用的广播,如果只是做简单播放用,可以将广播放在播放界面。


项目中用到的广播:

public class MusicBroadCast extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {Intent musicServiceIntent = new Intent(context, MusicService.class);if (intent.getAction().equals("play")) {musicServiceIntent.putExtra(MusicService.MusicCommandKey, ""+ MusicService.MusicPlayCommand);context.startService(musicServiceIntent);} else if (intent.getAction().equals("next")) {musicServiceIntent.putExtra(MusicService.MusicCommandKey, ""+ MusicService.MusicNextCommand);context.startService(musicServiceIntent);} else if (intent.getAction().equals("prew")) {musicServiceIntent.putExtra(MusicService.MusicCommandKey, ""+ MusicService.MusicNextCommand);context.startService(musicServiceIntent);} else if (intent.getAction().equals("close")) {musicServiceIntent.putExtra(MusicService.MusicCommandKey, "");context.startService(musicServiceIntent);} else if (intent.getAction().equals("android.media.AUDIO_BECOMING_NOISY")) {// 耳机拔出事件musicServiceIntent.putExtra(MusicService.MusicCommandKey,MusicService.MusicPauseCommand+ MusicService.MusicPauseCommand);context.startService(musicServiceIntent);}}}

我这里是在service注册的广播,这个应该有点夸张了,由于项目需要全局播放,然后由通知栏也可以控制,就这样做了。


service文件代码:


package com.example.musicdemo;import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.RemoteViews;import java.io.IOException;/*** Create by gaylen on 2015/12/9 11:07*/public class MusicService extends Service {// 其他对象控制Service进行音频播放操作// 全部采用命令+命令参数的形式处理public static final int MusicInitCommand = 0;public static final int MusicPlayCommand = 10;public static final int MusicStopCommand = 20;public static final int MusicPauseCommand = 30;public static final int MusicSeekToCommand = 40;public static final int MusicNextCommand = 50;public static final int MusicPrevCommand = 60;public static final int MusicNotificationCommand = 70;// 所有的命令参数都String传递// 非String类型,采取转型处理public static String MusicCommandKey = "CtrlCommand";public static String MusicParameterKey = "CommandParameter";private MusicBroadCast broadCast;@Overridepublic void onCreate() {super.onCreate();broadCast = new MusicBroadCast();IntentFilter filter = new IntentFilter();filter.addAction("play");filter.addAction("next");filter.addAction("prew");filter.addAction("close");// 耳机filter.addAction("android.media.AUDIO_BECOMING_NOISY");// 短信// mSystemFilter.addAction("android.provider.Telephony.SMS_RECEIVED");registerReceiver(broadCast, filter);regeisterCallLisenler();/*** 为了防止通知栏点击时出现闪屏,在开启service就将一些对象实例化了*/notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);mNotification = new Notification(R.drawable.ic_launcher, "MusicDemo",System.currentTimeMillis());mNotification.flags |= Notification.FLAG_ONGOING_EVENT;Intent intent = new Intent(Intent.ACTION_MAIN);intent.setClass(getApplicationContext(), MainActivity.class);PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent,PendingIntent.FLAG_CANCEL_CURRENT);mNotification.contentIntent = pendingIntent;}@Nullable@Overridepublic IBinder onBind(Intent intent) {return null;}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {// 分析传入的命令,根据不同命令调用不同方法String commandValue = intent.getStringExtra(MusicCommandKey);if (commandValue != null) {int command = Integer.parseInt(commandValue);switch (command) {case MusicService.MusicPlayCommand:// 得到play命令对应的参数String Param = intent.getStringExtra(MusicParameterKey);// 执行doPlayCommand方法doPlayCommand(Param);break;case MusicService.MusicStopCommand:stopPlayCommand();break;case MusicService.MusicSeekToCommand:// 解析命令参数执行相关方法// 得到SeekTo的进度(字符串形式)String strProgressSet = intent.getStringExtra(MusicService.MusicParameterKey);doSeekToCommand(strProgressSet);break;case MusicService.MusicNextCommand:doNextCommand();break;case MusicService.MusicPrevCommand:doPreCommand();break;case MusicService.MusicNotificationCommand:createNotifiView();break;}}return super.onStartCommand(intent, flags, startId);}@Overridepublic void onDestroy() {super.onDestroy();// Service 被结束,则音乐停止unregisterReceiver(broadCast);}/*** 停止播放*/private void stopPlayCommand() {Log.i("play", "stop");createNotifiView();}private void doPause() {Log.i("play", "pause");}/*** 播放* * @param param*/private void doPlayCommand(String param) {if (MainActivity.isPlay) {doPause();} else {Log.i("play", "play");}createNotifiView();}// 播放下一首命令处理private void doNextCommand() {Log.i("play", "next");}// 播放上一首命令处理private void doPreCommand() {Log.i("play", "pre");}private void doSeekToCommand(String seekToValue) {int seekTo = Integer.parseInt(seekToValue);// 设置跳转进度// mMediaPlayer.seekTo(seekTo);}Notification mNotification;RemoteViews mRemoteViews;NotificationManager notificationManager;public void createNotifiView() {if (mRemoteViews == null) {mRemoteViews = new RemoteViews(getPackageName(),R.layout.notify_view);}Intent buttoncloseIntent = new Intent("close");PendingIntent pendcloseButtonIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, buttoncloseIntent, 0);mRemoteViews.setOnClickPendingIntent(R.id.close, pendcloseButtonIntent);Intent buttonplayIntent = new Intent("play");PendingIntent pendplayButtonIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, buttonplayIntent, 0);mRemoteViews.setOnClickPendingIntent(R.id.play, pendplayButtonIntent);//Intent buttonnextIntent = new Intent("next");PendingIntent pendnextButtonIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, buttonnextIntent, 0);mRemoteViews.setOnClickPendingIntent(R.id.next, pendnextButtonIntent);Intent buttonprewtIntent = new Intent("prew");PendingIntent pendprewButtonIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, buttonprewtIntent, 0);mRemoteViews.setOnClickPendingIntent(R.id.prew, pendprewButtonIntent);mRemoteViews.setTextViewText(R.id.songName, "歌曲名");if (!MainActivity.isPlay) {mRemoteViews.setImageViewResource(R.id.play,R.drawable.statusbar_btn_play);mRemoteViews.setOnClickPendingIntent(R.id.play,pendplayButtonIntent);} else {mRemoteViews.setImageViewResource(R.id.play,R.drawable.statusbar_btn_pause);mRemoteViews.setOnClickPendingIntent(R.id.play,pendplayButtonIntent);}mNotification.contentView = mRemoteViews;notificationManager.notify(0, mNotification);}private AudioManager mAudioManager;public void regeisterCallLisenler() {mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);// 添加来电监听事件TelephonyManager telManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); // 获取系统服务telManager.listen(new MobliePhoneStateListener(),PhoneStateListener.LISTEN_CALL_STATE);}/*** @author wwj 电话监听器类*/private class MobliePhoneStateListener extends PhoneStateListener {@Overridepublic void onCallStateChanged(int state, String incomingNumber) {switch (state) {case TelephonyManager.CALL_STATE_IDLE: // 挂机状态// doPlayCommand("");break;case TelephonyManager.CALL_STATE_OFFHOOK: // 通话状态case TelephonyManager.CALL_STATE_RINGING: // 响铃状态Log.i("tag", "接收到来电-->");doPause();break;default:break;}}}
}

最后就是播放主界面:

public class MainActivity extends ActionBarActivity {public static boolean isPlay = false;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);player();}public void player() {Intent musicServiceIntent = new Intent(MainActivity.this,MusicService.class);// 设置播放控制命令:playCommandmusicServiceIntent.putExtra(MusicService.MusicCommandKey, ""+ MusicService.MusicPlayCommand);MainActivity.this.startService(musicServiceIntent);}
}

布局跟通知栏布局差不多,这里就不写了。


完整项目源码可以去:http://download.csdn.net/detail/caihuajian235/9365027下载。



 



本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/419366.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MyBatis 多表联合查询及优化

关于优化 对于优化嘛&#xff0c;我这里简单的提几点&#xff0c;大家可以考虑一下。首先&#xff0c;就是对表的设计&#xff0c;在设计表初期&#xff0c;不仅仅要考虑到数据库的规范性&#xff0c;还好考虑到所谓的业务&#xff0c;以及对性能的影响&#xff0c;比如&#x…

React Native windows环境安装遇到的坑

在官方中文文档中&#xff08;http://reactnative.cn/docs/0.37/getting-started.html&#xff09;有一段话是&#xff1a;使用Chocolatey来安装NodeJS。注意&#xff0c;目前已知Node 7.1版本在windows上无法正常工作&#xff0c;请注意避开这个版本&#xff01; 如何避开&…

linux指令查看tomcat日志

实际开发中经常遇到查看远程tomcat日志&#xff0c;来查找原因:因此总结了一些常用的linux指令 1、先切换到&#xff1a;cd usr/local/tomcat5/logs 2、tail -f catalina.out3、这样运行时就可以实时查看运行日志了 Ctrlc 是退出tail命令。 其他常用的linux指令整理&#x…

iptables对请求的URL作IP访问控制

服务器运行环境是Tomcat&#xff0c;现在要实现的目的是&#xff0c;只允许特定的IP访问某个目录&#xff0c;一种方法是在tomcat配置文件server.conf中&#xff0c;使用RemoteAddrValve对虚拟主机做访问控制。另外一种方法可以通过iptables规则。个人比较喜欢iptables例如&…

React-Native填坑之TextInput value属性

TextInput用法就不多讲了&#xff0c;主要记录下遇到的一个怪问题。 背景&#xff1a;项目需要开发一个充值页面&#xff0c;需要一个输入框&#xff0c;然后几个按钮&#xff0c;输入框是允许用户自己输入任意金额&#xff0c;按钮是可以让用户快捷选择金额。那么问题来了&…

Spring的特点

Spring框架Spring框架是一个分层架构,有7个定义良好的模块组成spring模块构建在核心容器智之上, 核心容器定义了创建、 配置、和管理bean的方式组成spring框架的每个模块(或组件)都可以单独存在, 或者与其他一个或多个模块联合实现 模块如下: 1--核心容器 核心容器提供spring框…

MySQL对一行多列求和

SUM函数的语法是&#xff1a; SELECT SUM(expression ) FROM tables WHERE predicates; 表达式可以是一个数值字段或公式。 SELECT column1 column1 column1 …… column1 AS Total FROM table

mybatis判断集合为空或者元素个数为零

mybatis判断集合为空或者元素个数为零&#xff1a; <if test"mlhs ! null and mlhs.size() ! 0">and t.mlh_name not in <foreach collection"mlhs" item"item1" open"(" close")" index"i" separator&…

React-Native 填坑之ListView(item更新)

一 背景 效果图如下&#xff1a;二 解决办法 我的目的是实现单选item&#xff0c;正常情况设置一个state变量来保存选中的Index,在每次点击item的时候改变index就OK&#xff01;但是&#xff0c;我想的太天真了。this.setState()只能渲染外部组件&#xff0c;而ListView子组件…

锋利的jQuery--编写jQuery插件(读书笔记五)[完结篇]

1.表单验证插件Validation2.表单插件Form3.动态事件绑定插件livequery可以为后来的元素绑定事件类似于jQuery中的live()方法4.jQuery UI5.jQuery Cookie6.遮罩层插件:thickbox7.编写jQuery插件<1>编写插件的目的&#xff1a;给已经有的一些列方法或函数做一个封装&#x…

Java中的注解以及应用 @Deprecated @SupressWarning @Override

Annotation注解在 Java 中有着很广泛的,他是做为一种标识 为javac所识别,。每一个注解 都对应这一个Java类 在java.lang包中 有三个注解 分别是Deprecated SuppressWarning Override 在使用 注解前必须要在 注解类前面加上 每增加一个注解 就意味着产生了一个注解…

React Native 实现物流进度信息

1.实现效果 2.直接上代码 use strict; import React, {Component} from react; import {View, StyleSheet, Text, Dimensions} from react-native export default class Button extends Component {render() {let invoice [{id: 111, content: 已签收,签收人&#xff1a;门…

String中intern的方法

intern public String intern() 返回字符串对象的规范化表示形式。 一个初始时为空的字符串池&#xff0c;它由类 String 私有地维护。 当调用 intern 方法时&#xff0c;如果池已经包含一个等于此 String 对象的字符串&#xff08;该对象由 equals(Object) 方法确定&#xff0…