Android 技巧汇总.docx
<<android的几个技巧1>>书目Qv<android的几个技巧1>>0.入门实例削析I1.在测试时,如何实现一个提示82.可以运用AIertDiaIog.Builder才产生一个提示框94 .menu的用法101 .简洁的代码IO2 .menu实现的两种方法IO5 .Aclivily的切换141 .代码142 .详解:156 .AlroidUI1.ayout191. AbeoIute1.ayoui197. Iab以及HosfFab操作208. 1.ist(图片/按钮/标Sfi/文本)261.ISTM-261.lSTMn36IJST例三409 .调用阅读器领入某网址4210 .监控应用程序包的安装&删除42方法一:42方法二:4511 .运用IbaSI给出-个字符串5212 .把一个字符串写进文件5213 .把文件内容读出到一个字符串5314 .调用AndroidinstaU0安装和和段程序5415 .结束某个进程5516 .设置默认来电铃声5517 .开机自启动5618 .线程与子线程57handlcrMcssagc实例5819 .Service591 .什么是SerViCe592 .如何运用SCrViCC603 .Service的生命周期65网)常用界面截图:66提示166提%:2674 堆670.入门实例剖析1开卷语俗话说,“把读唐诗三百首,不会作诗也会吟,最近收集了很多AndrOid的示例代码,从这些代码的回读和试骁中学习到很多学问,从而产生写这个系列的准备,目标就是一步步跟蓿实例进行动手实作,真正从“检”中体会和学习Andgid开发.本文目标是AndmKl自带的一个范例程序:记事本.预备学问搭建开发环境,尝试编写"HeIk)Wodd”,了解AiKlroid的地木概念,熟识Andtnid的APl(官方文档中都有,不赞述)。程序截图先来简洁了解下程序运行的效果ImQflB¾1:19PMlEditnote第一篇,写点啥好呢?Android看起来很美,不知道Jl正摸起来啥感觉哈?!程序入口点类似于Win32程序里的WinMain函数,Andwid自然也有它的程序入口点。它通过花AndroidManifcstAinl文件中配置来指明.可以看到名为NotCS1.iSt的activity打点下有这样个intcnl-11ltcr,Jiaction为android.intcnt.action.MAIN,Category指定为android.ineN心IegoIy1.AUNCHER这就指明白这个activity是作为入口activity,系统查找到它后,就会创建这个acli3y实例来运行,若未发觉就不启动(你可以把MAIN改名字试试.<imen<-fi!er><ac(ionandroid:naine=,'andrDid.intent.aclion.MAINMf><catcgoryandroid:namc=Nandroid.intent.catcgory.1.AUNCHER',t><intent-filler>Notes1.ist详解就从入口点所在的aciviiy(见图I)起先,可以看到这个aciMy最近要的功能就是显示11志列表。这个程序的日志都存放在SqIilC数据库中,因此须要读取出全部的日志记录并显示。先来看两个重要的私有数据.第个PROJEenoN字段指明白“日志列农”所关注的数据阵中的字段(即只须要ID和Tide就可以了,android:id="android:id.''tcxtI,android:Iay(HH_widih="fiH_parcnl”android:ayouUeight="7androidattrlistPrefe11edI(enHeigh(viindroid:lexlAppeanince="?andn>id:allr?texlAppeanince1.arge"androdgravity="ccntcr-vcrticaandraid:paddinglxft="5dipMandroid:SingIe1.ine="true.t>就是用来显示一条日志记录的ItxiVicw,最终两个字段指明门实际的字段映射关系,通过这个lx(View来显示一条口忐记录的IiUe字段。处理“选择日志”事务既然有了“口志列衣”,就白然要考虑如何处理某一条Fl志的单击小务,这通过柬我On1.islIteinClick方法来完成.0VCTTidCprotecledvoidon1.is(hemClick(1.istView1,Viewv.in(position,longid)(Uriuri=ContentUris.withAppendedld(gelIntent().getDala().id);Stringac(ion=gctln(cnt(),gctAclion();if(I11ent.ACTION.PICK.equals(ac(ion)Inlent.ACTION_GET_CONTENT.equals(action)</Thecalleriswaitingforustoreturnanoteselectedby/theuser.Thehaveclick<xionone.soreturnitnow.seResult(RESU1.T-OK.newInienK).seDaa(uri);Jelse(H1.aunchactivitytoview/editthecurrentlyselecteditemMartActiviy(ncwIntcnt(Intcnt.ACTION_EDIT.uri):JI首先通过”和日志的id号拼接得到选中日志的真正UR1.然后创建一个新的Intern.其操作类型为IntentACTION-EDIT.数据域指出待编辑的Il志URI(这电只分析else块>.Intent深度剖析那么,上面这句sta11Ac(ivity(ncwlntcnt(ln(cnt.ACTION_EDIT,Uli)执行后会发生什么事情呢?这时候AndrOid系统就跳出来接管了,它会依据inien中的信息找到对应的activity,在这里找到的是NoteEditor这个activity.然后创建2个activity的实例并运行.那么.Android又是如何找到NowEditor这个对应的activity的呢?这就是icnt发挥作用的时刻了。newIntenKInlent.ACTION-EDlT.uri>这里的ImCm.ACT1ON_EDIT="",另外通过设置断点,我们看下这里的Uri值:'二*u11-UnSHerychcaflUriOd-8300S9050968)EJauthority=UhSPart(id=830058677160)Adecoded-com.Qogte.provider.NotePocT1±encoded-acom.9o<>gle.fxov1der.NotePad三iffrg11>ent=UnSPaftSEfrptyPart(d=8X003817304)SKosyWOTCACHSrEifPath-UnSPathPartOd-8X059050944)®decoded-"NOTCACHED*(Saencoded=rhotes然后我们再来看下Androidmanfesl.xm其中有这个provider<providerandroid:Mme二"No<eP:KiPlX)Vider'andx)!dzaulhri(ies="cm.ggk.provider.NolePad">发觉没有?它也有com.google.pvider.NotePad,这个是conlenCcom.google.providcr.No<cPa1.,notes,l的一部分.同时VaCliVilyandroid:namc="NotcEdi(or*android:Iheme='©android:Style/Theme.1.ighT'android:label="string/(itk_noteMandmid:scrccnOrientation="scnsorMandroid:COnfigchangekkCybOardHiddCnlOriCng【ion”><!-Thisfillersaysthatwecanvieworcdi(thedataofasinglenote><incnt-flhcrandioid:labcl=nstring/rcsolvc_cdit"><ac<ionandid:naine=Mandroid.iinen(,ac(ion.VIEW*i><actionandmidznamc=,'android.intcnt.action.ED11*"f>VQionandix)id:name='*com.android.no<ep<Kl.action.EDIT.NOTE,f><catcgorj,androidznamc="android.inicnt.catcgor).DEFAU1.T*,!><daiaalroid3nineTpe=,'vnd.android.cusor.itenVvnd.google.note"t><.,intcnt-fihcr><!-ThisfiltersaysthatwccanCrCaICanewnoteinsideofadirectoryOfnOIe§-><intent-11ller><actionandroidznamc=,'android.intcnt.actionJNSEK*<categoryandrokkname="android.imetHCaIegory.DEFAU1.T*f><dataandroidmimc,Iypc=,'vnd.android.cunior.dir'nd.googlc.notc,!><i11en(-fiher><activity>上面第一个加cmf11ur中有个action名为android.inem.action.EDIT,而前面我们创建的Iinent也正好是lntcnt.ACnON_EDIT=".想必大家已经明白是怎么回事门©“下面就进入activity选择机制了:系统从intent中获得道uri.得到了COmCnCOm.gogc.prvvkr.N°ICPddnoleWI.去抻起先的content:标识.得到com.gglc.proVidcr.NotcPadZnotcs/1.然后获褥曲Ifii的Com.google.provide匚NOICPad,然后就到Androidmanfcst.xml中找到authorities为COm.google.provider.NOlePad的provider.这个就是后面要讲的8UemPrOVider,然后就加载这个contentprovider<providcrandroid:name-*NotePadPvidcr"andnoid:auihorities="com.google.pix)vider.NotePad"f>在这里是NO(CPadPrDVidCr然后两用NotcPikiProvidcr的gcttypc函数.并把上述UR【传绐这个函数,函数返回URl所对应的类型这里返回NOlgCoNTENTTEM_TYPE,代表条日志记录,而CONTENTTEN1.TYPE=*vnd.andrid.cursor.itc!n'vnd.g(>gk.fHc"OPrridCpublicStringgctTypc<Uriuri)(switch(sUriMatcher.natch(uri)(caseNOTES:returnNoteCONTENTJYPE:caseNOTE.1D:*e(urnNOtgCONTENTTEMjrYPE;defauh:thrownewHegalArgumentException(vUnknownURI"÷uri);)I上面的sUriMatcher.match是用来检测ri是否能够被处理,而SUriMatchermatch(Uri)返回值其实是由SUriMatchcr=newUriMatchcrtUriMacchc1.NOeMATCH);sUriMatcher.a(MURI(No(ePad.Al11HORITY/no<esM,NOTES);sUriMatchcr.addURI(NotePad.AUTFiORITY.'notes/#,.NOTE.ID>:确定的.然后系SE运用获得的"VnCi.android.cursor.itcm/vnd.googlc.nctc.和”到androidmanfcs1.xml中去找匹配的activity.<intcnt-fihcrandroidJabcl="<stringrcsolvc-cdit,><actionandroi<namc-',android.intcnt.ac(ion.VIEV'f><ac(ionandroid:name=Handroid.intent.aclit>n.EDITMO<actionandroid:namei'com.andrcid.no<cpad.aclion.EDIT_NOTE''f><catcgoryand11)idzname=',alroid.inlcnl.cilegory.DEFAU1.T*,f>Vdalaandroid:mimcTypc="sd.3ndrCid.cursor.iicnVvnd.googlc.noc”f><inlent-filter>正好NOtCEdigr这个activity的intent-filter满意上述条件,这样就找到了NoicEditor于是系统加我这个类并实例化,运行,然后就到了NowEdiI。!的OnC情He函数中(见后续文章)。小技巧1 .在吩咐行中运用"adbshek吩咐进入系统中,然后”CdaPp”进入应用程序所在书目JrmXXX”就可以州除你指定的叩k,从而去掠其在系统顶层界面占据的图标,若两次”data"则可以进入应用程序运用的数据竹目,你的数据可以保存在这里,例如NOI叩而就是把其数据库放在它的databases书目下.名为notc-pad.db.2 .第一次比动模拟涔会比较慢,但以后就别关闭模拟器了,修改代码,网试都不须要再次自动的,干脆修改后Rin或debug就是,1.在测试时,如何实现一个提示可以运用1. TOaSt.makeTe×t(this,"这是一个提示",Toast.1.ENGTH_SHORT).show();2. 从资源文件String.xml里面取提示信息3. Toast.makeText(this,getString(R.string.welcome),ToaSt.1.ENGTH.SHoRT).show。;这个提示会几秒钟后消逝2.可以运用AIertDiaIog.BuiIder才产生一个提示框.例如像messagebox那样的1. newAIertDiaIog.Builder(this)2. .SetTitIeCAndroid提示“)3. .setMessage("这是一个提示,请确定)4. .show();带一个确定的对话框1. newAlertDIaIog.BuiIder(Ihis)2. .setMessage("这是其次个提示“)3. .setPositiveButton("i5E"f4. newDialoginterface.OnClick1.istener()5. publicvoidonClick(DialogInterfacedialoginterface,intl)按钮事务)».show();AIertDiaIog-BuiIder还存很多困雄的用法,有确定和取消的对话框1. newAIertDiaIog.BuiIder(Ihis)2. .semtle("提示")3. .setMessage("fi½jHH?")4. .setIcon(R.drawable.quit)5. .setPositiveButton("确定",newDialoglnterface-OnCIick1.istenerO6. publicvoidonClick(Dialoglnterfacedialog,intWhichButton)7. SetReSUlt(RESU1.TJDK);确定按钮事务8. finish();9. 10. )11. .setNegativeButton(-取消",newDialoglnterface.OnCIick1.istenerO12. publicvoidOnCIlCk(DialOglnterfaCedialog,intWhichButton)13. 取消按铀事务14. 15. )16. .show();4.menu的用法.1 .简洁的代码1. publicstaticfinalintITEM_1_ID=Menu.FIRST;2. publicstaticfinalintITEM_2_ID=Menu.FIRST+1;3. publicstaticfinalintITEM_3_ID=Menu.FIRST+2;4.5. publicbooleanonCreateOptionsMenu(Menumenu)6. super.onCreateOptionsMenu(menu);7. 不带图标的menu8. menu.add(O,ITEM_1_ID,0,"item-l");9. 带图标的menu10. menu.add(0,ITEM_2_ID,1,"item-2").setIcon(R.drawable.editbills2);11. menu.add(0,ITEM_3_ID,2,"item-3").setIcon(R.drawable.billsuml);12. returntrue;13. 14.15. publicbooleanonOptionsRemSelected(MenuItemitem)16. switch(item.getltemld()17. case1:18. Toast.makeText(this,"menul",Toast.1.ENGTH_SHORT).show();19. returntrue;20. case2:21.22. returntrue;23. case3:24.25. returntrue;26. 27. returnfalse;28. )2.menu实现的两种方法大部分的应用程序都包括两种人机互动方式,一种是干脆通过GUI的VieWs,其可以满意大部分的交互操作.另外一种是应用Menu,当按下MCnU按钮后,会弹出与当前活动状态下的应用程序相匹配的菜单。这两种方式相比较都有各自的优势,而且可以很好的相辅相成,即便用户可以由主界面完成大部分操作,但是适当的拓展Meml功能可以更加完善应用程序,至少用户可以通过排列整齐的按钮清楚的了解当前模式下可以运用的功能。有两种方法可以为AndroidAPPS添加菜单功能,下边将对设置过程给出具体的介绍:第一种方法,通过1.ayout来添加伸态菜单元素.般状况下,开发拧在rcs/1.ayout路径下来定义应用程序的GUIe应用Eclipse创建一个新项目后,可以看到res/layout中存在一个预置的main.xml文件,其作为程序默认启动界面。同样,可以通过这种方式创建一个静态的Menu,创建方法参阅卜边的源代码:.'ViewCodeXM1.<?xmlversion"I.O"encoding'utf-K,*7><menuxmlns:android=H'''schenas.androidapk<,res,andv>k><itcmandn>idzid="(gl+id<,prcvious"andrDid2titic=*(Sstring,prcvious*androidxnablcd*falsc"andn>id:icon=Mandn>id:dniwahkic_mcdkiprevious><!-thesemayhoibeavailableinnextapi(level>J),sobecarefull->Vitemandn>id:id-M®*id/playj)ause*android:Ime二§而昨»悔”androidzicon=',andruidrdrawahlc.,icmedia_play'7><itemandroid:&-+id,nexi"and11>idzlitk=slring',nex*android:icon=Mandroid:drawablc.icmenunext><menu>在ACIiViIy类中调用刚刚创建的MenU,首先将当前的ACIiVily与指定的MenuXM1.相关联:1. SOverride2. publicbooleanOnCreateOptionsMenu(Menumenu)3. super.OnCreateOptionsMenu(menu);4. getMenuInflater().inflate(R.layout,player_menu,menu):5. returntrue;6. 实现OnoPtionSIteInSCIeCted方法:(其目的是捕获到菜单触发事务后,对具体触发的选项作出响应,实际调用的函数包含在各自的CaSC中)01.eOverride02.publicbooleanonOptionslIemSclecled(MenuIlemitem)03.switch(item,getItemIdO)01.caseR.id.previous:05.previous();/gotoprevioussongintheplaylist06.returntrue;07.caseR.id.play_pause:08.isPlaying()?pauseO:play();/toggleplay/pause09.returntrue;10.caseR.id.next:U.nextO:/gotonextsongintheplaylist12.13.)returntrue:14.returnfalse:/shouldneverhappen15.最终可以通过OnPrePareOPlionMenU方法初始化MenUItems的属性:01.Override02.publicbooleanOnPrcpareOptionsMcnu(Menumenu)03./setPlay_PaUSemenuitemlook04.if(isPlaying()(05.06.07.menu.findItem(R.id.Pla1.PaUSe).setTitle(R.string,pause).setIcon(android.R.drawable,icmediaPilUSe);else(menu.find!tem(R.id.playpause).setTilIe(R.siring,play).seticon(android.R.drawable.ic_media_play);)returntrue;大部分程序都通过这种方式添加MCnU菜单功能,而且通过以上的步骤来看,其实现方法特别简洁。其次种方法,在ACtiVity类中动态创建Menuious):06.menu07.add(0,MEN1.P1.AjPAUSE,0,R.string,play)08.seiIcon(android.R.draw<ble.icmediaplay);09.menu10. .add(0,MEN1.NEXT,0,R.string,next)11. .setIcon(android.R.drawable,icmedianext);12.13.returntrue;引用与第一种方法相同的方式来捕获菜单的行为:01.SOverride02.publicbooleanonOptions11emSeIected(Menu11cmitem)03.04.05.06.07.08.09.10.11.12.13.14.15. switch(item,getItemIdO)casecasecaseMENl-PREVIOUS:previous():/gotoprevioussongintheplaylistreturntrue:HENlPI<APAUSE:isPlaying()?pause0:play0;/toggleplay/pausereturntrue;MENlNEXT:nextO:/gotonextsongintheplaylistreturntrue;Jreturnfalse:/shouldneverhappen对以上两种方法的补充:依据须要设冏不同MenUIIem的属性:I.menu.findItem(R.id.next).SetEnabled(false);设置MenUIten从属关系(添加子父级别):干脆写在方法中:1. menu2. .addSubMenu(R.id.repeat)3. .add(R.i<l.one)4. .add(R.id.all)5. .add(R.id.none);干脆定义在XM1.1.ayout中:,ViewCodeXM1.<itemandrokkid"i<lrepeal"andriduitlc"、trin?.TCpCaI”><menu><itcmandroid:id="(g+d'(ne"amln>id:ti(le=''slring'rcpe;it<>>e"xi(cm><itemandroid:id="(+id''alandroidztitlc="(ist1111g'rq,catall"><Ziten><itcmandroidzd='*(+idnonc"and11>idztitlc=*'<iis(11nprepeatnone"Xitem><nwnu>这两种不同的方法实现的目的是一样的,而且不存在本质上的却别,具体依据实际状况(依据项目的结构须要或者团队开发标准)选择合适的方法来创建Menu,5.Activity的切换1 .代码2个ACtiVily的切换,没有数据传迅1. 从A到B2. Intentintent=newIntent();3. intent.setClass(A.this,B.class);4. StartACtiVity(intent);2个Activity之间传遢数据相关的几个函数StartActivityForResuItpublicfinalvoidsetResult(intresultCode,Stringdata)回调函数protectedvoidOnACtiVityReSUlt(intrequestcode,intresultCode,Intentdata)例如A到B,从B得到数据1. /A3B2. staticfinalintRG_REQUEST=0;3. Intentintent=newIntent();4. intent.setClass(A.this,B.class);5. StartActivityForResuIt(IntentrRG-REQlIEST);6.7. 在B中处理8. Bundlebundle=newBundle();bundle.putString("DataKey",edittext.getText().tOString();给bundle.入数据Intentmlntent=newIntent();mintent.putExtras(bundle);SetReSUIt(RESU1.T_0K,mintent);finlsh();10. 以终在A的回调函数电面接收数据11. if(requestcode=RG_REQUEST)if(resultcode=RESU1.T.CANCE1.ED)SetTItIeCCanceIed.");elseif(resultCode=RESU1.T_OK)setTitle(String)data.getCharSequenceExtra("DataKey");2.详解:一个Android应用程序很少会只有一个ACtiVity对软,如何在多个AetiVity之间进行跳转.而且能终相互传值是一个很基本的要求.在前面创建的MyApp中,我们通过点击按钮可以更新当前界面上的文本内容.现在我们想换种方式,在点击按钿后,显示一个新的屏林,在这个屏辨上输入一段话,然后再返回到原先的界面显示刚才输入的那句话.首先我的新建这个新屏幕的布局文件input.xml,并添加一个文本输入框和一个按钮(留意,xml元素的命名不要和其他布局文件中的定义空名,因为全部的资源都在R中进行索引,比如id,假如很名J'在运用R.id.*的时候就会有问题了1.这个布局文件对应的是一个ACtiVity.因此我们再新建一个InPUt类(继承自ACtiVity用于显示这个布局并响应事务。p>licclass£putestedsActivity<CvxrxprotctdvoidoaCratBundle0vdetaoSt><wroCrw(wdMt<ncwS>SezContentView(X.layout.xQpuei然后,还有一个用要的工作,那就是在清单文件AndroidManlfeSt.xml中告知程序,我定义了一个新的ACtiVity,你可以去调用它.我们希望在以前的那个主界面上点击按钮以后可以跳转到文本输入界面,所以我们须要对按钮的OnCIick事务进行定义:v9>4coCrt9>llv*4Zs*taacvStac1IW4ta>tM94l<11MC*MV4Vlft.lrM.M4JfMco*XasOatWic*l<R.11t-rXm>fzwl>t.MtflBCiieaar(wrViw.OwCic*tt>tMro,p«Miewt.oeClietr1111*vtmviIlMtK4tM1.aMtt0Met*t9t.e4M14<rctvt<<o<WkcIIBI*tit在这段代码里出现了一些新东西.首先是Intena它是Android个很羽要的类.Intent直译是“意图”,什么是意图眼?比如你想从这个AetiVity跳转到另外一个Activity.这就是一个意图.它不但可以连接多个ACtiVity还可以在它In之间传递数据.在这里,我们就是用Intent从MyApp对象跣转到了Input对象。再看紧跟着的StanACIiVilyForReSUIto方法,顾名忠义,它可以从,个定义好的InN对象启动一个新的ACIiYiIy,并H.,这个ACIiViIy会返回执行的结果,这些内容下面立刻就会提到,好,这里我们己经可以调出新ACtiVity了,我们看一卜执行的结果:你立刻可以想到.现在缜要对新的ACtiVity(Input)进行处理了.我们在点击“确定”按钮的时候,须要扶得上面EditTeXt对象中的文本.然后返I可到前一个ACtiVity<MyApp)中去。看我们的按钮“务处理:6.AndroidUl1.ayout1.Absolute1.avout在AIKkOidUI中最基本的构建中.位(buildingblock)是android.icw.Vicw.个ViCw占据解幕上的一个矩形区域,并负击该区域的绘图和事务处理.Vicw有一些子类,比如ImageView.T闪VieW等可分别用来显示图像.文字View还有一个特殊的子类ViewGroup.VicwGwup在UihIyoUt中充当“容器”的角色,用以“包含”其他View以及VicwGroup:vicwgroup.png由于ViewGroup是一个abstractclass无法干腌实例化.所以在I”。UI中真IE充当”容涔*角色的应当是ViCWGroUP的子类:AbsoIutc1.ayout、Framc1.ayout、1.incar1.ayout.Rclativclyout等.在实际的Ul编程中,运用不同的layout类作为容器,对该容器中的各个子View的排列方式有很大影晌,比如,1.igr1.ayo中的各个子Vkw依据横向或者纵向我性排列:而AbsoIutc1.ayout中各个子View可以指定以像素为单位的“确定”位置.AbsoIutc1.ayout的这种“确定”定位的布局方式和我£)特别然识的Windows编程中的SetwindowPosO或Form1.Uft=IO的布同方式是一样的,比较简洁:现在我们新建一个Andmid工程中,在其主Activity类中添加如下三个成员:privateAbsoIutc1.ayouKal;PfiVaIeTexiViewtv;privateViewv;改写这个类的OnCrcatc方法如下,publicvoidonCreaie(BundIeicicle)(super.onCreate(icicle);构造一个Absolulc1.ayout,设置其背景色al=newAbsolu(e1.ayou(lhi$):al.setBakgn>u11dColr(Color.YE1.1.OW);构造一个TcxtVicw