Slik lager du anrop og bruker SMS i Android Apps

I denne opplæringen lærer du om Android-telefoni og SMS-API. Du lærer hvordan du ringer fra appen din og hvordan du overvåker telefonanropshendelser, samt hvordan du sender og mottar SMS.

1. Hvordan ringe 

For å begynne med, viser jeg deg hvordan du starter en samtale fra din søknad, enten ved å bruke telefonoppringingsapp eller direkte fra appen din for å gjøre det enklere for brukerne dine.

Opprett et nytt Android Studio-prosjekt

Brann opp Android Studio og opprett et nytt prosjekt med en tom aktivitet som heter Hoved aktivitet.


Legg ut skjermen

For nå vil vårt layout bare ha en EditText felt og a Slå knapp:

   

Endre Hoved aktivitet Klasse

I kodeblokken nedenfor lager vi en ACTION_DIAL hensikt å vise telefonoppringeren. Telefonnummeret blir analysert fra vår tlf URI-skjema: tlf: XXXXXXXX. Legg merke til at du ikke trenger noen tillatelse for at dette skal fungere:

importer android.content.Intent; importer android.net.Uri; importere android.os.Bundle; importer android.support.v7.app.AppCompatActivity; importer android.text.TextUtils; importer android.view.View; importer android.widget.Button; importer android.widget.EditText; importer android.widget.Toast; offentlig klasse MainActivity utvider AppCompatActivity @Override protected void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); Knapp mDialButton = (Button) findViewById (R.id.btn_dial); Endelig EditText mPhoneNoEt = (EditText) findViewById (R.id.et_phone_no); mDialButton.setOnClickListener (new View.OnClickListener () @Override public void onClick (Vis visning) String phoneNo = mPhoneNoEt.getText (). toString (); hvis (! TextUtils.isEmpty (phoneNo)) String dial = "tel : "+ phoneNo; startActivity (new Intent (Intent.ACTION_DIAL, Uri.parse (dial)); else Toast.makeText (MainActivity.this," Skriv inn et telefonnummer ", Toast.LENGTH_SHORT) .show (); ); 

Hvis du kjører appen og klikker på ringetasten, blir du tatt til oppringingsprogrammet, og derfra må du faktisk ringe nummeret. Du kan endre denne strømmen for å faktisk ringe fra appen din ved å bare endre ACTION_DIAL hensikt å ACTION_CALL i stedet. Dette vil kreve android.permission.CALL_PHONE tillatelse, skjønt. 

2. Overvåke telefonsamtaler

I denne delen skal vi lære å overvåke telefonanropshendelser i Android-systemet. Telefonen kan være i tre stater: 

  1. tomgang (når den er ubrukt)
  2. ringing (når det er et innkommende anrop)
  3. off-hook (når samtalen er besvart)

Legg til tillatelsen 

Vi trenger tillatelsen READ_PHONE_STATE for å kunne overvåke telefonstatusen. Legg det til AndroidManifest.xml:

Opprett PhoneStateListener Gjenstand

Vi lager et objekt av PhoneStateListener klassen, og overstyr deretter sin onCallStateChanged () metode (i IntelliJ er det lett å gjøre dette med Kontroll-O, og velg deretter eller søk etter metoden for å overstyre). Vi håndterer endringer i endring av anropsstatus ved å vise en Skål. Vær oppmerksom på at vi også kan få tilgang til innkommende telefonnumre når denne metoden utløses:

// ... PhoneStateListener mPhoneStateListener = ny PhoneStateListener () @Overtrid offentlig tomgang onCallStateChanged (int state, String incomingNumber) super.onCallStateChanged (state, incomingNumber); bytte (tilstand) tilfelle TelephonyManager.CALL_STATE_IDLE: Toast.makeText (MainActivity.this, "CALL_STATE_IDLE", Toast.LENGTH_SHORT) .show (); gå i stykker; tilfelle TelephonyManager.CALL_STATE_RINGING: Toast.makeText (MainActivity.this, "CALL_STATE_RINGING", Toast.LENGTH_SHORT) .show (); gå i stykker; tilfelle TelephonyManager.CALL_STATE_OFFHOOK: Toast.makeText (MainActivity.this, "CALL_STATE_OFFHOOK", Toast.LENGTH_SHORT) .show (); gå i stykker; ; // ... 

Avhengig av søknadens behov kan du også overstyre en av disse andre hendelsesmetodene: onCellInfoChanged ()onCallForwardingIndicatorChanged ()onCellLocationChanged (), eller onSignalStrengthChanged ().

Lytte til telefonanropsstaten

For å begynne å lytte til telefonsamtalen tilstand, må vi få TelephonyManager fra systemtjenesten og initialiser den i onCreate ().

// ... privat telefonsjef mTelefoniManager; @Override protected void onCreate (Bundle savedInstanceState) // ... mTelephonyManager = (TelephonyManager) getSystemService (getApplicationContext (). TELEPHONY_SERVICE); 

I onResume () Metode, vi kan begynne å lytte ved hjelp av TelephonyManager lytte() metode, passerer den PhoneStateListener forekomst og statisk LISTEN_CALL_STATE. Vi slutter å lytte i onStop () metode ved å passere LISTEN_NONE som det andre argumentet til lytte().

// ... @Override protected void onResume () super.onResume (); mTelefephonyManager.listen (mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);  @Override protected void onStop () super.onStop (); mTelefephonyManager.listen (mPhoneStateListener, PhoneStateListener.LISTEN_NONE);  // ... 

Andre telefonlyttealternativer er mulig LISTEN_CELL_LOCATIONLISTEN_SIGNAL_STRENGTHLISTEN_CALL_FORWARDING_INDICATOR, og LISTEN_CELL_INFO.

Endelig kjør appen og sørg for at et innkommende anrop kommer inn. 

Denne overvåkingen vil bare fungere når appen er i forgrunnen. For at dette skal fungere i bakgrunnen (når programmet ikke kjører), må vi opprette en BroadcastReceiver slik at selv om appen ikke kjører, kan vi fortsatt overvåke for telefonsamtalestater. Avhengig av appens krav kan det være en mye bedre måte å lytte til endringer i anropsanrop. Jeg skal vise deg hvordan du gjør dette i neste avsnitt.

Vær oppmerksom på at vi bare overvåker innkommende anrop. For oss å overvåke utgående anrop, trenger vi tilleggstillatelser. For å overvåke utgående anrop, ta med følgende linje i din AndroidManifest.xml fil.

 

Slik bruker du emulatoren til å ringe og sende SMS-meldinger

Du kan bruke din emulator til å simulere å ringe eller sende en SMS-melding, men du må gjøre et lite oppsett. Åpne emulatoren din, klikk på den siste knappen i navigeringslinjen til høyre for å åpne den utvidede kontrolldialogen, og velg deretter telefonens kontrollknapp. 

3. Overvåke telefonanropshendelser i bakgrunnen

Lag en BroadcastReceiver

På samme måte som i forrige avsnitt, må vi opprette en hendelseslytter for å overvåke endringer i telefonstatus. Den største forskjellen er at denne gangen vil vi utvide BroadcastReceiver baseklasse, slik at vi kan lytte til telefonanropstilstanden selv om programmet ikke kjører. Pass på at du ikke registrerer lytteren mer enn en gang! Vår sjekk for dette er på linje 36.

importer android.content.BroadcastReceiver; importer android.content.Context; importer android.content.Intent; importere android.telephony.PhoneStateListener; importere android.telephony.TelephonyManager; importer android.widget.Toast; offentlig klasse PhoneCallStateReceiver utvider BroadcastReceiver private TelephonyManager mTelefephonyManager; offentlig statisk boolean isListening = false; @Override public void onReceive (siste kontekst kontekst, hensikt) mTelephonyManager = (TelephonyManager) context.getSystemService (context.TELEPHONY_SERVICE); PhoneStateListener mPhoneStateListener = ny PhoneStateListener () @Overtrid offentlig tomgang onCallStateChanged (int state, String incomingNumber) super.onCallStateChanged (state, incomingNumber); bytte (tilstand) tilfelle TelephonyManager.CALL_STATE_IDLE: Toast.makeText (kontekst, "CALL_STATE_IDLE", Toast.LENGTH_SHORT) .show (); gå i stykker; tilfelle TelephonyManager.CALL_STATE_RINGING: Toast.makeText (kontekst, "CALL_STATE_RINGING", Toast.LENGTH_SHORT) .show (); gå i stykker; tilfelle TelephonyManager.CALL_STATE_OFFHOOK: Toast.makeText (kontekst, "CALL_STATE_OFFHOOK", Toast.LENGTH_SHORT) .show (); gå i stykker; ; hvis (! erListening) mTelephonyManager.listen (mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE); isListening = true; 

endre AndroidManifest.xml

En kringkasting mottaker fungerer bare hvis den er registrert. Vi må fortelle Android-systemet om vår kringkasting mottaker ved å registrere den i AndroidManifest.xml fil ved å koble til vår PhoneCallStateReceiver klasse til som beskriver systemutsendingen vi ønsker å motta - i dette tilfellet, PHONE_STATE.

    

Overvåkning av utgående anrop

For utgående anrop må du inkludere NEW_OUTGOING_CALL handling hensikt  i av mottakeren i AndroidManifest.xml

For å få telefonnummeret til ønsket utgående samtale, inne i onReceive (Context, Intent) metode, vi får nummeret fra hensikten som en ekstra. For å hindre at det tilsiktede anropet går gjennom, kan vi ringe setResultData () og send det et nullargument. De resultData brukes som det faktiske nummeret som skal ringes. 

@Override public void onReceive (endelig kontekst kontekst, hensikt) // for utgående samtale String outgoingPhoneNo = intent.getStringExtra (Intent.EXTRA_PHONE_NUMBER) .toString (); // forhindre utgående anropssettResultData (null); 

Du kan lære mer om kringkasting og kringkasting mottakere i vår veiledning her på Envato Tuts +:

4. Sende SMS-meldinger

Du har bare to store valg for å sende SMS: Bruk SMS-applikasjonen til enheten eller hoppe over klienten ved å sende SMS direkte fra appen din. Vi ser på begge scenariene, og du kan bestemme hvilken som er bedre for brukssaken din. La oss begynne med å sende en SMS ved hjelp av SMS-klienten til enheten.

Sett opp oppsettet

Først må vi endre vårt hovedoppsett for å ha en EditText feltet for meldingen og a Sende melding knapp.

  

Endre MainActivity 

Inne i vår onCreate () metode i vår Hoved aktivitet klasse, skape en intensjon med ACTION_SENDTO som det første argumentet og a SMSTO: URI som det andre argumentet. Tekstmeldingen vil være verdien av sms_body ekstra: 

// ... Knapp sendMessageBtn = (Button) findViewById (R.id.btn_send_message); Endelig EditText messagetEt = (EditText) findViewById (R.id.et_message); sendMessageBtn.setOnClickListener (ny View.OnClickListener () @Override public void onClick (Vis visning) String message = messagetEt.getText (). toString (); String phoneNo = mPhoneNoEt.getText (). toString (); TextUtils.isEmpty (message) &&! TextUtils.isEmpty (phoneNo)) Intent smsIntent = ny Intent (Intent.ACTION_SENDTO, Uri.parse ("smsto:" + phoneNo)); smsIntent.putExtra ("sms_body", melding); startAktivitet (smsIntent);); // ... 

Her vil SMS-klienten overvåke statusen for meldingen. 

Kjør programmet

Når alle obligatoriske felt er oppgitt, klikker du på Send tekstmelding knappen åpner brukerens SMS-klient, eller vil gi brukerens valg for å velge en app hvis man ikke allerede har valgt.

5. Sende SMS-meldinger direkte

Neste, la oss se hvordan du sender SMS direkte fra vår applikasjon i stedet for å bruke SMS-klienten til enheten. 

Legg til tillatelse i AndroidManifest.xml

Som vanlig må vi registrere tillatelsen i AndroidManifest.xml.

 

Endre MainActivity-klassen 

Deretter, for Android 6.0 (API nivå 23) og over, må vi be om SEND TEKSTMELDING tillatelse under kjøretid. 

Hvis du vil vite mer om Android-kjøretidsrettigheter og hvordan de har endret seg i versjon 6.0, kan du se vår veiledning her på Envato Tuts +:

For å sende en SMS, får vi standard SmsManager eksempel og deretter ringe det sendTextMessage () metode, passerer i telefonnummeret som det første argumentet og meldingen som det andre argumentet:

// ... endelig int SEND_SMS_PERMISSION_REQUEST_CODE = 111; privat knapp mSendMessageBtn; @Override protected void onCreate (Bundle savedInstanceState) // ... mSendMessageBtn = (Button) findViewById (R.id.btn_send_message); Endelig EditText messagetEt = (EditText) findViewById (R.id.et_message); mSendMessageBtn.setEnabled (false); if (checkPermission (Manifest.permission.SEND_SMS)) mSendMessageBtn.setEnabled (true);  else ActivityCompat.requestPermissions (dette, ny streng [] Manifest.permission.SEND_SMS, SEND_SMS_PERMISSION_REQUEST_CODE);  mSendMessageBtn.setOnClickListener (ny View.OnClickListener () @Override public void onClick (Vis visning) String message = messagetEt.getText (). toString (); String phoneNo = mPhoneNoEt.getText () .String (); ! TextUtils.isEmpty (message) &&! TextUtils.isEmpty (phoneNo)) if (checkPermission (Manifest.permission.SEND_SMS)) SmsManager smsManager = SmsManager.getDefault (); smsManager.sendTextMessage (phoneNo, null, message, null, null); else Toast.makeText (MainActivity.this, "Tillatelse nektet", Toast.LENGTH_SHORT) .show (););  Private Boolean checkPermission (String Tillatelse) int checkPermission = ContextCompat.checkSelfPermission (dette, tillatelse); returnere (checkPermission == PackageManager.PERMISSION_GRANTED);  @Override public void onRequestPermissionsResult (int requestCode, @NonNull String [] tillatelser, @NonNull int [] grantResults) bytt (requestCode) tilfelle SEND_SMS_PERMISSION_REQUEST_CODE: if (grantResults.length> 0 && (grantResults [0] == PackageManager .PERMISSION_GRANTED)) mSendMessageBtn.setEnabled (true);  komme tilbake;  // ... 

For å overvåke status for levering, skal SMSManager sendTextMessage () Metoden har to valgfrie PendingIntent parametere: sentIntent og deliveryIntent.

void sendTextMessage (String destinationAddress, String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent)

Hvis du vil bruke sentIntent, se etter resultatkoden Activity.RESULT_OK på suksess, eller en av RESULT_ERROR_GENERIC_FAILURERESULT_ERROR_RADIO_OFF, og RESULT_ERROR_NULL_PDU for å indikere en feil.

6. Motta en SMS-melding

For appen din å begynne å motta SMS-meldinger fra brukerens telefon, er det best å ha en kringkastingsmottaker registrert slik at den kan varsles når en ny SMS kommer, selv om appen din ikke kjører i forgrunnen. 

Legg til tillatelsen 

Legg til RECEIVE_SMS tillatelse til AndroidManifest.xml:

Deretter må vi sjekke og se om appen har tillatelse til å motta SMS-meldinger ved kjøring. Så i Hoved aktivitet klasse, sjekk for RECEIVE_SMS tillatelse. Hvis det ikke er funnet, be om det.

// ... @Override protected void onCreate (Bundle savedInstanceState) // ... hvis (! CheckPermission (Manifest.permission.RECEIVE_SMS)) ActivityCompat.requestPermissions (dette, nye String [] Manifest.permission.RECEIVE_SMS, 222);  // ... 

Opprett en kringkasting mottaker

Vi henter hvert objekt av SmsMessage klasse ved å bruke metoden createFromPdu (byte [] pdu), sender den en PDU (protokolldataenhet). Vi legger da til det i vårt meldingsarrangement. 

For å støtte API 23 og over, bør du inkludere formatet String ekstra (enten "3gpp" for GSM / UMTS / LTE-meldinger i 3GPP-format eller "3gpp2" for CDMA / LTE-meldinger i 3GPP2-format). 

importer android.content.BroadcastReceiver; importer android.content.Context; importer android.content.Intent; importere android.os.Build; importere android.os.Bundle; importere android.telephony.SmsMessage; importer android.widget.Toast; offentlig klasse SMSReceiver utvider BroadcastReceiver @Override public void onReceive (Kontekst kontekst, hensikt) Bundle bundle = intent.getExtras (); hvis (pakke! = null) Objekt [] pdus = (Objekt []) bundle.get ("pdus"); Stringformat = bundle.getString ("format"); siste SmsMessage [] messages = new SmsMessage [pdus.length]; for (int i = 0; i < pdus.length; i++)  if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) messages [i] = SmsMessage.createFromPdu ((byte []) pdus [i], format);  else messages [i] = SmsMessage.createFromPdu ((byte []) pdus [i]);  String senderPhoneNo = meldinger [i] .getDisplayOriginatingAddress (); Toast.makeText (kontekst, "Melding" + meldinger [0] .getMessageBody () + ", fra" + senderPhoneNo, Toast.LENGTH_SHORT) .show (); 

