【Android】Notification的使用及無法更改largeIcon問題

1.Notification的使用

??Notification的創(chuàng)建使用建造者模式踱侣,通過Builder構(gòu)造器來創(chuàng)建Notification對(duì)象,并通過NotificationManager來對(duì)Notification進(jìn)行管理
??但是由于android各個(gè)版本對(duì)這個(gè)功能有部分的修改探膊,因此我們最好使用support-v7庫中提供的NotificationCompat類待榔,使用這個(gè)類的Builder構(gòu)造器來構(gòu)建Notification就能解決不同版本android系統(tǒng)的兼容問題

//通過Context獲取到NotificationManager 
NotificationManager manager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);

//構(gòu)建PendingIntent
//第一個(gè)參數(shù)為Context
//第二個(gè)參數(shù)為requestCode,類似于startActivityForResult()中的requestCode吧(不確定)
//第三個(gè)傳入Intent腌闯,表示觸發(fā)時(shí)要做的行為
//第四個(gè)參數(shù)則用于確定PendingIntent的模式雕憔,有FLAG_ONE_SHOT、FLAG_NO_CREATE 分瘦、FLAG_CANCEL_CURRENT琉苇、FLAG_UPDATE_CURRENT等4個(gè)值可選
Intent intent = new Intent(this, NofiticationActivity.class);
PendingIntent pi = PendingIntent.getActivity(this, 0, intent, FLAG_UPDATE_CURRENT);

//通過NotificationCompat.Builder(Context context)構(gòu)建Notification,使用build()獲取到Notification實(shí)例
Notification notification= new NotificationCompat.Builder(MainActivity.this)
                        .setLargeIcon(BitmapFactory.decodeResource(MainActivity.this.getResources(), R.mipmap.icon_spring_festival_logo))
                        .setSmallIcon(R.mipmap.icon_main_app_small_logo)
                        .setContentTitle("通知")// 設(shè)置在下拉status
                        .setContentText("這是一條通知")// TextView中顯示的詳細(xì)內(nèi)容
                        .setContentIntent(mPendingIntent) // 關(guān)聯(lián)PendingIntent
                        .setNumber(pushBean.id) // 在TextView的右方顯示的數(shù)字,可放大圖片看拜马,在最右側(cè)沐绒。這個(gè)number同時(shí)也起到一個(gè)序列號(hào)的左右,如果多個(gè)觸發(fā)多個(gè)通知(同一ID)扮超,可以指定顯示哪一個(gè)
                        .setAutoCancel(true) //設(shè)置是否點(diǎn)擊后通知自動(dòng)消失蹋肮,也可以手動(dòng)調(diào)用manager.cancel(id),id對(duì)應(yīng)后面每個(gè)通知所指定的id
                        //進(jìn)階功能
                        //.setSound(Uri.parse("android.resource://" + packageName + File.separator + R.raw.ring_6))
                        .setSound(Uri.fromFile(new File("/system/media/audio/ringtones/Luna.ogg"))) //設(shè)置聲音
                        .setVibrate(new long[]{0, 1000, 1000, 1000})//設(shè)置震動(dòng),手機(jī)靜止時(shí)長(zhǎng)-振動(dòng)時(shí)長(zhǎng)-靜止時(shí)長(zhǎng)-震動(dòng)時(shí)長(zhǎng)....(以此類推)
                        .setLights(Color.GREEN, 1000, 1000) //設(shè)置LED燈的顏色馁龟、亮起時(shí)長(zhǎng)漆魔、暗去時(shí)長(zhǎng)
                        //.setDefaults(android.support.v7.app.NotificationCompat.DEFAULT_ALL)  //設(shè)置默認(rèn)模式却音,自動(dòng)選擇聲音矢炼、震動(dòng)句灌、燈光
                        .build();
//發(fā)出通知
manager.notify(id, notification); //第一個(gè)參數(shù)為id,要保證每個(gè)通知所指定的id都是不同的

關(guān)于Notification的largeIcon無法更改的問題

??在項(xiàng)目中我需要通過后臺(tái)傳入的url來加載通知的消息欄圖片涯塔,于是我的demo如下

package com.sfexpress.testnotificationloadpicure;

import android.app.Notification;
import android.app.NotificationManager;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.app.NotificationCompat;
import android.view.View;
import android.widget.Button;

import rx.Subscriber;
import rx.functions.Func1;

public class MainActivity extends AppCompatActivity {

    private Button btn_show_notification;

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

        final String url = "http://b.hiphotos.baidu.com/zhidao/pic/item/a6efce1b9d16fdfafee0cfb5b68f8c5495ee7bd8.jpg";
        btn_show_notification = (Button) findViewById(R.id.show_notification);
        btn_show_notification.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                long when = System.currentTimeMillis();
                final NotificationManager manager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);


                int requestCode = 1;
                try {
                    requestCode = (int) when;
                } catch (Exception e) {
                    //不處理
                }
                final Notification notification = new NotificationCompat.Builder(MainActivity.this)

                        //在這里設(shè)置默認(rèn)的largeIcon
                        .setLargeIcon(BitmapFactory.decodeResource(MainActivity.this.getResources(), R.mipmap.icon_spring_festival_logo))  

                        .setSmallIcon(R.mipmap.icon_main_app_small_logo)
                        .setContentTitle("通知")
                        .setContentText("這是一條通知")
                        .build();

                final int requestCodeInner = requestCode;
                rx.Observable.just(url)
                        .map(new Func1<String, Bitmap>() {
                            @Override
                            public Bitmap call(String url) {
                                //根據(jù)url對(duì)圖片進(jìn)行加載爹谭,并裁剪為192 X 192的尺寸
                                ImageLoader imageLoader = ImageLoader.build(MainActivity.this);
                                return imageLoader.loadBitmap(url,192, 192);
                            }
                        })
                        .compose(RxUtils.<Bitmap>applySchedulers())
                        .subscribe(new Subscriber<Bitmap>() {
                            @Override
                            public void onCompleted() {
                                //空實(shí)現(xiàn)
                            }

                            @Override
                            public void onError(Throwable e) {
                                //空實(shí)現(xiàn)
                            }

                            @Override
                            public void onNext(Bitmap bitmap) {
                                if(bitmap != null){
                                    //將bitmap設(shè)置到notification當(dāng)中
                                    notification.largeIcon = bitmap;
                                }
                                manager.notify(requestCodeInner, notification);
                            }
                        });

            }
        });
    }
}

??程序運(yùn)行的結(jié)果是largeIcon仍然顯示為我在構(gòu)建notification時(shí)的默認(rèn)icon诺凡,而不是通過網(wǎng)絡(luò)url加載的icon践惑。
??剛開始我以為是因?yàn)槟涿麅?nèi)部類導(dǎo)致外部Notification對(duì)象必須定義為final而導(dǎo)致不可修改,但是我們知道final在修飾一個(gè)對(duì)象的時(shí)候只是會(huì)使這個(gè)對(duì)象始終指向同一個(gè)地址凉袱,而不會(huì)限制對(duì)象中成員變量的修改侦铜。
??因此我嘗試對(duì)程序打斷點(diǎn),結(jié)果發(fā)現(xiàn)涤躲,在最后調(diào)用manager.notify()的時(shí)候贡未,notification中的largeIcon實(shí)際上已經(jīng)被替換為了新加載的bitmap,因此我猜測(cè)在Builder構(gòu)建的時(shí)候設(shè)置LargeIcon會(huì)將其設(shè)置到一個(gè)map當(dāng)中俊卤,在manager.notify()的時(shí)候會(huì)優(yōu)先從map中進(jìn)行取值消恍,為空才會(huì)查詢notification的largeIcon字段,因此這種方式無法成功加載網(wǎng)絡(luò)圖片哺哼,那么解決方案就有兩種:

  • 第一種方案:在Builder構(gòu)建notification的時(shí)候不設(shè)置largeIcon,但是這種方式不優(yōu)雅
  • 第二種方案: Builder構(gòu)建notification時(shí)不直接調(diào)用build獲取Notificaition實(shí)例,而是在manager.notify()調(diào)用前再調(diào)用build()方法棍苹,下面使用這種方案
package com.sfexpress.testnotificationloadpicure;

import android.app.Notification;
import android.app.NotificationManager;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.app.NotificationCompat;
import android.view.View;
import android.widget.Button;

import rx.Subscriber;
import rx.functions.Func1;

public class MainActivity extends AppCompatActivity {

    private Button btn_show_notification;

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

