138

Android Apps – Phone Calls and SMS · Android telephony features you can use from within your app by launching the Phone app with an implicit intent. You can add code to your app

  • Upload
    others

  • View
    5

  • Download
    0

Embed Size (px)

Citation preview

  • 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/