狀態欄消息提示——使用Notification


什么是Notification


Notification用於在狀態欄顯示信息。這些信息一般來源於app的消息推送,或應用的一些功能控制(如播放器)

 

Notification的兩種視圖


普通視圖

借用官方的圖片說明一下Notification視圖中包括的內容

1. 內容標題

2. 大圖標(Bitmap)

3. 正文內容

4. 附加信息

5. 小圖標

6. Notification的推送時間

 

大視圖

除了上圖中標出的第7點外,其他的基本和普通視圖中的一樣。

其中第7點可顯示為一下幾種內容

1. 顯示大圖片

      在詳情區域可以顯示一張最大為256dp的圖片

2. 顯示長文本

      在詳情區域顯示長文本

3. inbox style(因為不知道中文怎樣才能說得准確,這里用英文表達)

        inbox style在詳情區域顯示多行文本.

4. 大內容標題

        允許用戶為擴展視圖定義另一個標題。

5. 摘要文本

        允許用戶在詳情區域添加一行額外的文本

 

創建標准的Notification


以下三項式創建一個標准的Notification的先決條件

1. 小圖標, 通過setSmallIcon()方法設置

2. 標題, 通過setContentTitle()方法設置

3. 內容文本, 通過setContentText()方法設置

 

我們這里不通過調用Notification構造方法的方式創建Notification,因為這種方法已經不推薦使用。

我們使用通過NotificationCompat.Builder類創建Notification。

 

程序的主布局文本中只有一個id為btnShow的按鈕,點擊這個按鈕顯示Notification

package com.whathecode.notificationdemo;

import android.app.Notification;
import android.app.NotificationManager;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.Button;

public class MainActivity extends ActionBarActivity {

    private Notification mNotification;
    private NotificationManager mNotificationManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        Button btnShow = (Button) findViewById(R.id.btnShow);

        mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

        mNotification = new NotificationCompat.Builder(this)
                // 設置小圖標
                .setSmallIcon(R.drawable.ic_launcher)
                // 設置標題
                .setContentTitle("you have a meeting")
                // 設置內容
                .setContentText("you have a meeting at 3:00 this afternoon")
                .build();

        btnShow.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                mNotificationManager.notify(0, mNotification);
            }
        });
    }
}

運行效果

Notification2

 

當然,這個Demo在4.x系統上是可以正常運行的。

當同樣的代碼在2.x的系統上面運行,程序會崩潰的。如下

Notification

而且,會拋出一個異常:

java.lang.IllegalArgumentException: contentIntent required: pkg=com.whathecode.notificationdemo id=0 notification=Notification(vibrate=null,sound=null,defaults=0x0,flags=0x0)

上面的錯誤已經說得很清楚了,contentIntent required , 也就是需要contentIntent

這個contentIntent可以通過setContentIntent設置。

也就是說,上面所提到的三個先決條件只是確保4.x版本可以正常運行,

如果你的程序需要兼容2.x版本的,你就需要一個contentIntent

contentIntent的作用是點擊Notification時跳轉到其他的Activity

 

更新后的代碼:

package com.whathecode.notificationdemo;

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.Button;

public class MainActivity extends ActionBarActivity {

    private Notification mNotification;
    private NotificationManager mNotificationManager;
    private PendingIntent mResultIntent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button btnShow = (Button) findViewById(R.id.btnShow);

        mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

        /*
         * 取得PendingIntent,
         * 因為我們現在不需要跳轉到其他Activity,
         * 所以這里只實例化一個空的Intent
         */
        Intent intent = new Intent();
        mResultIntent = PendingIntent.getActivity(this, 1, intent,
                Intent.FLAG_ACTIVITY_NEW_TASK);

        mNotification = new NotificationCompat.Builder(this)
                // 設置小圖標
                .setSmallIcon(R.drawable.ic_launcher)
                // 設置標題
                .setContentTitle("系統更新")
                // 設置內容
                .setContentText("發現系統更新,點擊查看詳情")
                //設置ContentIntent
                .setContentIntent(mResultIntent)
                .build();

        btnShow.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                mNotificationManager.notify(0, mNotification);
            }
        });
    }
}

運行效果

Notification3

 

完整的Notification實例


上面代碼中的例子並不完整,只是演示了一個可以正常運行的實例

說它不完整是因為Notification到來的時候狀態欄只有圖標,沒有文字,也沒有聲音提示,用戶體驗並不好。

當我們不設置LargeIcon的時候,系統就會使用當前設置的小圖標作為大圖標使用,小圖標位置(位置5)則置空。

下面的代碼是比較完整的Notification示例

package com.whathecode.notificationdemo;

import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.RingtoneManager;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
import android.support.v7.app.ActionBarActivity;
import android.view.View;
import android.widget.Button;

public class MainActivity extends ActionBarActivity {

    private Notification mNotification;
    private NotificationManager mNotificationManager;
    private PendingIntent mResultIntent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button btnShow = (Button) findViewById(R.id.btnShow);

        mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

        /*
         * 取得PendingIntent, 並設置跳轉到的Activity,
         */
        Intent intent = new Intent(this, UpdateActivity.class);
        mResultIntent = PendingIntent.getActivity(this, 1, intent,
                Intent.FLAG_ACTIVITY_NEW_TASK);

