? ? ? ? ? 在過去蚓再,手機的功能都比較單調,僅僅就是用來打電話和發(fā)短信一姿。而如今七咧,手機在我們的生活中正扮演著越來越重要的角色跃惫,各種娛樂方式都可以在手機上進行。上班的路上太無聊坑雅,可以帶著耳機聽音樂辈挂。外出旅游的時候,可以在手機上看電影裹粤。無論走到哪里终蒂,遇到喜歡的事物都可以隨手拍下來。
? ? ? ? ?眾多的娛樂方式少不了強大的多媒體的支持遥诉,而Android在這方面也做得非常出色拇泣。它提供了一系列的API,使得我們可以在程序中調用很多手機的多媒體資源矮锈,從而編寫出更加豐富多彩的應用程序霉翔,本章我們就將對Android中一些常用的多媒體功能的使用進行學習。
? ? ? ? ?前面的7章內容苞笨,我們一直都是使用模擬器來運行程序的债朵,不過本章涉及的一些功能必須要在真正手機上運行程序。
8.1 ?將程序運行到手機上
? ? ? ? 不必我多說瀑凝,首先你需要擁有一部Android手機序芦,現在Android手機早就不是什么稀罕物,機會已 經是人手一部了粤咪,如果你還沒有的話谚中,趕緊去購買吧!
? ? ? ? ?想要將程序運行在手機上寥枝,我們需要先通過數據先把手機連接到電腦上宪塔。然后進入到設置----->開發(fā)者選項界面,并在這個界面中勾選中進行USB調試囊拜,如圖8.1所示:
? ? ? ? ? 注意從Android4.2系統開始某筐,開發(fā)者選項默認是隱藏的,你需要先進入到“關于手機”界面艾疟,然后對著最下面的版本號那一欄連續(xù)點擊来吩,就會讓開發(fā)者顯示出來。
? ? ? ? ? 然后如果你使用的Windows操作系統蔽莱,安裝完成后就可以看到手機已經連接到電腦上了弟疆,如圖8.2所示:
? ? ? ? ? 現在觀察Android Monitor,你會發(fā)現當前是有兩個設備在線的盗冷,一個是我們一直使用的模擬器怠苔,另一個則是剛剛連接上的手機了,如圖8.3所示仪糖。
? ? ? ? ?然后運行一下當前項目柑司,這時不會直接將程序運行到模擬器或者手機上迫肖,而是會彈出一個對話框讓你進行選擇,如圖8.4所示:
? ? ? ? ?選中下面的LGE Nexus 5 后點擊ok攒驰,就會將程序運行到手機上蟆湖。
8.2 ?使用通知
? ? ? ? 通知(Notification)是Android系統中比較有特色的一個功能,當某個應用程序希望向用戶發(fā)出一些提示信息玻粪,而該應用程序又不在前臺運行時隅津,就可以借助通知來實現。發(fā)出一條通知后劲室,手機最上方的狀態(tài)欄中會顯示一個通知的圖標伦仍,下拉狀態(tài)欄后可以看到通知的詳細內容。Android的通知功能獲得了大量用戶的認可和喜愛很洋,就連IOS也是5.0版本之后加入了類似的功能充蓝。
8.2.1 ? ? ?通知的基本用法
? ? ? ? ?了解了通知的基本概念,下面我們就來看一下通知的使用方法吧喉磁,通知的用法還是比較靈活的谓苟,既可以在活動里創(chuàng)建,也可以在廣播接收器里創(chuàng)建协怒,當然還可以在下一章中我們將學習的服務里創(chuàng)建娜谊。相比于廣播接收器和服務,在活動里創(chuàng)建通知的場景還是比較少的斤讥,因為一般只有當程序進入到后臺的時候我們才需要使用通知。
不過湾趾,無論是在哪里創(chuàng)建通知芭商,整體的步驟都是相同的,下面我們就來學習一下創(chuàng)建通知的詳細步驟搀缠。首先需要一個NotificationManager來對通知進行管理铛楣,可以通過調用Context的getSystemService()方法獲取到。getSystemService()方法接收一個字符串參數用于確定回去系統的那個服務艺普,這里我們傳入Context.NOTIFICATION_SERVICE即可簸州。因此,獲取
NotificationManager的實例就可以寫成:
? ? ? ? ?接下來需要使用一個Builder構造器來創(chuàng)建Notification對象歧譬,但問題在于岸浑,幾乎Android系統的每一個版本都會對通知這部分功能進行或多或少的修改,API不穩(wěn)定性問題在通知上顯得尤其嚴重瑰步。那么該如何解決這個問題啦矢洲?其實解決方案我們之前已經加過好幾回了,就是使用support庫中提供兼容API缩焦。support-v4庫中人提供了一個NotificationCompat類读虏,使用這個類的構造器來創(chuàng)建Notification對象责静,就可以保證我們的程序在所有Android系統版本上都能正常工作了,代碼如下所示:
? ? ? ? ?當然盖桥,上述代碼只是創(chuàng)建了一個空的Notification對象灾螃,并沒有什么實際作用,我們可以在最終的buidle()方法之前連綴任意多個設置方法來創(chuàng)建一個豐富的Notification對象揩徊,先來看一些最基礎的設置:
? ? ? ? ?上述代碼中一共調用了5各設置方法腰鬼,下面來一一解析一下。setContentTitle()方法用于指定通知的標題內容靴拱,下拉系統狀態(tài)就可以看到這部分內容垃喊。setContentText()方法用于指定通知的正文內容,同樣下拉系統狀態(tài)欄就可以看到這部分內容袜炕。setWhen()方法用于指定通知被創(chuàng)建的時間本谜,以毫秒為單位,當下拉系統狀態(tài)欄時這里指定的時間會顯示在相應的通知上偎窘。setSmallIcon方法用于設置通知的小圖標乌助,注意只能使用純alpha圖層的圖片進行設置,小圖標會顯示在系統狀態(tài)欄上陌知。setLargeIcon()方法用于設置通知的大圖標他托,當下拉系統狀態(tài)欄時,就可以看到設置的大圖標了仆葡。
? ? ? ? ?以上工作都完成之后赏参,只需要調用NotificationManager的notify()方法就可以讓通知顯示出來了。notify()方法接受兩個參數沿盅,第一個參數是id把篓,要保證為每個同志所指定的id都是不同的。第二個參數則是Notification對象腰涧,這里直接將我們剛剛創(chuàng)建好的Notification對象傳入即可韧掩。因此,顯示一個通知就可以寫成:
? ? ? ? ? manager.notify(1窖铡,notification)疗锐;
? ? ? ? ? 到這里就已經把創(chuàng)建通知的每一個步驟都解析完了,下面就讓我們通過一個具體的例子來看一看通知到底是長什么樣的费彼。
新建一個Notification項目滑臊,并修改acyivity_main.xml中的代碼,如下所示:
? ? ? ? ?可以看到敌买,我們在點擊按鈕的點擊事件里面完成了通知的創(chuàng)建工作简珠,創(chuàng)建的過程正如前面描述所描述的一樣。不過這里簡單起見,我將通知欄的大小圖都直接設置成了ic_launcher這張圖聋庵,這樣就不用再去專門準備圖標了膘融,而在實際項目中千萬不要這樣偷懶。
? ? ? ? 現在可以運行一下程序了祭玉,點擊按鈕氧映,你會在系統狀態(tài)欄最左邊看到一個小圖標,如圖8.5所示脱货。
? ? ? ? ?下拉系統狀態(tài)欄可以看到該通知的詳細信息岛都,如圖8.6所示。
? ? ? ? ?如果你是用過Android手機振峻,此時應該會下意識的認為這條通知是可以點擊的臼疫。但是當你去點擊它的時候,你會發(fā)現需要在代碼中進行相應的設置扣孟,這就涉及到了一個新的概念烫堤。PendingItent。
? ? ? ? ?PendingItent從名字上看起來和Intent有些類似凤价,他們之間也確實存在著不小共同點鸽斟。比如他們都可以去指明某一個“意圖”,都可以用于啟動活動利诺、啟動服務以及發(fā)送廣播等富蓄。不同的是Intent更傾向于去立即執(zhí)行某個動作,而PendingItent更傾向于在某個合適的時候去執(zhí)行某個動作慢逾。所以立倍,也可以把PendingItent簡單理解為延遲執(zhí)行的Intent。
? ? ? ? ?PendingItent的用法同樣很簡單侣滩,他主要提供了幾個靜態(tài)方法用于獲取PendingIntent的實例帐萎,可以根據需求來選擇是使用getActivity()方法、getBroadcast()方法胜卤,還是getService()方法。這幾個方法所接收的參數都是相同的赁项,第一個參數依舊是Context葛躏,不用多解釋。第二個參數一般用不到悠菜,通常傳入0即可舰攒。第三個參數是Intent對象。我們可以通過這個對象構建出PendingItent的“意圖”悔醋,第四個參數用于確定PendingItent的行為摩窃,有FLAG_ONE_SHOT、FLAG_NO_CREATE、FlAG_CANCEL_CURRENT和FLAG_UPDATE_CURRENT這四種值可以選猾愿,沒種值的具體含義你可以查看文檔鹦聪,通常情況下這個參數傳入0就可以了。
? ? ? ? ? 對PendingItent有一定了解后蒂秘,我們再回過頭來看一下NotificationCompat.Builder泽本。這個構造期還可以在連綴一個SetContentIntent方法,接收的參數正是一個PendingItent對象姻僧。因此规丽,這里就可以通過PendingItent構建出一個延遲執(zhí)行的“意圖”,當用戶點擊這條通知時就會執(zhí)行相應的邏輯撇贺。
? ? ? ? ? 現在我們來優(yōu)化一下NotificationTest項目赌莺,給剛才通知加上點擊功能,讓用戶點擊它的時候可以啟動另一個活動松嘶。
? ? ? ? ? 首先需要準備好另一個活動艘狭,右擊com.example.notificationtest包----->Activity------->EmptyActivity,新建NotificationActivity喘蟆,布局名為notification_layout缓升。然后修改notification_layout.xml中的代碼。如下所示:
? ? ? ? ? ?這樣就把NotificationActivity這個活動準備好了蕴轨,下面我們修改MainActivity中的代碼港谊,給通知加入點擊功能如圖所示:(手動創(chuàng)建點擊通知跳轉)
? ? ? ? ?可以看到,這里先是使用Intent表達出我們想要啟動NotificationActivity的“意圖”橙弱,然后間構建好的Intent對象傳入到PendingIntent的getActivity方法里歧寺,已得到pendingIntent的實例,接著在NotificationCompat.Builder中調用setContenIntent()方法棘脐,把它作為參數傳入即可斜筐。
? ? ? ? ?現在重新運行以下程序,并點擊按鈕蛀缝,有就會發(fā)出一條通知顷链。然后下拉系統狀態(tài)欄,點擊一下該通知屈梁,就會看到NotificationActivity這個活動界面了嗤练,如圖8.7所示。
? ? ? ? ?咦在讶?怎么系統狀態(tài)上的通知圖標還沒有消失啦煞抬?是這樣的,如果我們沒有在代碼中對該通知進行取消构哺,他就會一直顯示在系統的狀態(tài)欄上革答。解決的方法有兩種,一種是在NotificationCompat.Builder中再連綴一個setAutoCancel()方法,一種是現實地調用NotificationManager的cancel()方法將它取消残拐,兩種方法我們都來學習一下途茫。
? ? ? ? 第一種方法寫法如下:
? ? ? ? ?可以看到,setAutoCancel()方法傳入true蹦骑,就表示當點擊了這個通知的時候慈省,通知會自動取消掉仔掸。
? ? ? ? ?第二種方法寫法如下:
? ? ? ? ? 這里我們在Cancel()方法中傳入了1洼哎,這里是什么意思啦?還記得在創(chuàng)建通知的時候給每條通知指定的id嗎叮称?當時我們給這條通知設置的id就是1.因此捎废,如果你想取消那條通知笑窜,在cancel()方法中傳入該通知的id就行了。
8.2.2 通知的進階技巧
? ? ? ? ?現在你已經掌握了創(chuàng)建和取消的方法了登疗,并且知道了如何去響應通知的點擊事件排截。不過通知的用法并不僅僅是這些啦,下面我們就來探究一下通知的更多技巧辐益。
? ? ? ? ?上一小節(jié)中創(chuàng)建的通知屬于最基本的通知断傲,實際上,NotificationCompat.Builder中提供了非常豐富的API來讓我們創(chuàng)建出更加多樣的通知效果智政。當然认罩,每一個API都詳細的講一遍都不太可能,我們只能從中選一些比較常用的API來進行學習续捂。先來看看setSound()方法吧垦垂,它可以再通知發(fā)出的時候播放一段音頻,這樣就可以告訴用戶通知到來了牙瓢。setSound()方法接收一個Uri參數劫拗,所以在指定音頻文件的時候還需要先獲取到音頻文件對應的URI。比如說矾克,每個手機的/system/media/audio/ringtones目錄下都有很多的音頻文件页慷,我們可以從中隨便選一個音頻文件,那么我們在代碼中就可以這樣指定:
? ? ? ? ? ?除了允許播放音頻外胁附,我們還可以在通知到來的時候讓手機進行震動差购,使用的是vibrate這個屬性。它是一個長整型的數組汉嗽,用于設置手機靜止和振動的時長,以毫秒為單位找蜜。下標為0的值表示手機靜止的時長饼暑,下標為1的值表示手機震動的時長,下標為2的值又表示手機靜止的時長,以此類推弓叛。所以彰居,如果想要讓手機再通知到來的時候立刻振動1秒,然后靜止1秒撰筷,再振動1秒陈惰,代碼就可以寫成:
不過,想要控制手機振動還需要申明權限毕籽。因此還得在AndroidManifest.xml文件加入如下聲明:
學會了控制通知的聲音和振動抬闯,下面我們來看一下如何再通知來到時控制手機LED燈的顯示。