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

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

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

NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
接下来需要使用一个Builder构造器来创建Notification对象,但问题在于,几乎Android系统的每一个版本都会对通知这部分功能进行或多或少的修改,API不稳定性问题在通知上面突显得尤其严重,那么改如何解决这个问题呢?就是使用support库中提供的兼容API,support-v4库中提供了一个NotificationCompat类,使用这个类的构造器来创建Notification对象,就可以保证我们的程序在所有Android系统版本上都能正常工作了,代码如下:

Notification notification = new NotificationCompat.Builder(this)
.setContentTitle("This is content title")
.setContentText("This is content text")
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.drawable.small_icon)
.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.large_icon))
.build();
上述代码中一共调用了5个设置方法,setContentTitle()方法用于指定通知的标题内容,下拉系统状态栏就可以看到这部分内容,setContentText()方法用于指定通知的正文内容,同样下拉系统状态栏就可以看到这部分内容,setWhen()方法用于指定通知被创建的时间,以毫秒为单位,当下拉系统状态栏时,这里指定的时间会显示在相应的通知上,setSmallIcon()方法用于设置通知的小图标,注意只能使用纯alpha图层的图片进行设置,小图标会显示在系统状态栏上,setLargeIcon()方法用于设置通知的大图标,当下拉系统状态栏时,就可以看到设置的大图标了。

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

manager.notify(1,notification);
到这里就已经把创建通知的每一步骤都分析完了,下面通过一个小例子来看一看通知到底长什么样的。

activity_main.xml中的代码如下:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.notificationtest.MainActivity">

<Button
android:id="@+id/send_notice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Send notice"
android:textAllCaps="false"/>

</android.support.constraint.ConstraintLayout>
MainActivity.java中的代码如下:

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button sendNotice = findViewById(R.id.send_notice);
sendNotice.setOnClickListener(this);
}

@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.send_notice:
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new NotificationCompat.Builder(this)
.setContentTitle("This is content title")
.setContentText("This is content text")
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.drawable.small_icon)
.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.large_icon))
.build();
manager.notify(1,notification);
break;
default:
break;
}
}
}
可以看到,我们在Send notice按钮的点击事件里面完成了通知的创建工作,创建的过程正如前面所描述的一样,现在运行一下程序,并点击Send notice按钮,可以在系统状态栏的最左边看到一个小图标,如下:

下拉系统状态栏可以看到该通知的详细信息,如下:


如果你使用过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这4种值可选,通常情况下这个参数传入0就可以了。

对PendingIntent有了一定的了解后,我们再回过头看一下NotificationCompat.Builder,这个构造器还可以再连缀一个setContentIntent()方法,接收的参数正是一个PendingIntent对象,这里就可以通过PendingIntent构建出一个延迟执行的"意图",当用户点击这条通知时就会执行相应的逻辑。

notification_layout.xml中的代码:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.notificationtest.NotificationActivity">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="24sp"
android:text="This is notification activity"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>

</android.support.constraint.ConstraintLayout>
Notification.java不需要做任何的操作,如下:

public class NotificationActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_notification);
}
}
这样就把NotificationActivity这个活动准备好了,下面修改MainActivity中的代码,添加点击功能,如下:

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

...

@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.send_notice:
Intent intent = new Intent(this,NotificationActivity.class);
PendingIntent pi = PendingIntent.getActivity(this,0,intent,0);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new NotificationCompat.Builder(this)
.setContentTitle("This is content title")
.setContentText("This is content text")
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.drawable.small_icon)
.setLargeIcon(BitmapFactory.decodeResource(getResources(),R.drawable.large_icon))
.setContentIntent(pi)
.build();
manager.notify(1,notification);
break;
default:
break;
}
}
}
可以看到,这里先是使用Intent表达出我们想要启动NotificationActivity的"意图",然后将构建好的Intent对象传入到PendingIntent的getActivity()方法里,以得到PendingIntent的实例,接着在NotificationCompat.Builder中调用setContentIntent()方法,把它作为参数传入。

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

咦?怎么系统状态上的通知图标还没有消失呢?是这样的,如果我们没有在代码中对该通知进行取消,它就会一直显示在系统的状态栏上,解决的办法有两种,一种是在NotificationCompat.Builder中再连缀一个setAutoCancel()方法,一种是显式的调用NotificationManager的cancel()方法将它取消。

第一种方法写法如下:

    @Override
public void onClick(View view) {
switch (view.getId()){
case R.id.send_notice:
Intent intent = new Intent(this,NotificationActivity.class);
PendingIntent pi = PendingIntent.getActivity(this,0,intent,0);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new NotificationCompat.Builder(this)
...
.setAutoCancel(true)
.build();
manager.notify(1,notification);
break;
default:
break;
}
}
}
可以看到,setAutoCancel()方法传入true,就表示当点击了这个通知的时候,通知会自动取消掉。

第二种写法如下:

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
...
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.cancel(1);
}
这里我们在cancel()方法中传入1,这个1是什么意思呢?还记得在创建通知的时候给每条通知指定的id吗?当时我们给这条通知设置的id就是1,因此,如果你想取消哪条通知,在cancel()方法中传入通知的id就行了。

更多相关文章

  1. android在onCreate()方法中获取View的宽度与高度的方法实战
  2. W/System.err:at java.net.PlainDatagramSocketImpl.bind(PlainDa
  3. Android Studio获取数字签名(SHA1)的方法
  4. Android Volley:使用方法总结及实例解析
  5. eclipse下运行EasyAR官方sample的方法
  6. Android App性能信息获取方法
  7. Android Studio 检测内存泄漏与解决方法
  8. C#/Java 调用WSDL接口及方法
  9. Javadoc转换chm帮助文档的四种方法总结

随机推荐

  1. Android标题栏的各种设置
  2. Android layout属性大全
  3. android操作通讯录的联系人
  4. android > tabHost > 微博布局风格
  5. Android autoLink的注意点
  6. android 程序分享。。
  7. [Android UI] listview 自定义style
  8. Android 之 SeekBar用法介绍
  9. Android 7.1.2(Android N) Android系统启
  10. Android安装