您的位置:首页 > 移动开发 > Android开发

Android仿虾米音乐播放器之通知栏notification解析

2015-07-18 20:21 841 查看
通知栏notification是Android中一个很重要的组件,可以在顶部状态栏中存在,用户也可以通过此来操作应用,在Android中只有3.0以上的版本才加入了notification的按钮点击功能。

先看一下仿虾米写出来的通知的效果



这是一个自定义的notification,添加了,前一曲、播放、暂停、下一曲等功能,自定义的notification需要自己写布局文件,并通过remoteview显示在界面中。

res/layout/customnotice.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="100dp"
    android:background="#37383D"
    android:id="@+id/notice"
    android:orientation="horizontal" >

    <ImageView
        android:id="@+id/widget_album"
        android:layout_width="100dp"
        android:layout_height="match_parent"
        android:contentDescription="这是专辑图片" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:orientation="vertical" >

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:orientation="vertical"
            android:paddingLeft="9dp"
            android:paddingRight="9dp"
            android:paddingTop="9dp" >

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="25dp"
                android:orientation="horizontal" >

                <TextView
                    android:id="@+id/widget_title"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="1"
                    android:ellipsize="end"
                    android:singleLine="true"
                    android:textColor="#ffffff"
                    android:textSize="16sp" />

                <ImageView
                    android:id="@+id/widget_close"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center_vertical"
                    android:layout_marginRight="10dp"
                    android:src="@drawable/global_close" />
            </LinearLayout>

            <TextView
                android:id="@+id/widget_artist"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:ellipsize="end"
                android:singleLine="true"
                android:textColor="#A0A0A0"
                android:textSize="10sp" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:gravity="center"
            android:orientation="horizontal" >

            <ImageView
                android:id="@+id/widget_prev"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:src="@drawable/widget_prev" />

            <ImageView
                android:id="@+id/widget_play"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                />

            <ImageView
                android:id="@+id/widget_next"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:src="@drawable/widget_next" />

            <ImageView
                android:id="@+id/widget_fav"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:src="@drawable/widget_fav" />
        </LinearLayout>
    </LinearLayout>

</LinearLayout>


写了布局之后就需要实例化通知了

1.定义一个NotificationManager对象,并实例化

2.定义一个RemoteViews对象

3.设置RemoteViews属性

private NotificationManager manager;
	private RemoteViews remoteViews;


manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);


/**
	 * 设置通知
	 */
	@SuppressLint("NewApi")
	private void setNotification() {

		NotificationCompat.Builder builder = new Builder(this);

		Intent intent = new Intent(this, MainActivity.class);
		// 点击跳转到主界面
		PendingIntent intent_go = PendingIntent.getActivity(this, 5, intent,
				PendingIntent.FLAG_UPDATE_CURRENT);
		remoteViews.setOnClickPendingIntent(R.id.notice, intent_go);

		// 4个参数context, requestCode, intent, flags
		PendingIntent intent_close = PendingIntent.getActivity(this, 0, intent,
				PendingIntent.FLAG_UPDATE_CURRENT);
		remoteViews.setOnClickPendingIntent(R.id.widget_close, intent_close);

		// 设置上一曲
		Intent prv = new Intent();
		prv.setAction(Constants.ACTION_PRV);
		PendingIntent intent_prev = PendingIntent.getBroadcast(this, 1, prv,
				PendingIntent.FLAG_UPDATE_CURRENT);
		remoteViews.setOnClickPendingIntent(R.id.widget_prev, intent_prev);

		// 设置播放
		if (Myapp.isPlay) {
			Intent playorpause = new Intent();
			playorpause.setAction(Constants.ACTION_PAUSE);
			PendingIntent intent_play = PendingIntent.getBroadcast(this, 2,
					playorpause, PendingIntent.FLAG_UPDATE_CURRENT);
			remoteViews.setOnClickPendingIntent(R.id.widget_play, intent_play);
		}
		if (!Myapp.isPlay) {
			Intent playorpause = new Intent();
			playorpause.setAction(Constants.ACTION_PLAY);
			PendingIntent intent_play = PendingIntent.getBroadcast(this, 6,
					playorpause, PendingIntent.FLAG_UPDATE_CURRENT);
			remoteViews.setOnClickPendingIntent(R.id.widget_play, intent_play);
		}

		// 下一曲
		Intent next = new Intent();
		next.setAction(Constants.ACTION_NEXT);
		PendingIntent intent_next = PendingIntent.getBroadcast(this, 3, next,
				PendingIntent.FLAG_UPDATE_CURRENT);
		remoteViews.setOnClickPendingIntent(R.id.widget_next, intent_next);

		// 设置收藏
		PendingIntent intent_fav = PendingIntent.getBroadcast(this, 4, intent,
				PendingIntent.FLAG_UPDATE_CURRENT);
		remoteViews.setOnClickPendingIntent(R.id.widget_fav, intent_fav);

		builder.setSmallIcon(R.drawable.notification_bar_icon); // 设置顶部图标

		Notification notify = builder.build();
		notify.contentView = remoteViews; // 设置下拉图标
		notify.bigContentView = remoteViews; // 防止显示不完全,需要添加apisupport
		notify.flags = Notification.FLAG_ONGOING_EVENT;
		notify.icon = R.drawable.notification_bar_icon;

		manager.notify(100, notify);
	}


PendingIntent是一种特殊的intent,设置之后并不会马上使用,而是在真正点击后只会调用。Android默认使用的通知高度大概是64dp,无法满足大界面的显示,所以需要在其中设置bigContentView,这样才能显示大图。manager.notify(id, notification)中第一个参数是一个标识码,在取消通知的时候需要传入这个参数,第二个就是一个notify对象。

通知栏一次实例化后里面按钮的点击事件就确定了,如果当前设置的是播放的按钮,那么暂停是不会起作用的,所以需要重新设置通知,目前采用的是用Handler来更新通知栏。

public Handler handler = new Handler() {

		public void handleMessage(android.os.Message msg) {

			Mp3Info info = (Mp3Info) msg.obj;
			Bitmap bitmap = MediaUtil.getArtwork(getApplicationContext(),
					info.getId(), info.getAlbumId(), true, false);
			btm_album.setImageBitmap(bitmap);
			btm_artist.setText(info.getArtist());
			btm_title.setText(info.getTitle());

			// 播放歌曲
			btm_state
					.setImageResource(R.drawable.player_btn_radio_pause_normal);

			// 设置通知栏的图片文字
			remoteViews = new RemoteViews(getPackageName(),
					R.layout.customnotice);
			remoteViews.setImageViewBitmap(R.id.widget_album, bitmap);
			remoteViews.setTextViewText(R.id.widget_title, info.getTitle());
			remoteViews.setTextViewText(R.id.widget_artist, info.getArtist());
			if (Myapp.isPlay) {
				remoteViews.setImageViewResource(R.id.widget_play, R.drawable.widget_btn_pause_normal);
			}else {
				remoteViews.setImageViewResource(R.id.widget_play, R.drawable.widget_btn_play_normal);
			}
		
			setNotification();
		};
	};


在退出的时候需要取消通知栏,用NotificationManager的manager对象取消通知view,其中的100是notify设置的id,用来区别通知,因为在其他应用中可能会产生好多通知。

@Override
	protected void onDestroy() {
		Log.i("---"+TAG, "ondestory");
		super.onDestroy();
		if (remoteViews != null) {
			manager.cancel(100);
		}
		if (receiver != null) {
			unregisterReceiver(receiver);
		}
	}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: