Android 7编程入门经典:使用Android Studio 2(第4版)
上QQ阅读APP看书,第一时间看更新

3.4 显示Notification

到目前为止,已经使用过Toast类向用户显示消息。虽然Toast类是一种显示用户警报的非常便利的方法,但它不是持久的。它会在屏幕上显示几秒钟之后就消失。如果它包含非常重要的信息,如果用户没有看屏幕,他们很可能会错过它。

对于非常重要的消息,需要使用更加持久性的方法。在这种情况下,就要使用NotificationManager在设备顶部显示一条持久的消息,这块区域通常称作状态栏(有时也称作通知栏)。下面的“试一试”部分将演示如何实现。

试一试:在状态栏上显示Notification(Notifications.zip)

(1) 使用Android Studio新建一个Android项目并命名为Notifications。

(2) 在包中添加一个新的类文件并命名为NotificationView。与此同时,在res/layout文件夹中添加一个新的布局资源文件notification.xml。

(3) notification.xml文件的代码如下。请确保将所有com.jfdimarzio实例修改成你自己项目使用的包名。

        <? xml version="1.0" encoding="utf-8"? >
        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
            android:orientation="vertical" android:layout_width="match_parent"
            android:layout_height="match_parent">
            <TextView
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:text="Here are the details for the notification..." />
        </LinearLayout>

(4) NotificationView.java文件的代码如下:

        package com.jfdimarzio.notifications;

    import android.app.Activity;
    import android.app.NotificationManager;
    import android.os.Bundle;


    public class NotificationView extends Activity {


        @Override
        public void onCreate(Bundle savedInstanceState)
        {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.notification);
          //---look up the notification manager service---
          NotificationManager nm = (NotificationManager)
                  getSystemService(NOTIFICATION_SERVICE);
          //---cancel the notification that we started---
          nm.cancel(getIntent().getExtras().getInt("notificationID"));
        }


    }

(5) 在AndroidManifest.xml文件中添加以下示例代码中的粗体显示部分。

    <? xml version="1.0" encoding="utf-8"? >
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.jfdimarzio.notifications">
        <uses-permission android:name="android.permission.VIBRATE"/>
        <application
          android:allowBackup="true"
          android:icon="@mipmap/ic_launcher"
          android:label="@string/app_name"
          android:supportsRtl="true"
          android:theme="@style/AppTheme">
          <activity android:name=".MainActivity">
              <intent-filter>
                  <action android:name="android.intent.action.MAIN" />


                  <category android:name="android.intent.category.LAUNCHER" />
              </intent-filter>
          </activity>
          <activity android:name=".NotificationView"
              android:label="Details of notification">
              <intent-filter>
                  <action android:name="android.intent.action.MAIN" />
                  <category android:name="android.intent.category.DEFAULT" />
              </intent-filter>
            </activity>
        </application>


    </manifest>

(6) 在activity_main.xml文件中添加以下示例代码中的粗体显示部分。

    <? xml version="1.0" encoding="utf-8"? >
    <RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
        android:paddingLeft="@dimen/activity_horizontal_margin"
        android:paddingRight="@dimen/activity_horizontal_margin"
        android:paddingTop="@dimen/activity_vertical_margin"
        tools:context="com.jfdimarzio.notifications.MainActivity">


        <Button
            android:id="@+id/btn_displaynotif"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="Display Notification"
            android:onClick="onClick"/>
    </RelativeLayout>

(7) 在MainActivity.java文件中添加以下示例代码中的粗体显示部分。

    package com.jfdimarzio.notifications;


    import android.app.Activity;
    import android.app.NotificationManager;
    import android.app.PendingIntent;
    import android.content.Intent;
    import android.os.Bundle;
    import android.support.v4.app.NotificationCompat;
    import android.view.View;


    public class MainActivity extends Activity {
        int notificationID = 1;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
        }
        public void onClick(View view) {
            displayNotification();
        }


        protected void displayNotification()
        {
            //---PendingIntent to launch activity if the user selects
            // this notification---
            Intent i = new Intent(this, NotificationView.class);
            i.putExtra("notificationID", notificationID);
            PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, i, 0);

              NotificationManager nm = (NotificationManager)getSystemService
                (NOTIFICATION_SERVICE);
              NotificationCompat.Builder notifBuilder;
              notifBuilder = new NotificationCompat.Builder(this)
                      .setSmallIcon(R.mipmap.ic_launcher)
                      .setContentTitle("Meeting Reminder")
                      .setContentText("Reminder: Meeting starts in 5 minutes");
              nm.notify(notificationID, notifBuilder.build());
          }
      }

(8) 单击快捷键Shift+F9在Android模拟器中调试应用。

(9) 单击Display Notification按钮在状态栏中显示一个通知文本(在Notification对象的构造函数中设置)。

(10) 单击并且下拉状态栏显示通知详情,通知详情是通过调用Notification对象的setLatestEventInfo()方法设置的(如图3-19所示)。

图3-19

示例说明

要显示一个通知,首先要创建一个指向NotificationView类的Intent对象:

              Intent i = new Intent(this, NotificationView.class);
              i.putExtra("notificationID", notificationID);

当用户从列表中选择notification时,这个Intent被用来载入另一个Activity。在本示例中,需要向Intent对象添加一个名称/值对,这样就可以打一个notification ID标签,标识该notification对应的目标Activity。稍后,需要使用这个ID消除对应的notification。

也需要创建一个PendingIntent对象。之后不管应用是否在运行,它都可以以应用的名义执行操作。在本示例中,可以按如下方式初始化PendingIntent对象:

              PendingIntent pendingIntent =
                  PendingIntent.getActivity(this, 0, i, 0);

getActivity()方法可以获取一个PendingIntent对象,需要使用下列参数调用它:

● context——应用上下文

● request code——Intent的请求代码

● intent——用来启动目标Activity的Intent

● flags——要被启动的Activity的操作标识

然后,需要得到一个NotificationManager类的实例,并且创建一个NotificationCompat. Builder类的实例:

              NotificationManager nm = (NotificationManager)getSystemService
                                        (NOTIFICATION _SERVICE);
               NotificationCompat.Builder notifBuilder;
               notifBuilder = new NotificationCompat.Builder(this)
                      .setSmallIcon(R.mipmap.ic_launcher)
                      .setContentTitle("Meeting Reminder")
                      .setContentText("Reminder: Meeting starts in 5 minutes");

NotificationCompat.Builder类使你可以指定notification的主要信息。最后,调用notify()方法显示notification:

        nm.notify(notificationID, notifBuilder.build());