Android Notification学习

本文详细介绍了Android系统中Notification和PendingIntent的使用方法及其应用场景,包括如何创建和更新Notification,如何利用PendingIntent处理用户交互。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.  实例FM的notification

/**
     * Show notification
     */
    private void showNotification() {
        Intent notificationIntent = new Intent();
        notificationIntent.setClassName(getPackageName(), FmRadioActivity.class.getName());
        PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(),  0, notificationIntent, 0);
        Notification notification = new Notification(R.drawable.fm_title_icon, null, System.currentTimeMillis());
        notification.flags |= Notification.FLAG_ONGOING_EVENT | Notification.FLAG_NO_CLEAR;
        String fmUnit = mContext.getString(R.string.fm_unit);
        String text = FmRadioUtils.formatStation(mCurrentStation) + " " + fmUnit;
        notification.setLatestEventInfo(getApplicationContext(),getResources().getString(R.string.app_name), text, pendingIntent);
        Log.d(TAG, "Add notification to the title bar.");
        startForeground(NOTIFICATION_ID, notification);
    }
    //转台之后需要update,就是重新加载下
    private void updateNotification() {
        Log.d(TAG, "FmRadioService.updateNotification");
        if (mIsPowerUp) {
            showNotification();
        }
    }
    //关闭FM时,也要关闭相应的notification
    private void removeNotification() {
        Log.d(TAG, "FmRadioService.removeNotification");
        stopForeground(true);
    }

2. Music 的Notification

 private void updateNotification(Context context, Bitmap bitmap) {
        RemoteViews views = new RemoteViews(getPackageName(), R.layout.newstatusbar);
        String trackinfo = getTrackName();
        String artist = getArtistName();
        if (artist == null || artist.equals(MediaStore.UNKNOWN_STRING)) {
            artist = getString(R.string.unknown_artist_name);
        }
        Resources res = getResources();
        int textColor = res.getThemeMainColor();
        if (textColor != 0) {
            views.setTextColor(R.id.txt_trackinfo, textColor);
        }
        trackinfo += " - " + artist;
        views.setTextViewText(R.id.txt_trackinfo, trackinfo);
        Intent intent;
        PendingIntent pIntent;

        intent = new Intent("com.android.music.PLAYBACK_VIEWER");
        intent.putExtra("collapse_statusbar", true);
        pIntent = PendingIntent.getActivity(context, 0, intent, 0);
        views.setOnClickPendingIntent(R.id.iv_cover, pIntent);

        intent = new Intent(PREVIOUS_ACTION);
        intent.setClass(context, MediaPlaybackService.class);
        pIntent = PendingIntent.getService(context, 0, intent, 0);
        views.setOnClickPendingIntent(R.id.btn_prev, pIntent);

        intent = new Intent(PAUSE_ACTION);
        intent.setClass(context, MediaPlaybackService.class);
        pIntent = PendingIntent.getService(context, 0, intent, 0);
        views.setOnClickPendingIntent(R.id.btn_pause, pIntent);

        intent = new Intent(NEXT_ACTION);
        intent.setClass(context, MediaPlaybackService.class);
        pIntent = PendingIntent.getService(context, 0, intent, 0);
        views.setOnClickPendingIntent(R.id.btn_next, pIntent);

        intent = new Intent("my.nullaction");
        pIntent = PendingIntent.getService(context, 0, intent, 0);
        views.setOnClickPendingIntent(R.id.rl_newstatus, pIntent);
        if (bitmap != null) {
            views.setImageViewBitmap(R.id.iv_cover, bitmap);
            mAlbumArt = bitmap;
        }
        intent = new Intent("com.android.music.PLAYBACK_VIEWER");
        Notification status = new Notification();
        /*Add by dongyang.li Begin: modified 添加修改代码*/  
        //status_icon 为状态栏图标,R.id.statusbar_pause 为通知 的 暂停/开始按钮  
        int status_icon = R.drawable.ic_appwidget_music_pause;  
        //根据播放状态,来决定 暂停/开始 图标  
        if(isPlaying()){  
            views.setImageViewResource(R.id.status_pause, R.drawable.ic_appwidget_music_pause);  
        }else{  
            views.setImageViewResource(R.id.status_pause, R.drawable.ic_appwidget_music_play);  
            status_icon = R.drawable.ic_appwidget_music_pause;  
         }   
        //给通知栏 暂停/开始 按钮 添加点击事件   
        views.setOnClickPendingIntent(R.id.status_pause, pause_PendingIntent());   
        /*End:  */  
        status.contentView = views;
        status.flags |= Notification.FLAG_ONGOING_EVENT;
        //status.icon = R.drawable.stat_notify_musicplayer;
        status.icon = status_icon;
        status.contentIntent = PendingIntent.getActivity(context, 0, intent, 0);
        mMediaplayerHandler.removeMessages(DEALY_STOPFORGROUND);
        startForeground(PLAYBACKSERVICE_STATUS, status);  
    }

    private PendingIntent pause_PendingIntent(){ 
        Intent intent = new Intent(TOGGLEPAUSE_ACTION);  
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);  
         return pendingIntent;  
    } 





Notification除了用于后台服务通知,还常用在下面情况:

(1)保持服务存在。当系统内存不足时,系统会认为某后台服务占用内存时间太长而中止该服务,以释放内存。对于某些服务,例如播放音乐,如果系统对该服务进行资源释放,用户体验就成了音乐突然没有声音。对这类服务,我们希望享有更高的优先级别,不会被系统干掉。

