Android Notification

来源:互联网 发布:galgame机翻软件 编辑:程序博客网 时间:2024/06/05 07:43

通知(Notification)是Android系统中比较有特色的一个功能,当某个应用程序希望向用户发出一些提示信息,而该应用程序又不在前台运行时,就可以借助通知来实现。发出一条通知后,手机最上方的状态栏中会显示一个通知的图标,下拉状态栏后可以看到通知的详细内容。Android的通知功能获得了大量用户的认可和喜爱,就连iOS系统也在5.0版本之后加入了类似的功能。

了解了通知的基本概念,下面我们就来看一下通知的使用方法吧。通知的用法还是比较灵活的,既可以在活动里创建,也可以在广播接收器里创建,当然还可以在下一章中我们即将学习的服务里创建。相比于广播接收器和服务,在活动里创建通知的场景还是比较少的,因为一般只有当程序进入到后台的时候我们才需要使用通知。

不过,无论是在哪里创建通知,整体的步骤都是相同的,下面我们就来学习一下创建通知的详细步骤。首先需要一个NotificationManager来对通知进行管理,可以调用ContextgetSystemService()方法获取到。getSystemService()方法接收一个字符串参数用于确定获取系统的哪个服务,这里我们传入Context.NOTIFICATION_SERVICE即可。因此,获取NotificationManager的实例就可以写成:

NotificationManager manager = (NotificationManager) 

getSystemService(Context.NOTIFICATION_SERVICE);

接下来需要创建一个Notification对象,这个对象用于存储通知所需的各种信息,我们可以使用它的有参构造函数来进行创建。Notification的有参构造函数接收三个参数,第一个参数用于指定通知的图标,比如项目的res/drawable目录下有一张icon.png图片,那么这里就可以传入R.drawable.icon。第二个参数用于指定通知的ticker内容,当通知刚被创建的时候,它会在系统的状态栏一闪而过,属于一种瞬时的提示信息。第三个参数用于指定通知被创建的时间,以毫秒为单位,当下拉系统状态栏时,这里指定的时间会显示在相应的通知上。因此,创建一个Notification对象就可以写成:

Notification notification = new Notification(R.drawable.icon, "This is ticker text",System.currentTimeMillis());

创建好了Notification对象后,我们还需要对通知的布局进行设定,这里只需要调用NotificationsetLatestEventInfo()方法就可以给通知设置一个标准的布局。这个方法接收四个参数,第一个参数是Context,这个没什么好解释的。第二个参数用于指定通知的标题内容,下拉系统状态栏就可以看到这部分内容。第三个参数用于指定通知的正文内容,同样下拉系统状态栏就可以看到这部分内容。第四个参数我们暂时还用不到,可以先传入null。因此,对通知的布局进行设定就可以写成:

notification.setLatestEventInfo(context, "This is content title", "This is content text", null);

以上工作都完成之后,只需要调用NotificationManagernotify()方法就可以让通知显示出来了。notify()方法接收两个参数,第一个参数是id,要保证为每个通知所指定的id都是不同的。第二个参数则是Notification对象,这里直接将我们刚刚创建好的Notification对象传入即可。因此,显示一个通知就可以写成:

manager.notify(1, notification);

到这里就已经把创建通知的每一个步骤都分析完了,下面就让我们通过一个具体的例子来看一看通知到底是长什么样的。

新建一个NotificationTest项目,并修改activity_main.xml中的代码,如下所示:

<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="match_parent"

    android:orientation="vertical" >


<Button 

    android:id="@+id/send_notice"

    android:layout_width="match_parent"

    android:layout_height="wrap_content"

    android:text="Send notice"

    />

</LinearLayout>

布局文件非常简单,里面只有一个Send notice按钮,用于发出一条通知。接下来修改MainActivity中的代码,如下所示:

public class MainActivity extends Activity implements OnClickListener {


private Button sendNotice;


@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

sendNotice = (Button) findViewById(R.id.send_notice);

sendNotice.setOnClickListener(this);

}


@Override

public void onClick(View v) {

switch (v.getId()) {

case R.id.send_notice:

NotificationManager manager = (NotificationManager) 

getSystemService(NOTIFICATION_SERVICE);

Notification notification = new Notification(R.drawable. ic_launcher, "This is ticker text", System.currentTimeMillis());

notification.setLatestEventInfo(this, "This is content title", "This is content text", null);

manager.notify(1, notification);

break;

default:

break;

}

}


}

