Android设计和开发系列第一篇:Notifications通知(Develop—Training)
2015-02-27 16:01
519 查看
Develop篇
BuildingaNotification
THISLESSONTEACHESYOUTO
YOUSHOULDALSOREAD
Thislessonexplainshowtocreateandissueanotification.
Theexamplesinthisclassarebasedonthe
class.NotificationCompat.Builder
isintheNotificationCompat.Builder
anditssubclasses,particularlyNotificationCompat
,toprovidethebestnotificationsupportforawiderangeofplatforms.NotificationCompat.Builder
CreateaNotificationBuilder
Whencreatinganotification,specifytheUIcontentandactionswithaobject.Atbareminimum,aNotificationCompat.Builder
objectmustincludethefollowing:Builder
Asmallicon,setby
setSmallIcon()
Atitle,setby
setContentTitle()
Detailtext,setby
setContentText()
Forexample:
NotificationCompat.BuildermBuilder= newNotificationCompat.Builder(this) .setSmallIcon(R.drawable.notification_icon) .setContentTitle("Mynotification") .setContentText("HelloWorld!");
DefinetheNotification'sAction
Althoughactionsareoptional,youshouldaddatleastoneactiontoyournotification.Anactiontakesusersdirectlyfromthenotificationtoaninyourapplication,wheretheycanlookattheeventthatcausedthenotificationordofurtherwork.Insideanotification,theactionitselfisdefinedbyaActivity
containinganPendingIntent
thatstartsanIntent
inyourapplication.Activity
Howyouconstructthe
dependsonwhattypeofPendingIntent
you'restarting.WhenyoustartanActivity
fromanotification,youmustpreservetheuser'sexpectednavigationexperience.Inthesnippetbelow,clickingthenotificationopensanewactivitythateffectivelyextendsthebehaviorofthenotification.Inthiscasethereisnoneedtocreateanartificialbackstack(seeActivity
IntentresultIntent=newIntent(this,ResultActivity.class); ... //Becauseclickingthenotificationopensanew("special")activity,there's //noneedtocreateanartificialbackstack. PendingIntentresultPendingIntent= PendingIntent.getActivity( this, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT );
SettheNotification'sClickBehavior
Toassociatethecreatedinthepreviousstepwithagesture,calltheappropriatemethodofPendingIntent
.Forexample,tostartanactivitywhentheuserclicksthenotificationtextinthenotificationdrawer,addtheNotificationCompat.Builder
bycallingPendingIntent
.Forexample:setContentIntent()
PendingIntentresultPendingIntent; ... mBuilder.setContentIntent(resultPendingIntent);
IssuetheNotification
Toissuethenotification:Getaninstanceof
.NotificationManager
Usethe
methodtoissuethenotification.Whenyoucallnotify()
,specifyanotificationID.YoucanusethisIDtoupdatethenotificationlateron.Thisisdescribedinmoredetailinnotify()
Call
,whichreturnsabuild()
objectcontainingyourspecifications.Notification
Forexample:
NotificationCompat.BuildermBuilder; ... //SetsanIDforthenotification intmNotificationId=001; //GetsaninstanceoftheNotificationManagerservice NotificationManagermNotifyMgr= (NotificationManager)getSystemService(NOTIFICATION_SERVICE); //Buildsthenotificationandissuesit. mNotifyMgr.notify(mNotificationId,mBuilder.build());
PreservingNavigationwhenStartinganActivity
THISLESSONTEACHESYOUTO
YOUSHOULDALSOREAD
Partofdesigninganotificationispreservingtheuser'sexpectednavigationexperience.Foradetaileddiscussionofthistopic,seethe
RegularactivityYou'restartingan
that'spartoftheapplication'snormalworkflow.SpecialactivityTheuseronlyseesthisActivity
ifit'sstartedfromanotification.Inasense,theActivity
extendsthenotificationbyprovidinginformationthatwouldbehardtodisplayinthenotificationitself.Activity
SetUpaRegularActivityPendingIntent
TosetupathatstartsadirectentryPendingIntent
,followthesesteps:Activity
Defineyourapplication's
hierarchyinthemanifest.ThefinalXMLshouldlooklikethis:Activity
<activity android:name=".MainActivity" android:label="@string/app_name"> <intent-filter> <actionandroid:name="android.intent.action.MAIN"/> <categoryandroid:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <activity android:name=".ResultActivity" android:parentActivityName=".MainActivity"> <meta-data android:name="android.support.PARENT_ACTIVITY" android:value=".MainActivity"/> </activity>
Createabackstackbasedonthe
thatstartstheIntent
.Forexample:Activity
intid=1; ... IntentresultIntent=newIntent(this,ResultActivity.class); TaskStackBuilderstackBuilder=TaskStackBuilder.create(this); //Addsthebackstack stackBuilder.addParentStack(ResultActivity.class); //AddstheIntenttothetopofthestack stackBuilder.addNextIntent(resultIntent); //GetsaPendingIntentcontainingtheentirebackstack PendingIntentresultPendingIntent= stackBuilder.getPendingIntent(0,PendingIntent.FLAG_UPDATE_CURRENT); ... NotificationCompat.Builderbuilder=newNotificationCompat.Builder(this); builder.setContentIntent(resultPendingIntent); NotificationManagermNotificationManager= (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE); mNotificationManager.notify(id,builder.build());
SetUpaSpecialActivityPendingIntent
Aspecialdoesn'tneedabackstack,soyoudon'thavetodefineitsActivity
hierarchyinthemanifest,andyoudon'thavetocallActivity
tobuildabackstack.Instead,usethemanifesttosetuptheaddParentStack()
taskoptions,andcreatetheActivity
bycallingPendingIntent
:getActivity()
Inyourmanifest,addthefollowingattributestothe
elementforthe<activity>
:Activity
Theactivity'sfully-qualifiedclassname.android:name="activityclass"
Combinedwiththeandroid:taskAffinity=""
flagthatyousetincode,thisensuresthatthisFLAG_ACTIVITY_NEW_TASK
doesn'tgointotheapplication'sdefaulttask.Anyexistingtasksthathavetheapplication'sdefaultaffinityarenotaffected.Activity
ExcludesthenewtaskfromRecents,sothattheusercan'taccidentallynavigatebacktoit.android:excludeFromRecents="true"
Thissnippetshowstheelement:
<activity android:name=".ResultActivity" ... android:launchMode="singleTask" android:taskAffinity="" android:excludeFromRecents="true"> </activity> ...
Buildandissuethenotification:
Createan
thatstartstheIntent
.Activity
Setthe
tostartinanew,emptytaskbycallingActivity
withtheflagssetFlags()
andFLAG_ACTIVITY_NEW_TASK
.FLAG_ACTIVITY_CLEAR_TASK
Setanyotheroptionsyouneedforthe
.Intent
Createa
fromthePendingIntent
bycallingIntent
.YoucanthenusethisgetActivity()
astheargumenttoPendingIntent
.setContentIntent()
Thefollowingcodesnippetdemonstratestheprocess:
//InstantiateaBuilderobject. NotificationCompat.Builderbuilder=newNotificationCompat.Builder(this); //CreatesanIntentfortheActivity IntentnotifyIntent= newIntent(newComponentName(this,ResultActivity.class)); //SetstheActivitytostartinanew,emptytask notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK| Intent.FLAG_ACTIVITY_CLEAR_TASK); //CreatesthePendingIntent PendingIntentnotifyIntent= PendingIntent.getActivity( this, 0, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT ); //PutsthePendingIntentintothenotificationbuilder builder.setContentIntent(notifyIntent); //Notificationsareissuedbysendingthemtothe //NotificationManagersystemservice. NotificationManagermNotificationManager= (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE); //BuildsananonymousNotificationobjectfromthebuilder,and //passesittotheNotificationManager mNotificationManager.notify(id,builder.build());
UpdatingNotifications
THISLESSONTEACHESYOUTO
YOUSHOULDALSOREAD
Whenyouneedtoissueanotificationmultipletimesforthesametypeofevent,youshouldavoidmakingacompletelynewnotification.Instead,youshouldconsiderupdatingapreviousnotification,eitherbychangingsomeofitsvaluesorbyaddingtoit,orboth.
Thefollowingsectiondescribeshowtoupdatenotificationsandalsohowtoremovethem.
ModifyaNotification
Tosetupanotificationsoitcanbeupdated,issueitwithanotificationIDbycalling.Toupdatethisnotificationonceyou'veissuedit,updateorcreateaNotificationManager.notify(ID,notification)
object,buildaNotificationCompat.Builder
objectfromit,andissuetheNotification
withthesameIDyouusedpreviously.Notification
Thefollowingsnippetdemonstratesanotificationthatisupdatedtoreflectthenumberofeventsthathaveoccurred.Itstacksthenotification,showingasummary:
mNotificationManager= (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE); //SetsanIDforthenotification,soitcanbeupdated intnotifyID=1; mNotifyBuilder=newNotificationCompat.Builder(this) .setContentTitle("NewMessage") .setContentText("You'vereceivednewmessages.") .setSmallIcon(R.drawable.ic_notify_status) numMessages=0; //Startofaloopthatprocessesdataandthennotifiestheuser ... mNotifyBuilder.setContentText(currentText) .setNumber(++numMessages); //BecausetheIDremainsunchanged,theexistingnotificationis //updated. mNotificationManager.notify( notifyID, mNotifyBuilder.build()); ...
RemoveNotifications
Notificationsremainvisibleuntiloneofthefollowinghappens:Theuserdismissesthenotificationeitherindividuallyorbyusing"ClearAll"(ifthenotificationcanbecleared).
Theusertouchesthenotification,andyoucalled
whenyoucreatedthenotification.setAutoCancel()
Youcall
foraspecificnotificationID.Thismethodalsodeletesongoingnotifications.cancel()
Youcall
,whichremovesallofthenotificationsyoupreviouslyissued.cancelAll()
UsingBigViewStyles
THISLESSONTEACHESYOUTO
YOUSHOULDALSOREAD
Notificationsinthenotificationdrawerappearintwomainvisualstyles,normalviewandbigview.Thebigviewofanotificationonlyappearswhenthenotificationisexpanded.Thishappenswhenthenotificationisatthetopofthedrawer,ortheuserclicksthenotification.
BigviewswereintroducedinAndroid4.1,andthey'renotsupportedonolderdevices.Thislessondescribeshowtoincorporatebigviewnotificationsintoyourappwhilestillprovidingfullfunctionalityviathenormalview.Seethe
Hereisanexampleofanormalview:
Figure1.Normalviewnotification.
Hereisanexampleofabigview:
Figure2.Bigviewnotification.
Inthesampleapplicationshowninthislesson,boththenormalviewandthebigviewgiveusersaccesstosamefunctionality:
Theabilitytosnoozeordismissthenotification.
Awaytoviewtheremindertexttheusersetaspartofthetimer.
Thenormalviewprovidesthesefeaturesthroughanewactivitythatlauncheswhentheuserclicksthenotification.Keepthisinmindasyoudesignyournotifications—firstprovidethefunctionalityinthenormalview,sincethisishowmanyuserswillinteractwiththenotification.
SetUptheNotificationtoLaunchaNewActivity
Thesampleapplicationusesansubclass(IntentService
PingService)toconstructandissuethenotification.
Inthissnippet,the
methodIntentService
specifiesthenewactivitythatwillbelaunchediftheuserclicksthenotificationitself.ThemethodonHandleIntent()
definesapendingintentthatshouldbefiredwhentheuserclicksthenotification,therebylaunchingtheactivity.setContentIntent()
IntentresultIntent=newIntent(this,ResultActivity.class); resultIntent.putExtra(CommonConstants.EXTRA_MESSAGE,msg); resultIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK| Intent.FLAG_ACTIVITY_CLEAR_TASK); //Becauseclickingthenotificationlaunchesanew("special")activity, //there'snoneedtocreateanartificialbackstack. PendingIntentresultPendingIntent= PendingIntent.getActivity( this, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT ); //Thissetsthependingintentthatshouldbefiredwhentheuserclicksthe //notification.Clickingthenotificationlaunchesanewactivity. builder.setContentIntent(resultPendingIntent);
ConstructtheBigView
Thissnippetshowshowtosetupthebuttonsthatwillappearinthebigview://SetsuptheSnoozeandDismissactionbuttonsthatwillappearinthe //bigviewofthenotification. IntentdismissIntent=newIntent(this,PingService.class); dismissIntent.setAction(CommonConstants.ACTION_DISMISS); PendingIntentpiDismiss=PendingIntent.getService(this,0,dismissIntent,0); IntentsnoozeIntent=newIntent(this,PingService.class); snoozeIntent.setAction(CommonConstants.ACTION_SNOOZE); PendingIntentpiSnooze=PendingIntent.getService(this,0,snoozeIntent,0);
Thissnippetshowshowtoconstructthe
object.Itsetsthestyleforthebigviewtobe"bigtext,"andsetsitscontenttobetheremindermessage.ItusesBuilder
toaddtheSnoozeandDismissbuttons(andtheirassociatedpendingintents)thatwillappearinthenotification'sbigview:addAction()
//ConstructstheBuilderobject. NotificationCompat.Builderbuilder= newNotificationCompat.Builder(this) .setSmallIcon(R.drawable.ic_stat_notification) .setContentTitle(getString(R.string.notification)) .setContentText(getString(R.string.ping)) .setDefaults(Notification.DEFAULT_ALL)//requiresVIBRATEpermission /* *Setsthebigview"bigtext"styleandsuppliesthe *text(theuser'sremindermessage)thatwillbedisplayed *inthedetailareaoftheexpandednotification. *Thesecallsareignoredbythesupportlibraryfor *pre-4.1devices. */ .setStyle(newNotificationCompat.BigTextStyle() .bigText(msg)) .addAction(R.drawable.ic_stat_dismiss, getString(R.string.dismiss),piDismiss) .addAction(R.drawable.ic_stat_snooze, getString(R.string.snooze),piSnooze);
DisplayingProgressinaNotification
THISLESSONTEACHESYOUTO
YOUSHOULDALSOREAD
Notificationscanincludeananimatedprogressindicatorthatshowsusersthestatusofanongoingoperation.Ifyoucanestimatehowlongtheoperationtakesandhowmuchofitiscompleteatanytime,usethe"determinate"formoftheindicator(aprogressbar).Ifyoucan'testimatethelengthoftheoperation,usethe"indeterminate"formoftheindicator(anactivityindicator).
Progressindicatorsaredisplayedwiththeplatform'simplementationofthe
class.ProgressBar
Touseaprogressindicator,call
.Thedeterminateandindeterminateformsaredescribedinthefollowingsections.setProgress()
DisplayaFixed-durationProgressIndicator
Todisplayadeterminateprogressbar,addthebartoyournotificationbycallingandthenissuethenotification.Thethirdargumentisabooleanthatindicateswhethertheprogressbarisindeterminate(true)ordeterminate(false).Asyouroperationproceeds,incrementsetProgress(max,progress,false)
progress,andupdatethenotification.Attheendoftheoperation,
progressshouldequal
max.Acommonwaytocall
istosetsetProgress()
maxto100andthenincrement
progressasa"percentcomplete"valuefortheoperation.
Youcaneitherleavetheprogressbarshowingwhentheoperationisdone,orremoveit.Ineithercase,remembertoupdatethenotificationtexttoshowthattheoperationiscomplete.Toremovetheprogressbar,call
.Forexample:setProgress(0,0,false)
intid=1; ... mNotifyManager= (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE); mBuilder=newNotificationCompat.Builder(this); mBuilder.setContentTitle("PictureDownload") .setContentText("Downloadinprogress") .setSmallIcon(R.drawable.ic_notification); //Startalengthyoperationinabackgroundthread newThread( newRunnable(){ @Override publicvoidrun(){ intincr; //Dothe"lengthy"operation20times for(incr=0;incr<=100;incr+=5){ //Setstheprogressindicatortoamaxvalue,the //currentcompletionpercentage,and"determinate" //state mBuilder.setProgress(100,incr,false); //Displaystheprogressbarforthefirsttime. mNotifyManager.notify(id,mBuilder.build()); //Sleepsthethread,simulatinganoperation //thattakestime try{ //Sleepfor5seconds Thread.sleep(5*1000); }catch(InterruptedExceptione){ Log.d(TAG,"sleepfailure"); } } //Whentheloopisfinished,updatesthenotification mBuilder.setContentText("Downloadcomplete") //Removestheprogressbar .setProgress(0,0,false); mNotifyManager.notify(id,mBuilder.build()); } } //Startsthethreadbycallingtherun()methodinitsRunnable ).start();
Theresultingnotificationsareshowninfigure1.Ontheleftsideisasnapshotofthenotificationduringtheoperation;ontherightsideisasnapshotofitaftertheoperationhasfinished.
Figure1.Theprogressbarduringandaftertheoperation.
DisplayaContinuingActivityIndicator
Todisplayacontinuing(indeterminate)activityindicator,addittoyournotificationwithandissuethenotification.Thefirsttwoargumentsareignored,andthethirdargumentdeclaresthattheindicatorisindeterminate.Theresultisanindicatorthathasthesamestyleasaprogressbar,exceptthatitsanimationisongoing.setProgress(0,0,true)
Issuethenotificationatthebeginningoftheoperation.Theanimationwillrununtilyoumodifyyournotification.Whentheoperationisdone,call
andthenupdatethenotificationtoremovetheactivityindicator.Alwaysdothis;otherwise,theanimationwillrunevenwhentheoperationiscomplete.Alsoremembertochangethenotificationtexttoindicatethattheoperationiscomplete.setProgress(0,0,false)
Toseehowcontinuingactivityindicatorswork,refertotheprecedingsnippet.Locatethefollowinglines:
//Setstheprogressindicatortoamaxvalue,thecurrentcompletion //percentage,and"determinate"state mBuilder.setProgress(100,incr,false); //Issuesthenotification mNotifyManager.notify(id,mBuilder.build());
Replacethelinesyou'vefoundwiththefollowinglines.Noticethatthethirdparameterinthe
callissettosetProgress()
truetoindicatethattheprogressbarisindeterminate:
//Setsanactivityindicatorforanoperationofindeterminatelength mBuilder.setProgress(0,0,true); //Issuesthenotification mNotifyManager.notify(id,mBuilder.build());
Theresultingindicatorisshowninfigure2:
Figure2.Anongoingactivityindicator.
相关文章推荐
- Android设计和开发系列第一篇:Notifications通知(Develop—API Guides)
- Android设计和开发系列第一篇:Notifications通知(Design)
- Android设计和开发系列第二篇:Action Bar(Develop—Training)
- Android设计和开发系列第二篇:Action Bar(Develop—API Guides)
- Android官方开发文档Training系列课程中文版:通知用户之在通知中显示进度
- Android官方开发文档Training系列课程中文版:通知用户之创建不同导航方式的Activity
- Android设计和开发系列第二篇:Navigation Drawer(Develop)
- Android官方开发文档Training系列课程中文版:通知用户之更新或移除通知
- Android官方开发文档Training系列课程中文版:通知用户之构建通知
- Android官方开发文档Training系列课程中文版:通知用户之大视图通知
- Android Metro风格的Launcher开发系列第一篇
- Android Metro风格的Launcher开发系列第一篇
- Android Ap 开发 设计模式第一篇:迭代器模式 推荐
- Android Ap 开发 设计模式第一篇:迭代器模式
- Android设计和开发系列第二篇:Action Bar(Design)
- Android Metro风格的Launcher开发系列第一篇
- 【转发】Android Metro风格的Launcher开发系列第一篇
- Android Metro风格的Launcher开发系列第一篇
- Android开发设计模式系列集锦
- Android App 开发 设计模式第一篇:迭代器模式