(2)用户随时与服务进行互动。例如播放音乐的服务,用户可随时暂停音乐播放,或选择其他曲目,甚至中止播放音乐服务。

要实现上述两点,方法是在Service中宣称自己是foreground,并维持一个通知来向用户表明foreground状态,用户可以通过下拉通知并点击通知,进入该服务界面,实施互动操作。

//设置notification的flag,表明在点击通知后,通知并不会消失,也在最右图上仍在通知栏显示图标。这是确保在activity中退出后,状态栏仍有图标可提下拉、点击,再次进入activity。
            myNotify.flags |= Notification.FLAG_NO_CLEAR;

startForeground( int, Notification)将服务设置为foreground状态,使系统知道该服务是用户关注,低内存情况下不会killed,并提供通知向用户表明处于foreground状态。
            startForeground
( NOTIFY_FAKEPLAYER_ID, myNotify);

 

根据activity的生命周期,在activity不显示时,会执行onStop函数(比如按下home键),所以你在onStop函数(按退出键除外)里面把notification放在通知栏里,再此显示时,把notification从通知栏里去掉。或者,只要程序在运行就一直显示通知栏图标。
 
         
 
下面对Notification类中的一些常量,字段,方法简单介绍一下:
常量:
DEFAULT_ALL    使用所有默认值,比如声音,震动,闪屏等等
DEFAULT_LIGHTS 使用默认闪光提示
DEFAULT_SOUNDS 使用默认提示声音
DEFAULT_VIBRATE 使用默认手机震动
【说明】:加入手机震动,一定要在manifest.xml中加入权限:
<uses-permission android:name= "android.permission.VIBRATE" />
以上的效果常量可以叠加,即通过
notification.defaults =DEFAULT_SOUND|DEFAULT_VIBRATE; 
notification.defaults |= DEFAULT_SOUND (最好在真机上测试,震动效果模拟器上没有)
 
             
 
//设置flag位
FLAG_AUTO_CANCEL  该通知能被状态栏的清除按钮给清除掉
FLAG_NO_CLEAR     该通知能被状态栏的清除按钮给清除掉
FLAG_ONGOING_EVENT 通知放置在正在运行
FLAG_INSISTENT 是否一直进行,比如音乐一直播放,知道用户响应
 
           
 
常用字段:
contentIntent  设置PendingIntent对象,点击时发送该Intent
defaults 添加默认效果
flags 设置flag位,例如FLAG_NO_CLEAR等
icon 设置图标
sound 设置声音
tickerText 显示在状态栏中的文字
when 发送此通知的时间戳
 
                 
 
NotificationManager常用方法介绍:
public void cancelAll() 移除所有通知(只是针对当前Context下的Notification)
public  void cancel( int id) 移除标记为id的通知 (只是针对当前Context下的所有Notification)
public  void notify(String tag , int id, Notification notification) 将通知加入状态栏,标签为tag,标记为id
public  void notify( int id, Notification notification) 将通知加入状态栏,标记为id



知识点

1)什么是PendingIntent


PendingIntent和Intent略有不同,它可以设置执行次数,主要用于远程服务通信、闹铃、通知、启动器、短信中,在一般情况下用的比较少。


2)PendingIntent什么用


Notification支持多种Intent来响应单击事件、消除事件、处理紧急状态的全屏事件等。

这里就用到了setContentIntent(PendingIntent intent)来处理以上这么多的事件。


3)相关属性和方法

属性:

PendingIntent的位标识符:

FLAG_ONE_SHOT   表示返回的PendingIntent仅能执行一次,执行完后自动取消

FLAG_NO_CREATE     表示如果描述的PendingIntent不存在,并不创建相应的PendingIntent,而是返回NULL

FLAG_CANCEL_CURRENT      表示相应的PendingIntent已经存在,则取消前者,然后创建新的PendingIntent,这个有利于数据保持为最新的,可以用于即时通信的通信场景

FLAG_UPDATE_CURRENT     表示更新的PendingIntent


方法:


可以看出,它支持多种相应方式,有Activity、Broadcast、Service,就根据你自身需求去选择。


在各种情况下情况下它还会根据各种情况出发效果:

contentIntent:在通知窗口区域,Notification被单击时的响应事件由该intent触发;

deleteIntent:当用户点击全部清除按钮时,响应该清除事件的Intent;

fullScreenIntent:响应紧急状态的全屏事件(例如来电事件),也就是说通知来的时候,跳过在通知区域点击通知这一步,直接执行fullScreenIntent代表的事件。


例如:在执行了点击通知之后要跳转到指定的XXX的Activity的时候,可以设置以下方法来相应点击事件:

  1. Intent intent = new Intent(context,XXX.class);  
  2. PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);  
  3. mBuilder.setContentIntent(pendingIntent)  


例如:在执行了清空全部的通知操作时候,可以设置以下方法来相应这个事件:

采用setDeleteIntent(PendingIntent intent)方法或按照以下写法

  1. Intent deleteIntent = new Intent();  
  2. deleteIntent.setClass(context, XXXReceiver.class);  
  3. deleteIntent.setAction(DELETE_ACTION);  
  4. notification.deleteIntent = PendingIntent.getBroadcast(context, 0, deleteIntent, 0);  

例如:在响应紧急事件(如来电)时候,可以设置以下方法来相应这个事件:

采用setFullScreenIntent(PendingIntent intent, boolean highPriority)



具体的Notification配置,可参考

http://www.cnblogs.com/newcj/archive/2011/03/14/1983782.html



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值