可以看到,我们在Send notice按钮的点击事件里面完成了通知的创建工作,创建的过程正如前面所描述的一样。现在就可以来运行一下程序了,点击Send notice按钮,就会看到有一条通知在系统状态栏显示出来,如图8.1所示。

 

图 8.1

下拉系统状态栏可以看到该通知的详细信息,如图8.2所示。

 

图 8.2

如果你使用过Android手机,此时应该会下意识地认为这条通知是可以点击的。但是当你去点击它的时候,你会发现没有任何效果。不对啊,好像每条通知点击之后都应该会有反应的呀?其实要想实现通知的点击效果,我们还需要在代码中进行相应的设置,这就涉及到了一个新的概念,PendingIntent

PendingIntent从名字上看起来就和Intent有些类似,它们之间也确实存在着不少共同点。比如它们都可以去指明某一个意图,都可以用于启动活动、启动服务以及发送广播等。不同的是,Intent更加倾向于去立即执行某个动作,而PendingIntent更加倾向于在某个合适的时机去执行某个动作。所以,也可以把PendingIntent简单地理解为延迟执行的Intent

PendingIntent的用法同样很简单,它主要提供了几个静态方法用于获取PendingIntent的实例,可以根据需求来选择是使用getActivity()方法、getBroadcast()方法、还是getService()方法。这几个方法所接收的参数都是相同的,第一个参数依旧是Context,不用多做解释。第二个参数一般用不到,通常都是传入0即可。第三个参数是一个Intent对象,我们可以通过这个对象构建出PendingIntent意图。第四个参数用于确定PendingIntent的行为,有FLAG_ONE_SHOTFLAG_NO_CREATEFLAG_CANCEL_CURRENTFLAG_UPDATE_ CURRENT这四种值可选,每种值的含义你可以查看文档,我就不一一进行解释了。

PendingIntent有了一定的了解后,我们再回过头来看一下NotificationsetLatestEventInfo()方法。刚才我们将setLatestEventInfo()方法的第四个参数忽略掉了,直接传入了null,现在仔细观察一下,发现第四个参数正是一个PendingIntent对象。因此,这里就可以通过PendingIntent构建出一个延迟执行的意图,当用户点击这条通知时就会执行相应的逻辑。

现在我们来优化一下NotificationTest项目,给刚才的通知加上点击功能,让用户点击它的时候可以启动另一个活动。

首先需要准备好另一个活动,这里新建布局文件notification_layout.xml,代码如下所示:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"

    android:layout_height="match_parent" >

    <TextView 

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_centerInParent="true"

        android:textSize="24sp"

        android:text="This is notification layout"

        />

    

</RelativeLayout>

布局文件的内容非常简单,只有一个居中显示的TextView,用于展示一段文本信息。然后新建NotificationActivity继承自Activity,在这里加载刚才定义的布局文件,代码如下所示:

public class NotificationActivity extends Activity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.notification_layout);

}

}

接着修改AndroidManifest.xml中的代码,在里面加入NotificationActivity的注册声明,如下所示:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="com.example.notificationtest"

    android:versionCode="1"

    android:versionName="1.0" >

    ……

    <application

        android:allowBackup="true"

        android:icon="@drawable/ic_launcher"

        android:label="@string/app_name"

        android:theme="@style/AppTheme" >

        ……

        <activity android:name=".NotificationActivity" >

        </activity>

    </application>


</manifest>

这样就把NotificationActivity这个活动准备好了,下面我们修改MainActivity中的代码,给通知加入点击功能,如下所示:

public class MainActivity extends Activity implements OnClickListener {

……

@Override

public void onClick(View v) {

switch (v.getId()) {

case R.id.send_notice:

NotificationManager manager = (NotificationManager) 

getSystemService(NOTIFICATION_SERVICE);

Notification notification = new Notification(R.drawable. ic_launcher, "This is ticker text", System.currentTimeMillis());

Intent intent = new Intent(this, NotificationActivity.class);

PendingIntent pi = PendingIntent.getActivity(this, 0, intent,

PendingIntent.FLAG_CANCEL_CURRENT);

notification.setLatestEventInfo(this, "This is content title", "This is content text", pi);

manager.notify(1, notification);

break;

default:

break;

}

}


}

可以看到,这里先是使用Intent表达出我们想要启动NotificationActivity意图,然后将构建好的Intent对象传入到PendingIntentgetActivity()方法里,以得到PendingIntent的实例,接着把它作为第四个参数传入到NotificationsetLatestEventInfo()方法中。

现在重新运行一下程序,并点击Send notice按钮,依旧会发出一条通知。然后下拉系统状态栏,点击一下该通知,就会看到NotificationActivity这个活动的界面了,如图8.3所示。

 

图 8.3

咦?怎么系统状态上的通知图标还没有消失呢?是这样的,如果我们没有在代码中对该通知进行取消,它就会一直显示在系统的状态栏上显示。解决的方法也很简单,调用NotificationManagercancel()方法就可以取消通知了。修改NotificationActivity中的代码,如下所示:

public class NotificationActivity extends Activity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.notification_layout);

NotificationManager manager = (NotificationManager) 

getSystemService(NOTIFICATION_SERVICE);

manager.cancel(1);

}


}

可以看到,这里我们在cancel()方法中传入了1,这个1是什么意思呢?还记得在创建通知的时候给每条通知指定的id吗?当时我们给这条通知设置的id就是1。因此,如果你想要取消哪一条通知,就在cancel()方法中传入该通知的id就行了。

通知的高级技巧

现在你已经掌握了创建和取消通知的方法,并且知道了如何去响应通知的点击事件。不过通知的用法并不仅仅是这些呢,那么本节中我们就来探究一下通知更多的高级技巧。

观察Notification这个类,你会发现里面还有很多我们没有使›用过的属性。先来看看sound这个属性吧,它可以在通知发出的时候播放一段音频,这样就能够更好地告知用户有通知到来。sound这个属性是一个Uri对象,所以在指定音频文件的时候还需要先获取到音频文件对应的URI。比如说,我们手机的/system/media/audio/ringtones目录下有一个Basic_tone.ogg音频文件,那么在代码中这样就可以这样指定:

Uri soundUri = Uri.fromFile(new File("/system/media/audio/ringtones/ Basic_tone.ogg"));

notification.sound = soundUri;

除了允许播放音频外,我们还可以在通知到来的时候让手机进行振动,使用的是vibrate这个属性。它是一个长整型的数组,用于设置手机静止和振动的时长,以毫秒为单位。下标为0的值表示手机静止的时长,下标为1的值表示手机振动的时长,下标为2的值又表示手机静止的时长,以此类推。所以,如果想要让手机在通知到来的时候立刻振动1秒,然后静止1秒,再振动1秒,代码就可以写成:

long[] vibrates = {0, 1000, 1000, 1000};

notification.vibrate = vibrates;

不过,想要控制手机振动还需要声明权限的。因此,我们还得编辑AndroidManifest.xml文件,加入如下声明:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

    package="com.example.notificationtest"

    android:versionCode="1"

    android:versionName="1.0" >

……

    <uses-permission android:name="android.permission.VIBRATE" />

……

</manifest>

学会了控制通知的声音和振动,下面我们来看一下如何在通知到来时控制手机LED灯的显示。

现在的手机基本上都会前置一个LED灯,当有未接电话或未读短信,而此时手机又处于锁屏状态时,LED灯就会不停地闪烁,提醒用户去查看。我们可以使用ledARGBledOnMSledOffMS以及flags这几个属性来实现这种效果。ledARGB用于控制LED灯的颜色,一般有红绿蓝三种颜色可选。ledOnMS用于指定LED灯亮起的时长,以毫秒为单位。ledOffMS用于指定LED灯暗去的时长,也是以毫秒为单位。flags可用于指定通知的一些行为,其中就包括显示LED灯这一选项。所以,当通知到来时,如果想要实现LED灯以绿色的灯光一闪一闪的效果,就可以写成:

notification.ledARGB = Color.GREEN;

notification.ledOnMS = 1000;

notification.ledOffMS = 1000;

notification.flags = Notification.FLAG_SHOW_LIGHTS;

当然,如果你不想进行那么多繁杂的设置,也可以直接使用通知的默认效果,它会根据当前手机的环境来决定播放什么铃声,以及如何振动,写法如下:

notification.defaults = Notification.DEFAULT_ALL;

注意,以上所涉及的这些高级技巧都要在手机上运行才能看得到效果,模拟器是无法表现出振动、以及LED灯闪烁等功能的。

