Notification(Notification的通知欄常駐、各種樣式、點選無效、禁止滑動刪除、相容低版本)
Notification(Notification的通知欄常駐、Notification的各種樣式、Notification點選無效、Notification禁止滑動刪除)
Android的Notification是android系統中很重要的一個機制, 產品人員常常利用通知欄的方式,跟使用者進行弱溝通。擁有推送通知的app要比沒有此類功能的app活躍率要高很多。另外類似於墨跡天氣,清理大師等app,也會將通知欄常駐,利用自定義的佈局,方便使用者及時快捷的檢視所需的資訊和使用快捷的功能。所以Notification的使用,也在開發當中, 使用的越來越頻繁。今天我就來跟大家分享一下Notification的常用事項。
我不瞭解大家平時怎麼使用Notification,我常常看到有些人的程式碼是這樣寫的:
- Notification notification=new Notification(notificationIcon, notificationTitle, when);
- notification.defaults=Notification.DEFAULT_ALL;
- Intent intent=new Intent(MainActivity.this,SecondActivity.class);
- PendingIntent pendingIntent=PendingIntent.getActivity(MainActivity.this, 0, intent, 0);
- notification.setLatestEventInfo(this,"測試展開title", "測試展開內容",pendingIntent);
- 。。。。。。。。。。。。。
具體的程式碼我就不貼全了,因為大家如果注意IDE的提示的話,就會發現,其實這是一種不推薦的用法,API的支援已經過時了。最新的Notification的用法,是推薦使用V4包下的NotificationCompat.Builder, 利用它,進行各種設定,具體的用法先彆著急,我們慢慢道來。
- NotificationCompat.Builder notifyBuilder = new NotificationCompat.Builder(
- this);
首先,我們需要先初始化一個notifyBuilder,然後利用它的各種set方法,進行相關設定,具體的設定,我們參考下圖:
圖示中的序號1,叫做
- notifyBuilder.setContentTitle("This is My Notification");
圖示中的序號3,叫做
- notifyBuilder.setContentText("Hello World");
圖示中的需要5,叫做利用下面的方法來設定:
這三個引數的設定是必須的,每次呼叫Notification,必須得設定這三個引數。除去這三個以外,另外的2,4,6區域,分別是Large Icon,Content Info,Time,設定方法如下所示:
- Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.bigicon);
- notifyBuilder.setLargeIcon(bitmap);
- // 這裡用來顯示右下角的數字
- notifyBuilder.setNumber(10);
- notifyBuilder.setWhen(System.currentTimeMillis());
以上就是關於Notification的基本設定,下面,我們繼續看看其它方面的設定,直接上程式碼:
- // 將AutoCancel設為true後,當你點選通知欄的notification後,它會自動被取消消失
- notifyBuilder.setAutoCancel(true);
- // 將Ongoing設為true 那麼notification將不能滑動刪除
- // notifyBuilder.setOngoing(true);
- // 從Android4.1開始,可以通過以下方法,設定notification的優先順序,優先順序越高的,通知排的越靠前,優先順序低的,不會在手機最頂部的狀態列顯示圖示
- notifyBuilder.setPriority(NotificationCompat.PRIORITY_MAX);
- // notifyBuilder.setPriority(NotificationCompat.PRIORITY_MIN);
- notifyBuilder.setTicker("Hi,Notification is here");
- // Uri uri =
- // Uri.parse("android.resource://"+getPackageName()+"/"+R.raw.cat);
- // Uri uri = Uri.parse("file:///mnt/sdcard/cat.mp3");
- // notifyBuilder.setSound(uri);
- // Notification.DEFAULT_ALL:鈴聲、閃光、震動均系統預設。
- // Notification.DEFAULT_SOUND:系統預設鈴聲。
- // Notification.DEFAULT_VIBRATE:系統預設震動。
- // Notification.DEFAULT_LIGHTS:系統預設閃光。
- // notifyBuilder.setDefaults(Notification.DEFAULT_ALL);
- NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
- mNotificationManager.notify(NOTIFY_ID, notifyBuilder.build());
如上面的註釋所示,如果你想點選完notification後,該通知自動消失,那麼你就需要呼叫setAutoCancel(booleanb)這個方法,並且將其設為true,如果你想讓你的通知欄常駐,使用者無法滑動刪除,也不能通過手機的清除鍵刪除,類似於墨跡天氣等app的通知欄,那麼你可以設定setOngoing方法,也設為true,這樣,通知欄只能通過程式碼呼叫cancel方法才能消失,很霸道地,有木有!另外,從Android4.1時代開始,系統允許設定Notification的優先順序,對於優先順序高的通知,會排在通知欄的前面,並在會在手機最上端的Status Bar顯示一個圖示,如果優先順序設定的較低,那麼就會被系統顯示在通知欄的後面,並且Status Bar不再顯示相應的圖示,設定優先順序的方法,就是呼叫setPriority(intp)。另外,當啟動通知欄的時候,我們常常可以在手機最上端的Status Bar上面,會閃現一段提示語,用來提醒使用者,這段提示語具體顯示的文字,就是靠setTicker() 這個方法來實現的。除此之外,我們還可以設定,推送通知時的鈴聲、震動效果,閃光燈效果等等,具體的我就不一一列舉了,參考上面的示例程式碼即可,需要注意一點的是,設定通知的鈴聲,除去呼叫系統自帶的外,還有兩種方式,分別是呼叫SD卡中的聲音檔案和專案工程自帶的聲音檔案,這兩種方式都需要用到Uri的 地址,具體如何獲取這兩種的Uri,我已經在上面的程式碼中,寫的很詳細了,大家可以參考上面的程式碼,在自己的專案中實驗一下。
說了這麼多,還有最重要的一點沒有講,那就是在你設定完notification的各 種屬性後,你需要啟動這個notification,否則就前功盡棄了,啟動的方法,如上面的示例程式碼所示,你需要先獲取一個 NotificationManager的例項,然後呼叫notify的方法,notifyBuilder.build()這個方法,可以例項化一個notification的例項,另外,你還需要為這個notification分配一個獨一無二的的id號,將來notification的更新和刪 除,都是依靠這個id號來做索引對應的。
有時候,我們會涉及到這麼一個需求,那就是,產品設計,希望我們能夠監聽 notification的銷燬,意思就是說,當用戶手動滑動通知將其刪除或者通過手機的刪除按鈕將其清空時,我們希望可以捕獲到這一資訊,並作出相應的處理。比如說,我們在通知欄傳送了一個通知,用來更新一個資源的下載進度,當用戶刪除這個通知後,我們希望可以監聽到這一變化,作出相應的處理,比如取消 下載,比如重新下載等等,那麼,應該如何監聽取消的行為呢?請看程式碼:
- Intent deleteIntent = new Intent(this, DeleteService.class);
- int deleteCode = (int) SystemClock.uptimeMillis();
- PendingIntent deletePendingIntent = PendingIntent.getService(this,
- deleteCode, deleteIntent, PendingIntent.FLAG_UPDATE_CURRENT);
- notifyBuilder.setDeleteIntent(deletePendingIntent);
我 們給notifyBuilder設定一個DeleteIntent,這裡指向了一個service,當刪除的行為發生後,系統就會啟動這個 service,我們就可以在這個service中,做相應的邏輯處理了,當然,這裡我只是舉了一個例子,用來啟動service,大家也可以將 Intent指向一個Activity或者一個廣播,不過PendingIntent.getService()這個方法,就需要換成PendingIntent.getActivity()或者PendingIntent.getBroadCast()這兩個方法。
上面的內容,我們大概瞭解瞭如何給notification設定顯示的內容,和如何監聽銷燬的行為。但是常常,我們會發現,除了以上功能外,我們經常遇見的情形時,當我們點選了一個notification後,就會自動開啟一個頁面,展示出資訊來源的具體頁面,接下來,我們就針對這種情況,來看看程式碼是如何控制的。
剛剛提到的自動跳轉頁面的功能,看似很簡單的一個邏輯,其實也包含了各種邏輯處理情況,其中最主要的是有兩種:
一:當我們處在手機桌面主屏的時候,突然來了一條郵箱的資訊,來了一封新郵件,我們點選通知欄,系統會為我們開啟最新收到的郵件,當我們看完郵件後,按返回鍵,我們並不會馬上回到手機桌面的主屏上,而是先返回到收件箱界 面,然後再返回到郵件APP的主介面,然後再返回到手機桌面的主屏上,它是按照郵件APP的頁面佇列返回的。
二:還是舉剛才那個例子,當我們收到新郵件的通知後,我們點選開啟新收到的郵件,當我們閱讀完之後,我們想要點選返回鍵,立刻返回到我們剛剛所處的介面,繼續進行剛才還在進行的任務。
這兩種情況,在產品設計中,常常出現,所以我們也要想辦法去實現,那麼如何去實現這兩種情況呢,我們一個一個來看。
首先請看第一種情況的程式碼:
- Intent notifyIntent = new Intent(this, NotifyRegularActivity.class);
- TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
- stackBuilder.addParentStack(NotifyRegularActivity.class);
- stackBuilder.addNextIntent(notifyIntent);
- // 當設定下面PendingIntent.FLAG_UPDATE_CURRENT這個引數的時候,常常使得點選通知欄沒效果,你需要給notification設定一個獨一無二的requestCode
- int requestCode = (int) SystemClock.uptimeMillis();
- PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(
- requestCode, PendingIntent.FLAG_UPDATE_CURRENT);
- notifyBuilder.setContentIntent(resultPendingIntent);
我們繼續貼上AndroidManist.xml的配置程式碼:
- <activity
- android:name="com.example.notificationtest.MainActivity"
- android:label="@string/app_name" >
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- <activity
- android:name="com.example.notificationtest.OtherActivity"
- android:label="OtherActivity"
- android:parentActivityName="com.example.notificationtest.MainActivity" >
- <meta-data
- android:name="android.support.PARENT_ACTIVITY"
- android:value="com.example.notificationtest.MainActivity" />
- </activity>
- <activity
- android:name="com.example.notificationtest.NotifyRegularActivity"
- android:label="NotifyRegularActivity"
- android:parentActivityName="com.example.notificationtest.OtherActivity" >
- <meta-data
- android:name="android.support.PARENT_ACTIVITY"
- android:value="com.example.notificationtest.OtherActivity" />
- </activity>
好,我們來分析一下上面的程式碼。首先我們設定了一個Intent,將其指向 NotifyRegularActivity,然後我們用到了TaskStackBuilder,它可以用來控制介面返回的導航堆疊。
- TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
- stackBuilder.addParentStack(NotifyRegularActivity.class);
- stackBuilder.addNextIntent(notifyIntent);
我們利用這段程式碼,首先例項化了一個TaskStackBuilder,然後呼叫addParentStack()和addNextIntent(), 設定它的返回堆疊和跳轉頁面,跳轉頁面的Intent很好理解,跟大家平時的設定方式是一樣的,那麼它的返回堆疊是如何控制的呢?這就需要上面xml配置 檔案的配置了,大家請看,在上面的配置檔案中,一共有三個Activity,分別是MainActivity,OtherActivity,和
NotifyRegularActivity,其中NotifyRegularActivity就是我們點選通知欄後,要自動跳轉的介面。在配置檔案當中,
我們給後面兩個Activity,設定了這麼一個屬性android:parentActivityName,它指的就是該activity的返回路徑,因為剛剛我們在呼叫addParentStack()這個方法的時候,設定的引數是NotifyRegularActivity.class所以根據上面配置檔案的配置內容,那麼它的返回堆疊的順序就是:
需要注意的是,為了向下相容版本,我們在設定android:parentActivityName這個屬性的時候,還需要在配置檔案中,為每個Activity進行如下設定:
- <meta-data
- android:name="android.support.PARENT_ACTIVITY"
- android:value="com.example.notificationtest.MainActivity" />
具體的value的指向,就需要你自己設定了,總之,它指向了該activity的返回頁面。對TaskStackBuilder設定完成之後,我們再通過下面的程式碼獲取PendingIntent,,然後賦值給notifyBuilder即可:
- // 當設定下面PendingIntent.FLAG_UPDATE_CURRENT這個引數的時候,常常使得點選通知欄沒效果,你需要給notification設定一個獨一無二的requestCode
- int requestCode = (int) SystemClock.uptimeMillis();
- PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(
- requestCode, PendingIntent.FLAG_UPDATE_CURRENT);
- notifyBuilder.setContentIntent(resultPendingIntent);
這裡有兩點需要注意一下:
1:PendingIntent.FLAG_UPDATE_CURRENT這個引數一般有四種選擇分別是:
FLAG_CANCEL_CURRENT:如果構建的PendingIntent已經存在,則取消前一個,重新構建一個。
FLAG_NO_CREATE:如果前一個PendingIntent已經不存在了,將不再構建它。
FLAG_ONE_SHOT:表明這裡構建的PendingIntent只能使用一次。
FLAG_UPDATE_CURRENT:如果構建的PendingIntent已經存在,那麼系統將不會重複建立,只是把之前不同的傳值替換掉。
如果沒有特殊要求的話,我們常常會使用FLAG_UPDATE_CURRENT這個引數來構造PendingIntent,但是這樣常常會引發第二個問題,什麼問題呢?呵呵~
2:如上所述我們使用 FLAG_UPDATE_CURRENT這個引數後,常常會發現,我們點選通知欄後,系統沒有響應,時靈時不靈的,很是憂鬱,這是為什麼呢?原來使用 FLAG_UPDATE_CURRENT這個引數後,系統不會重新建立新的PendingIntent,這樣一來,如果你傳遞的Intent的 extra引數沒有變化的話,那麼系統就會認為你沒有傳送新的PendingIntent,這樣就不會重新響應你的點選事件。一般情況下,為了能夠區分每 次的PendingIntent不一樣,我們常常會在構造Intent的時候,設定不同的Action或者Extra值,這樣一來,及時是使用 FLAG_UPDATE_CURRENT這個引數,系統也會因為傳值引數的變化而去響應每次的點選跳轉事件。不過這種解決方法還是有些麻煩,有時候,我們根本不需要傳遞額外的Aciton或者引數值,這該怎麼辦呢?哈哈,解決程式碼已經在上面的程式碼中寫出來了,在stackBuilder.getPendingIntent(requestCode,PendingIntent.FLAG_UPDATE_CURRENT)這個方法中,我們注意到第一個引數,這裡,我們只要為這個引數設定一個獨一無二的標識,那麼剛剛提到的點選無響應的問題就迎刃而解了,我平時的設定辦法就是利用這段程式碼:
- int requestCode = (int) SystemClock.uptimeMillis();
獲取釋出通知時的時間,將它作為requestCode,這樣就可以避免這些問題了。不過如果你要是使用FLAG_CANCEL_CURRENT這個引數的話,就會每次都建立一個新的,那麼剛剛提到的這兩個問題,也都不存在了,具體怎麼用,看你實際的業務要求了。
上面的講解,我們就可以解決剛剛討論的第一種情形了,下面我們來說一下,第二種情形,也就是點選返回鍵後,直接返回剛剛任務所處的介面,看看這個如何實現。來,看程式碼:
- Intent notifyIntent = new Intent(this, NotifySpecialActivity.class);
- notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
- | Intent.FLAG_ACTIVITY_CLEAR_TASK);
- // Creates the PendingIntent
- // 當設定下面PendingIntent.FLAG_UPDATE_CURRENT這個引數的時候,常常使得點選通知欄沒效果,你需要給notification設定一個獨一無二的requestCode
- int requestCode = (int) SystemClock.uptimeMillis();
- PendingIntent pendIntent = PendingIntent.getActivity(this, requestCode,
- notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
- notifyBuilder.setContentIntent(pendIntent);
繼續看配置檔案的設定:
- <activity
- android:name="com.example.notificationtest.NotifySpecialActivity"
- android:excludeFromRecents="true"
- android:label="NotifySpecialActivity"
- android:launchMode="singleTask"
- android:taskAffinity="" >
- </activity>
在程式碼中,我們設定NotifySpecialActivity為我們要跳轉的介面,然後在xml的配置檔案中,我們重點設定了這三個屬性:android:excludeFromRecents="true",android:launchMode="singleTask",android:taskAffinity="",第一個屬性的設定,是將該介面從最近工作列當中移除,防止使用者通過最近工作列而進入到該介面,這樣一來,只能通過通知來的點選來進入。第二種屬性的設定就很常見了,是為了防止該介面存在的情況下,重複建立該Activity,第三屬性是為了配置程式碼中的這段來設定的:
- notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
- | Intent.FLAG_ACTIVITY_CLEAR_TASK);
這樣的作用是為此次跳轉介面的行為重新分配一個任務堆疊,而不從屬於其它的任務堆疊,這樣的話,當我們點選返回鍵後,就可以直接返回到剛剛使用者所處的任務介面了。由於這裡我們不再使用TaskStackBuilder,所以最後需要呼叫PendingIntent.getActivity(this,requestCode,notifyIntent,PendingIntent.FLAG_UPDATE_CURRENT)這個方法來構造一個PendingIntent,然後賦值給notifyBuilder。這樣,剛剛討論過的第二種情形,我們就可以解決了,相比較第一種來說,這種解決方式更為簡潔,不過處理的業務邏輯也不一樣,大家斟酌而定。
Notificaton在平時的產品設計中,常常用來顯示跟網路互動的進度,我們常常的做法是在通知欄上面,顯示一個進度條,用來更新互動的進度,這個的實現方式很簡單,主要依賴於mBuilder.setProgress()這個方法,具體的做法可以參考下面的程式碼:
- final NotificationManager mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
- final NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
- this);
- mBuilder.setContentTitle("Picture Download")
- .setContentText("Download in progress")
- .setSmallIcon(R.drawable.small);
- new Thread(new Runnable() {
- @Override
- public void run() {
- int incr;
- for (incr = 0; incr <= 100; incr += 5) {
- // mBuilder.setProgress(100, incr, false);
- mBuilder.setProgress(0, 0, true);
- mNotifyManager.notify(NOTIFY_ID, mBuilder.build());
- try {
- Thread.sleep(1 * 1000);
- } catch (InterruptedException e) {
- }
- }
- mBuilder.setContentText("Download complete").setProgress(0, 0,
- false);
- mNotifyManager.notify(NOTIFY_ID, mBuilder.build());
- }
- }
- // Starts the thread by calling the run() method in its Runnable
- ).start();
- }
在程式碼中,我們開啟了一個執行緒,裡面進行20次for迴圈,每次迴圈都會呼叫setProgress這個方法,因為每次呼叫的NOTIFY_ID都是相同的,所以系統會根據這個ID來更新notification的進度而不會重新建立一個新的Notification。setProgress這個方法一共有兩種方法,一種是這樣的:
- mBuilder.setProgress(100, incr, false);
第一個引數指的的是進度的總長度,第二個引數是目前進行的長度,然後將第三個引數設為false,我們可以看到的效果就如下圖:
我們可以看見進度條的確切位置和進度情況。還有一種使用方法是這樣的:
- mBuilder.setProgress(0, 0, true);
將前兩個引數都設為0,然後將最後這個引數設為true,這樣的進度條效果是一種連續模糊的,適合進行時間不確定的網路連線,效果圖如下:
最後,當我們的任務完成後,我們需要取消進度條的顯示,這時候我們需要呼叫如下方法:
- mBuilder.setContentText("Download complete").setProgress(0, 0,
- false);
設定一個任務完成後的文字描述,然後將setProgress的前兩個引數都設為0,最後一個引數設為false,這樣進度條就不會在通知欄上面顯示了,效果圖:
Notification的進度條的使用方法就是這些,如果大家平時用的不多,最好還是根據上面貼出的原始碼,自己聯絡一遍,稍候我也會把本次工程的原始碼打包,上傳到CSDN的資源庫中,供大家參考。
上面跟大家介紹的,都是Notification的一種常規樣式,自從Android4.1之後,谷歌引入了一種新的樣式,叫做Big View,效果就是相對於傳統的Notification,它的顯示區域更大,顯示的內容也更多一些。關於Big View,谷歌支援了三種模式,分別是:
Big text style還有 new NotificationCompat.Builder(
- this).setSmallIcon(R.drawable.small)
- .setContentTitle("Picture tracker")
- .setContentText("Picture received");
- NotificationCompat.BigPictureStyle picStyle = new NotificationCompat.BigPictureStyle();
- Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.bigpic);
- picStyle.bigPicture(bitmap);
- mBuilder.setStyle(picStyle);
- NotificationManager mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
- mNotifyManager.notify(NOTIFY_ID, mBuilder.build());
首先我們例項化一個NotificationCompat.BigPictureStyle,然後讀取要展示的圖片資源,呼叫picStyle.bigPicture(bitmap)這個方法設定圖片,最後呼叫notifyBuilder的mBuilder.setStyle(picStyle)方法,設定好BIGVIEW的樣式,就OK了,程式碼簡單的令人髮指,我就不多解釋了,大家參考上面的示例程式碼即可。
接下來,我們再看看Inbox style這種樣式是如何設定的:
- NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
- this).setSmallIcon(R.drawable.small)
- .setContentTitle("Inbox tracker")
- .setContentText("Inbox received");
- NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle();
- String[] events = new String[6];
- events[0] = "Hello my one world";
- events[1] = "Hello my two world";
- events[2] = "Hello my three world";
- events[3] = "Hello my four world";
- events[4] = "Hello my five world";
- events[5] = "Hello my six world";
- inboxStyle.setBigContentTitle("Inbox tracker details:");
- for (int i = 0; i < events.length; i++) {
- inboxStyle.addLine(events[i]);
- }
- inboxStyle.setBigContentTitle("Thers are six messages");
- inboxStyle.setSummaryText("It‘s so easy,right?");
- mBuilder.setStyle(inboxStyle);
- NotificationManager mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
- mNotifyManager.notify(NOTIFY_ID, mBuilder.build());
唉,程式碼是不是再簡單不過了,我都不好意思班門弄斧的介紹這段程式碼了。主要宣告一下三個方法的使用吧,inboxStyle.addLine(),這個方法是用來設定下圖中黃色區域的文字,inboxStyle.setBigContentTitle("Thers are six messages")這個方法是用來設定紅色區域的文字內容,inboxStyle.setSummaryText("It‘s soeasy,right?")是用來設定綠色區域的內容顯示,其他的基本設定在之前的內容中,都已經介紹了很多了,我就不重複介紹了。
通過上面的學習,想必大家已經對Notification有了一個比較全面的瞭解了,最後,我再給大家介紹一種自定義 Notification佈局的用法。自定義Notification佈局的app有很多,比如像墨跡天氣,Clean Master等等,利用自定義佈局,將使用者所需資訊和快捷功能,多樣化的展示在通知欄上面,給大家看一下Clean Master的截圖:
其實要是實現這種自定義佈局的Notification,非常簡單,我們這就給大家展示程式碼設定和佈局配置:
先看看java程式碼:
- NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);
- RemoteViews remoteView = new RemoteViews(getPackageName(),R.layout.remote);
- remoteView.setTextViewText(R.id.text, "Custom Text");
- remoteView.setTextViewText(R.id.btn, "Custom Button");
- remoteView.setImageViewResource(R.id.image, R.drawable.ic_launcher);
- Intent notifyIntent = new Intent(this, NotifySpecialActivity.class);
- notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
- | Intent.FLAG_ACTIVITY_CLEAR_TASK);
- // Creates the PendingIntent
- // 當設定下面PendingIntent.FLAG_UPDATE_CURRENT這個引數的時候,常常使得點選通知欄沒效果,你需要給notification設定一個獨一無二的requestCode
- int requestCode = (int) SystemClock.uptimeMillis();
- PendingIntent pendIntent = PendingIntent.getActivity(this, requestCode,
- notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
- remoteView.setOnClickPendingIntent(R.id.btn, pendIntent);
- mBuilder.setSmallIcon(R.drawable.small);
- mBuilder.setContent(remoteView);
- NotificationManager mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
- mNotifyManager.notify(NOTIFY_ID, mBuilder.build());
再來看看xml佈局檔案是什麼樣的:
- <?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="64dp" >
- <ImageView
- android:id="@+id/image"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_alignParentLeft="true"
- android:gravity="center" />
- <TextView
- android:id="@+id/text"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_centerInParent="true"
- android:gravity="center" />
- <Button
- android:id="@+id/btn"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:gravity="center" />
- </RelativeLayout>
我們首先利用下面這行程式碼去解析上面的佈局檔案
- RemoteViews remoteView = new RemoteViews(getPackageName(),R.layout.remote);
然後根據每個控制元件的id號進行資源設定:
- remoteView.setTextViewText(R.id.text, "Custom Text");
- remoteView.setTextViewText(R.id.btn, "Custom Button");
- remoteView.setImageViewResource(R.id.image, R.drawable.ic_launcher);
我們也可以為這些控制元件單獨設定點選事件,比如設定Button的點選事件:
- remoteView.setOnClickPendingIntent(R.id.btn, pendIntent);
上面第二個引數pendingIntent的獲取,在之前的講解中,已經介紹了好幾種方式了,這裡我們隨便選擇一種來實現了:
- Intent notifyIntent = new Intent(this, NotifySpecialActivity.class);
- notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
- | Intent.FLAG_ACTIVITY_CLEAR_TASK);
- // Creates the PendingIntent
- // 當設定下面PendingIntent.FLAG_UPDATE_CURRENT這個引數的時候,常常使得點選通知欄沒效果,你需要給notification設定一個獨一無二的requestCode
- int requestCode = (int) SystemClock.uptimeMillis();
- PendingIntent pendIntent = PendingIntent.getActivity(this, requestCode,
- notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
最後,我們要呼叫下面這段程式碼,將自定義的RemoteView設定給notifyBuilder,然後呼叫傳送通知的方法就OK了。
- mBuilder.setContent(remoteView);
最後的最後,需要再給大家介紹兩個方法,那就是通過程式碼來取消Notification,咱不能只管殺不管埋啊,哈哈~
- NotificationManager cancelNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
- cancelNotificationManager.cancel(NOTIFY_ID);
- cancelNotificationManager.cancelAll();
cancelNotificationManager.cancel(NOTIFY_ID)這個方法是根據之前釋出通知時,分配的ID號,來取消對應的通知欄。cancelNotificationManager.cancelAll()這個方法是取消所有之前釋出過的通知欄,比較暴力一點哈。
相關推薦
Notification(Notification的通知欄常駐、各種樣式、點選無效、禁止滑動刪除、相容低版本)
Notification(Notification的通知欄常駐、Notification的各種樣式、Notification點選無效、Notification禁止滑動刪除) Android的Notification是android系統中很重要的一個機制, 產品人員常常利用通
如何用資料驅動實現通用化巡檢APP(如何一個介面裡新增多個點選拍照按鈕並顯示在不同的imageview裡)
最近啟動了一個新專案叫通用化,老師的設想是這樣的:APP裡顯示的內容和佈局都是不確定的,需要從後臺傳過來的json串中解析出來,然後經過一系列的迴圈和判斷語句,為APP新增上json中要求的佈局和內容,就連文字的大小和顏色也都是從後臺獲取的。 剛開始的時候覺得
iOS抽屜效果、二級選單(點選,拖拽滑動)
好像最近,看到好多Android上的抽屜效果,也忍不住想要自己寫一個。在Android裡面可以用SlidingDrawer,很方便的實現。IOS上面就只有自己寫了。其實原理很簡單就是 UIView 的移動,和一些手勢的操作。 // //
陰陽師魂十掛機實現(後臺控制代碼截圖+滑鼠點選)
學習繁忙,但是作為癢癢鼠的忠實粉,抽空寫了個小指令碼,後臺掛機魂十,業原火,御靈,覺醒,還是美滋滋的。 指令碼實現的關鍵主要有兩部分:一是通過控制代碼後臺獲得截圖,二是通過控制代碼後臺對視窗傳送滑鼠點選
leaflet選中要素,設定向量樣式,點選要素獲取其屬性
leaflet自身沒有選擇的控制,需要自己寫程式碼實現 主要是通過featurelayer的onclick事件來設定點選要素的style,並獲取對應feature的屬性資訊 let featureLayer = L.esri.featureLayer({ url:'http://mg
git分支管理(建立分支,分支間轉換,檢視分支,合併分支,刪除分支,分支衝突)
分支(branch)這玩意兒我也不知道該怎麼解釋,就按照自己的理解來吧~ 在你第一次commit的時候,git會自動建立一個master分支(當然前提是你沒有在這之前就轉換到另一個分支上),這就是主線。有的時候,會想對倉庫進行某些操作,但是我們又不想影響到倉庫當前的狀態,這個時候就可以建立一
pc端、手機端瀏覽器、微信內.點選返回鍵,返回到上一個頁面瀏覽的位置的實現
第一步:需要注意引入的js jquery.js jquery.cookie.js 第二部:在被返回的前一頁加入以下程式碼 <script type="text/javascript"> $(function () {
android狀態列一體化、沉浸式狀態列(相容低版本)
<TextView android:id="@+id/tv_title" android:layout_centerVertical="true" android:layout_width="match_parent"
IDEA開啟游標是粗黑色,backspace鍵、insert鍵點選無效的解決辦法
問題描述: 開啟IDEA的編譯器之後,介面顯示的游標變粗,點選backspace鍵和insert鍵盤之後無效 解決方法: 開啟File——Settings——Plugins,在右側的搜尋欄
Android點選文字編輯進行縮放、移動和改變字型、顏色的實現
實現效果如下: 需求功能點包含: 1:介面的文字為動態新增; 2:點選介面中的文字,開啟編輯模式:可編輯文字內容,可設定字型顏色,字型型別,粗體及對齊等; 3:點選刪除從介面上清除文字塊; 4:拖動編輯模式下的文字塊的四個錨點,可以按文字中心位置縮放,同時工具欄跟隨文字
移動端、pc端通用點選複製
點選複製 function copyArticle(event){ const range = document.createRange(); range.selectNode(document.getElementById('dd')); const selection = w
webpack 4.14.0 版本太高,無法執行相關指令,(將webpack高版本切換到低版本)--直接覆蓋
(1)問題:webpack 4.14.0 版本太高,無法執行相關指令,(2) 解決辦法:將高版本切換到低版本(3)實現webpack 4.14.0 版本太高,無法執行相關指令,指令不熟悉,高版本切換到低版本,
SoundPool工具類(單例模式),相容低版本
public class ClickSoundUtil { private Context context; private static SoundPool soundPool; private static int soundID; public stat
ng-repeat設定第一個元素為預設樣式,點選其餘元素切換樣式
如何在ng-repeat時預設第一個元素background-color為紅色,點選對應元素背景變紅同時更換其他全為黑色 提供一個簡單思路: JS: $scope.isActive = 0; $scope.arr = [ { //code he
EditText控制元件的基本使用(點選Button按鈕,Toast提示EditText中的內容)
EditText是程式用於和使用者進行互動的另一個重要控制元件,它允許使用者在空間裡輸入和編輯內容,並可以在程式中對這些內容進行處理。EditText的應用場景非常普遍,在進行發簡訊、發微博、聊QQ等操作時,你不得不使用EditText。接下來我們直接看實現效果圖,再看程式碼。 效果圖:
Android點選跳轉到聯絡人列表、撥號面板和通話記錄
public class MainActivity extends Activity { private String mTelNum=10086; @Override protected void onCreate(Bundle savedInstanceState
iOS通用連結(Universal Links)突然點選無效的解決方案
問題描述 測試告訴我,如果從微信開啟App之後,點選App右上角的應用網址之後,iOS通用連結就費了,在也用不了了,如圖: 原因分析 因為你點選右上角的網址之後,預設就把通用連結禁
【IOS】實現IOS版的抽屜效果(點選,拖拽滑動)
原文連結:http://blog.csdn.net/toss156/article/details/7400065 好像最近,看到好多Android上的抽屜效果,也忍不住想要自己寫一個。在Android裡面可以用SlidingDrawer,很方便的實現。IOS上面就只有自
android之View座標系(view獲取自身座標的方法和點選事件中座標的獲取)
在做一個view背景特效的時候被座標的各個獲取方法搞暈了,幾篇抄來抄去的部落格也沒弄很清楚。 現在把整個總結一下。 其實只要把下面這張圖看明白就沒問題了。 涉及到的方法一共有下面幾個: view獲取自身座標:getLeft(),getTop(),getRigh
百度地圖Map、Marker以及Label點選事件的區分
當我們同時為Marker和Map新增click事件後,會發現點選Marker時,不僅觸發了Marker的click事件,Map的click事件也會同時被觸發。實際上點選地圖上的任何覆蓋物都會傳遞到Map,這是因為API會將事件向上傳遞。那麼如何區分呢?在Map的