前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android开发笔记(五十二)通知推送Notification

Android开发笔记(五十二)通知推送Notification

作者头像
aqi00
发布2019-01-18 11:12:06
2.1K0
发布2019-01-18 11:12:06
举报
文章被收录于专栏:老欧说安卓老欧说安卓

PendingIntent

准备工作复习一下PendingIntent,前面的博文《Android开发笔记(五十)定时器AlarmManager》已经提到了它。PendingIntent意即延迟的Intent,主要用于非立即响应的通信场合。上回的博文,博主介绍了PendingIntent的用法,下面再列出有用到它的场合: 1、用于定时器AlarmManager,处理时刻到达后的提醒动作 2、用于通知推送Notification,处理点击通知后的相应动作 3、用于远程视图RemoteViews,处理远程控件上的点击动作 4、用于发送短信SmsManager,处理短信发送完的后续动作

Notification

Android的消息通知栏放的是APP想即时提醒用户的消息,Notification就是这么一个由APP提供的通知推送内容,每条通知基本都有这些元素:图标、标题、内容、时间等等,它的参数通过建造者模式来构建。下面是Notification.Builder常用的构建参数方法: setWhen : 设置推送时间,以“小时:分钟”格式显示 setShowWhen : 设置是否显示推送时间 setUsesChronometer : 设置是否显示时间计数。为true时将不显示推送时间,动态显示从通知被推送到当前的时间间隔,以“分钟:秒钟”格式显示 setSmallIcon : 设置状态栏里面的图标(小图标) setTicker : 设置状态栏里面的提示文本 setLargeIcon : 设置下拉列表里面的图标(大图标) setContentTitle : 设置下拉列表里面的标题文本 setContentText : 设置下拉列表里面的内容文本 setSubText : 设置下拉列表里面的附加说明文本,位于内容文本下方。若调用该方法,则setProgress的设置将失效 setProgress : 设置进度条与当前进度。进度条位于标题文本与内容文本中间 setNumber : 设置下拉列表右下方的数字,可与setProgress联合使用,表示进度条的当前进度数值 setContentInfo : 设置下拉列表右下方的文本。若调用该方法,则setNumber的设置将失效 setContentIntent : 设置内容的PendingIntent,在点击该通知时触发Intent动作 setDeleteIntent : 设置删除的PendingIntent,在滑掉该通知时触发Intent动作 setAutoCancel : 设置该通知是否自动清除。若为true,点击该通知后,通知会自动消失;若为false,点击该通知后,通知不会消失。 setSound : 设置通知推送时的声音 setVibrate : 设置通知推送时的震动方式 setOngoing : 设置该通知是否保持在下拉列表中。为true时用户将不能从下拉列表中去掉该通知 setPriority : 设置该通知的优先级 setExtras : 设置该通知的Bundle参数信息 setContent : 设置一个定制视图RemoteViews,用于取代Builder的默认视图模板 build : 构建方法。在以上参数都设置完毕后,调用该方法会返回Notification对象

NotificationManager

Notification只是生成通知的内容,实际推送动作还需要借助于系统的通知服务来实现。NotificationManager便是系统通知服务的管理类,它的常用方法如下: notify : 推送指定通知到状态栏和下拉列表 cancel : 取消指定通知。调用该方法后,状态栏和下拉列表中的指定通知将消失 cancelAll : 取消所有通知 下面是NotificationManager的调用代码例子:

代码语言:javascript
复制
			NotificationManager notifyMgr = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
			notifyMgr.notify(R.string.app_name, notify);

Notification除了可由NotificationManager进行推送,也可由Service的startForeground方法推送,从而使得后台服务保持在前台运行,详细说明见《Android开发笔记(四十一)Service的生命周期》。

RemoteViews

远程视图RemoteViews与页面视图一样也是从layout下的布局文件中得到,二者之间的区别主要有: 1、远程视图主要用于桌面部件与通知栏部件,而页面视图用于APP页面; 2、远程视图只支持少数几种控件,如TextView、ImageView、Button、ImageButton、ProcessBar、Chronometer(计时器)、AnalogClock(模拟时钟); 3、远程视图不可直接设置控件信息,只能通过RemoteViews对象的set方法来设置; 下面是RemoteViews的常用方法: RemoteViews : 构造函数。第一个参数是包名,第二个参数是布局文件id setViewVisibility : 设置控件是否可见 setViewPadding : 设置控件的间距 setTextViewText : 设置TextView和Button的文本内容 setTextViewTextSize : 设置TextView和Button的文本大小 setTextColor : 设置TextView和Button的文本颜色 setTextViewCompoundDrawables : 设置TextView的周围图标 setImageViewResource : 设置ImageView和ImageButton的图片id setImageViewBitmap : 设置ImageView和ImageButton的图片位图 setChronometer : 设置计时器信息 setProgressBar : 设置进度条信息 setOnClickPendingIntent : 设置控件点击的响应动作

使用示例