        final String url = "http://b.hiphotos.baidu.com/zhidao/pic/item/a6efce1b9d16fdfafee0cfb5b68f8c5495ee7bd8.jpg";
        btn_show_notification = (Button) findViewById(R.id.show_notification);
        btn_show_notification.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                long when = System.currentTimeMillis();
                final NotificationManager manager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);


                int requestCode = 1;
                try {
                    requestCode = (int) when;
                } catch (Exception e) {
                    //不處理
                }

                //獲取到Builder對(duì)象
                final NotificationCompat.Builder builder = new NotificationCompat.Builder(MainActivity.this);
                //給Builder對(duì)象設(shè)置默認(rèn)屬性
                builder.setLargeIcon(BitmapFactory.decodeResource(MainActivity.this.getResources(), R.mipmap.icon_spring_festival_logo))
                        .setSmallIcon(R.mipmap.icon_main_app_small_logo)
                        .setContentTitle("通知")// 設(shè)置在下拉status
                        .setContentText("這是一條通知")// TextView中顯示的詳細(xì)內(nèi)容
                        .setWhen(when);


                final int requestCodeInner = requestCode;
                rx.Observable.just(url)
                        .map(new Func1<String, Bitmap>() {
                            @Override
                            public Bitmap call(String url) {
                                ImageLoader imageLoader = ImageLoader.build(MainActivity.this);
                                return imageLoader.loadBitmap(url,192, 192);
                            }
                        })
                        .compose(RxUtils.<Bitmap>applySchedulers())
                        .subscribe(new Subscriber<Bitmap>() {
                            @Override
                            public void onCompleted() {
                                //空實(shí)現(xiàn)
                            }

                            @Override
                            public void onError(Throwable e) {
                                //空實(shí)現(xiàn)
                            }

                            @Override
                            public void onNext(Bitmap bitmap) {
                                if(bitmap != null){
                                    builder.setLargeIcon(bitmap);
                                }
                                //在notify()調(diào)用前通過builder方法獲取Notification實(shí)例并作為參數(shù)傳入notify()方法
                                manager.notify(requestCodeInner, builder.build());
                            }
                        });

            }
        });
    }
}

??以這種方案實(shí)現(xiàn)就能夠更加輕松的將notificaiton的通用構(gòu)造過程封裝起來,僅返回一個(gè)Builder對(duì)象栏豺,然后通過操作Builder對(duì)象對(duì)Notification進(jìn)行個(gè)性化設(shè)置

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末奥洼,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子灵奖,更是在濱河造成了極大的恐慌,老刑警劉巖骡尽,帶你破解...
    沈念sama閱讀 216,372評(píng)論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件攀细,死亡現(xiàn)場(chǎng)離奇詭異爱态,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)肢藐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門吆豹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來理盆,“玉大人,你說我怎么就攤上這事猿规。” “怎么了蘸拔?”我有些...
    開封第一講書人閱讀 162,415評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)宝冕。 經(jīng)常有香客問我邓萨,道長(zhǎng),這世上最難降的妖魔是什么宝剖? 我笑而不...
    開封第一講書人閱讀 58,157評(píng)論 1 292
  • 正文 為了忘掉前任歉甚,我火速辦了婚禮,結(jié)果婚禮上雅镊,老公的妹妹穿的比我還像新娘刃滓。我一直安慰自己,他們只是感情好咧虎,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評(píng)論 6 388
  • 文/花漫 我一把揭開白布砰诵。 她就那樣靜靜地躺著,像睡著了一般茁彭。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上摄闸,一...
    開封第一講書人閱讀 51,125評(píng)論 1 297
  • 那天妹萨,我揣著相機(jī)與錄音,去河邊找鬼熏兄。 笑死,一個(gè)胖子當(dāng)著我的面吹牛摩桶,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播岛宦,決...
    沈念sama閱讀 40,028評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼耍缴,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了防嗡?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤裙盾,失蹤者是張志新(化名)和其女友劉穎他嫡,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體钢属,經(jīng)...
    沈念sama閱讀 45,310評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡淆党,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了山孔。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片荷憋。...
    茶點(diǎn)故事閱讀 39,690評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖串前,靈堂內(nèi)的尸體忽然破棺而出锅铅,到底是詐尸還是另有隱情减宣,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評(píng)論 5 343
  • 正文 年R本政府宣布贼邓,位于F島的核電站,受9級(jí)特大地震影響塑径,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜匆骗,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評(píng)論 3 325
  • 文/蒙蒙 一誉简、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧瓮钥,春花似錦烹吵、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至跃惫,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間爆存,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評(píng)論 1 268
  • 我被黑心中介騙來泰國(guó)打工携冤, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留闲勺,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,693評(píng)論 2 368
  • 正文 我出身青樓翘地,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親昧穿。 傳聞我的和親對(duì)象是個(gè)殘疾皇子橙喘,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評(píng)論 2 353