状态栏消息提示——使用Notification
什么是Notification
Notification用于在狀態(tài)欄顯示信息。這些信息一般來源于app的消息推送,或應(yīng)用的一些功能控制(如播放器)
?
Notification的兩種視圖
普通視圖
借用官方的圖片說明一下Notification視圖中包括的內(nèi)容
1. 內(nèi)容標(biāo)題
2. 大圖標(biāo)(Bitmap)
3. 正文內(nèi)容
4. 附加信息
5. 小圖標(biāo)
6. Notification的推送時(shí)間
?
大視圖
除了上圖中標(biāo)出的第7點(diǎn)外,其他的基本和普通視圖中的一樣。
其中第7點(diǎn)可顯示為一下幾種內(nèi)容
1. 顯示大圖片
????? 在詳情區(qū)域可以顯示一張最大為256dp的圖片
2. 顯示長文本
????? 在詳情區(qū)域顯示長文本
3. inbox style(因?yàn)椴恢乐形脑鯓硬拍苷f得準(zhǔn)確,這里用英文表達(dá))
??????? inbox style在詳情區(qū)域顯示多行文本.
4. 大內(nèi)容標(biāo)題
??????? 允許用戶為擴(kuò)展視圖定義另一個(gè)標(biāo)題。
5. 摘要文本
??????? 允許用戶在詳情區(qū)域添加一行額外的文本
?
創(chuàng)建標(biāo)準(zhǔn)的Notification
以下三項(xiàng)式創(chuàng)建一個(gè)標(biāo)準(zhǔn)的Notification的先決條件
1. 小圖標(biāo), 通過setSmallIcon()方法設(shè)置
2. 標(biāo)題, 通過setContentTitle()方法設(shè)置
3. 內(nèi)容文本, 通過setContentText()方法設(shè)置
?
我們這里不通過調(diào)用Notification構(gòu)造方法的方式創(chuàng)建Notification,因?yàn)檫@種方法已經(jīng)不推薦使用。
我們使用通過NotificationCompat.Builder類創(chuàng)建Notification。
?
程序的主布局文本中只有一個(gè)id為btnShow的按鈕,點(diǎn)擊這個(gè)按鈕顯示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;@Overrideprotected 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)// 設(shè)置小圖標(biāo) .setSmallIcon(R.drawable.ic_launcher)// 設(shè)置標(biāo)題.setContentTitle("you have a meeting")// 設(shè)置內(nèi)容.setContentText("you have a meeting at 3:00 this afternoon").build();btnShow.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {mNotificationManager.notify(0, mNotification);}});} }運(yùn)行效果
?
當(dāng)然,這個(gè)Demo在4.x系統(tǒng)上是可以正常運(yùn)行的。
當(dāng)同樣的代碼在2.x的系統(tǒng)上面運(yùn)行,程序會(huì)崩潰的。如下
而且,會(huì)拋出一個(gè)異常:
java.lang.IllegalArgumentException: contentIntent required: pkg=com.whathecode.notificationdemo id=0 notification=Notification(vibrate=null,sound=null,defaults=0x0,flags=0x0)
上面的錯(cuò)誤已經(jīng)說得很清楚了,contentIntent required , 也就是需要contentIntent
這個(gè)contentIntent可以通過setContentIntent設(shè)置。
也就是說,上面所提到的三個(gè)先決條件只是確保4.x版本可以正常運(yùn)行,
如果你的程序需要兼容2.x版本的,你就需要一個(gè)contentIntent
contentIntent的作用是點(diǎn)擊Notification時(shí)跳轉(zhuǎn)到其他的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;@Overrideprotected 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,* 因?yàn)槲覀儸F(xiàn)在不需要跳轉(zhuǎn)到其他Activity,* 所以這里只實(shí)例化一個(gè)空的Intent*/Intent intent = new Intent();mResultIntent = PendingIntent.getActivity(this, 1, intent,Intent.FLAG_ACTIVITY_NEW_TASK);mNotification = new NotificationCompat.Builder(this)// 設(shè)置小圖標(biāo) .setSmallIcon(R.drawable.ic_launcher)// 設(shè)置標(biāo)題.setContentTitle("系統(tǒng)更新")// 設(shè)置內(nèi)容.setContentText("發(fā)現(xiàn)系統(tǒng)更新,點(diǎn)擊查看詳情")//設(shè)置ContentIntent .setContentIntent(mResultIntent).build();btnShow.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {mNotificationManager.notify(0, mNotification);}});} }運(yùn)行效果
?
完整的Notification實(shí)例
上面代碼中的例子并不完整,只是演示了一個(gè)可以正常運(yùn)行的實(shí)例
說它不完整是因?yàn)镹otification到來的時(shí)候狀態(tài)欄只有圖標(biāo),沒有文字,也沒有聲音提示,用戶體驗(yàn)并不好。
當(dāng)我們不設(shè)置LargeIcon的時(shí)候,系統(tǒng)就會(huì)使用當(dāng)前設(shè)置的小圖標(biāo)作為大圖標(biāo)使用,小圖標(biāo)位置(位置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;@Overrideprotected 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, 并設(shè)置跳轉(zhuǎn)到的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")@Overridepublic void onClick(View v) {Bitmap largeIcon = BitmapFactory.decodeResource(MainActivity.this.getResources(), R.drawable.luffy);mNotification = new NotificationCompat.Builder(getBaseContext())// 設(shè)置大圖標(biāo) .setLargeIcon(largeIcon)// 設(shè)置小圖標(biāo) .setSmallIcon(R.drawable.ic_launcher)// 設(shè)置小圖標(biāo)旁的文本信息.setContentInfo("1")// 設(shè)置狀態(tài)欄文本標(biāo)題.setTicker("你的系統(tǒng)有更新")// 設(shè)置標(biāo)題.setContentTitle("系統(tǒng)更新")// 設(shè)置內(nèi)容.setContentText("發(fā)現(xiàn)系統(tǒng)更新,點(diǎn)擊查看詳情")// 設(shè)置ContentIntent .setContentIntent(mResultIntent)// 設(shè)置Notification提示鈴聲為系統(tǒng)默認(rèn)鈴聲 .setSound(RingtoneManager.getActualDefaultRingtoneUri(getBaseContext(),RingtoneManager.TYPE_NOTIFICATION))// 點(diǎn)擊Notification的時(shí)候使它自動(dòng)消失.setAutoCancel(true).build();mNotificationManager.notify(0, mNotification);}});} }運(yùn)行效果(Android 2.x)???????????????????????????????????????????????????????????? 運(yùn)行效果(Android 4.x)
????????????????
?
通過觀察上面兩張圖你會(huì)發(fā)現(xiàn),在2.x版本下LargeIcon和contentInfo并沒有生效。
這是因?yàn)閟etLargeIcon和setContentInfo都是在api level 11(honeycomb)才添加的功能
?
使用自定義布局統(tǒng)一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"><ImageViewandroid:id="@+id/largeIcon"android:layout_width="64dp"android:layout_height="64dp"android:src="@drawable/luffy"android:contentDescription="largeIcon" /><TextViewandroid: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="系統(tǒng)更新"/><TextViewandroid: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="發(fā)現(xiàn)系統(tǒng)更新,點(diǎn)擊查看詳情"android:textSize="12sp"/><TextViewandroid: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"/><ImageViewandroid: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" /><TextViewandroid: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;@Overrideprotected 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, 并設(shè)置跳轉(zhuǎn)到的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")@Overridepublic void onClick(View v) {RemoteViews customView = new RemoteViews(getPackageName(),R.layout.customerviews);mNotification = new NotificationCompat.Builder(getBaseContext())// 設(shè)置小圖標(biāo) .setSmallIcon(R.drawable.ic_launcher)// 設(shè)置狀態(tài)欄文本標(biāo)題.setTicker("你的系統(tǒng)有更新")//設(shè)置自定義布局 .setContent(customView)// 設(shè)置ContentIntent .setContentIntent(mResultIntent)// 設(shè)置Notification提示鈴聲為系統(tǒng)默認(rèn)鈴聲 .setSound(RingtoneManager.getActualDefaultRingtoneUri(getBaseContext(),RingtoneManager.TYPE_NOTIFICATION))// 點(diǎn)擊Notification的時(shí)候自動(dòng)移除.setAutoCancel(true).build();/** 當(dāng)API level 低于14的時(shí)候使用setContent()方法是沒有用的* 需要對(duì)contentView字段直接賦值才能生效*/if (Build.VERSION.SDK_INT < 14) {mNotification.contentView = customView;}mNotificationManager.notify(0, mNotification);}});} }上面的布局文件中的內(nèi)容是硬編碼的,也可以通過RemoteViews類中的setXXX方法動(dòng)態(tài)設(shè)定內(nèi)容。
這樣程序便更加靈活
?
運(yùn)行效果(android 2.x)???????????????????????????????????????????????????????????????????????????? 運(yùn)行效果(android 4.x)
?????????????????
?
在兩個(gè)版本中的運(yùn)行效果基本一樣了,但是,在低版本下不是很完美,有部分灰白的地方特別扎眼
網(wǎng)上查了很久也沒有找到解決辦法,有知道的請(qǐng)告知
?
更新Notification的內(nèi)容
因?yàn)槲覀儎?chuàng)建的Notification是通過一個(gè)Id分別的,因此只要在使用NotificationManager的notify()方法的時(shí)候使用
相同的Id就可以更新這個(gè)Notification的內(nèi)容
當(dāng)然在使用notify()方法之前我們還是要?jiǎng)?chuàng)建一個(gè)Notification實(shí)例。
轉(zhuǎn)載于:https://www.cnblogs.com/ai-developers/p/4304962.html
總結(jié)
以上是生活随笔為你收集整理的状态栏消息提示——使用Notification的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: quick cocos2dx 3.x 配
- 下一篇: 关于安卓的好东西