为演示本文提到的几种推送,博主编码实现了下列三种方式的推送: 1、采用默认模板推送一个通知; 2、采用RemoteViews方式推送通知,并可根据部件上的点击事件改变通知内容; 3、采用RemoteViews方式让后台服务保持在前台运行,并可由后台服务的运行进度来实时更新通知内容; 下面是采用RemoteViews方式的通知推送效果图:

下面是通知推送的示例代码:

代码语言:javascript
复制
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.BitmapFactory;
import android.os.Build;
import android.os.Bundle;
import android.os.SystemClock;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.RemoteViews;

@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public class NotificationActivity extends Activity implements OnClickListener {

	private static final String TAG = "NotificationActivity";
	private String mSong = "《两只老虎》";
	private String PLAY_EVENT = "";
	private boolean bPlay = true;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_notification);

		Button btn_default = (Button) findViewById(R.id.btn_default);
		Button btn_custom = (Button) findViewById(R.id.btn_custom);
		Button btn_service = (Button) findViewById(R.id.btn_service);
		btn_default.setOnClickListener(this);
		btn_custom.setOnClickListener(this);
		btn_service.setOnClickListener(this);

		PLAY_EVENT = getResources().getString(R.string.play_event);
	}
	
	private void sendDefaultNotify() {
		Intent clickIntent = new Intent(this, MainActivity.class);
		PendingIntent contentIntent = PendingIntent.getActivity(this,
				R.string.app_name, clickIntent,
				PendingIntent.FLAG_UPDATE_CURRENT);
		Intent cancelIntent = new Intent(this, MessengerActivity.class);
		PendingIntent deleteIntent = PendingIntent.getActivity(this,
				R.string.app_name, cancelIntent,
				PendingIntent.FLAG_UPDATE_CURRENT);

		Notification.Builder builder = new Notification.Builder(this);
		builder.setContentIntent(contentIntent)
				.setDeleteIntent(deleteIntent)
				.setUsesChronometer(true)
				.setProgress(100, 60, false)
				.setSubText("这里是副本")
				.setNumber(99)
				.setAutoCancel(false)
				.setSmallIcon(R.drawable.tt_s)
				.setTicker("提示文本")
				//.setWhen(System.currentTimeMillis())
				.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.tt_s))
				.setContentTitle("标题文本")
				.setContentText("内容文本");
		Notification notify = builder.build();

		NotificationManager notifyMgr = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
		notifyMgr.notify(R.string.app_name, notify);
	}
	
	private void sendCustomNotify(boolean is_play) {
		bPlay = !bPlay;
		Intent pIntent = new Intent(PLAY_EVENT);
		PendingIntent nIntent = PendingIntent.getBroadcast(
				this, R.string.app_name, pIntent, PendingIntent.FLAG_UPDATE_CURRENT);
		RemoteViews widget_notify = new RemoteViews(getPackageName(), R.layout.widget_notify);
		if (is_play == true) {
			widget_notify.setTextViewText(R.id.btn_play, "暂停");
			widget_notify.setTextViewText(R.id.tv_play, mSong+"正在播放");
			widget_notify.setProgressBar(R.id.pb_play, 100, 10, false);
			widget_notify.setOnClickPendingIntent(R.id.btn_play, nIntent);
			widget_notify.setChronometer(R.id.chr_play, SystemClock.elapsedRealtime(), "%s", true);
		} else {
			widget_notify.setTextViewText(R.id.btn_play, "继续");
			widget_notify.setTextViewText(R.id.tv_play, mSong+"暂停播放");
			widget_notify.setProgressBar(R.id.pb_play, 100, 60, false);
			widget_notify.setChronometer(R.id.chr_play, SystemClock.elapsedRealtime(), "%s", false);
		}
		widget_notify.setOnClickPendingIntent(R.id.btn_play, nIntent);
		Intent intent = new Intent(this, MainActivity.class);
		PendingIntent contentIntent = PendingIntent.getActivity(this,
				R.string.app_name, intent,
				PendingIntent.FLAG_UPDATE_CURRENT);

		Notification.Builder builder = new Notification.Builder(this);
		builder.setContentIntent(contentIntent)
				.setContent(widget_notify)
				.setTicker(mSong)
				.setSmallIcon(R.drawable.tt_s);
		Notification notify = builder.build();
		
		NotificationManager notifyMgr = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
		notifyMgr.notify(R.string.app_name, notify);
	}

	@Override
	public void onClick(View v) {
		if (v.getId() == R.id.btn_default) {
			sendDefaultNotify();
		} else if (v.getId() == R.id.btn_custom) {
			sendCustomNotify(bPlay);
		} else if (v.getId() == R.id.btn_service) {
			Intent intent = new Intent(this, MusicService.class);
			intent.putExtra("is_play", bPlay);
			intent.putExtra("song", mSong);
			if (bPlay == true) {
				startService(intent);
			} else {
				stopService(intent);
			}
			bPlay = !bPlay;
		}
	}

	@Override
	public void onStart() {
		super.onStart();
		notifyReceiver = new NotifyReceiver();
		IntentFilter filter = new IntentFilter(PLAY_EVENT);
        registerReceiver(notifyReceiver, filter);
	}

	@Override
	public void onStop() {
        unregisterReceiver(notifyReceiver);
		super.onStop();
	}

    private NotifyReceiver notifyReceiver;
    public class NotifyReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent != null) {
        		sendCustomNotify(bPlay);
            }
        }
    }

}