        btnShow.setOnClickListener(new View.OnClickListener() {

            @SuppressLint("NewApi")
            @Override
            public void onClick(View v) {

                Bitmap largeIcon = BitmapFactory.decodeResource(
                        MainActivity.this.getResources(), R.drawable.luffy);

                mNotification = new NotificationCompat.Builder(getBaseContext())

                // 設置大圖標
                        .setLargeIcon(largeIcon)

                        // 設置小圖標
                        .setSmallIcon(R.drawable.ic_launcher)

                        // 設置小圖標旁的文本信息
                        .setContentInfo("1")

                        // 設置狀態欄文本標題
                        .setTicker("你的系統有更新")

                        // 設置標題
                        .setContentTitle("系統更新")

                        // 設置內容
                        .setContentText("發現系統更新,點擊查看詳情")

                        // 設置ContentIntent
                        .setContentIntent(mResultIntent)

                        // 設置Notification提示鈴聲為系統默認鈴聲
                        .setSound(
                                RingtoneManager.getActualDefaultRingtoneUri(
                                        getBaseContext(),
                                        RingtoneManager.TYPE_NOTIFICATION))

                        // 點擊Notification的時候使它自動消失
                        .setAutoCancel(true).build();

                mNotificationManager.notify(0, mNotification);
            }
        });

    }
}

運行效果(Android 2.x)                                                             運行效果(Android 4.x)

Notification 2.x                 Notification 4.x

 

通過觀察上面兩張圖你會發現,在2.x版本下LargeIcon和contentInfo並沒有生效。

這是因為setLargeIcon和setContentInfo都是在api level 11(honeycomb)才添加的功能

 

使用自定義布局統一Notification的顯示效果


布局文件代碼

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="?android:attr/colorBackground">
    
    <ImageView
        android:id="@+id/largeIcon"
        android:layout_width="64dp"
        android:layout_height="64dp"
        android:src="@drawable/luffy"
        android:contentDescription="largeIcon" />

    <TextView
        android:id="@+id/contentTitle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@+id/largeIcon"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="5dp"
        android:text="系統更新"/>

    <TextView
        android:id="@+id/contentText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/contentTitle"
        android:layout_below="@+id/contentTitle"
        android:layout_marginTop="5dp"
        android:text="發現系統更新,點擊查看詳情"
        android:textSize="12sp"/>
    
    <TextView
        android:id="@+id/when"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:layout_marginRight="5dp"
        android:text="11:00"/>

    <ImageView
        android:id="@+id/smallIcon"
        android:layout_width="15dp"
        android:layout_height="15dp"
        android:layout_alignRight="@+id/when"
        android:layout_alignTop="@+id/contentText"
        android:src="@drawable/ic_launcher" />

    <TextView
        android:id="@+id/contentInfo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignTop="@+id/smallIcon"
        android:layout_toLeftOf="@+id/smallIcon"
        android:text="信息"
        android:textSize="12sp" />

</RelativeLayout>

 

程序代碼:

package com.whathecode.notificationdemo;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.media.RingtoneManager;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
import android.view.View;
import android.widget.Button;
import android.widget.RemoteViews;

public class MainActivity extends Activity {

    private Notification mNotification;
    private NotificationManager mNotificationManager;
    private PendingIntent mResultIntent;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Button btnShow = (Button) findViewById(R.id.btnShow);

        mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);

        /*
         * 取得PendingIntent, 並設置跳轉到的Activity,
         */
        Intent intent = new Intent(this, UpdateActivity.class);
        mResultIntent = PendingIntent.getActivity(this, 1, intent,
                Intent.FLAG_ACTIVITY_NEW_TASK);

        btnShow.setOnClickListener(new View.OnClickListener() {

            @SuppressLint("NewApi")
            @Override
            public void onClick(View v) {

                RemoteViews customView = new RemoteViews(getPackageName(),
                        R.layout.customerviews);

                mNotification = new NotificationCompat.Builder(getBaseContext())

                         // 設置小圖標
                        .setSmallIcon(R.drawable.ic_launcher)

                        // 設置狀態欄文本標題
                        .setTicker("你的系統有更新")

                        //設置自定義布局
                        .setContent(customView)

                        // 設置ContentIntent
                        .setContentIntent(mResultIntent)

                        // 設置Notification提示鈴聲為系統默認鈴聲
                        .setSound(
                                RingtoneManager.getActualDefaultRingtoneUri(
                                        getBaseContext(),
                                        RingtoneManager.TYPE_NOTIFICATION))

                        // 點擊Notification的時候自動移除
                        .setAutoCancel(true).build();

                /*
                 * 當API level 低於14的時候使用setContent()方法是沒有用的
                 * 需要對contentView字段直接賦值才能生效
                 */
                if (Build.VERSION.SDK_INT < 14) {
                    mNotification.contentView = customView;
                }

                mNotificationManager.notify(0, mNotification);
            }
        });

    }
}

上面的布局文件中的內容是硬編碼的,也可以通過RemoteViews類中的setXXX方法動態設定內容。

這樣程序便更加靈活

 

運行效果(android 2.x)                                                                             運行效果(android 4.x)

Notification 2.x 2                  Notification 4.x 2

 

在兩個版本中的運行效果基本一樣了,但是,在低版本下不是很完美,有部分灰白的地方特別扎眼

網上查了很久也沒有找到解決辦法,有知道的請告知

 

更新Notification的內容


因為我們創建的Notification是通過一個Id分別的,因此只要在使用NotificationManager的notify()方法的時候使用

相同的Id就可以更新這個Notification的內容

當然在使用notify()方法之前我們還是要創建一個Notification實例。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM