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.
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.
Brann opp Android Studio og opprett et nytt prosjekt med en tom aktivitet som heter Hoved aktivitet
.
For nå vil vårt layout bare ha en EditText
felt og a Slå knapp:
Hoved aktivitet
KlasseI 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.
I denne delen skal vi lære å overvåke telefonanropshendelser i Android-systemet. Telefonen kan være i tre stater:
Vi trenger tillatelsen READ_PHONE_STATE
for å kunne overvåke telefonstatusen. Legg det til AndroidManifest.xml:
PhoneStateListener
GjenstandVi 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 ()
.
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_LOCATION
, LISTEN_SIGNAL_STRENGTH
, LISTEN_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.
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.
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;
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
.
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 +:
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.
Først må vi endre vårt hovedoppsett for å ha en EditText
feltet for meldingen og a Sende melding knapp.
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.
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.
Neste, la oss se hvordan du sender SMS direkte fra vår applikasjon i stedet for å bruke SMS-klienten til enheten.
Som vanlig må vi registrere tillatelsen i AndroidManifest.xml.
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_FAILURE
, RESULT_ERROR_RADIO_OFF
, og RESULT_ERROR_NULL_PDU
for å indikere en feil.
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 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); // ...
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.
I denne veiledningen lærte du om:
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!