android apps – phone calls and sms · android telephony features you can use from within your app...
TRANSCRIPT
-
1.1
1.2
1.2.1
1.2.1.1
1.2.2
1.2.2.1
1.2.2.2
1.3
1.3.1
1.3.1.1
1.3.2
1.3.2.1
1.3.2.2
TableofContentsIntroduction
Lesson1.PhoneCalls
Concepts
1:PhoneCalls
Practicals
1.1:MakingPhoneCalls-Part1
1.2:MakingPhoneCalls-Part2
Lesson2.SMSMessages
Concepts
2:SMSMessages
Practicals
2.1:SendingandReceivingSMSMessages-Part1
2.2:SendingandReceivingSMSMessages-Part2
TableofContents
2
-
AndroidApps–PhoneCallsandSMSTheAndroidApps–PhoneCallsandSMScourseincludestwolessonscreatedbytheGoogleDeveloperTrainingteam.Thelessonsaredesignedtobeusedininstructor-ledtraining,butthematerialsarealsoavailableonlineforself-study.
Prerequisites
CompletionoftheentireAndroidDeveloperFundamentalscourse,orequivalentknowledgeJavaprogrammingexperienceKnowledgeofAndroidprogrammingfundamentals
Coursematerials
ThecoursematerialsincludetheconceptuallessonsandpracticalexercisesinthisGitBook.Slidedecksarealsoavailableforoptionalusebyinstructors.
Whatdothelessonscover?
InAndroidPhoneCalls,studentslearnhowtousethetelephonyfeaturesinAndroid.Inthepractical,theycreateanappthatlaunchesthePhoneappwithaphonenumbertomakeacall,andanotherappthatchecksforneededpermissionsandservices,andthenletstheusermakeaphonecallfromwithintheapp.
InAndroidSMSMessages,studentslearnhowtousetheSMSfeaturesinAndroid.Inthepractical,theycreateanappthatlaunchesanSMSmessagingappwithamessage,andanotherappthatchecksforneededpermissions,sendsanSMSmessage,andreceivesSMSmessages.
DevelopedbytheGoogleDeveloperTrainingTeam
Lastupdated:March2017
Introduction
3
https://developers.google.com/training/courses/android-fundamentalshttps://drive.google.com/drive/folders/0B5Kg0X0yIQ1PTWJlNG9nSFdFYk0
-
ThisworkislicensedunderaCreativeCommonsAttribution-NonCommercial4.0InternationalLicense
Introduction
4
-
1:PhoneCallsContents:
ThedifferencebetweendialingandcallingSendinganintentwithaphonenumbertodialMakingacallfromwithinyourappUsingemulatorstotestphonecallsRelatedpracticalLearnmore
Androidmobiledeviceswithtelephone/cellularservicearesuppliedwithaPhoneappformakingcalls,whichincludesadialerfordialingaphonenumber.ThischapterdescribestheAndroidtelephonyfeaturesyoucanusefromwithinyourappbylaunchingthePhoneappwithanimplicitintent.Youcanaddcodetoyourappto:
Dial:LaunchthePhoneapp'sdialerwithaphonenumbertodialacall.Thisisthepreferredtechniqueforappsthatdon'tneedtomonitorthephone'sstate.Call:Requesttheuser'spermissionifnecessary,andmakeaphonecallfromwithintheapp,withtheabilitytomonitorthephone'sstate.Thistechniquekeepstheuserwithinyourapp,withouthavingtonavigatebacktotheapp.ItalsoenablesphonecallsifthePhoneapphasbeendisabledinSettings.
Android'sPhoneappautomaticallyreceivesincomingphonecalls.YoucanusethePhoneStateListenerclasstomonitorthephone'sringingstateandshowtheincomingphonenumber.
Tip:YoucanalsouseabroadcastreceiverinyourapptodetectanincomingcallorSMSmessage.BroadcastreceiversaredescribedinBroadcastReceiversintheAndroidDeveloperFundamentalsCourse.
ThedifferencebetweendialingandcallingYouuseanimplicitintenttolaunchthePhoneappfromyourapp.Youcandothisintwoways:
UseanimplicitIntentandACTION_DIALtolaunchthePhoneappanddisplaythephonenumberinthedialer.
Thisisthesimplestway,withnoneedtorequestpermissionfromtheuser(thePhoneappasksforuserpermissionifneeded).
1:PhoneCalls
5
https://google-developer-training.gitbooks.io/android-developer-fundamentals-course-concepts/content/Unit%203/73_c_broadcast_receivers.htmlhttps://developer.android.com/reference/android/content/Intent.htmlhttps://developer.android.com/reference/android/content/Intent.html#ACTION_DIAL
-
Theusercanchangethephonenumberbeforedialingthecall.TheusernavigatesbacktoyourappusingtheBackbuttonafterthecalliscompleted.
UseanimplicitIntentandACTION_CALLtomakethephonecalldirectlyfromwithinyourapp.
Thisactionkeepstheuserwithinyourapp,withouthavingtonavigatebackfromthePhoneapp.Yourcodemustasktheuserforpermissionbeforemakingthecalliftheuserhasn'talreadygrantedpermission.Justasyourappneedstheuser'spermissiontoaccessthecontactsorusethebuilt-incamera,itneedstheuser'spermissiontodirectlyusethephone.Yourappcanmonitorthestateofthephonecall.
FormattingaphonenumberTouseanintenttolaunchthePhoneappwithaphonenumbertodial,yourappneedstoprepareaUniformResourceIdentifier(URI)forthephonenumber.TheURIisastringprefixedby"tel:",forexample,tel:14155551212foraU.S.number(usethecompletenumberasyouwouldenteritonaphonekeypad).Youcanhard-codeaphonenumberinsideyourapp,orprovideanEditTextfieldwheretheusercanenteraphonenumber.
ThePhoneNumberUtilsclassprovidesutilitymethodsfornormalizingandformattingphonenumberstrings.Forexample,toremoveextraneouscharacterssuchasdashesandparentheses,usethenormalizeNumber()method,whichremovescharactersotherthandigitsfromaphonenumberstring.Forexample,thestatementbelownormalizesaphonenumberenteredintoanEditTextviewnamededitText:
StringnormalizedPhoneNumber=PhoneNumberUtils.normalizeNumber(editText.getText().toString());
Note:ThenormalizeNumber()method,addedtoAndroidAPIlevel21(correspondingtoLollipop),isnotavailableinolderversionsoftheAPI.UsetheformatNumber()methodtoformataphonenumberstringforaspecificcountryifthegivennumberdoesn'tincludeacountrycode.YoucanuseLocale.getDefault().getCountry()togetthecurrentcountrysetting,orusetheISO3166-1two-lettercountrycodetospecifyacountrytouse:
StringformattedNumber=PhoneNumberUtils.formatNumber(normalizedPhoneNumber,Locale.getDefault().getCountry());
1:PhoneCalls
6
https://developer.android.com/reference/android/content/Intent.htmlhttps://developer.android.com/reference/android/content/Intent.html#ACTION_CALLhttps://developer.android.com/reference/android/telephony/PhoneNumberUtils.htmlhttps://developer.android.com/reference/android/telephony/PhoneNumberUtils.html#normalizeNumber(java.lang.String)https://developer.android.com/reference/android/telephony/PhoneNumberUtils.html#normalizeNumber(java.lang.String)https://developer.android.com/reference/android/telephony/PhoneNumberUtils.html#formatNumber(java.lang.String,%20java.lang.String)
-
UsinganintentwiththephonenumbertodialTouseanintenttolaunchthePhoneapp,useabuttontolettheuserstartthecall.Whentheusertapsthebutton,itsclickhandlerinitiatesthecall.Forexample,asimplelayoutcouldprovideanImageButtonlikethephoneiconinthefigurebelow.
1:PhoneCalls
7
-
1:PhoneCalls
8
-
ThePhoneappopenswiththenumbertobedialed.Theusercanchangethenumberandinitiatethecall.ThePhoneappthenmakesthecall.
InthedialNumber()method,useanimplicitintentwiththeintentactionACTION_DIALtopassthephonenumbertothePhoneappasaURI.
publicvoiddialNumber(){TextViewtextView=(TextView)findViewById(R.id.number_to_call);//Useformatwith"tel:"andphonenumbertocreatephoneNumber.StringphoneNumber=String.format("tel:%s",textView.getText().toString());//Createtheintent.IntentdialIntent=newIntent(Intent.ACTION_DIAL);//Setthedatafortheintentasthephonenumber.dialIntent.setData(Uri.parse(phoneNumber));//Ifpackageresolvestoanapp,sendintent.if(dialIntent.resolveActivity(getPackageManager())!=null){startActivity(dialIntent);}else{Log.e(TAG,"Can'tresolveappforACTION_DIALIntent.");}}
Intheaboveexample,thecodedoesthefollowing:
GetsthetextofthephonenumberfromtextViewwithgetText()andusesitwithString.formattoincludethetel:prefix(forexampletel:14155551212):
...StringphoneNumber=String.format("tel:%s",textView.getText().toString());...
CreatesanimplicitintentwiththeintentactionACTION_DIAL,andsetsthephonenumberasthedatafortheintentusingsetData():
…Intentintent=newIntent(Intent.ACTION_DIAL);//Setthedatafortheintentasthephonenumber.intent.setData(Uri.parse(phoneNumber));...
1:PhoneCalls
9
https://developer.android.com/reference/android/content/Intent.html#setData(android.net.Uri)
-
Checksiftheimplicitintentresolvestoanappthatisinstalledonthedevice.
1. Ifitdoes,thecodesendstheintentwithstartActivity(),andthesystemlaunchesthePhoneapp,asshowninthefigurebelow.
1:PhoneCalls
10
-
1:PhoneCalls
11
-
2. Ifitdoesnot,anerrorislogged.
Iftherearenoappsonthedevicethatcanreceivetheimplicitintent,yourappwillcrashwhenitcallsstartActivity().Tofirstverifythatanappexiststoreceivetheintent,callresolveActivity()onyourIntentobjectwithgetPackageManager()togetaPackageManagerinstanceforfindingpackageinformation.TheresolveActivity()methoddeterminesthebestactiontoperformforagivenintent.Iftheresultisnon-null,thereisatleastoneappthatcanhandletheintentandit'ssafetocallstartActivity().
…if(intent.resolveActivity(getPackageManager())!=null){startActivity(intent);}else{Log.e(TAG,"Can'tresolveappforACTION_DIALIntent.");}...
Thisexampleusesahard-codedphonenumber,whichisausefultechniqueforprovidingasupporthotlinenumber,ortheselectedphonenumberforacontact.Inthenextexample,userscanentertheirownnumberstomakecalls.
MakingacallfromwithinyourappTomakeaphonecalldirectlyfromyourapp,dothefollowing:
1. Addpermissionsthatenablemakingacallandreadingthephoneactivity.2. Checktoseeiftelephonyisenabled;ifnot,disablethephonefeature.3. Checktoseeiftheusercontinuestograntpermission,orrequestpermissionifneeded.4. ExtendPhoneStateListener,andregisterthelistenerusingtheTelephonyManager
class.5. UseanimplicitintentwithACTION_CALLtomakethephonecall.
Addingpermissionstothemanifest
Accesstotelephonyinformationispermission-protected.Inordertomakeacall,yourappneedstheCALL_PHONEpermission.Inaddition,inordertomonitorthephonestate,yourappneedstheREAD_PHONE_STATEpermission.Bothmustbedeclaredintheapps'sAndroidManifest.xmlfile.
Addthefollowingtoyourapp'sAndroidManifest.xmlfileafterthefirstline(withthepackagedefinition)andbeforethesection:
1:PhoneCalls
12
https://developer.android.com/reference/android/content/pm/PackageManager.html#resolveActivity(android.content.Intent,%20int)https://developer.android.com/reference/android/content/Context.html#getPackageManager()https://developer.android.com/reference/android/telephony/PhoneStateListener.htmlhttps://developer.android.com/reference/android/telephony/TelephonyManager.html
-
...
-
...if(isTelephonyEnabled()){Log.d(TAG,getString(R.string.telephony_enabled));//Todo:RegisterthePhoneStateListener....//Todo:Checkforpermissionhere....}else{Toast.makeText(this,R.string.telephony_not_enabled,Toast.LENGTH_LONG).show();Log.d(TAG,getString(R.string.telephony_not_enabled));//Disablethecallbutton.disableCallButton();}...
Checkingandrequestinguserpermission
BeginninginAndroid6.0(APIlevel23),usersgrantpermissionstoappswhiletheappisrunning,notwhentheyinstalltheapp.Thisapproachstreamlinestheappinstallprocess,sincetheuserdoesnotneedtograntpermissionswhentheyinstallorupdatetheapp.Italsogivestheusermorecontrolovertheapp'sfunctionality.However,yourappmustcheckforpermissioneverytimeitdoessomethingthatrequirespermission(suchasmakingaphonecall).IftheuserhasusedtheSettingsapptoturnoffPhonepermissionsfortheapp,yourappcandisplayadialogtorequestpermission.
Tip:Foracompletedescriptionoftherequestpermissionprocess,seeRequestingPermissionsatRunTime.
Followthesestepstocheckforandrequestuserpermissiontomakephonecalls:
1. Atthetopoftheactivitythatmakesaphonecall,andbelowtheactivity'sclassdefinition,defineaconstantvariabletoholdtherequestcode,andsetitto1:
privatestaticfinalintMY_PERMISSIONS_REQUEST_CALL_PHONE=1;
Whytheinteger1?Eachpermissionrequestneedsthreeparameters:thecontext,astringarrayofpermissions,andanintegerrequestCode.TherequestCodeisanintegerattachedtotherequest,anditcanbeanyintegerthatsuitsyourusecase.Whenaresultreturnsintheactivity,itcontainsthiscodeandusesittodifferentiatemultiplepermissionresultsfromeachother.
2. Intheactivitythatmakesaphonecall,createaprivatemethodcheckForPhonePermission()thatreturnsvoid.
1:PhoneCalls
14
https://developer.android.com/training/permissions/requesting.html
-
privatevoidcheckForPhonePermission(){if(ActivityCompat.checkSelfPermission(this,Manifest.permission.CALL_PHONE)!=PackageManager.PERMISSION_GRANTED){//Permissionnotyetgranted.UserequestPermissions().Log.d(TAG,getString(R.string.permission_not_granted));ActivityCompat.requestPermissions(this,newString[]{Manifest.permission.CALL_PHONE},MY_PERMISSIONS_REQUEST_CALL_PHONE);}else{//Permissionalreadygranted.}
3. Intheactivity'sonCreate()method,callthemethodtoperformthetelephonycheck:
...if(isTelephonyEnabled()){//Checkforphonepermission.checkForPhonePermission();//Todo:RegisterthePhoneStateListener.}else{...
NotethefollowingaboutthecheckForPhonePermission()method:
ThecodeusescheckSelfPermission()todeterminewhetheryourapphasbeengrantedaparticularpermissionbytheuser.Ifpermissionhasnotbeengranted,thecodeusestherequestPermissions()methodtodisplayastandarddialogfortheusertograntpermission.TherequestPermissions()methodneedsthreeparameters:thecontext,astringarrayofpermissions,andthepredefinedintegerrequestCode.WhenyourappcallsrequestPermissions(),thesystemshowsastandardpermissiondialogtotheuser,asshowninthefigurebelow.Yourappcan'tconfigureoralterthedialog.
Tip:Ifyouwanttoprovideanyinformationorexplanationtotheuser,youmustdothatbeforeyoucallrequestPermissions(),asdescribedinExplainwhytheappneedspermissions.
1:PhoneCalls
15
https://developer.android.com/reference/android/support/v4/content/ContextCompat.html#checkSelfPermission(android.content.Context,%20java.lang.String)https://developer.android.com/reference/android/support/v4/app/ActivityCompat.html#requestPermissions(android.app.Activity,%20java.lang.String[],%20int)https://developer.android.com/reference/android/support/v4/app/ActivityCompat.html#requestPermissions(android.app.Activity,%20java.lang.String[],%20int)https://developer.android.com/training/permissions/requesting.html#explain
-
Whentheuserrespondstotherequestpermissiondialog,thesysteminvokesyourapp'sonRequestPermissionsResult()method,passingittheuserresponse.Overridethatmethodtofindoutwhetherthepermissionwasgranted:
@OverridepublicvoidonRequestPermissionsResult(intrequestCode,Stringpermissions[],int[]grantResults){switch(requestCode){caseMY_PERMISSIONS_REQUEST_CALL_PHONE:{if(permissions[0].equalsIgnoreCase(Manifest.permission.CALL_PHONE)&&grantResults[0]==PackageManager.PERMISSION_GRANTED){//Permissionwasgranted.}else{//Permissiondenied.Stoptheapp.Log.d(TAG,getString(R.string.failure_permission));Toast.makeText(this,getString(R.string.failure_permission),Toast.LENGTH_SHORT).show();//DisablethecallbuttondisableCallButton();}}}}
TheabovecodesnippetshowsaswitchstatementbasedonthevalueofrequestCode,withonecasetocheckifthepermissionistheoneyoudefinedasMY_PERMISSIONS_REQUEST_CALL_PHONE.
Tip:Ithelpstouseaswitchstatementsothatyoucanaddmorerequeststotheapp.
Theuser'sresponsetotherequestdialogisreturnedinthepermissionsarray(index0ifonlyonepermissionisrequestedinthedialog).Comparethistothecorrespondinggrantresult,whichiseitherPERMISSION_GRANTEDorPERMISSION_DENIED.
Iftheuserdeniesapermissionrequest,yourappshouldtakeappropriateaction.Forexample,yourappmightdisablethefunctionalitythatdependsonthispermission(suchasthecallbutton)andshowadialogexplainingwhyitcouldnotperformit.
ExtendingandregisteringPhoneStateListener
PhoneStateListenermonitorschangesinspecifictelephonystatessuchasringing,off-hook,andidle.TousePhoneStateListener:
ImplementalistenerclassthatextendsPhoneStateListener,andoverrideits
1:PhoneCalls
16
https://developer.android.com/reference/android/support/v4/app/ActivityCompat.OnRequestPermissionsResultCallback.html#onRequestPermissionsResult(int,%20java.lang.String[],%20int[])https://developer.android.com/reference/android/telephony/PhoneStateListener.html
-
onCallStateChanged()method.IntheonCallStateChanged()method,provideactionsbasedonthephonestate.RegisterthelistenerusingtheTelephonyManagerclass,whichprovidesaccesstoinformationaboutthetelephonyservicesonthedevice.
Implementingalistener
CreateaprivateclassinyouractivitythatextendsPhoneStateListener:
privateclassMyPhoneCallListenerextendsPhoneStateListener{...}
Withinthisclass,implementtheonCallStateChanged()methodofPhoneStateListenertotakeactionsbasedonthephonestate.ThecodebelowusesaswitchstatementwithconstantsoftheTelephonyManagerclasstodeterminewhichofthreestatesthephoneisin:CALL_STATE_RINGING,CALL_STATE_OFFHOOK,andCALL_STATE_IDLE:
@OverridepublicvoidonCallStateChanged(intstate,StringincomingNumber){switch(state){caseTelephonyManager.CALL_STATE_RINGING://Incomingcallisringing.break;caseTelephonyManager.CALL_STATE_OFFHOOK://Phonecallisactive--offthehook.break;caseTelephonyManager.CALL_STATE_IDLE://Phoneisidlebeforeandafterphonecall....break;default://Mustbeanerror.Raiseanexceptionorjustlogit.break;}}
Provideactionsforphonestates
Addtheactionsyouwanttotakebasedonthephonestates.Forexample,yourcodecanlogamessagefortestingpurposes,anddisplayatoasttotheuser.TheCALL_STATE_RINGINGstateincludestheincomingphonenumber,whichyourcodecanshowinatoast.
1:PhoneCalls
17
https://developer.android.com/reference/android/telephony/PhoneStateListener.html#onCallStateChanged(int,%20java.lang.String)https://developer.android.com/reference/android/telephony/TelephonyManager.htmlhttps://developer.android.com/reference/android/telephony/PhoneStateListener.htmlhttps://developer.android.com/reference/android/telephony/PhoneStateListener.html#onCallStateChanged(int,%20java.lang.String)https://developer.android.com/reference/android/telephony/TelephonyManager.html
-
ThephoneisintheCALL_STATE_IDLEstateuntilacallisstarted.ThephonestatechangestoCALL_STATE_OFFHOOKinordertomaketheconnectionandstaysinthestateforthedurationofthecall.ThephonestatereturnstotheCALL_STATE_IDLEstateafterthecallfinishesorifthecallisdeniedornotcompleted.
YourappresumeswhenthestatechangesbacktotheCALL_STATE_IDLEstate.
Tip:AnapprunningonAndroidversionspriortoKitKat(version19)doesn'tresumewhenthephonestatereturnstoCALL_STATE_IDLEfromCALL_STATE_OFFHOOKattheendofacall.ThecodebelowsetstheflagreturningFromOffHooktotruewhenthestateisCALL_STATE_OFFHOOK,sothatwhenthestateisbacktoCALL_STATE_IDLE,youcanusetheflagtocatchtheend-of-callandrestarttheapp'sactivity.
privateclassMyPhoneCallListenerextendsPhoneStateListener{privatebooleanreturningFromOffHook=false;
@OverridepublicvoidonCallStateChanged(intstate,StringincomingNumber){//Defineastringforthemessagetouseinatoast.Stringmessage=getString(R.string.phone_status);switch(state){caseTelephonyManager.CALL_STATE_RINGING://Incomingcallisringingmessage=message+getString(R.string.ringing)+incomingNumber;Toast.makeText(MainActivity.this,message,Toast.LENGTH_SHORT).show();Log.i(TAG,message);break;caseTelephonyManager.CALL_STATE_OFFHOOK://Phonecallisactive--offthehookmessage=message+getString(R.string.offhook);Toast.makeText(MainActivity.this,message,Toast.LENGTH_SHORT).show();Log.i(TAG,message);returningFromOffHook=true;break;caseTelephonyManager.CALL_STATE_IDLE://Phoneisidlebeforeandafterphonecall.//Ifrunningonversionolderthan19(KitKat),//restartactivitywhenphonecallends.message=message+getString(R.string.idle);Toast.makeText(MainActivity.this,message,Toast.LENGTH_SHORT).show();Log.i(TAG,message);if(returningFromOffHook){//Noneedtodoanythingif>=versionKif(Build.VERSION.SDK_INT<Build.VERSION_CODES.KITKAT){Log.i(TAG,getString(R.string.restarting_app));//Restarttheapp.
1:PhoneCalls
18
-
Intentintent=getPackageManager().getLaunchIntentForPackage(.getPackageName());i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);startActivity(i);}}break;default:message=message+"Phoneoff";Toast.makeText(MainActivity.this,message,Toast.LENGTH_SHORT).show();Log.i(TAG,message);break;}}}
Registeringyourlistener
RegisterthelistenerobjectusingtheTelephonyManagerclass:
UsegetSystemService()withContext.TELEPHONY_SERVICE.UsetelephonyManager.listen()withthePhoneStateListenersettotheLISTEN_CALL_STATE.
Agoodplacetodothisisintheactivity'sonCreate()methodrightaftercheckingforphonepermission,whichisafterensuringthattelephonyisenabled.Followthesesteps:
1. Atthetopoftheactivity,defineavariableforthePhoneStateListener:
privateMyPhoneCallListenermListener;
2. IntheonCreate()method,addthefollowingcodeaftercheckingfortelephonyandpermission:
...if(isTelephonyEnabled()){...checkForPhonePermission();//RegisterthePhoneStateListenertomonitorphoneactivity.mListener=newMyPhoneCallListener();telephonyManager.listen(mListener,PhoneStateListener.LISTEN_CALL_STATE);}else{...
3. Youmustalsounregisterthelistenerintheactivity'sonDestroy()method.Thismethodisusuallyimplementedtofreeresourceslikethreadsthatareassociatedwithan
1:PhoneCalls
19
https://developer.android.com/reference/android/telephony/TelephonyManager.htmlhttps://developer.android.com/reference/android/content/Context.html#getSystemService(java.lang.String)https://developer.android.com/reference/android/telephony/PhoneStateListener.htmlhttps://developer.android.com/reference/android/telephony/PhoneStateListener.htmlhttps://developer.android.com/reference/android/app/Activity.html#onDestroy()
-
activity,sothatadestroyedactivitydoesnotleavesuchthingsaroundwhiletherestofitsapplicationisstillrunning.OverridetheonDestroy()methodbyaddingthefollowingcode:
@OverrideprotectedvoidonDestroy(){super.onDestroy();if(isTelephonyEnabled()){telephonyManager.listen(mListener,PhoneStateListener.LISTEN_NONE);}}
Usinganimplicitintenttomakethecall
TolaunchthePhoneappandstartthecall:
UseabuttoninthelayoutwithanonClickmethodsuchascallNumber().InthecallNumber()method,createanimplicitintentwiththeintentactionACTION_CALL.SetthephonenumberasthedatafortheintentwithsetData().
ThefollowingisansamplecallNumber()method:
publicvoidcallNumber(Viewview){EditTexteditText=(EditText)findViewById(R.id.editText_main);//Useformatwith"tel:"andphonenumbertocreatephoneNumber.StringphoneNumber=String.format("tel:%s",editText.getText().toString());//Createtheintent.IntentcallIntent=newIntent(Intent.ACTION_CALL);//Setthedatafortheintentasthephonenumber.callIntent.setData(Uri.parse(phoneNumber));//Ifpackageresolvestoanapp,checkforphonepermission,//andsendintent.if(callIntent.resolveActivity(getPackageManager())!=null){checkForPhonePermission();startActivity(callIntent);}else{Log.e(TAG,"Can'tresolveappforACTION_CALLIntent.");}}
Asinthepreviousexampleforpassinganumberfordialing,youuseastringforthephonenumberwiththetel:prefix.
1:PhoneCalls
20
-
Iftheimplicitintentresolvestoaninstalledapp,usethecheckForPhonePermission()methodyoucreatedpreviouslytochecktoseeiftheappstillhaspermissiontomakethecall.Youmustcheckforthatpermissioneverytimeyouperformanoperationthatrequiresit,becausetheuserisalwaysfreetorevokethepermission.Eveniftheappusedthephoneaminuteago,itcan'tassumeitstillhasthatpermissionaminutelater.
UsingemulatorstotestphonecallfunctionalityIfyoudon'thavecellularserviceonyourdevice,ortelephonyisnotenabled,youcantesttheappusingtwoemulatorinstances—oneemulatorinstancecallstheotherone.
1. LaunchanemulatordirectlyfromtheAVDManagerbychoosingTools>Android>AVDManager.
2. Double-clickapredefineddevice.Notethenumberthatappearsintheemulator'swindowtitleonthefarright,asshowninthefigurebelowas#1(5556).Thisistheportnumberoftheemulatorinstance.
3. OpentheAndroidStudioprojectforthephone-callingapp.4. Runthephone-callingapp,butchooseanotheremulatorfromthelist—nottheonethat
1:PhoneCalls
21
-
isalreadyrunning.5. Inthephone-callingapp,insteadofarealphonenumber,entertheportnumber(asin
5556),andclickthecallbutton.Theemulatorshowsthephonecallstartingup,asshowninthefigurebelow.
1:PhoneCalls
22
-
1:PhoneCalls
23
-
Theotheremulatorinstanceshouldnowbereceivingthecall,asshowninthefigurebelow:
1:PhoneCalls
24
-
1:PhoneCalls
25
-
6. ClickAnswerorDismissontheemulatorreceivingthecall,.AfteryouclickAnswer,alsoclicktheredHang-upbuttontoendthecall.
1:PhoneCalls
26
-
1:PhoneCalls
27
-
RelatedpracticalMakingPhoneCalls-Part1MakingPhoneCalls-Part2
LearnmoreAndroidDeveloperReference:
CommonIntentsTelephonyManagerPhoneStateListenerRequestingPermissionsatRunTimecheckSelfPermissionRunAppsontheAndroidEmulatorIntentsandIntentFiltersIntent
StackOverflow:HowtoformataphonenumberusingPhoneNumberUtils?Howtomakephonecallusingintentinandroid?RingingmyselfusingandroidemulatorFakeIncomingCallAndroidSimulatingincomingcallorsmsinAndroidStudio
OtherUser(beginner)tutorial:HowtoMakePhoneCallswithAndroidDeveloperVideo:HowtoMakeaPhoneCall
1:PhoneCalls
28
https://developer.android.com/guide/components/intents-common.htmlhttps://developer.android.com/reference/android/telephony/TelephonyManager.htmlhttps://developer.android.com/reference/android/telephony/PhoneStateListener.htmlhttps://developer.android.com/training/permissions/requesting.htmlhttps://developer.android.com/reference/android/support/v4/content/ContextCompat.html#checkSelfPermission(android.content.Context,%20java.lang.String)https://developer.android.com/studio/run/emulator.htmlhttp://developer.android.com/guide/components/intents-filters.htmlhttp://developer.android.com/reference/android/content/Intent.htmlhttp://stackoverflow.com/questions/6106859/how-to-format-a-phone-number-using-phonenumberutilshttp://stackoverflow.com/questions/4275678/how-to-make-phone-call-using-intent-in-androidhttp://stackoverflow.com/questions/2577785/ringing-myself-using-android-emulatorhttp://stackoverflow.com/questions/4964703/fake-incoming-call-androidhttp://stackoverflow.com/questions/27638462/simulating-incoming-call-or-sms-in-android-studiohttp://www.beginandroid.com/phonecall.shtmlhttps://youtu.be/3PHDcQOGFtg
-
1.1:Part1-MakingPhoneCallsContents:
WhatyoushouldalreadyKNOWWhatyouwillLEARNWhatyouwillDOAppoverviewTask1:SendanintentwiththephonenumbertodialTask2:Makeaphonecallfromwithinanapp
Androidmobiledeviceswithtelephone/cellularservicearepre-installedwithaPhoneappformakingcalls,whichincludesadialerfordialinganyphonenumber.YouuseanimplicitIntenttolaunchthePhoneappfromyourapp.Youhavetwochoices:
UseACTION_DIALtolaunchthePhoneappindependentlyfromyourappwiththephonenumberdisplayedinthedialer.TheuserthenmakesthecallinthePhoneapp.Thisisthepreferredactionforappsthatdon'thavetomonitorthephone'sstate.UseACTION_CALLtolaunchthePhoneappinthecontextofyourapp,makingthecalldirectlyfromyourapp,andmonitoringthephonestate.Thisactionkeepstheuserwithinyourapp,withouthavingtonavigatebacktotheapp.Yourappmustrequestpermissionfromtheuserbeforemakingthecalliftheuserhasn'talreadygrantedpermission.
WhatyoushouldalreadyKNOWFromthepreviouschapters,youshouldbeableto:
CreateandruninteractiveappsinAndroidStudio.WorkwithXMLlayouts.Createanimplicitintenttoperformanactionusinganotherapp.
WhatyouwillLEARNInthispractical,youwilllearnto:
PassaphonenumbertothePhoneapp'sdialer.Performaphonecallwithinyourapp.Testtoseeiftelephonyservicesareenabled.
1.1:MakingPhoneCalls-Part1
29
https://developer.android.com/reference/android/content/Intent.htmlhttps://developer.android.com/reference/android/content/Intent.html#ACTION_DIALhttps://developer.android.com/reference/android/content/Intent.html#ACTION_CALL
-
Checkforcallingpermission,andrequestpermissionifrequired.
WhatyouwillDOInthispractical,youwill:
CreateanappthatusesanimplicitintenttolaunchthePhoneapp.Createanotherappthatmakesphonecallsfromwithintheapp.Testtoseeiftelephonyservicesareenabledbeforeenablingtheapp.Checkforcallingpermission,whichcanchangeatanytime.Requestpermissionfromtheuser,ifnecessary,tomakethecall.
AppoverviewYouwillcreatetwoapps:
PhoneCallDial:AbasicappthatusesanimplicitintenttolaunchthePhoneappwithahard-codedphonenumberfordialing.ThePhoneappmakesthecall.Youcouldusethistechniquetoprovideaone-buttondialertocustomsupport.Inthislessonyouwillbuildalayout,showninthefigurebelow.ItincludesaTextViewwithahard-codedphonenumber,andanImageButtonwithanicontolaunchthePhoneappwiththatphonenumberinitsdialer.
1.1:MakingPhoneCalls-Part1
30
https://github.com/google-developer-training/android-fundamentals-phone-sms/tree/master/PhoneCallDial
-
1.1:MakingPhoneCalls-Part1
31
-
PhoneCallingSample:Anappthatsecurespermission,usesanimplicitintenttomakeaphonecallfromtheapp,andusestheTelephonyManagerclasstomonitorthephone'sstate.Youwouldusethistechniqueifyouwanttokeeptheuserwithinyourapp,withouthavingtonavigatebacktotheapp.Inthislesson,youmodifytheabovelayouttouseanEditTextsothatuserscanenterthephonenumber.Thelayoutlookslikethefigurebelow:
1.1:MakingPhoneCalls-Part1
32
https://github.com/google-developer-training/android-fundamentals-phone-sms/tree/master/PhoneCallingSamplehttps://developer.android.com/reference/android/telephony/TelephonyManager.html
-
1.1:MakingPhoneCalls-Part1
33
-
Task1.SendanintentwiththephonenumbertodialInthistaskyouwillcreateanappthatusesanimplicitintenttolaunchthePhoneapptodialagivenphonenumber.Tosendthatintent,yourappneedstoprepareaUniformResourceIdentifier(URI)thatisprefixedby"tel:"(forexampletel:14155551212).
1.1Createtheappandlayout
1. CreateaprojectusingtheEmptyActivitytemplateandcallitPhoneCallDial.
2. Addaniconforthecallbuttonbyfollowingthesesteps:
i. Selectthedrawable/folderintheProject:AndroidviewandchooseFile>New>VectorAsset.
ii. ClicktheAndroidiconnextto"Icon:"tochooseanicon.Tofindahandseticon,chooseCommunicationintheleftcolumn.
iii. Selecttheicon,clickOK,clickNext,andthenclickFinish.
3. Opentheactivity_main.xmllayoutfile.
i. ChangetherootviewtoRelativeLayout.ii. Inthe"HelloWorld"TextViewelement,removethelayout_constraintattributes,if
theyarepresent.iii. ChangetheTextViewtoshowadummycontactname,asiftheapphadretrieved
thenamefromacontactsdatabaseandassignedittoaTextView:
4. Extractthestringsanddimensionsintoresources:
24sp:contact_text_sizeforthetextsize.JaneDoe:contact_nameforthetext.
5. AddanotherTextViewforthephonenumber:
1.1:MakingPhoneCalls-Part1
34
-
Youwillusetheandroid:idnumber_to_calltoretrievethephonenumber.
6. Afteraddingahard-codedphonenumberstring,extractitintotheresourcephone_number.
7. AddanImageButtonforinitiatingthecall:
Usethevectorassetyouaddedpreviously(forexampleic_call_black_24dpforaphonehandseticon)fortheandroid:srcattribute.Youwillusetheandroid:id@phone_icontorefertothebuttonfordialingthephone.
ThedialNumbermethodreferredtointheandroid:onClickattributeremainshighlighteduntilyoucreatethismethodintheMainActivity,whichyoudointhenextstep.
8. Afteraddingahard-codedcontentdescription,extractitintothestringresourcemake_a_call.
9. ClickdialNumberintheandroid:onClickattribute,clicktheredlightbulbthatappears,andthenselectCreatedialNumber(View)in'MainActivity'.AndroidStudioautomaticallycreatesthedialNumber()methodinMainActivityaspublic,returningvoid,withaViewparameter.ThismethodiscalledwhentheusertapstheImageButton.
publicvoiddialNumber(Viewview){}
1.1:MakingPhoneCalls-Part1
35
-
Thelayoutshouldlooksomethinglikethefigurebelow.
1.1:MakingPhoneCalls-Part1
36
-
1.1:MakingPhoneCalls-Part1
37
-
ThefollowingisthecompletecodefortheXMLlayoutinactivity_main.xml,includingcomments:
1.2EdittheonClickmethodinMainActivity
1. InMainActivity,defineaconstantforthelogtag.
publicstaticfinalStringTAG=MainActivity.class.getSimpleName();
2. InsidethedialNumber()methodcreatedintheprevioussection,createareferencetothenumber_to_callTextView:
publicvoiddialNumber(Viewview){TextViewtextView=(TextView)findViewById(R.id.number_to_call);...
1.1:MakingPhoneCalls-Part1
38
-
3. TocreatethephonenumberURIstringphoneNumber,getthephonenumberfromtextViewanduseitwithString.formattoincludethetel:prefix:
...//Useformatwith"tel:"andphonenumbertocreatemPhoneNum.StringphoneNumber=String.format("tel:%s",textView.getText().toString());...
4. Defineanimplicitintent(dialIntent)withtheintentactionACTION_DIAL,andsetthephoneNumberasdatafortheintent:
...//Createtheintent.IntentdialIntent=newIntent(Intent.ACTION_DIAL);//Setthedatafortheintentasthephonenumber.dialIntent.setData(Uri.parse(phoneNumber));...
5. Toverifythatanappexiststoreceivetheintent,callresolveActivity()onyourIntentobjectwithgetPackageManager()togetaPackageManagerinstanceforfindingpackageinformation.TheresolveActivity()methoddeterminesthebestactiontoperformforagivenintent.Iftheresultisnon-null,thereisatleastoneappthatcanhandletheintentandit'ssafetocallstartActivity().
...//Ifpackageresolvestoanapp,sendintent.if(dialIntent.resolveActivity(getPackageManager())!=null){startActivity(dialIntent);}else{Log.e(TAG,"Can'tresolveappforACTION_DIALIntent.");}...
Thefullmethodshouldnowlooklikethefollowing:
1.1:MakingPhoneCalls-Part1
39
https://developer.android.com/reference/android/content/pm/PackageManager.html#resolveActivity(android.content.Intent,%20int)https://developer.android.com/reference/android/content/Context.html#getPackageManager()
-
publicvoiddialNumber(){TextViewtextView=(TextView)findViewById(R.id.number_to_call);//Useformatwith"tel:"andphonenumbertocreatephoneNumber.StringphoneNumber=String.format("tel:%s",textView.getText().toString());//Createtheintent.IntentdialIntent=newIntent(Intent.ACTION_DIAL);//Setthedatafortheintentasthephonenumber.dialIntent.setData(Uri.parse(phoneNumber));//Ifpackageresolvestoanapp,sendintent.if(dialIntent.resolveActivity(getPackageManager())!=null){startActivity(dialIntent);}else{Log.e(TAG,"Can'tresolveappforACTION_DIALIntent.");}}
1.3Runtheapp
Youcanruntheapponeitheranemulatororadevice:
1. Clickortapthephoneicon.Thedialershouldappearwiththephonenumberreadytouse,asshowninthefigurebelow:
1.1:MakingPhoneCalls-Part1
40
-
1.1:MakingPhoneCalls-Part1
41
-
2. Thephone_numberstringholdsafixednumber(1-415-555-1212).YoucanchangethenumberinthePhoneapp'sdialerbeforecalling.
3. UsetheBackbuttontoreturntotheapp.YoumayneedtotaporclickittwoorthreetimestonavigatebackwardsfromthePhoneapp'sdialerandFavoriteslist.
Solutioncode
AndroidStudioproject:PhoneCallDial
Task2.MakeaphonecallfromwithinanappInthistaskyouwillcopythePhoneCallDialappfromtheprevioustask,refactorandrenameittoPhoneCallingSample,andmodifyitslayoutandcodetocreateanappthatenablesausertoenteraphonenumberandperformthephonecallfromwithinyourapp.
Inthefirststepyouwilladdthecodetomakethecall,buttheappwillworkonlyiftelephonyisenabled,andiftheapp'spermissionforPhoneissetmanuallyinSettingsonthedeviceoremulator.
Insubsequentstepsyouwilldoawaywithsettingthispermissionmanuallybyrequestingphonepermissionfromtheuserifitisnotalreadygranted.Youwillalsoaddatelephonychecktodisplayamessageiftelephonyisnotenabledandcodetomonitorthephonestate.
2.1Createtheappandaddpermission
1. CopythePhoneCallDialprojectfolder,renamethefoldertoPhoneCallingSample,andrefactortheapptopopulatethenewnamethroughouttheappproject.(SeetheAppendixforinstructionsoncopyingaproject.)
2. AddthefollowingpermissiontotheAndroidManifest.xmlfileafterthefirstline(withthepackagedefinition)andbeforethesection:
Yourappcan'tmakeaphonecallwithouttheCALL_PHONEpermissionlineinAndroidManifest.xml.ThispermissionlineenablesasettingfortheappintheSettingsappthatgivestheuserthechoiceofallowingordisallowinguseofthephone.(Inthenexttaskyouwilladdawayfortheusertograntthatpermissionfromwithintheapp.)
2.2Createtheapplayout
1.1:MakingPhoneCalls-Part1
42
https://github.com/google-developer-training/android-fundamentals-phone-sms/tree/master/PhoneCallDialhttps://google-developer-training.gitbooks.io/android-developer-fundamentals-course-practicals/content/appendix_utilities.html
-
1. Openactivity_main.xmltoeditthelayout.2. Removethecontact_nameTextView,andreplacethenumber_to_callTextViewwith
thefollowingEditTextview:
3. Afteraddingahard-codedstringfortheandroid:hintattribute,extractitintothestringresourceenter_phone,andnotethefollowing:
Youwillusetheandroid:idfortheEditTextviewinyourcodetoretrievethephonenumber.TheEditTextviewusestheandroid:inputTypeattributesetto"phone"foraphone-stylenumerickeypad.
4. ChangetheImageButtonasfollows:
i. Changetheandroid:layout_below,android:layout_toRightOf,andandroid:layout_toEndOfattributestorefertoeditText_main.
ii. Addtheandroid:visibilityattributesettovisible.YouwillcontrolthevisibilityofthisImageButtonfromyourcode.
iii. Changetheandroid:onClickmethodtocallNumber.ThiswillremainhighlighteduntilyouaddthatmethodtoMainActivity.
5. AddthefollowingButtonattheendofthelayout,beforetheendingtag:
1.1:MakingPhoneCalls-Part1
43
-
6. Afteraddingahard-codedstring"Retry"fortheandroid:contentDescriptionattribute,extractitintothestringresourceretry,andthenreplacethehard-codedstringintheandroid:textattributeto"@string/retry".
7. Notethefollowing:Youwillrefertothetheandroid:idbutton_retryinyourcode.Makesureyouincludetheandroid:visibilityattributesetto"invisible".Itshouldappearonlyiftheappdetectsthattelephonyisnotenabled,oriftheuserpreviouslydeniedphonepermissionwhentheapprequestedit.
Yourapp'slayoutshouldlooklikethefollowingfigure(thebutton_retryButtonisinvisible):
1.1:MakingPhoneCalls-Part1
44
-
1.1:MakingPhoneCalls-Part1
45
-
2.3ChangetheonClickmethodinMainActivity
1. InMainActivity,refactorandrenamethedialNumber()methodtocallitcallNumber().2. Changethefirststatement,whichreferredtoaTextView,touseanEditTextview:
publicvoidcallNumber(Viewview){EditTexteditText=(EditText)findViewById(R.id.editText_main);...}
3. ChangethenextstatementtogetthephonenumberfromtheEditTextview(editText)tocreatethephonenumberURIstringphoneNumber:
//Useformatwith"tel:"andphonenumbertocreatephoneNumber.StringphoneNumber=String.format("tel:%s",editText.getText().toString());
4. Beforetheintent,addcodetoshowalogmessageandatoastmessagewiththephonenumber:
//Logtheconcatenatedphonenumberfordialing.Log.d(TAG,"PhoneStatus:DIALING:"+phoneNumber);Toast.makeText(this,"PhoneStatus:DIALING:"+phoneNumber,Toast.LENGTH_LONG).show();
5. Extract"PhoneStatus:DIALING:"toastringresource(dial_number).ReplacetheseconduseofthestringintheToast.makeText()statementtogetString(R.string.dial_number).
6. RefactorandrenamethedialIntentimplicitintenttocallIntent,andreplaceACTION_DIALwithACTION_CALL.Asaresult,thestatementsshouldnowlooklikethis:
...//Createtheintent.IntentcallIntent=newIntent(Intent.ACTION_CALL);//Setthedatafortheintentasthephonenumber.callIntent.setData(Uri.parse(phoneNumber));//Ifpackageresolvestoanapp,sendintent.if(callIntent.resolveActivity(getPackageManager())!=null){startActivity(callIntent);}else{Log.e(TAG,"Can'tresolveappforACTION_CALLIntent.");}...
Thefullmethodshouldnowlooklikethefollowing:
1.1:MakingPhoneCalls-Part1
46
-
publicvoidcallNumber(){EditTexteditText=(EditText)findViewById(R.id.editText_main);//Useformatwith"tel:"andphonenumbertocreatephoneNumber.StringphoneNumber=String.format("tel:%s",editText.getText().toString());//Logtheconcatenatedphonenumberfordialing.Log.d(TAG,getString(R.string.dial_number)+phoneNumber);Toast.makeText(this,getString(R.string.dial_number)+phoneNumber,Toast.LENGTH_LONG).show();//Createtheintent.IntentcallIntent=newIntent(Intent.ACTION_CALL);//Setthedatafortheintentasthephonenumber.callIntent.setData(Uri.parse(phoneNumber));//Ifpackageresolvestoanapp,sendintent.if(callIntent.resolveActivity(getPackageManager())!=null){startActivity(callIntent);}else{Log.e(TAG,"Can'tresolveappforACTION_CALLIntent.");}}
2.4Runtheapp
Whenyouruntheapp,theappmaycrashwiththefollowingscreendependingonwhetherthedeviceoremulatorhasbeenpreviouslysettoallowtheapptomakephonecalls:
1.1:MakingPhoneCalls-Part1
47
-
1.1:MakingPhoneCalls-Part1
48
-
InsomeversionsofAndroid,thispermissionisturnedonbydefault.Inothers,thispermissionisturnedoffbydefault.
Tosettheapp'spermissiononadeviceoremulatorinstance,performthefunctionthatauserwouldperform:chooseSettings>Apps>PhoneCallingSample>Permissionsonthedeviceoremulator,andturnonthePhonepermissionfortheapp.SincetheusercanturnonoroffPhonepermissionatanytime,youhavetoaddacheckinyourappforthispermission,andrequestitfromtheuserifrequired.Youwilldothisinthenexttask.
Ifyoudon'thavecellularserviceonyourdevice,oriftelephonyisnotenabled,youcantesttheappusingtwoemulatorinstances—oneemulatorinstancecallstheotherone.Followthesesteps:
1. TolaunchanemulatordirectlyfromtheAVDManager,chooseTools>Android>AVDManager.
2. Double-clickapredefineddevice.Notethenumberthatappearsintheemulator'swindowtitleonthefarright,asshowninthefigurebelowas#1(5556).Thisistheport
numberoftheemulatorinstance.
3. OpentheAndroidStudioprojectfortheapp,ifitisn'talreadyopen.
1.1:MakingPhoneCalls-Part1
49
-
4. Runtheapp,butchooseanotheremulator—nottheonethatisalreadyrunning.AndroidStudiolaunchestheotheremulator.
5. Intheapp,entertheportnumberoftheotheremulatorratherthanarealphonenumber.
6. Clickthecallbuttonintheapp.Theemulatorshowsthephonecallstartingup,asshowninthefigurebelow.
1.1:MakingPhoneCalls-Part1
50
-
1.1:MakingPhoneCalls-Part1
51
-
Theotheremulatorinstanceshouldnowbereceivingthecall,asshowninthefigurebelow:
1.1:MakingPhoneCalls-Part1
52
-
1.1:MakingPhoneCalls-Part1
53
-
7. ClickAnswerorDismissontheemulatorreceivingthecall.IfyouclickAnswer,alsoclicktheredHang-upbuttontoendthecall.
1.1:MakingPhoneCalls-Part1
54
-
1.1:MakingPhoneCalls-Part1
55
-
EndofPart1-ContinuewithPart2
1.1:MakingPhoneCalls-Part1
56
-
1.2:Part2-MakingPhoneCallsContents:
Task3:CheckfortelephonyserviceandrequestpermissionTask4:MonitorthephonestateCodingchallengeSummaryRelatedconceptLearnmore
Task3.CheckfortelephonyserviceandrequestpermissionIftelephonyfeaturesarenotenabledforadevice,yourappshoulddetectthatanddisablethephonefeatures.
Inaddition,yourappmustalwaysgetpermissiontouseanythingthatisnotpartoftheappitself.IntheprevioustaskyouaddedthefollowingpermissiontotheAndroidManifest.xmlfile:
ThisstatementenablesapermissionsettingforthisappinSettings.TheusercanallowordisallowthispermissionatanytimeinSettings.Youcanaddcodetorequestpermissioniftheuserhasturnedoffphonepermission.
3.1Checkiftelephonyservicesareenabled
1. OpentheAndroidStudioprojectforthePhoneCallingSampleapp,ifitisn'talreadyopen.
2. AtthetopofMainActivitybelowtheclassdefinition,defineavariablefortheTelephonyManagerclassobject:
privateTelephonyManagermTelephonyManager;
3. AddthefollowingstatementtoonCreate()methodinMainActivitytousethestringconstantTELEPHONY_SERVICEwithgetSystemService()andassignitto
1.2:MakingPhoneCalls-Part2
57
https://developer.android.com/reference/android/telephony/TelephonyManager.html
-
mTelephonyManager.Thisgivesyouaccesstosomeofthetelephonyfeaturesofthedevice.
@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//Createatelephonymanager.mTelephonyManager=(TelephonyManager)getSystemService(TELEPHONY_SERVICE);
4. CreateamethodinMainActivitytocheckiftelephonyisenabled:
privatebooleanisTelephonyEnabled(){if(mTelephonyManager!=null){if(mTelephonyManager.getSimState()==TelephonyManager.SIM_STATE_READY){returntrue;}}returnfalse;}
5. CalltheabovemethodintheonCreate()method,rightafterassigningmTelephonyManager,inanifstatementtotakeactioniftelephonyisenabled.Theactionshouldbetologamessage(toshowthattelephonyisenabled),andincludeacommentaboutcheckingpermission,whichyouwilladdinthenextstep.Iftelephonyisnotenabled,displayatoastmessage,logamessage,anddisablethecallbutton:
@OverrideprotectedvoidonCreate(BundlesavedInstanceState){...mTelephonyManager=(TelephonyManager)getSystemService(TELEPHONY_SERVICE);if(isTelephonyEnabled()){Log.d(TAG,"Telephonyisenabled");//ToDo:Checkforphonepermission.//ToDo:RegisterthePhoneStateListener.}else{Toast.makeText(this,"TELEPHONYNOTENABLED!",Toast.LENGTH_LONG).show();Log.d(TAG,"TELEPHONYNOTENABLED!");//DisablethecallbuttondisableCallButton();}}
1.2:MakingPhoneCalls-Part2
58
-
6. Extractthehard-codedstringsintheabovecodetostringresources:
"Telephonyisenabled":telephony_enabled"TELEPHONYNOTENABLED!":telephony_not_enabled
7. CreatethedisableCallButton()methodinMainActivity,andcodeto:
Displayatoasttonotifytheuserthatthephonefeatureisdisabled.Findandthensetthecallbuttontobeinvisiblesothattheusercan'tmakeacall.Iftelephonyisenabled(butthephonepermissionhadnotbeengranted),settheRetrybuttontobevisible,sothattheusercanstarttheactivityagainandallowpermission.
privatevoiddisableCallButton(){Toast.makeText(this,"Phonecallingdisabled",Toast.LENGTH_LONG).show();ImageButtoncallButton=(ImageButton)findViewById(R.id.phone_icon);callButton.setVisibility(View.INVISIBLE);if(isTelephonyEnabled()){ButtonretryButton=(Button)findViewById(R.id.button_retry);retryButton.setVisibility(View.VISIBLE);}}
8. Extractastringresource(phone_disabled)forthehard-codedstring"Phonecallingdisabled"inthetoaststatement.
9. CreateanenableCallButton()methodinMainActivitythatfindsandthensetsthecallbuttontobevisible:
privatevoidenableCallButton(){ImageButtoncallButton=(ImageButton)findViewById(R.id.phone_icon);callButton.setVisibility(View.VISIBLE);}
10. CreatetheretryApp()methodinMainActivitythatwillbecalledwhentheuserclicksthevisibleRetrybutton.Addcodeto:
CallenableCallButton()toenablethecallbutton.Createanintenttostart(inthiscase,restart)theactivity.
publicvoidretryApp(Viewview){enableCallButton();Intentintent=getPackageManager().getLaunchIntentForPackage(getPackageName());startActivity(intent);}
11. Addtheandroid:onClickattributetotheRetrybuttontocallretryApp:
1.2:MakingPhoneCalls-Part2
59
-
3.2Requestpermissionforphonecalling
1. AtthetopofMainActivitybelowtheclassdefinition,defineaglobalconstantforthecall-phonepermissionrequestcode,andsetitto1:
privatestaticfinalintMY_PERMISSIONS_REQUEST_CALL_PHONE=1;
Whytheinteger1?Eachpermissionrequestneedsthreeparameters:thecontext,astringarrayofpermissions,andanintegerrequestCode.TherequestCodeisacodeattachedtotherequest,andcanbeanyintegerthatsuitsyourusecase.Whenaresultreturnsbacktotheactivity,itcontainsthiscodeandusesittodifferentiatemultiplepermissionresultsfromeachother.
2. InMainActivity,createaprivatemethodcalledcheckForPhonePermissiontocheckforCALL_PHONEpermission,whichreturnsvoid.Youputthiscodeinaseparatemethodbecauseyouwilluseitmorethanonce:
privatevoidcheckForPhonePermission(){if(ActivityCompat.checkSelfPermission(this,Manifest.permission.CALL_PHONE)!=PackageManager.PERMISSION_GRANTED){Log.d(TAG,"PERMISSIONNOTGRANTED!");ActivityCompat.requestPermissions(this,newString[]{Manifest.permission.CALL_PHONE},MY_PERMISSIONS_REQUEST_CALL_PHONE);}else{//Permissionalreadygranted.Enablethecallbutton.enableCallButton();}}
3. UsecheckSelfPermission()todeterminewhetheryourapphasbeengrantedaparticularpermissionbytheuser.Ifpermissionhasnotbeengrantedbytheuser,usetherequestPermissions()methodtodisplayastandarddialogfortheusertograntpermission.
4. WhenyourappcallsrequestPermissions(),thesystemshowsastandarddialogtotheuser,asshowninthefigurebelow.
1.2:MakingPhoneCalls-Part2
60
https://developer.android.com/reference/android/support/v4/content/ContextCompat.html#checkSelfPermission(android.content.Context,%20java.lang.String)https://developer.android.com/reference/android/support/v4/app/ActivityCompat.html#requestPermissions(android.app.Activity,%20java.lang.String[],%20int)https://developer.android.com/reference/android/support/v4/app/ActivityCompat.html#requestPermissions(android.app.Activity,%20java.lang.String[],%20int)
-
1.2:MakingPhoneCalls-Part2
61
-
5. Extractthehard-codedstring"PERMISSIONNOTGRANTED!"intheabovecodetothestringresourcepermission_not_granted.
6. IntheonCreate()methodaftercheckingtoseeiftelephonyisenabled,addacalltocheckForPhonePermission():
@OverrideprotectedvoidonCreate(BundlesavedInstanceState){...if(isTelephonyEnabled()){//Checkforphonepermission.checkForPhonePermission();//ToDo:RegisterthePhoneStateListener....
7. Whentheuserrespondstotherequestpermissiondialog,thesysteminvokesyourapp'sonRequestPermissionsResult()method,passingittheuserresponse.Overridethatmethodtofindoutwhetherthepermissionwasgranted:
@OverridepublicvoidonRequestPermissionsResult(intrequestCode,Stringpermissions[],int[]grantResults){//Checkifpermissionisgrantedornotfortherequest....}
8. ForyourimplementationofonRequestPermissionsResult(),useaswitchstatementwitheachcasebasedonthevalueofrequestCode.UseonecasetocheckifthepermissionistheoneyoudefinedasMY_PERMISSIONS_REQUEST_CALL_PHONE:
1.2:MakingPhoneCalls-Part2
62
https://developer.android.com/reference/android/support/v4/app/ActivityCompat.OnRequestPermissionsResultCallback.html#onRequestPermissionsResult(int,%20java.lang.String[],%20int[])
-
...//Checkifpermissionisgrantedornotfortherequest.switch(requestCode){caseMY_PERMISSIONS_REQUEST_CALL_PHONE:{if(permissions[0].equalsIgnoreCase(Manifest.permission.CALL_PHONE)&&grantResults[0]==PackageManager.PERMISSION_GRANTED){//Permissionwasgranted.}else{//Permissiondenied.Log.d(TAG,"Failuretoobtainpermission!");Toast.makeText(this,"Failuretoobtainpermission!",Toast.LENGTH_LONG).show();//DisablethecallbuttondisableCallButton();}}}
9. Extractthehard-codedstring"Failuretoobtainpermission!"intheabovecodetothestringresourcefailure_permission,andnotethefollowing:
Theuser'sresponsetotherequestdialogisreturnedinthepermissionsarray(index0ifonlyonepermissionisrequestedinthedialog).Thecodesnippetabovecomparesthistothecorrespondinggrantresult,whichiseitherPERMISSION_GRANTEDorPERMISSION_DENIED.Iftheuserdeniesapermissionrequest,yourappshouldtakeappropriateaction.Forexample,yourappmightdisablethefunctionalitythatdependsonthispermissionandshowadialogexplainingwhyitcouldnotperformit.Fornow,logadebugmessage,displayatoasttoshowthatpermissionwasnotgranted,anddisablethecallbuttonwithdisableCallButton().
3.3Runtheappandtestpermission
1. Runtheapponce.Afterrunningtheapp,turnoffthePhonepermissionfortheapponyourdeviceoremulatorsothatyoucantestthepermission-requestfunction:
i. ChooseSettings>Apps>PhoneCallingSample>Permissionsonthedeviceoremulator.
ii. TurnoffthePhonepermissionfortheapp.
2. Runtheappagain.Youshouldseetherequestdialoginthefigureintheprevioussection.
1.2:MakingPhoneCalls-Part2
63
-
i. TapDenytodenypermission.Theappshoulddisplayatoastmessageshowingthefailuretogainpermission,andtheRetrybutton.Thephoneiconshoulddisappear.
ii. TapRetry,andwhentherequestdialogappears,tapAllow.Thephoneiconshouldreappear.Testtheapp'sabilitytomakeaphonecall.
3. SincetheusermightturnoffPhonepermissionwhiletheappisstillrunning,addthesamepermissioncheckmethodtothecallNumber()method—aftertheintentresolvestoapackage,asshownbelow—tocheckforpermissionrightbeforemakingacall:
//Ifpackageresolvestoanapp,checkforphonepermission,//andsendintent.if(callIntent.resolveActivity(getPackageManager())!=null){checkForPhonePermission();startActivity(callIntent);}else{Log.e(TAG,"Can'tresolveappforACTION_CALLIntent");}
4. Runtheapp.IftheuserchangesthePhonepermissionfortheappwhiletheappisrunning,therequestdialogappearsagainfortheusertoAlloworDenythepermission.
i. ClickAllowtotesttheapp'sabilitytomakeaphonecall.Theappshouldmakethecallwithoutaproblem.
ii. JumptotheSettingsapptoturnoffPhonepermissionfortheapp(theappshouldstillberunning):
i. ChooseSettings>Apps>PhoneCallingSample>Permissionsonthedeviceoremulator.
ii. TurnoffthePhonepermissionfortheapp.
iii. Gobacktotheappandtrytomakeacall.Therequestdialogshouldappearagain.Thistime,ClickDenytodenypermissiontomakeaphonecall.Theappshoulddisplayatoastmessageshowingthefailuretogainpermission,andtheRetrybutton.Thephoneiconshoulddisappear.
Task4.MonitorthephonestateYoucanmonitorthephonestatewithPhoneStateListener,whichmonitorschangesinspecifictelephonystates.Youcanthenshowtheuserthestateinatoastmessage,sothattheusercanseeifthephoneisidleoroffthehook.
1.2:MakingPhoneCalls-Part2
64
https://developer.android.com/reference/android/telephony/PhoneStateListener.html
-
Whenthephonecallfinishesandthephoneswitchestotheidlestate,yourapp'sactivityresumesiftheappisrunningonKitKat(version19)ornewerversions.However,iftheappisrunningonaversionofAndroidolderthanKitKat(version19),thePhoneappremainsactive.Youcancheckthephonestateandrestarttheactivityifthestateisidle.
TousePhoneStateListener,youneedtoregisteralistenerobjectusingtheTelephonyManagerclass,whichprovidesaccesstoinformationaboutthetelephonyservicesonthedevice.CreateanewclassthatextendsPhoneStateListenertoperformactionsdependingonthephonestate.YoucanthenregisterthelistenerobjectintheonCreate()methodoftheactivity,usingtheTelephonyManagerclass.
4.1Setthepermissionandloggingtag
1. OpentheAndroidStudioprojectforthePhoneCallingSampleapp,ifitisn'talreadyopen.
2. AddthefollowingREAD_PHONE_STATEpermissiontotheAndroidManifest.xmlfileafteraftertheCALL_PHONEpermission,andbeforethesection:
Monitoringthestateofaphonecallispermission-protected.ThispermissionisinadditiontotheCALL_PHONEpermission.
4.2CreateaclassthatextendsPhoneStateListener
1. Tocreatealistenerobjectandlistentothephonestate,createaprivateinnerclasscalledMyPhoneCallListenerinMainActivitythatextendsPhoneStateListener.
privateclassMyPhoneCallListenerextendsPhoneStateListener{...}
2. Withinthisclass,implementtheonCallStateChanged()methodofPhoneStateListenertotakeactionsbasedonthephonestate.ThecodebelowusesaswitchstatementwithconstantsoftheTelephonyManagerclasstodeterminewhichofthreestatesthephoneisin:CALL_STATE_RINGING,CALL_STATE_OFFHOOK,andCALL_STATE_IDLE:
1.2:MakingPhoneCalls-Part2
65
https://developer.android.com/reference/android/telephony/TelephonyManager.htmlhttps://developer.android.com/reference/android/telephony/PhoneStateListener.html#onCallStateChanged(int,%20java.lang.String)https://developer.android.com/reference/android/telephony/TelephonyManager.html
-
@OverridepublicvoidonCallStateChanged(intstate,StringincomingNumber){switch(state){caseTelephonyManager.CALL_STATE_RINGING://Incomingcallisringing(notusedforoutgoingcall).break;caseTelephonyManager.CALL_STATE_OFFHOOK://Phonecallisactive--offthehook.break;caseTelephonyManager.CALL_STATE_IDLE://Phoneisidlebeforeandafterphonecall.break;default://Mustbeanerror.Raiseanexceptionorjustlogit.break;}}
3. Justabovetheswitch(state)line,createaStringcalledmessagetouseinatoastasaprefixforthephonestate:
...//Defineastringforthemessagetouseinatoast.Stringmessage="PhoneStatus:";switch(state){...
4. Extractthestring"PhoneStatus:"tothestringresourcephone_status.5. FortheCALL_STATE_RINGINGstate,assembleamessageforlogginganddisplayinga
toastwiththeincomingphonenumber:
...switch(state){caseTelephonyManager.CALL_STATE_RINGING://Incomingcallisringing(notusedforoutgoingcall).message=message+"RINGING,number:"+incomingNumber;Toast.makeText(MainActivity.this,message,Toast.LENGTH_SHORT).show();Log.i(TAG,message);break;...
6. Extract"RINGING,number:"tothestringresourceringing.7. AddabooleanreturningFromOffHook,settofalse,atthetopofthe
MyPhoneCallListenerdeclaration,inordertouseitwiththetheCALL_STATE_OFFHOOKstate:
1.2:MakingPhoneCalls-Part2
66
-
privateclassMyPhoneCallListenerextendsPhoneStateListener{privatebooleanreturningFromOffHook=false;...}
Tip:AnapprunningonAndroidversionspriortoKitKat(version19)doesn'tresumewhenthephonestatereturnstoCALL_STATE_IDLEfromCALL_STATE_OFFHOOKattheendofacall.ThebooleanreturningFromOffHookisusedasaflag,andsettotruewhenthestateisCALL_STATE_OFFHOOK,sothatwhenthestateisbacktoCALL_STATE_IDLE,theflagdesignatesanend-of-callinordertorestarttheapp'sactivity.
8. FortheCALL_STATE_OFFHOOKstate,assembleamessageforlogginganddisplayingatoast,andsetthereturningFromOffHookbooleantotrue.
...switch(state){caseTelephonyManager.CALL_STATE_OFFHOOK://Phonecallisactive--offthehook.message=message+"OFFHOOK";Toast.makeText(MainActivity.this,message,Toast.LENGTH_SHORT).show();Log.i(TAG,message);returningFromOffHook=true;break;...
9. Extract"OFFHOOK"tothestringresourceoffhook.10. FortheCALL_STATE_IDLEstate,loganddisplayatoast,andcheckif
returningFromOffHookistrue;ifso,restarttheactivityiftheversionofAndroidisearlierthanKitKat.
1.2:MakingPhoneCalls-Part2
67
-
...switch(state){caseTelephonyManager.CALL_STATE_IDLE://Phoneisidlebeforeandafterphonecall.//Ifrunningonversionolderthan19(KitKat),//restartactivitywhenphonecallends.message=message+"IDLE";Toast.makeText(MainActivity.this,message,Toast.LENGTH_SHORT).show();Log.i(TAG,message);if(returningFromOffHook){//Noneedtodoanythingif>=versionKitKat.if(Build.VERSION.SDK_INT<Build.VERSION_CODES.KITKAT){Log.i(TAG,"Restartingapp");//Restarttheapp.Intentintent=getPackageManager().getLaunchIntentForPackage(.getPackageName());intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);startActivity(intent);}}break;...
IftheappisrunningonKitKat(version19)ornewerversions,thereisnoneedtorestarttheactivityafterthephonecallends.ButiftheappisrunningonaversionofAndroidolderthanKitKat(version19),thecodemustrestartthecurrentactivitysothattheusercanreturntotheappafterthecallends.
Tip:ThecodealsosetsFLAG_ACTIVITY_CLEAR_TOPsothatinsteadoflaunchinganewinstanceofthecurrentactivity,anyotheractivitiesontopofthecurrentactivityareclosedandanintentisdeliveredtothe(nowontop)currentactivity.Thisflaghelpsyoumanageastackofactivitiesinanapp.
11. Extract"IDLE"tothestringresourceidle,andextract"Restartingapp"tothestringresourcerestarting_app.
ThecodebelowshowstheentireonCallStateChanged()method:
...@OverridepublicvoidonCallStateChanged(intstate,StringincomingNumber){//Defineastringforthemessagetouseinatoast.Stringmessage=getString(R.string.phone_status);switch(state){caseTelephonyManager.CALL_STATE_RINGING://Incomingcallisringing(notusedforoutgoingcall).
1.2:MakingPhoneCalls-Part2
68
https://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_CLEAR_TOP
-
message=message+getString(R.string.ringing)+incomingNumber;Toast.makeText(MainActivity.this,message,Toast.LENGTH_SHORT).show();Log.i(TAG,message);break;caseTelephonyManager.CALL_STATE_OFFHOOK://Phonecallisactive--offthehook.message=message+getString(R.string.offhook);Toast.makeText(MainActivity.this,message,Toast.LENGTH_SHORT).show();Log.i(TAG,message);returningFromOffHook=true;break;caseTelephonyManager.CALL_STATE_IDLE://Phoneisidlebeforeandafterphonecall.//Ifrunningonversionolderthan19(KitKat),//restartactivitywhenphonecallends.message=message+getString(R.string.idle);Toast.makeText(MainActivity.this,message,Toast.LENGTH_SHORT).show();Log.i(TAG,message);if(returningFromOffHook){//Noneedtodoanythingif>=versionKitKat.if(Build.VERSION.SDK_INT<Build.VERSION_CODES.KITKAT){Log.i(TAG,getString(R.string.restarting_app));//Restarttheapp.Intentintent=getPackageManager().getLaunchIntentForPackage(.getPackageName());intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);startActivity(intent);}}break;default:message=message+"Phoneoff";Toast.makeText(MainActivity.this,message,Toast.LENGTH_SHORT).show();Log.i(TAG,message);break;}}...
4.3RegisterthePhoneStateListener
1. AtthetopofMainActivitybelowtheclassdefinition,defineavariableforthePhoneStateListener:
1.2:MakingPhoneCalls-Part2
69
https://developer.android.com/reference/android/telephony/PhoneStateListener.html
-
privateMyPhoneCallListenermListener;
2. IntheonCreate()method,addthefollowingcodeaftercheckingfortelephonyandpermission:
...if(isTelephonyEnabled()){...checkForPhonePermission();//RegisterthePhoneStateListenertomonitorphoneactivity.mListener=newMyPhoneCallListener();telephonyManager.listen(mListener,PhoneStateListener.LISTEN_CALL_STATE);}else{...
3. Youmustalsounregisterthelistenerintheactivity'sonDestroy()method.OverridetheonDestroy()methodbyaddingthefollowingcode:
@OverrideprotectedvoidonDestroy(){super.onDestroy();if(isTelephonyEnabled()){telephonyManager.listen(mListener,PhoneStateListener.LISTEN_NONE);}}
4.4Runtheapp
1. Runtheapp.IftheuserchangesthePhonepermissionfortheappwhiletheappisrunning,therequestdialogappearsagainfortheusertoAlloworDenythepermission.ClickAllowtotesttheapp'sabilitytomakeaphonecall.
2. Afterenteringaphonenumberandclickingthecallbutton,theemulatorordeviceshowsthephonecallstartingup,asshowninthefigurebelow.Atoastmessageappearsshowingthephonenumber(leftsideoffigure),andthetoastmessagechangestoshowanewstatusof"OFFHOOK"(rightsideoffigure)afterthecallhasstarted.
1.2:MakingPhoneCalls-Part2
70
https://developer.android.com/reference/android/app/Activity.html#onDestroy()
-
3. Theotheremulatorinstanceordeviceshouldnowbereceivingthecall,asshowninthefigurebelow.ClickAnswerorDismissonthedeviceoremulatorreceivingthecall.
1.2:MakingPhoneCalls-Part2
71
-
1.2:MakingPhoneCalls-Part2
72
-
4. IfyouclickAnswer,besuretoalsoclicktheredHang-upbuttontofinishthecall,asshowninthefigurebelow.
1.2:MakingPhoneCalls-Part2
73
-
1.2:MakingPhoneCalls-Part2
74
-
Afteryouhangup,theappshouldreappearwithatoastmessageshowingthatthephoneisnowintheidlestate,asshowninthefigurebelow.
1.2:MakingPhoneCalls-Part2
75
-
1.2:MakingPhoneCalls-Part2
76
-
Solutioncode
AndroidStudioproject:PhoneCallingSample
CodingchallengeNote:Allcodingchallengesareoptionalandarenotprerequisitesforlaterlessons.Challenge:
1. UsethenormalizeNumber()methodinthePhoneNumberUtilsclasstoremovecharactersotherthandigitsfromthephonenumberaftertheuserhasenteredit.ThismethodwasaddedtoAPIlevel21.Ifyouneedyourapptorunonolderversions,includeacheckfortheversionthatusesthenormalizeNumber()methodonlyiftheversionisolderthanLollipop.Yourappalreadyusesalogstatementtoshowthephonenumberasdialed,soiftheuserenters"1-415-555-1212"thelogmessageshouldshowthatthenumberwasnormalized:
D/MainActivity:PhoneStatus:DIALING:tel:14155551212
2. AddaninvisibleTextViewtothePhoneCallingSampleapp.ThisTextViewshouldappearbelowtheinvisibleRetrybutton,butonlywhenthephoneisringing(indicatinganincomingcall),anditshouldshowthephonenumberofthecaller.
Ifyouhavebothemulatorsopenasdescribedpreviously,installtheapponbothemulators.Youcanthentestanincomingcallbyusingtheappononeemulatortocalltheotheremulator.
Tip:Youcanalsoemulatereceivingacallbyclickingthe…(More)iconatthebottomoftheemulator'stoolbarontherightside.ClickPhoneintheleftcolumntoseetheextendedphonecontrols,andclickCallDevicetocalltheemulator.
AndroidStudioproject:PhoneCallingSampleChallenge
SummaryTosendanintenttothePhoneappwithaphonenumber,yourappneedstoprepareaURIforthephonenumberasastringprefixedby"tel:"(forexampletel:14155551212).Todialaphonenumber,createanimplicitintentwithACTION_DIAL,andsetthephonenumberURIasthedatafortheintentwithsetData():
1.2:MakingPhoneCalls-Part2
77
https://github.com/google-developer-training/android-fundamentals-phone-sms/tree/master/PhoneCallingSamplehttps://developer.android.com/reference/android/telephony/PhoneNumberUtils.html#normalizeNumber(java.lang.String)https://developer.android.com/reference/android/telephony/PhoneNumberUtils.htmlhttps://developer.android.com/reference/android/telephony/PhoneNumberUtils.html#normalizeNumber(java.lang.String)https://github.com/google-developer-training/android-fundamentals-phone-sms/tree/master/PhoneCallingSampleChallenge
-
IntentcallIntent=newIntent(Intent.ACTION_DIAL);callIntent.setData(Uri.parse(phoneNumber));
Forphonepermission,addthefollowingtotheAndroidManifest.xmlfile:
Tomakeaphonecall,createanimplicitintentwithACTION_CALL,andsetthephonenumberURIasthedatafortheintentwithsetData():
IntentcallIntent=newIntent(Intent.ACTION_CALL);callIntent.setData(Uri.parse(phoneNumber));
Tocheckiftelephonyisenabled,usethestringconstantTELEPHONY_SERVICEwithgetSystemService()toretrieveaTelephonyManager,whichgivesyouaccesstotelephonyfeatures.UsecheckSelfPermission()todeterminewhetheryourapphasbeengrantedaparticularpermissionbytheuser.Ifpermissionhasnotbeengranted,usetherequestPermissions()methodtodisplayastandarddialogfortheusertograntpermission.TomonitorthephonestatewithPhoneStateListener,registeralistenerobjectusingtheTelephonyManagerclass.Forphonemonitoringpermission,addthefollowingtotheAndroidManifest.xmlfile:
Tomonitorphonestates,createaprivateclassthatextendsPhoneStateListener,andoverridetheonCallStateChanged()methodofPhoneStateListenertotakedifferentactionsbasedonthephonestate:CALL_STATE_RINGING,CALL_STATE_OFFHOOK,orCALL_STATE_IDLE.
RelatedconceptPhoneCalls
LearnmoreAndroiddeveloperdocumentation:
CommonIntentsTelephonyManager
1.2:MakingPhoneCalls-Part2
78
https://developer.android.com/reference/android/content/Context.html#TELEPHONY_SERVICEhttps://developer.android.com/reference/android/content/Context.html#getSystemService(java.lang.String)https://developer.android.com/reference/android/telephony/TelephonyManager.htmlhttps://developer.android.com/reference/android/support/v4/content/ContextCompat.html#checkSelfPermission(android.content.Context,%20java.lang.String)https://developer.android.com/reference/android/support/v4/app/ActivityCompat.html#requestPermissions(android.app.Activity,%20java.lang.String[],%20int)https://developer.android.com/reference/android/telephony/PhoneStateListener.htmlhttps://developer.android.com/reference/android/telephony/TelephonyManager.htmlhttps://developer.android.com/reference/android/telephony/PhoneStateListener.htmlhttps://developer.android.com/reference/android/telephony/PhoneStateListener.html#onCallStateChanged(int,%20java.lang.String)https://developer.android.com/guide/components/intents-common.htmlhttps://developer.android.com/reference/android/telephony/TelephonyManager.html
-
PhoneStateListenerRequestingPermissionsatRunTimecheckSelfPermissionRunAppsontheAndroidEmulatorIntentsandIntentFiltersIntent
StackOverflow:HowtoformataphonenumberusingPhoneNumberUtils?Howtomakephonecallusingintentinandroid?RingingmyselfusingandroidemulatorFakeIncomingCallAndroidSimulatingincomingcallorsmsinAndroidStudio
Other:User(beginner)tutorial:HowtoMakePhoneCallswithAndroidDeveloperVideo:HowtoMakeaPhoneCall
1.2:MakingPhoneCalls-Part2
79
https://developer.android.com/reference/android/telephony/PhoneStateListener.htmlhttps://developer.android.com/training/permissions/requesting.htmlhttps://developer.android.com/reference/android/support/v4/content/ContextCompat.html#checkSelfPermission(android.content.Context,%20java.lang.String)https://developer.android.com/studio/run/emulator.htmlhttp://developer.android.com/guide/components/intents-filters.htmlhttp://developer.android.com/reference/android/content/Intent.htmlhttp://stackoverflow.com/questions/6106859/how-to-format-a-phone-number-using-phonenumberutilshttp://stackoverflow.com/questions/4275678/how-to-make-phone-call-using-intent-in-androidhttp://stackoverflow.com/questions/2577785/ringing-myself-using-android-emulatorhttp://stackoverflow.com/questions/4964703/fake-incoming-call-androidhttp://stackoverflow.com/questions/27638462/simulating-incoming-call-or-sms-in-android-studiohttp://www.beginandroid.com/phonecall.shtmlhttps://youtu.be/3PHDcQOGFtg
-
2:SMSMessagesContents:
SendingandreceivingSMSmessagesUsinganintenttolaunchanSMSappSendingSMSmessagesfromyourappReceivingSMSmessagesRelatedpracticalLearnmore
AndroiddevicescansendandreceivemessagestoorfromanyotherphonethatsupportsShortMessageService(SMS).AndroidofferstheMessengerappthatcansendandreceiveSMSmessages.Ahostofthird-partyappsforsendingandreceivingSMSmessagesarealsoavailableinGooglePlay.
ThischapterdescribeshowtouseSMSinyourapp.Youcanaddcodetoyourappto:
LaunchanSMSmessagingappfromyourapptohandleallSMScommunication.SendanSMSmessagefromwithinyourapp.ReceiveSMSmessagesinyourapp.
Note:TheSMSprotocolwasprimarilydesignedforuser-to-usercommunicationandisnotwell-suitedforappsthatwanttotransferdata.YoushouldnotuseSMStosenddatamessagesfromawebservertoyourapponauserdevice.SMSisneitherencryptednorstronglyauthenticatedoneitherthenetworkorthedevice.
SendingandreceivingSMSmessagesAccesstotheSMSfeaturesofanAndroiddeviceisprotectedbyuserpermissions.Justasyourappneedstheuser'spermissiontousephonefeatures,soalsodoesanappneedtheuser'spermissiontodirectlyuseSMSfeatures.
However,yourappdoesn'tneedpermissiontopassaphonenumbertoaninstalledSMSapp,suchasMessenger,forsendingthemessage.TheMessengerappitselfisgovernedbyuserpermission.
YouhavetwochoicesforsendingSMSmessages:
UseanimplicitIntenttolaunchamessagingappsuchasMessenger,withtheACTION_SENDTOaction.
2:SMSMessages
80
https://developer.android.com/reference/android/content/Intent.htmlhttps://developer.android.com/reference/android/content/Intent.html#ACTION_SENDTO
-
Thisisthesimplestchoiceforsendingmessages.Theusercanaddapictureorotherattachmentinthemessagingapp,ifthemessagingappsupportsaddingattachments.Yourappdoesn'tneedcodetorequestpermissionfromtheuser.IftheuserhasmultipleSMSmessagingappsinstalledontheAndroidphone,theAppchooserwillappearwithalistoftheseapps,andtheusercanchoosewhichonetouse.(Androidsmartphoneswillhaveatleastone,suchasMessenger.)Theusercanchangethemessageinthemessagingappbeforesendingit.TheusernavigatesbacktoyourappusingtheBackbutton.
SendtheSMSmessageusingthesendTextMessage()methodorothermethodsoftheSmsManagerclass.
Thisisagoodchoiceforsendingmessagesfromyourappwithouthavingtouseanotherinstalledapp.Yourcodemustasktheuserforpermissionbeforesendingthemessageiftheuserhasn'talreadygrantedpermission.Theuserstaysinyourappduringandaftersendingthemessage.YoucanmanageSMSoperationssuchasdividingamessageintofragments,sendingamultipartmessage,getcarrier-dependentconfigurationvalues,andsoon.
ToreceiveSMSmessages,thebestpracticeistousetheonReceive()methodoftheBroadcastReceiverclass.TheAndroidframeworksendsoutsystembroadcastsofeventssuchasreceivinganSMSmessage,containingintentsthataremeanttobereceivedusingaBroadcastReceiver.YourappreceivesSMSmessagesbylisteningfortheSMS_RECEIVED_ACTIONbroadcast.
Mostsmartphonesandmobilephonessupportwhatisknownas"PDUmode"forsendingandreceivingSMS.PDU(protocoldataunit)containsnotonlytheSMSmessage,butalsometadataabouttheSMSmessage,suchastextencoding,thesender,SMSservicecenteraddress,andmuchmore.Toaccessthismetadata,SMSappsalmostalwaysusePDUstoencodethecontentsofaSMSmessage.ThesendTextMessage()andsendMultimediaMessage()methodsoftheSmsManagerclassencodethecontentsforyou.WhenreceivingaPDU,youcancreateanSmsMessageobjectfromtherawPDUusingcreateFromPdu().
UsinganintenttolaunchanSMSappTouseanIntenttolaunchanSMSapp,yourappneedstoprepareaUniformResourceIdentifier(URI)forthephonenumberasastringprefixedby"smsto:"(asinsmsto:14155551212).Youcanuseahardcodedphonenumber,suchasthephonenumberof
2:SMSMessages
81
https://developer.android.com/reference/android/telephony/SmsManager.html#sendTextMessage(java.lang.String,%20java.lang.String,%20java.lang.String,%20android.app.PendingIntent,%20android.app.PendingIntent)https://developer.android.com/reference/android/telephony/SmsManager.htmlhttps://developer.android.com/reference/android/content/BroadcastReceiver.html#onReceive(android.content.Context,%20android.content.Intent)https://developer.android.com/reference/android/content/BroadcastReceiver.htmlhttps://developer.android.com/reference/android/provider/Telephony.Sms.Intents.html#SMS_RECEIVED_ACTIONhttps://developer.android.com/reference/android/telephony/SmsManager.html#sendTextMessage(java.lang.String,%20java.lang.String,%20java.lang.String,%20android.app.PendingIntent,%20android.app.PendingIntent)https://developer.android.com/reference/android/telephony/SmsManager.html#sendMultimediaMessage(android.content.Context,%20android.net.Uri,%20java.lang.String,%20android.os.Bundle,%20android.app.PendingIntent)https://developer.android.com/reference/android/telephony/SmsManager.htmlhttps://developer.android.com/reference/android/telephony/SmsMessage.htmlhttps://developer.android.com/reference/android/telephony/SmsMessage.html#createFromPdu(byte[],%20java.lang.String)https://developer.android.com/reference/android/content/Intent.html
-
asupportmessagecenter,orprovideanEditTextfieldinthelayouttoenabletheusertoenteraphonenumber.
Tip:FordetailsaboutusingmethodsinthePhoneNumberUtilsclasstoformataphonenumberstring,seetherelatedconceptPhoneCalls.
Useabutton(suchasanImageButton)thattheusercantaptopassthephonenumbertotheSMSapp.Forexample,anappthatenablesausermakeaphonecalland/orsendamessagetothephonenumbermightofferasimplelayoutwithaphoneiconbuttonforcalling,andamessagingiconbuttonforsendingamessage,asshowninthefigurebelow.
2:SMSMessages
82
https://developer.android.com/reference/android/telephony/PhoneNumberUtils.html
-
2:SMSMessages
83
-
TocallamethodsuchassmsSendMessage()thatwouldlaunchamessagingappwithaphonenumber,youcanaddtheandroid:onClickattributetothebuttonforsendingamessage:
InthesmsSendMessage()method,youwouldconvertthephonenumbertoastringprefixedby"smsto:"(asinsmsto:14155551212).UseanimplicitintentwithACTION_SENDTOtopassthephonenumbertotheSMSapp,andsetthephonenumberandmessagefortheintentwithsetData()andputExtra.
Tip:The"smsto:"prefixwithACTION_SENDTOensuresthatyourintentishandledonlybyatextmessagingapp(andnotbyotheremailorsocialapps).
IftheuserhasseveralSMSmessagingapps,theusercanchoosewhichonetoopen.TheSMSappopenswiththesuppliedphonenumberandmessage,enablingtheusertotapabuttontosendthemessage,orchangethenumberandmessagebeforesending.TheSMSappthensendsthemessage.
Thefollowingcodedemonstrateshowtoperformanimplicitintenttosendamessage:
publicvoidsmsSendMessage(Viewview){//FindtheTextViewnumber_to_callandassignittotextView.TextViewtextView=(TextView)findViewById(R.id.number_to_call);//Concatenate"smsto:"withphonenumbertocreatesmsNumber.StringsmsNumber="smsto:"+textView.getText().toString();//Findthesms_messageview.EditTextsmsEditText=(EditText)findViewById(R.id.sms_message);//Getthetextofthesmsmessage.Stringsms=smsEditText.getText().toString();//Createtheintent.IntentsmsIntent=newIntent(Intent.ACTION_SENDTO);//Setthedatafortheintentasthephonenumber.smsIntent.setData(Uri.parse(smsNumber));//Addthemessage(sms)withthekey("sms_body").smsIntent.putExtra("sms_body",sms);//Ifpackageresolves(targetappinstalled),sendintent.if(smsIntent.resolveActivity(getPackageManager())!=null){startActivity(smsIntent);}else{Log.e(TAG,"Can'tresolveappforACTION_SENDTOIntent.");}}
2:SMSMessages
84
-
Notethefollowingintheabovecode:
Themethodgetsthephonenumberfromthenumber_to_callTextView,andconcatenatesitwiththesmsto:prefix(asinsmsto:14155551212)beforeassigningittosmsNumber.ItalsogetsthemessageenteredintotheEditTextview.TolaunchanSMSmessagingapp,useanimplicitintent(smsIntent)withACTION_SENDTO,andsetthephonenumberandmessagefortheintentwithsetData()andputExtra.
TheputExtra()methodneedstwostrings:thekeyidentifyingthetypeofdata("sms_body")andthedataitself,whichisthetextofthemessage(sms).FormoreinformationaboutcommonintentsandtheputExtra()method,seeCommonIntents:TextMessaging.
Youneedtosupplyachecktoseeiftheimplicitintentresolvestoapackage(anapp),andifitdoes,youneedtostartthesmsIntentactivity.Ifitdoesn't,displayalogmessageaboutthefailure.
SendingSMSmessagesfromyourappTosendanSMSmessagefromyourapp,usethesendTextMessage()methodoftheSmsManagerclass.Performthesestepstoenablesendingmessagesfromwithinyourapp:
1. AddtheSEND_SMSpermissiontosendSMSmessages.2. Checktoseeiftheusercontinuestograntpermission.Ifnot,requestpermission.3. UsethesendTextMessage()methodoftheSmsManagerclass.
Checkingforuserpermission
BeginninginAndroid6.0(APIlevel23),usersgrantpermissionstoappswhiletheappisrunning,notwhentheyinstalltheapp.Thisapproachstreamlinestheappinstallprocess,sincetheuserdoesnotneedtograntpermissionswhentheyinstallorupdatetheapp.Italsogivestheusermorecontrolovertheapp'sfunctionality.However,yourappmustcheckforpermissioneverytimeitdoessomethingthatrequirespermission(suchassendinganSMSmessage).IftheuserhasusedtheSettingsapptoturnoffSMSpermissionsfortheapp,yourappcandisplayadialogtorequestpermission.
Tip:Foracompletedescriptionoftherequestpermissionprocess,seeRequestingPermissionsatRunTime.
AddtheSEND_SMSpermissiontotheAndroidManifest.xmlfileafterthefirstline(withthepackagedefinition)andbeforethesection:
2:SMSMessages
85
https://developer.android.com/reference/android/content/Intent.html#putExtra(java.lang.String,%20java.lang.String)https://developer.android.com/guide/components/intents-common.html#Messaginghttps://developer.android.com/reference/android/telephony/SmsManager.html#sendTextMessage(java.lang.String,%20java.lang.String,%20java.lang.String,%20android.app.PendingIntent,%20android.app.PendingIntent)https://developer.android.com/reference/android/telephony/SmsManager.htmlhttps://developer.android.com/training/permissions/requesting.html
-
Becausetheusercanturnpermissionsonoroffforeachapp,yourappmustcheckwhetheritstillhaspermissioneverytimeitdoessomethingthatrequirespermission(suchassendinganSMSmessage).IftheuserhasturnedSMSpermissionofffortheapp,yourappcandisplayadialogtorequestpermission.
Followthesesteps:
1. AtthetopoftheactivitythatsendsanSMSmessage,andbelowtheactivity'sclassdefinition,defineaconstantvariabletoholdtherequestcode,andsetittoaninteger:
privatestaticfinalintMY_PERMISSIONS_REQUEST_SEND_SMS=1;
Whytheinteger1?Eachpermissionrequestneedsthreeparameters:thecontext,astringarrayofpermissions,andanintegerrequestCode.TherequestCodeistheintegerattachedtotherequest.Whenaresultreturnsintheactivity,itcontainsthiscodeandusesittodifferentiatemultiplepermissionresultsfromeachother.
2. Intheactivitythatmakesaphonecall,createamethodthatusesthecheckSelfPermission()methodtodeterminewhetheryourapphasbeengrantedthepermission:
privatevoidcheckForSmsPermission(){if(ActivityCompat.checkSelfPermission(this,Manifest.permission.SEND_SMS)!=PackageManager.PERMISSION_GRANTED){Log.d(TAG,getString(R.string.permission_not_granted));//Permissionnotyetgranted.UserequestPermissions().//MY_PERMISSIONS_REQUEST_SEND_SMSisan//app-definedintconstant.Thecallbackmethodgetsthe//resultoftherequest.ActivityCompat.requestPermissions(this,newString[]{Manifest.permission.SEND_SMS},MY_PERMISSIONS_REQUEST_SEND_SMS);}else{//Permissionalreadygranted.Enablethemessagebutton.enableSmsButton();}}
ThecodeusescheckSelfPermission()todeterminewhetheryourapphasbeengrantedaparticularpermissionbytheuser.Ifpermissionhasnotbeengranted,thecodeusestherequestPermissions()methodtodisplayastandarddialogfortheusertograntpermission.
2:SMSMessages
86
https://developer.android.com/reference/android/support/v4/content/ContextCompat.html#checkSelfPermission(android.content.Context,%20java.lang.String)https://developer.android.com/reference/android/support/v4/app/ActivityCompat.html#requestPermissions(android.app.Activity,%20java.lang.String[],%20int)
-
UseyourcheckForSmsPermission()methodtocheckforpermissionatthefollowingtimes:
Whentheactivitystarts—initsonCreate()method.Everytimebeforesendingamessage.SincetheusermightturnofftheSMSpermissionwhiletheappisstillrunning,callthecheckForSmsPermission()methodinthesmsSendMessage()methodbeforeusingtheSmsManagerclass.
Requestinguserpermission
Ifpermissionhasnotbeengrantedbytheuser,usetherequestPermissions()methodoftheActivityCompatclass.TherequestPermissions()methodneedsthreeparameters:thecontext(this),astringarrayofpermissions(newString[]{Manifest.permission.SEND_SMS}),andthepredefinedintegerMY_PERMISSIONS_REQUEST_SEND_SMSfortherequestCode.
WhenyourappcallsrequestPermissions(),thesystemshowsastandarddialogtotheuser,asshowninthefigurebelow.
2:SMSMessages
87
https://developer.android.com/reference/android/support/v4/app/ActivityCompat.html#requestPermissions(android.app.Activity,%20java.lang.String[],%20int)
-
2:SMSMessages
88
-
WhentheuserrespondstotherequestpermissiondialogbytappingDenyorAllow,thesysteminvokestheonRequestPermissionsResult()method,passingittheuserresponse.Yourapphastooverridethatmethodtofindoutwhetherthepermissionwasgranted.
ThefollowingcodedemonstrateshowyoucanuseaswitchstatementinyourimplementationofonRequestPermissionsResult()basedonthevalueofrequestCode.Theuser'sresponsetotherequestdialogisreturnedinthepermissionsarray(index0ifonlyonepermissionisrequestedinthedialog).Thisiscomparedtothecorrespondinggrantresult,whichiseitherPERMISSION_GRANTEDorPERMISSION_DENIED.
Iftheuserdeniesapermissionrequest,yourappshoulddisablethefunctionalitythatdependsonthispermissionandshowadialogexplainingwhyitcouldnotperformit.Thecodebelowlogsadebugmessage,displaysatoasttoshowthatpermissionwasnotgranted,anddisablesthemessageiconusedasabutton.
@OverridepublicvoidonRequestPermissionsResult(intrequestCode,Stringpermissions[],int[]grantResults){switch(requestCode){caseMY_PERMISSIONS_REQUEST_SEND_SMS:{if(permissions[0].equalsIgnoreCase(Manifest.permission.SEND_SMS)&&grantResults[0]==PackageManager.PERMISSION_GRANTED){//Permissionwasgranted.}else{//Permissiondenied.Log.d(TAG,getString(R.string.failure_permission));Toast.makeText(MainActivity.this,getString(R.string.failure_permission),Toast.LENGTH_SHORT).show();//Disablethemessagebutton.disableSmsButton();}}}}
UsingSmsManagertosendthemessage
UsethesendTextMessage()methodoftheSmsManagerclasstosendthemessage,whichtakesthefollowingparameters:
destinationAddress:Thestringforthephonenumbertoreceivethemessage.scAddress:Astringfortheservicecenteraddress,ornulltousethecurrentdefaultSMSC.AShortMessageServiceCenter(SMSC)isanetworkelementinthemobiletelephonenetwork.Themobilenetworkoperatorusuallypresetsthecorrectservice
2:SMSMessages
89
https://developer.android.com/reference/android/support/v4/app/ActivityCompat.OnRequestPermissionsResultCallback.html#onRequestPermissionsResult(int,%20java.lang.String[],%20int[])https://developer.android.com/reference/android/telephony/SmsManager.html#sendTextMessage(java.lang.String,%20java.lang.String,%20java.lang.String,%20android.app.PendingIntent,%20android.app.PendingIntent)https://developer.android.com/reference/android/telephony/SmsManager.html
-
centernumberinthedefaultprofileofsettingsstoredinthedevice'sSIMcard.
Tip:YoucanfindthedefaultSMSCinanAndroidsmartphone'shiddenmenu.OpenthePhoneappanddial##4636##toopenthetestingmenu.TapPhoneinformation,andscrolltothebottom.TheSMSCnumbershouldappearblank.TapRefreshtoseethenumber.
smsMessage:Astringforthebodyofthemessagetosend.sentIntent:APendingIntent.Ifnotnull,thisisbroadcastwhenthemessageissuccessfullysentorifthemessagefailed.deliveryIntent:APendingIntent.Ifnotnull,thisisbroadcastwhenthemessageisdeliveredtotherecipient.
FollowthesestepstousethesendTextMessage()method:
1. CreateanonClickhandlerforabuttonthatsendsthemessage.2. Getthestringsforthephonenumber(destinationAddress)andthemessage
(smsMessage).3. DeclareadditionalstringandPendingIntentparameters:
...//Settheservicecenteraddressifneeded,otherwisenull.StringscAddress=null;//Setpendingintentstobroadcast//whenmessagesentandwhendelivered,orsettonull.PendingIntentsentIntent=null,deliveryIntent=null;...
4. UsetheSmsManagerclasstocreatesmsManager,whichautomaticallyimportsandroid.telephony.SmsManager,andusesendTextMessage()tosendthemessage:
...//UseSmsManager.SmsManagersmsManager=SmsManager.getDefault();smsManager.sendTextMessage(destinationAddress,scAddress,smsMessage,sentIntent,deliveryIntent);...
ThefollowingcodesnippetshowsasampleonClickhandlerforsendingamessage:
2:SMSMessages
90
https://developer.android.com/reference/android/app/PendingIntent.htmlhttps://developer.android.com/reference/android/app/PendingIntent.htmlhttps://developer.android.com/reference/android/telephony/SmsManager.html#sendTextMessage(java.lang.String,%20java.lang.String,%20java.lang.String,%20android.app.PendingIntent,%20android.app.PendingIntent)https://developer.android.com/reference/android/telephony/SmsManager.html
-
publicvoidsmsSendMessage(Viewview){EditTexteditText=(EditText)findViewById(R.id.editText_main);//SetthedestinationphonenumbertothestringineditText.StringdestinationAddress=editText.getText().toString();//Findthesms_messageview.EditTextsmsEditText=(EditText)findViewById(R.id.sms_message);//GetthetextoftheSMSmessage.StringsmsMessage=smsEditText.getText().toString();//Settheservicecenteraddressifneeded,otherwisenull.StringscAddress=null;//Setpendingintentstobroadcast//whenmessagesentandwhendelivered,orsettonull.PendingIntentsentIntent=null,deliveryIntent=null;//Checkforpermissionfirst.checkForSmsPermission();//UseSmsManager.SmsManagersmsManager=SmsManager.getDefault();smsManager.sendTextMessage(destinationAddress,scAddress,smsMessage,sentIntent,deliveryIntent);}
ReceivingSMSmessagesToreceiveSMSmessages,usetheonReceive()methodoftheBroadcastReceiverclass.TheAndroidframeworksendsoutsystembroadcastsofeventssuchasSMS_RECEIVEDforreceivinganSMSmessage.YoumustalsoincludeRECEIVE_SMSpermissioninyourproject'sAndroidManifest.xmlfile:
Touseabroadcastreceiver:
1. AddthebroadcastreceiverbychoosingFile>New>Other>BroadcastReceiver.TheOther>BroadcastReceiver.Makesure"Exported"and"Enabled"arechecked.The"Exported"optionallowsyourapptorespondtooutside
2:SMSMessages
91
https://developer.android.com/reference/android/content/BroadcastReceiver.html#onReceive(android.content.Context,%20android.content.Intent)https://developer.android.com/reference/android/content/BroadcastReceiver.html
-
broadcasts,while"Enabled"allowsittobeinstantiatedbythesystem.
AndroidStudioautomaticallygeneratesatagintheapp'sAndroidManifest.xmlfile,withyourchosenoptionsasattributes:
Registeringthebroadcastreceiver
Inordertoreceiveanybroadcasts,youmustregisterforspecificbroadcastintents.IntheIntentdocumentation,under"StandardBroadcastActions",youcanfindsomeofthecommonbroadcastintentssentbythesystem.
Thefollowingintentfilterregistersthereceiverfortheandroid.provider.Telephony.SMS_RECEIVEDintent:
ImplementingtheonReceive()method
Onceyourapp'sBroadcastReceiverinterceptsabroadcastitisregisteredfor(SMS_RECEIVED),theintentisdeliveredtothereceiver'sonReceive()method,alongwiththecontextinwhichthereceiverisrunning.
ThefollowingshowsthefirstpartoftheonReceive()method,whichdoesthefollowing:
Retrievestheextras(theSMSmessage)fromtheintent.Storesitinabundle.DefinesthemsgsarrayandstrMessagestring.GetstheformatforthemessagefromthebundleinordertouseitwithcreateFromPdu()tocreatetheSmsMessage.
2:SMSMessages
92
https://developer.android.com/reference/android/content/Intent.htmlhttps://developer.android.com/reference/android/telephony/SmsMessage.html#createFromPdu(byte[],%20java.lang.String)https://developer.android.com/reference/android/telephony/SmsMessage.html
-
Theformatisthemessage'smobiletelephonysystemformatpassedinanSMS_RECEIVED_ACTIONbroadcast.Itisusually"3gpp"forGSM/UMTS/