2014年3月18日

Android Notification的基本用法,顯示通知列圖片、播放音效、振動

Android Notification的基本用法,顯示通知列圖片、播放音效、振動

我們會發現,越來越多的手機軟體,都會使用「通知 Notification」這項功能,主要用來提醒新訊息、公告或是提示訊息等...
如圖片所示:


寫法其實很簡單,我們寫一個測試程式利用輸入文字送出通知訊息。

activity_main.xml
<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=".MainActivity" >

    <TextView
        android:id= "@+id/textView1"
        android:layout_width= "wrap_content"
        android:layout_height= "wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginTop= "20dp"
        android:text= "@string/input"
        android:textSize= "20sp" />

    <Button
        android:id= "@+id/button1"
        android:layout_width= "wrap_content"
        android:layout_height= "wrap_content"
        android:layout_alignBaseline="@+id/textView1"
        android:layout_alignParentRight="true"
        android:layout_alignParentTop="true"
        android:text= "@string/send"
        android:textSize= "16sp" />

    <EditText
        android:id= "@+id/editText1"
        android:layout_width= "wrap_content"
        android:layout_height= "wrap_content"
        android:layout_alignBaseline="@+id/textView1"
        android:layout_toLeftOf= "@id/button1"
        android:layout_toRightOf= "@+id/textView1"
        android:ems= "10"
        android:hint= ""
        android:inputType= "text"
        android:textSize= "16sp" >

        <requestFocus />
    </EditText >

</RelativeLayout>
MainActivity.java
public class MainActivity extends Activity {

     private Button btnSend;
     private EditText etMessage;
     private int i = 1;

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

            btnSend = (Button) findViewById(R.id. button1);
            etMessage = (EditText) findViewById(R.id. editText1);

            btnSend.setOnClickListener( new View.OnClickListener() {
                 @Override
                 public void onClick(View view) {

                     sendNotification( etMessage.getText().toString());
                      etMessage.setText( "");

                }

           });

     }

     public void sendNotificationOld(String message) {

            // -- 舊的寫法

           NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE );
           Notification notification = new Notification(R.drawable. ic_launcher,
                     message, System. currentTimeMillis());
           PendingIntent contentIndent = PendingIntent.getActivity(
                     MainActivity. this, 0, new Intent(MainActivity.this,
                                MainActivity. class), PendingIntent.FLAG_UPDATE_CURRENT );

           notification. setLatestEventInfo(MainActivity. this, "Notification " + i,
                     message, contentIndent) ; // 加i是為了顯示多條Notification
           notificationManager.notify( i, notification);
            i++;

            // --

     }

     @SuppressWarnings("deprecation")
     public void sendNotification(String message) {

            try {

                 // -- 新的寫法
                NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE );
                Builder builder = new Notification.Builder(MainActivity.this );
                PendingIntent contentIndent = PendingIntent.getActivity(
                           MainActivity. this, 0, new Intent(MainActivity.this,
                                     MainActivity. class),
                           PendingIntent. FLAG_UPDATE_CURRENT);
                builder.setContentIntent(contentIndent)
                           .setSmallIcon(R.drawable. ic_launcher)
                            // 設置狀態列裡面的圖示(小圖示)           
                           .setLargeIcon(
                                     BitmapFactory. decodeResource(this.getResources(),
                                                R.drawable. icon)) // 下拉下拉清單裡面的圖示(大圖示)
                           .setTicker(message) // 設置狀態列的顯示的資訊
                          .setWhen(System. currentTimeMillis())// 設置時間發生時間
                           .setAutoCancel( false) // 設置可以清除
                           .setContentTitle( "Notification " + i) // 設置下拉清單裡的標題
                           .setContentText(message); // 設置上下文內容

                Notification notification = builder.getNotification();

                 // notification.defaults |= Notification.DEFAULT_SOUND;
                notification. sound = Uri
                          . parse("file:///sdcard/Notifications/hangout_ringtone.m4a");
                notification. sound = Uri. withAppendedPath(
                           Audio.Media. INTERNAL_CONTENT_URI, "6");
                notification. sound = Uri.parse("android.resource://"
                           + getPackageName() + "/" + R.raw.koko);
                 // 後面的設定會蓋掉前面的

                 // 振動
                notification. defaults |= Notification.DEFAULT_VIBRATE ; // 某些手機不支援 請加
                                                                                            // try catch 

                 // 閃光燈
                notification. defaults |= Notification.DEFAULT_LIGHTS; // 測試沒反應


                 // 加i是為了顯示多條Notification
                notificationManager.notify(1, notification);
                 i++;
                 // --
           } catch (Exception e) {

           }
     }
}
舊的寫法
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE );
Notification notification = new Notification(R.drawable. ic_launcher ,
message, System. currentTimeMillis());
PendingIntent contentIndent = PendingIntent.getActivity(
MainActivity. this, 0, new Intent(MainActivity.this ,
MainActivity. class), PendingIntent.FLAG_UPDATE_CURRENT );

notification. setLatestEventInfo(MainActivity. this , "Notification " + i,
message, contentIndent) ; 
notificationManager.notify( i, notification);
i++;
通知訊息可以顯示多筆,若i只設為同數字,則只會顯示一筆,舊訊息會被新訊息所取代。
新的寫法
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE );
Builder builder = new Notification.Builder(MainActivity.this );
PendingIntent contentIndent = PendingIntent.getActivity(
MainActivity. this, 0, new Intent(MainActivity.this , MainActivity. class),
PendingIntent. FLAG_UPDATE_CURRENT);
builder.setContentIntent(contentIndent)
    .setSmallIcon(R.drawable. ic_launcher)
    // 設置狀態列裡面的圖示(小圖示)           
    .setLargeIcon(BitmapFactory. decodeResource( this.getResources(),
                  R.drawable. icon)) // 通知清單裡面的圖示(大圖示)
    .setTicker(message) // 設置狀態列的顯示的資訊
    .setWhen(System. currentTimeMillis()) // 設置發生時間
    .setContentTitle( "Notification " + i) // 設置通知清單裡的標題
    .setContentText(message); // 設置內容

                Notification notification = builder.getNotification();
notificationManager.notify(1, notification);
                 i++;
只會顯示一筆通知 notificationManager.notify(1, notification);
設置通知音效的部份,有幾種寫法:
1 設定為手機的預設鈴聲
notification.defaults |= Notification.DEFAULT_SOUND;
2 再來是直接將外部聲音來源,設定為通知音效。後面的設定會蓋掉前面的,若是聲音檔不存在也不會出現錯誤。但要自行設定音效的話,就不需要先設定notification.defaults,否則設定無效。
notification. sound = Uri. parse("file:///sdcard/Notifications/hangout_ringtone.m4a");
notification. sound = Uri. withAppendedPath(Audio.Media. INTERNAL_CONTENT_URI, "6");
notification. sound = Uri.parse("android.resource://" + getPackageName() + "/" + R.raw.ring);
參考相關網站 http://developer.android.com/guide/topics/ui/notifiers/notifications.html


程式範例附件下載