Android Notification
来源:互联网 发布:galgame机翻软件 编辑:程序博客网 时间:2024/06/05 07:43
通知(Notification)是Android系统中比较有特色的一个功能,当某个应用程序希望向用户发出一些提示信息,而该应用程序又不在前台运行时,就可以借助通知来实现。发出一条通知后,手机最上方的状态栏中会显示一个通知的图标,下拉状态栏后可以看到通知的详细内容。Android的通知功能获得了大量用户的认可和喜爱,就连iOS系统也在5.0版本之后加入了类似的功能。
了解了通知的基本概念,下面我们就来看一下通知的使用方法吧。通知的用法还是比较灵活的,既可以在活动里创建,也可以在广播接收器里创建,当然还可以在下一章中我们即将学习的服务里创建。相比于广播接收器和服务,在活动里创建通知的场景还是比较少的,因为一般只有当程序进入到后台的时候我们才需要使用通知。
不过,无论是在哪里创建通知,整体的步骤都是相同的,下面我们就来学习一下创建通知的详细步骤。首先需要一个NotificationManager来对通知进行管理,可以调用Context的getSystemService()方法获取到。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对象后,我们还需要对通知的布局进行设定,这里只需要调用Notification的setLatestEventInfo()方法就可以给通知设置一个标准的布局。这个方法接收四个参数,第一个参数是Context,这个没什么好解释的。第二个参数用于指定通知的标题内容,下拉系统状态栏就可以看到这部分内容。第三个参数用于指定通知的正文内容,同样下拉系统状态栏就可以看到这部分内容。第四个参数我们暂时还用不到,可以先传入null。因此,对通知的布局进行设定就可以写成:
notification.setLatestEventInfo(context, "This is content title", "This is content text", null);
以上工作都完成之后,只需要调用NotificationManager的notify()方法就可以让通知显示出来了。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_SHOT、FLAG_NO_CREATE、FLAG_CANCEL_CURRENT和FLAG_UPDATE_ CURRENT这四种值可选,每种值的含义你可以查看文档,我就不一一进行解释了。
对PendingIntent有了一定的了解后,我们再回过头来看一下Notification的setLatestEventInfo()方法。刚才我们将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对象传入到PendingIntent的getActivity()方法里,以得到PendingIntent的实例,接着把它作为第四个参数传入到Notification的setLatestEventInfo()方法中。
现在重新运行一下程序,并点击Send notice按钮,依旧会发出一条通知。然后下拉系统状态栏,点击一下该通知,就会看到NotificationActivity这个活动的界面了,如图8.3所示。
图 8.3
咦?怎么系统状态上的通知图标还没有消失呢?是这样的,如果我们没有在代码中对该通知进行取消,它就会一直显示在系统的状态栏上显示。解决的方法也很简单,调用NotificationManager的cancel()方法就可以取消通知了。修改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灯就会不停地闪烁,提醒用户去查看。我们可以使用ledARGB、ledOnMS、ledOffMS以及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灯闪烁等功能的。
最新:
- package net.loonggg.notification;
- import android.app.Activity;
- import android.app.Notification;
- import android.app.NotificationManager;
- import android.app.PendingIntent;
- import android.content.Context;
- import android.content.Intent;
- import android.os.Bundle;
- import android.view.View;
- import android.widget.RemoteViews;
- public class MainActivity extends Activity {
- private static final int NOTIFICATION_FLAG = 1;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- }
- public void notificationMethod(View view) {
- // 在Android进行通知处理,首先需要重系统哪里获得通知管理器NotificationManager,它是一个系统Service。
- NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
- switch (view.getId()) {
- // 默认通知
- case R.id.btn1:
- // 创建一个PendingIntent,和Intent类似,不同的是由于不是马上调用,需要在下拉状态条出发的activity,所以采用的是PendingIntent,即点击Notification跳转启动到哪个Activity
- PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
- new Intent(this, MainActivity.class), 0);
- // 下面需兼容Android 2.x版本是的处理方式
- // Notification notify1 = new Notification(R.drawable.message,
- // "TickerText:" + "您有新短消息,请注意查收!", System.currentTimeMillis());
- Notification notify1 = new Notification();
- notify1.icon = R.drawable.message;
- notify1.tickerText = "TickerText:您有新短消息,请注意查收!";
- notify1.when = System.currentTimeMillis();
- notify1.setLatestEventInfo(this, "Notification Title",
- "This is the notification message", pendingIntent);
- notify1.number = 1;
- notify1.flags |= Notification.FLAG_AUTO_CANCEL; // FLAG_AUTO_CANCEL表明当通知被用户点击时,通知将被清除。
- // 通过通知管理器来发起通知。如果id不同,则每click,在statu那里增加一个提示
- manager.notify(NOTIFICATION_FLAG, notify1);
- break;
- // 默认通知 API11及之后可用
- case R.id.btn2:
- PendingIntent pendingIntent2 = PendingIntent.getActivity(this, 0,
- new Intent(this, MainActivity.class), 0);
- // 通过Notification.Builder来创建通知,注意API Level
- // API11之后才支持
- Notification notify2 = new Notification.Builder(this)
- .setSmallIcon(R.drawable.message) // 设置状态栏中的小图片,尺寸一般建议在24×24,这个图片同样也是在下拉状态栏中所显示,如果在那里需要更换更大的图片,可以使用setLargeIcon(Bitmap
- // icon)
- .setTicker("TickerText:" + "您有新短消息,请注意查收!")// 设置在status
- // bar上显示的提示文字
- .setContentTitle("Notification Title")// 设置在下拉status
- // bar后Activity,本例子中的NotififyMessage的TextView中显示的标题
- .setContentText("This is the notification message")// TextView中显示的详细内容
- .setContentIntent(pendingIntent2) // 关联PendingIntent
- .setNumber(1) // 在TextView的右方显示的数字,可放大图片看,在最右侧。这个number同时也起到一个序列号的左右,如果多个触发多个通知(同一ID),可以指定显示哪一个。
- .getNotification(); // 需要注意build()是在API level
- // 16及之后增加的,在API11中可以使用getNotificatin()来代替
- notify2.flags |= Notification.FLAG_AUTO_CANCEL;
- manager.notify(NOTIFICATION_FLAG, notify2);
- break;
- // 默认通知 API16及之后可用
- case R.id.btn3:
- PendingIntent pendingIntent3 = PendingIntent.getActivity(this, 0,
- new Intent(this, MainActivity.class), 0);
- // 通过Notification.Builder来创建通知,注意API Level
- // API16之后才支持
- Notification notify3 = new Notification.Builder(this)
- .setSmallIcon(R.drawable.message)
- .setTicker("TickerText:" + "您有新短消息,请注意查收!")
- .setContentTitle("Notification Title")
- .setContentText("This is the notification message")
- .setContentIntent(pendingIntent3).setNumber(1).build(); // 需要注意build()是在API
- // level16及之后增加的,API11可以使用getNotificatin()来替代
- notify3.flags |= Notification.FLAG_AUTO_CANCEL; // FLAG_AUTO_CANCEL表明当通知被用户点击时,通知将被清除。
- manager.notify(NOTIFICATION_FLAG, notify3);// 步骤4:通过通知管理器来发起通知。如果id不同,则每click,在status哪里增加一个提示
- break;
- // 自定义通知
- case R.id.btn4:
- // Notification myNotify = new Notification(R.drawable.message,
- // "自定义通知:您有新短信息了,请注意查收!", System.currentTimeMillis());
- Notification myNotify = new Notification();
- myNotify.icon = R.drawable.message;
- myNotify.tickerText = "TickerText:您有新短消息,请注意查收!";
- myNotify.when = System.currentTimeMillis();
- myNotify.flags = Notification.FLAG_NO_CLEAR;// 不能够自动清除
- RemoteViews rv = new RemoteViews(getPackageName(),
- R.layout.my_notification);
- rv.setTextViewText(R.id.text_content, "hello wrold!");
- myNotify.contentView = rv;
- Intent intent = new Intent(Intent.ACTION_MAIN);
- PendingIntent contentIntent = PendingIntent.getActivity(this, 1,
- intent, 1);
- myNotify.contentIntent = contentIntent;
- manager.notify(NOTIFICATION_FLAG, myNotify);
- break;
- case R.id.btn5:
- // 清除id为NOTIFICATION_FLAG的通知
- manager.cancel(NOTIFICATION_FLAG);
- // 清除所有的通知
- // manager.cancelAll();
- break;
- default:
- break;
- }
- }
- }
- <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"
- tools:context=".MainActivity" >
- <Button
- android:id="@+id/btn1"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:onClick="notificationMethod"
- android:text="默认通知(已被抛弃,但是通用)" />
- <Button
- android:id="@+id/btn2"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:onClick="notificationMethod"
- android:text="默认通知(API11之后可用)" />
- <Button
- android:id="@+id/btn3"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:onClick="notificationMethod"
- android:text="默认通知(API16之后可用)" />
- <Button
- android:id="@+id/btn4"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:onClick="notificationMethod"
- android:text="自定义通知" />
- <Button
- android:id="@+id/btn5"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:onClick="notificationMethod"
- android:text="清除通知" />
- </LinearLayout>
- <?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="wrap_content"
- android:background="#ffffff"
- android:orientation="vertical" >
- <TextView
- android:id="@+id/text_content"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textSize="20sp" />
- </LinearLayout>
- ANdroid Notification
- android notification
- android notification
- android notification
- Android Notification
- android notification
- android notification
- android Notification
- Android Notification
- android Notification
- Android notification
- android Notification
- android:Notification
- Android Notification
- Android Notification
- Android Notification
- Android notification
- android Notification
- svn: E200030: sqlite[S11]: database disk image is malformed
- 通过jQuery Ajax使用FormData对象上传文件
- Android开发--判断网络是否连接
- python 通过logging写入日志到文件和控制台
- VC界面开发组件Xtreme Toolkit Pro全新发布v17.0.0|附下载
- Android Notification
- PAPER
- jpush app 消息推送项目 实例
- ios学习历程记录
- 批量添加删除用户方法三
- git 自动补全 (git auto completion)
- Vector,ArrayList,LinkedList 的区别是什么?
- Android实例-路径信息及文件和文件夹的操作(XE8+小米2)
- UIWebView头文件学习