I den här handledningen läser du om Android Telefoni och SMS API. Du lär dig hur man ringer ett samtal från din app och hur man övervakar telefonsamtalshändelser, liksom hur man skickar och tar emot SMS.
För att börja visa jag hur du initierar ett samtal från din ansökan, antingen genom att använda telefonuppringningsapp eller direkt från din app för att underlätta för användarna.
Avfyra Android Studio och skapa ett nytt projekt med en tom aktivitet som heter Huvudaktivitet
.
För tillfället kommer vår layout bara att ha en Redigera text
fält och a Ringa knapp:
Huvudaktivitet
KlassI kodblocket nedan skapar vi en ACTION_DIAL
Avsikten är att visa telefonuppringaren. Telefonnumret analyseras från vår tel
URI-schema: tel: XXXXXXXX
. Observera att du inte behöver något tillstånd för att detta ska fungera:
importera android.content.Intent; importera android.net.Uri; importera android.os.Bundle; importera android.support.v7.app.AppCompatActivity; importera android.text.TextUtils; importera android.view.View; importera android.widget.Button; importera android.widget.EditText; importera android.widget.Toast; public class MainActivity utökar AppCompatActivity @Override protected void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); Knapp mDialButton = (Button) findViewById (R.id.btn_dial); Final EditText mPhoneNoEt = (EditText) findViewById (R.id.et_phone_no); mDialButton.setOnClickListener (new View.OnClickListener () @Override public void onClick (Visa vy) String phoneNo = mPhoneNoEt.getText (). toString (); om (! TextUtils.isEmpty (phoneNo)) String dial = "tel : "+ phoneNo; startActivity (new Intent (Intent.ACTION_DIAL, Uri.parse (ringer)); else Toast.makeText (MainActivity.this," Ange ett telefonnummer ", Toast.LENGTH_SHORT) .show (); );
Om du kör appen och klickar på uppringningsknappen kommer du att tas till uppringningsappen, och därifrån måste du faktiskt ringa numret. Du kan ändra detta flöde för att faktiskt ringa samtalet från din app genom att helt enkelt ändra ACTION_DIAL
avsikt att ACTION_CALL
istället. Detta kommer att kräva android.permission.CALL_PHONE
tillåtelse.
I det här avsnittet ska vi lära oss hur vi övervakar telefonsamtalshändelser i Android-systemet. Telefonen kan vara i tre stater:
Vi behöver tillstånd READ_PHONE_STATE
för att kunna övervaka telefonens tillstånd. Lägg till den till AndroidManifest.xml:
PhoneStateListener
ObjektVi skapar ett objekt av PhoneStateListener
klassen och överrätta sedan dess onCallStateChanged ()
metod (i IntelliJ är det lätt att göra detta med Kontroll-O, och välj sedan eller sök efter metoden för att åsidosätta). Vi hanterar ändringar i ändringar av samtalstillstånd genom att visa en Rostat bröd
. Observera att vi även kan komma åt inkommande telefonnummer när den här metoden utlöses:
// ... PhoneStateListener mPhoneStateListener = ny PhoneStateListener () @Override public void onCallStateChanged (int state, String incomingNumber) super.onCallStateChanged (state, incomingNumber); switch (state) fallet TelephonyManager.CALL_STATE_IDLE: Toast.makeText (MainActivity.this, "CALL_STATE_IDLE", Toast.LENGTH_SHORT) .show (); ha sönder; case TelephonyManager.CALL_STATE_RINGING: Toast.makeText (MainActivity.this, "CALL_STATE_RINGING", Toast.LENGTH_SHORT) .show (); ha sönder; case TelephonyManager.CALL_STATE_OFFHOOK: Toast.makeText (MainActivity.this, "CALL_STATE_OFFHOOK", Toast.LENGTH_SHORT) .show (); ha sönder; ; // ...
Beroende på dina ansökningsbehov kan du också åsidosätta en av dessa andra händelsemetoder: onCellInfoChanged ()
, onCallForwardingIndicatorChanged ()
, onCellLocationChanged ()
, eller onSignalStrengthChanged ()
.
För att börja lyssna på telefonsamtalstillståndet behöver vi få TelephonyManager
från systemtjänsten och initiera den i onCreate ()
.
// ... privat TelefoniManager mTelefoniManager; @Override protected void onCreate (Bundle savedInstanceState) // ... mTelephonyManager = (TelephonyManager) getSystemService (getApplicationContext (). TELEPHONY_SERVICE);
I på CV()
metod kan vi börja lyssna med TelephonyManager
lyssna()
metod, passerar den PhoneStateListener
instans och det statiska LISTEN_CALL_STATE
. Vi slutar lyssna i onStop ()
metod genom att passera LISTEN_NONE
som det andra argumentet till lyssna()
.
// ... @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); // ...
Andra telefonlarmalternativ är möjliga LISTEN_CELL_LOCATION
, LISTEN_SIGNAL_STRENGTH
, LISTEN_CALL_FORWARDING_INDICATOR
, och LISTEN_CELL_INFO
.
Slutligen kör appen och se till att ett inkommande samtal kommer in.
Denna övervakning fungerar bara när appen är i förgrunden. För att detta ska fungera i bakgrunden (när vår applikation inte körs), skulle vi behöva skapa en BroadcastReceiver
så att även om appen inte körs kan vi fortfarande övervaka för telefonsamtalstillstånd. Beroende på dina appkrav kan det vara ett mycket bättre sätt att lyssna på ändringar av telefonsamtalstillstånd. Jag visar dig hur du gör det i nästa avsnitt.
Var medveten om att vi bara övervakar inkommande samtal. För oss att övervaka utgående samtal behöver vi ytterligare behörigheter. För att övervaka utgående samtal, ta med följande rad i din AndroidManifest.xml fil.
Du kan använda din emulator för att simulera att ringa eller skicka ett SMS, men du måste göra en liten inställning. Öppna din emulator, klicka på den sista knappen i navigeringsfältet till höger för att öppna den utvidgade kontrolldialogrutan och välj sedan telefonens kontrollknapp.
Precis som i föregående avsnitt måste vi skapa en händelseloggare för att övervaka ändringar i telefonstatus. Den stora skillnaden är att den här gången kommer vi att förlänga BroadcastReceiver
basklass så att vi kan lyssna på telefonsamtalstillståndet även om programmet inte körs. Var noga med att inte registrera lyssnaren mer än en gång! Vår check för detta är på rad 36.
importera android.content.BroadcastReceiver; importera android.content.Context; importera android.content.Intent; importera android.telephony.PhoneStateListener; importera android.telephony.TelephonyManager; importera android.widget.Toast; offentlig klass PhoneCallStateReceiver utökar BroadcastReceiver privat TelephonyManager mTelefephonyManager; offentliga statiska booleanska isListening = false; @Override public void onReceive (slutligt kontext sammanhang, Intent intention) mTelephonyManager = (TelephonyManager) context.getSystemService (context.TELEPHONY_SERVICE); PhoneStateListener mPhoneStateListener = new PhoneStateListener () @Override public void onCallStateChanged (int state, String incomingNumber) super.onCallStateChanged (state, incomingNumber); switch (state) fallet TelephonyManager.CALL_STATE_IDLE: Toast.makeText (kontext, "CALL_STATE_IDLE", Toast.LENGTH_SHORT) .show (); ha sönder; case TelephonyManager.CALL_STATE_RINGING: Toast.makeText (kontext, "CALL_STATE_RINGING", Toast.LENGTH_SHORT) .show (); ha sönder; case TelephonyManager.CALL_STATE_OFFHOOK: Toast.makeText (kontext, "CALL_STATE_OFFHOOK", Toast.LENGTH_SHORT) .show (); ha sönder; ; om (! isListening) mTelefephonyManager.listen (mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE); isListening = true;
En sändarmottagare fungerar bara om den är registrerad. Vi måste berätta för Android-systemet om vår sändarmottagare genom att registrera den i AndroidManifest.xml fil genom att ansluta vår PhoneCallStateReceiver
klass till
som beskriver systemutsändningen vi önskar att ta emot - i det här fallet, PHONE_STATE
.
För utgående samtal måste du inkludera NEW_OUTGOING_CALL
handlingsintention
i
av mottagaren i AndroidManifest.xml.
För att få telefonnumret till det avsedda utgående samtalet, inuti onReceive (Context, Intent)
metod, vi får numret från avsikt som extra. För att förhindra att det avsedda samtalet går igenom kan vi ringa setResultData ()
och ge det ett nollargument. De resultData
används som det faktiska numret som ska ringas.
@Override public void onReceive (slutligt kontext sammanhang, avsikt) // för utgående samtal String outgoingPhoneNo = intent.getStringExtra (Intent.EXTRA_PHONE_NUMBER) .toString (); // förhindra utgående samtal setResultData (null);
Du kan lära dig mer om sändningar och sändarmottagare i vår handledning här på Envato Tuts +:
Du har bara två stora val för att skicka SMS: Använd SMS-klientprogrammet för enheten eller hoppa över klienten genom att skicka SMS direkt från din app. Vi tittar på båda scenarierna och du kan bestämma vilken som är bättre för ditt användningsfall. Låt oss börja med att skicka ett SMS med hjälp av SMS-klienten.
Först måste vi ändra vår huvudsakliga layout för att ha en Redigera text
fält för meddelandet och a Skicka meddelande knapp.
Inuti vårt onCreate ()
metod i vårt Huvudaktivitet
klass, skapa en avsikt med ACTION_SENDTO
som det första argumentet och a smsto:
URI som det andra argumentet. Textmeddelandet kommer att vara värdet av sms_body
extra:
// ... Knapp sendMessageBtn = (Button) findViewById (R.id.btn_send_message); Final EditText messagetEt = (EditText) findViewById (R.id.et_message); sendMessageBtn.setOnClickListener (new View.OnClickListener () @Override public void onClick (Visa vy) String message = messagetEt.getText (). toString (); String phoneNo = mPhoneNoEt.getText () .String (); om (! TextUtils.isEmpty (message) &&! TextUtils.isEmpty (phoneNo)) Intent smsIntent = nytt Intent (Intent.ACTION_SENDTO, Uri.parse ("smsto:" + phoneNo)); smsIntent.putExtra ("sms_body", meddelande); startActivity (smsIntent);); // ...
Här kommer SMS-klienten att övervaka statusen för meddelandeleveransen.
När alla obligatoriska fält är angivna klickar du på Skicka sms knappen öppnar användarens SMS-klient, eller ger användaralternativen en app om en inte redan har valts.
Låt oss sedan se hur du skickar SMS direkt från vår ansökan istället för att använda SMS-klienten.
Som vanligt måste vi registrera tillståndet i AndroidManifest.xml.
Därefter, för Android 6.0 (API nivå 23) och högre måste vi begära SKICKA SMS
tillstånd under körtid.
Om du vill veta mer om Android-körkortstillstånd och hur de har ändrats i version 6.0, kolla vår handledning här på Envato Tuts +:
För att skicka ett SMS får vi standardvärdet SmsManager
exempel och ring sedan dess sendTextMessage ()
metod, passerar i telefonnummer som första argumentet och meddelandet som det andra argumentet:
// ... final int SEND_SMS_PERMISSION_REQUEST_CODE = 111; privat knapp mSendMessageBtn; @Override protected void onCreate (Bundle savedInstanceState) // ... mSendMessageBtn = (Button) findViewById (R.id.btn_send_message); Final EditText messagetEt = (EditText) findViewById (R.id.et_message); mSendMessageBtn.setEnabled (false); om (checkPermission (Manifest.permission.SEND_SMS)) mSendMessageBtn.setEnabled (true); else ActivityCompat.requestPermissions (den här nya strängen [] Manifest.permission.SEND_SMS, SEND_SMS_PERMISSION_REQUEST_CODE); mSendMessageBtn.setOnClickListener (new View.OnClickListener () @Override public void onClick (Visa vy) String message = messagetEt.getText (). toString (); String phoneNo = mPhoneNoEt.getText () .String (); om 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, "Tillstånd nekad", Toast.LENGTH_SHORT) .show ();); Privat Boolean checkPermission (String permission) int checkPermission = ContextCompat.checkSelfPermission (detta, tillstånd); returnera (checkPermission == PackageManager.PERMISSION_GRANTED); @Override public void onRequestPermissionsResult (int requestCode, @NonNull String [] behörigheter, @NonNull int [] grantResults) switch (requestCode) fall SEND_SMS_PERMISSION_REQUEST_CODE: if (grantResults.length> 0 && (grantResults [0] == PackageManager .PERMISSION_GRANTED)) mSendMessageBtn.setEnabled (true); lämna tillbaka; // ...
För att övervaka status för leverans, ska SMSManager
sendTextMessage ()
Metoden har två valfria PendingIntent
parameters: sentIntent
och deliveryIntent
.
void sendTextMessage (String destinationAddress, String scAddress, String text, PendingIntent sentIntent, PendingIntent deliveryIntent)
Om du vill använda sentIntent
, titta på resultatkoden Activity.RESULT_OK
på framgång eller en av RESULT_ERROR_GENERIC_FAILURE
, RESULT_ERROR_RADIO_OFF
, och RESULT_ERROR_NULL_PDU
för att ange ett fel.
För att din app ska börja ta emot sms från användarens telefon är det bäst att ha en sändarmottagare registrerad så att den kan varnas när ett nytt SMS kommer fram även om din app inte körs i förgrunden.
Lägg till RECEIVE_SMS
tillstånd att AndroidManifest.xml:
Därefter måste vi kolla och se om appen har behörighet att ta emot sms-meddelanden vid körning. Så i Huvudaktivitet
klass, kolla efter RECEIVE_SMS
lov. Om det inte hittas, begära det.
// ... @Override protected void onCreate (Bundle savedInstanceState) // ... om (! CheckPermission (Manifest.permission.RECEIVE_SMS)) ActivityCompat.requestPermissions (den här nya strängen [] Manifest.permission.RECEIVE_SMS, 222); // ...
Vi hämtar varje objekt av SmsMessage
klass genom att använda metoden createFromPdu (byte [] pdu)
, överför den till en PDU (protokolldataenhet). Vi lägger sedan till det i vår meddelandearray.
För att stödja API 23 eller senare bör du inkludera formatet String extra (antingen "3gpp" för GSM / UMTS / LTE-meddelanden i 3GPP-format eller "3gpp2" för CDMA / LTE-meddelanden i 3GPP2-format).
importera android.content.BroadcastReceiver; importera android.content.Context; importera android.content.Intent; importera android.os.Build; importera android.os.Bundle; importera android.telephony.SmsMessage; importera android.widget.Toast; public class SMSReceiver utökar BroadcastReceiver @Override public void onReceive (Context context, Intent intent) Bundle bundle = intent.getExtras (); om (bunt! = null) Objekt [] pdus = (Objekt []) bundle.get ("pdus"); Stringformat = bundle.getString ("format"); sista SmsMessage [] messages = nya SmsMessage [pdus.length]; för (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 = meddelanden [i] .getDisplayOriginatingAddress (); Toast.makeText (sammanhang, "Meddelande" + meddelanden [0] .getMessageBody () + ", från" + avsändarePhoneNo, Toast.LENGTH_SHORT) .show ();
Nu kör appen, stäng den och skicka din emulerade telefon ett SMS.
I denna handledning lärde du dig om:
Det finns mycket mer du kan göra med telefonsamtal och sms-meddelanden i Android. Besök API: n för Android-telefoni och dokumentationen för SMSManager API för att lära dig mer.
Under tiden kan du kolla in några av våra andra inlägg i Android-utveckling!