Kjør nå appen, lukk den, og send din emulerte telefon en SMS.

Konklusjon

I denne veiledningen lærte du om:

  • ringe fra appen din
  • overvåking av telefonsamtaler
  • sende sms-meldinger ved hjelp av enten appen for beskjed eller direkte fra din egen app
  • mottar SMS-meldinger i bakgrunnen

Det er mye mer du kan gjøre med telefonsamtaler og SMS-meldinger i Android. Gå til Android-telefoni-APIen og dokumentasjonen for SMSManager API for å lære mer. 

I mellomtiden kan du sjekke ut noen av våre andre innlegg på Android-utviklingen!

  • Android-sensorer i dybden: Nærhet og Gyroskop

    Gyroskoper og nærhetssensorer er tilgjengelig på de fleste Android-telefoner i dag. Ved å bruke dem kreativt, kan du legge til en helt ny dimensjon for brukeren din ...
    Ashraff Hathibelagal
    Android SDK
  • 6 Gjør og don'ts for en flott Android-brukeropplevelse

    De mest populære Android-appene har noe til felles: de gir alle en flott brukeropplevelse. I dette innlegget deler jeg noen tips som vil hjelpe appen din ...
    Jessica Thornsby
    Android SDK
  • Bakgrunnslyd på Android med MediaSessionCompat

    En av de mest populære bruksområder for mobile enheter er å spille av lyd gjennom musikkstrømstjenester, nedlastede podcaster eller et hvilket som helst antall lyd ...
    Paul Trebilcox-Ruiz
    Android SDK
  • Overfør en Android-app til Material Design

    For mange år siden, da Android fortsatt var et spirende mobiloperativsystem, var det ganske beryktet for sitt gale brukergrensesnitt. Fordi det ikke var noe design ...
    Ashraff Hathibelagal
    Android