最新:

  1. package net.loonggg.notification;  
  2.   
  3. import android.app.Activity;  
  4. import android.app.Notification;  
  5. import android.app.NotificationManager;  
  6. import android.app.PendingIntent;  
  7. import android.content.Context;  
  8. import android.content.Intent;  
  9. import android.os.Bundle;  
  10. import android.view.View;  
  11. import android.widget.RemoteViews;  
  12.   
  13. public class MainActivity extends Activity {  
  14.     private static final int NOTIFICATION_FLAG = 1;  
  15.   
  16.     @Override  
  17.     protected void onCreate(Bundle savedInstanceState) {  
  18.         super.onCreate(savedInstanceState);  
  19.         setContentView(R.layout.activity_main);  
  20.     }  
  21.   
  22.     public void notificationMethod(View view) {  
  23.         // 在Android进行通知处理,首先需要重系统哪里获得通知管理器NotificationManager,它是一个系统Service。  
  24.         NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);  
  25.         switch (view.getId()) {  
  26.         // 默认通知  
  27.         case R.id.btn1:  
  28.             // 创建一个PendingIntent,和Intent类似,不同的是由于不是马上调用,需要在下拉状态条出发的activity,所以采用的是PendingIntent,即点击Notification跳转启动到哪个Activity  
  29.             PendingIntent pendingIntent = PendingIntent.getActivity(this0,  
  30.                     new Intent(this, MainActivity.class), 0);  
  31.             // 下面需兼容Android 2.x版本是的处理方式  
  32.             // Notification notify1 = new Notification(R.drawable.message,  
  33.             // "TickerText:" + "您有新短消息,请注意查收!", System.currentTimeMillis());  
  34.             Notification notify1 = new Notification();  
  35.             notify1.icon = R.drawable.message;  
  36.             notify1.tickerText = "TickerText:您有新短消息,请注意查收!";  
  37.             notify1.when = System.currentTimeMillis();  
  38.             notify1.setLatestEventInfo(this"Notification Title",  
  39.                     "This is the notification message", pendingIntent);  
  40.             notify1.number = 1;  
  41.             notify1.flags |= Notification.FLAG_AUTO_CANCEL; // FLAG_AUTO_CANCEL表明当通知被用户点击时,通知将被清除。  
  42.             // 通过通知管理器来发起通知。如果id不同,则每click,在statu那里增加一个提示  
  43.             manager.notify(NOTIFICATION_FLAG, notify1);  
  44.             break;  
  45.         // 默认通知 API11及之后可用  
  46.         case R.id.btn2:  
  47.             PendingIntent pendingIntent2 = PendingIntent.getActivity(this0,  
  48.                     new Intent(this, MainActivity.class), 0);  
  49.             // 通过Notification.Builder来创建通知,注意API Level  
  50.             // API11之后才支持  
  51.             Notification notify2 = new Notification.Builder(this)  
  52.                     .setSmallIcon(R.drawable.message) // 设置状态栏中的小图片,尺寸一般建议在24×24,这个图片同样也是在下拉状态栏中所显示,如果在那里需要更换更大的图片,可以使用setLargeIcon(Bitmap  
  53.                                                         // icon)  
  54.                     .setTicker("TickerText:" + "您有新短消息,请注意查收!")// 设置在status  
  55.                                                                 // bar上显示的提示文字  
  56.                     .setContentTitle("Notification Title")// 设置在下拉status  
  57.                                                             // bar后Activity,本例子中的NotififyMessage的TextView中显示的标题  
  58.                     .setContentText("This is the notification message")// TextView中显示的详细内容  
  59.                     .setContentIntent(pendingIntent2) // 关联PendingIntent  
  60.                     .setNumber(1// 在TextView的右方显示的数字,可放大图片看,在最右侧。这个number同时也起到一个序列号的左右,如果多个触发多个通知(同一ID),可以指定显示哪一个。  
  61.                     .getNotification(); // 需要注意build()是在API level  
  62.             // 16及之后增加的,在API11中可以使用getNotificatin()来代替  
  63.             notify2.flags |= Notification.FLAG_AUTO_CANCEL;  
  64.             manager.notify(NOTIFICATION_FLAG, notify2);  
  65.             break;  
  66.         // 默认通知 API16及之后可用  
  67.         case R.id.btn3:  
  68.             PendingIntent pendingIntent3 = PendingIntent.getActivity(this0,  
  69.                     new Intent(this, MainActivity.class), 0);  
  70.             // 通过Notification.Builder来创建通知,注意API Level  
  71.             // API16之后才支持  
  72.             Notification notify3 = new Notification.Builder(this)  
  73.                     .setSmallIcon(R.drawable.message)  
  74.                     .setTicker("TickerText:" + "您有新短消息,请注意查收!")  
  75.                     .setContentTitle("Notification Title")  
  76.                     .setContentText("This is the notification message")  
  77.                     .setContentIntent(pendingIntent3).setNumber(1).build(); // 需要注意build()是在API  
  78.                                                                             // level16及之后增加的,API11可以使用getNotificatin()来替代  
  79.             notify3.flags |= Notification.FLAG_AUTO_CANCEL; // FLAG_AUTO_CANCEL表明当通知被用户点击时,通知将被清除。  
  80.             manager.notify(NOTIFICATION_FLAG, notify3);// 步骤4:通过通知管理器来发起通知。如果id不同,则每click,在status哪里增加一个提示  
  81.             break;  
  82.         // 自定义通知  
  83.         case R.id.btn4:  
  84.             // Notification myNotify = new Notification(R.drawable.message,  
  85.             // "自定义通知:您有新短信息了,请注意查收!", System.currentTimeMillis());  
  86.             Notification myNotify = new Notification();  
  87.             myNotify.icon = R.drawable.message;  
  88.             myNotify.tickerText = "TickerText:您有新短消息,请注意查收!";  
  89.             myNotify.when = System.currentTimeMillis();  
  90.             myNotify.flags = Notification.FLAG_NO_CLEAR;// 不能够自动清除  
  91.             RemoteViews rv = new RemoteViews(getPackageName(),  
  92.                     R.layout.my_notification);  
  93.             rv.setTextViewText(R.id.text_content, "hello wrold!");  
  94.             myNotify.contentView = rv;  
  95.             Intent intent = new Intent(Intent.ACTION_MAIN);  
  96.             PendingIntent contentIntent = PendingIntent.getActivity(this1,  
  97.                     intent, 1);  
  98.             myNotify.contentIntent = contentIntent;  
  99.             manager.notify(NOTIFICATION_FLAG, myNotify);  
  100.             break;  
  101.         case R.id.btn5:  
  102.             // 清除id为NOTIFICATION_FLAG的通知  
  103.             manager.cancel(NOTIFICATION_FLAG);  
  104.             // 清除所有的通知  
  105.             // manager.cancelAll();  
  106.             break;  
  107.         default:  
  108.             break;  
  109.         }  
  110.     }  
  111. }  