下面是后台服务的示例代码:

代码语言:javascript
复制
import android.annotation.TargetApi;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Binder;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.SystemClock;
import android.util.Log;
import android.widget.RemoteViews;

@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
public class MusicService extends Service {
	private static final String TAG = "MusicService";
	private final IBinder mBinder = new LocalBinder();

	public class LocalBinder extends Binder {
		public MusicService getService() {
			return MusicService.this;
		}
	}

	@Override
	public IBinder onBind(Intent intent) {
		Log.d(TAG, "onBind");
		return mBinder;
	}

	private String mSong;
	private String PAUSE_EVENT = "";
	private boolean bPlay = true;

	private long mBaseTime;
	private long mPauseTime = 0;
	private int mProcess = 0;
	private Handler mHandler = new Handler();
	private Runnable mPlay = new Runnable() {
		@Override
		public void run() {
			if (bPlay == true) {
				if (mProcess < 100) {
					mProcess+=2;
				} else {
					mProcess = 0;
				}
				mHandler.postDelayed(this, 200);
			}
			refresh();
		}
	};
	
	private void refresh() {
		Intent pIntent = new Intent(PAUSE_EVENT);
		PendingIntent nIntent = PendingIntent.getBroadcast(
				this, R.string.app_name, pIntent, PendingIntent.FLAG_UPDATE_CURRENT);
		RemoteViews widget_notify = new RemoteViews(getPackageName(), R.layout.widget_notify);
		if (bPlay == true) {
			widget_notify.setTextViewText(R.id.btn_play, "暂停");
			widget_notify.setTextViewText(R.id.tv_play, mSong+"正在播放");
			widget_notify.setProgressBar(R.id.pb_play, 100, mProcess, false);
			widget_notify.setOnClickPendingIntent(R.id.btn_play, nIntent);
			widget_notify.setChronometer(R.id.chr_play, mBaseTime, "%s", true);
		} else {
			widget_notify.setTextViewText(R.id.btn_play, "继续");
			widget_notify.setTextViewText(R.id.tv_play, mSong+"暂停播放");
			widget_notify.setProgressBar(R.id.pb_play, 100, mProcess, false);
			widget_notify.setChronometer(R.id.chr_play, mBaseTime, "%s", false);
		}
		widget_notify.setOnClickPendingIntent(R.id.btn_play, nIntent);
		Intent intent = new Intent(this, MainActivity.class);
		PendingIntent contentIntent = PendingIntent.getActivity(this,
				R.string.app_name, intent,
				PendingIntent.FLAG_UPDATE_CURRENT);

		Notification.Builder builder = new Notification.Builder(this);
		builder.setContentIntent(contentIntent)
				.setContent(widget_notify)
				.setTicker(mSong)
				.setSmallIcon(R.drawable.tt_s);
		Notification notify = builder.build();
		startForeground(1, notify);
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startid) {
		mBaseTime = SystemClock.elapsedRealtime();
		bPlay = intent.getBooleanExtra("is_play", true);
		mSong = intent.getStringExtra("song");
		Log.d(TAG, "bPlay="+bPlay+", mSong="+mSong);
		mHandler.postDelayed(mPlay, 200);
		
		return START_STICKY;
	}
	
	@Override
	public void onCreate() {
		PAUSE_EVENT = getResources().getString(R.string.pause_event);
		pauseReceiver = new PauseReceiver();
		IntentFilter filter = new IntentFilter(PAUSE_EVENT);
        registerReceiver(pauseReceiver, filter);
		super.onCreate();
	}
	
	@Override
	public void onDestroy() {
        unregisterReceiver(pauseReceiver);
		super.onDestroy();
	}

    private PauseReceiver pauseReceiver;
    public class PauseReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent != null) {
            	bPlay = !bPlay;
            	if (bPlay == true) {
            		mHandler.postDelayed(mPlay, 200);
            		if (mPauseTime > 0) {
                		long gap = SystemClock.elapsedRealtime() - mPauseTime;
                		mBaseTime += gap;
            		}
            	} else {
            		mPauseTime = SystemClock.elapsedRealtime();
            	}
            }
        }
    }

}

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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016年01月19日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • PendingIntent
  • Notification
  • NotificationManager
  • RemoteViews
  • 使用示例
相关产品与服务
短信
腾讯云短信(Short Message Service,SMS)可为广大企业级用户提供稳定可靠,安全合规的短信触达服务。用户可快速接入,调用 API / SDK 或者通过控制台即可发送,支持发送验证码、通知类短信和营销短信。国内验证短信秒级触达,99%到达率;国际/港澳台短信覆盖全球200+国家/地区,全球多服务站点,稳定可靠。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档