主布局文件:

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:orientation="vertical"  
  6.     tools:context=".MainActivity" >  
  7.   
  8.     <Button  
  9.         android:id="@+id/btn1"  
  10.         android:layout_width="fill_parent"  
  11.         android:layout_height="wrap_content"  
  12.         android:onClick="notificationMethod"  
  13.         android:text="默认通知(已被抛弃,但是通用)" />  
  14.   
  15.     <Button  
  16.         android:id="@+id/btn2"  
  17.         android:layout_width="fill_parent"  
  18.         android:layout_height="wrap_content"  
  19.         android:onClick="notificationMethod"  
  20.         android:text="默认通知(API11之后可用)" />  
  21.   
  22.     <Button  
  23.         android:id="@+id/btn3"  
  24.         android:layout_width="fill_parent"  
  25.         android:layout_height="wrap_content"  
  26.         android:onClick="notificationMethod"  
  27.         android:text="默认通知(API16之后可用)" />  
  28.   
  29.     <Button  
  30.         android:id="@+id/btn4"  
  31.         android:layout_width="fill_parent"  
  32.         android:layout_height="wrap_content"  
  33.         android:onClick="notificationMethod"  
  34.         android:text="自定义通知" />  
  35.   
  36.     <Button  
  37.         android:id="@+id/btn5"  
  38.         android:layout_width="fill_parent"  
  39.         android:layout_height="wrap_content"  
  40.         android:onClick="notificationMethod"  
  41.         android:text="清除通知" />  
  42.   
  43. </LinearLayout>  
还有一个是:自定义通知的布局文件my_notification.xml

  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="wrap_content"  
  5.     android:background="#ffffff"  
  6.     android:orientation="vertical" >  
  7.   
  8.     <TextView  
  9.         android:id="@+id/text_content"  
  10.         android:layout_width="wrap_content"  
  11.         android:layout_height="wrap_content"  
  12.         android:textSize="20sp" />  
  13.   
  14. </LinearLayout>  




0 0
原创粉丝点击