In diesem Lernprogramm erfahren Sie mehr über die Android-Telefonie- und SMS-API. Sie erfahren, wie Sie einen Anruf von Ihrer App aus tätigen und wie Sie Anrufereignisse überwachen und wie Sie SMS senden und empfangen.
Um zu beginnen, zeige ich Ihnen, wie Sie einen Anruf von Ihrer Anwendung aus initiieren, entweder mit der Telefonwähl-App oder direkt von Ihrer App, um es Ihren Benutzern zu erleichtern.
Starten Sie Android Studio und erstellen Sie ein neues Projekt mit einer leeren Aktivität Hauptaktivität
.
Fürs Erste wird unser Layout nur eine Text bearbeiten
Feld und a Wählen Taste:
Hauptaktivität
KlasseIm folgenden Codeblock erstellen wir eine ACTION_DIAL
Absicht, das Telefonwählgerät anzuzeigen. Die Telefonnummer wird von uns geparst tel
URI-Schema: tel: XXXXXXXX
. Beachten Sie, dass Sie dazu keine Berechtigung benötigen:
import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.text.TextUtils; Import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; public class MainActivity erweitert AppCompatActivity @Override protected void onCreate (Bundle savedInstanceState) super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); Button mDialButton = (Button) findViewById (R.id.btn_dial); final EditText mPhoneNoEt = (EditText) findViewById (R.id.et_phone_no); mDialButton.setOnClickListener (neuer View.OnClickListener () @Override public void onClick (Ansicht)) String phoneNo = mPhoneNoEt.getText (). toString (); if (! TextUtils.isEmpty) "String dial =" : "+ phoneNo; startActivity (neuer Intent (Intent.ACTION_DIAL, Uri.parse (dial))); else Toast.makeText (MainActivity.this," Geben Sie eine Telefonnummer ein ", Toast.LENGTH_SHORT) .show (); );
Wenn Sie die App ausführen und auf die Wähltaste klicken, gelangen Sie zur Dialer-App. Von dort müssen Sie die Nummer tatsächlich wählen. Sie können diesen Ablauf ändern, um den Anruf von innerhalb Ihrer App aus zu tätigen, indem Sie einfach die ACTION_DIAL
Absicht zu ACTION_CALL
stattdessen. Dies erfordert die android.permission.CALL_PHONE
Erlaubnis jedoch.
In diesem Abschnitt erfahren Sie, wie Sie Telefonanrufe im Android-System überwachen. Das Telefon kann sich in drei Zuständen befinden:
Wir brauchen die Erlaubnis READ_PHONE_STATE
in der Lage sein, den Telefonstatus zu überwachen. Fügen Sie es zu hinzu AndroidManifest.xml:
PhoneStateListener
ObjektWir erstellen ein Objekt der PhoneStateListener
Klasse und überschreiben Sie dann seine onCallStateChanged ()
Methode (in IntelliJ ist dies leicht mit Steuerung-O, und dann die zu überschreibende Methode auswählen oder suchen). Änderungen an den Anrufstatusänderungen behandeln wir durch Anzeigen von a Toast
. Beachten Sie, dass wir auch auf die eingehenden Telefonnummern zugreifen können, wenn diese Methode ausgelöst wird:
//… PhoneStateListener mPhoneStateListener = new PhoneStateListener () @Override public void onCallStateChanged (int state, Zeichenfolge incomingNumber) super.onCallStateChanged (state, incomingNumber); switch (state) case TelephonyManager.CALL_STATE_IDLE: Toast.makeText (MainActivity.this, "CALL_STATE_IDLE", Toast.LENGTH_SHORT) .show (); brechen; case TelephonyManager.CALL_STATE_RINGING: Toast.makeText (MainActivity.this, "CALL_STATE_RINGING", Toast.LENGTH_SHORT) .show (); brechen; case TelephonyManager.CALL_STATE_OFFHOOK: Toast.makeText (MainActivity.this, "CALL_STATE_OFFHOOK", Toast.LENGTH_SHORT) .show (); brechen; ; //…
Je nach den Anforderungen Ihrer Anwendung können Sie auch eine dieser anderen Ereignismethoden überschreiben: onCellInfoChanged ()
, onCallForwardingIndicatorChanged ()
, onCellLocationChanged ()
, oder onSignalStrengthChanged ()
.
Um den Anrufstatus abhören zu können, müssen wir den TelephonyManager
vom Systemdienst und initialisieren Sie es in onCreate ()
.
//… privater TelefonieManager mTelephonyManager; @Override protected void onCreate (Bundle savedInstanceState) //… mTelephonyManager = (TelephonyManager) getSystemService (getApplicationContext (). TELEPHONY_SERVICE);
In dem auf Wiederaufnahme()
Methode können wir anfangen zu hören, indem wir die TelephonyManager
Hör mal zu()
Methode, übergeben es die PhoneStateListener
Instanz und die Statik LISTEN_CALL_STATE
. Wir hören auf zu hören im onStop ()
Methode durch Weitergeben der LISTEN_NONE
als zweites Argument an Hör mal zu()
.
//… @Override protected void onResume () super.onResume (); mTelephonyManager.listen (mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE); @Override protected void onStop () super.onStop (); mTelephonyManager.listen (mPhoneStateListener, PhoneStateListener.LISTEN_NONE); //…
Andere Hörmöglichkeiten sind möglich LISTEN_CELL_LOCATION
, LISTEN_SIGNAL_STRENGTH
, LISTEN_CALL_FORWARDING_INDICATOR
, und LISTEN_CELL_INFO
.
Führen Sie schließlich die App aus und stellen Sie sicher, dass ein eingehender Anruf eingeht.
Diese Überwachung funktioniert nur, wenn sich die App im Vordergrund befindet. Damit dies im Hintergrund funktioniert (wenn unsere Anwendung nicht läuft), müssten Sie eine erstellen Rundfunkempfänger
Selbst wenn die App nicht ausgeführt wird, können wir die Anrufzustände weiterhin überwachen. Je nach den Anforderungen Ihrer App kann dies eine viel bessere Möglichkeit sein, auf Änderungen des Anrufstatus zu achten. Ich werde Ihnen im nächsten Abschnitt zeigen, wie das geht.
Beachten Sie, dass wir nur eingehende Anrufe überwachen. Um ausgehende Anrufe zu überwachen, benötigen wir zusätzliche Berechtigungen. Um ausgehende Anrufe zu überwachen, fügen Sie die folgende Zeile in Ihre ein AndroidManifest.xml Datei.
Sie können Ihren Emulator zum Simulieren eines Anrufs oder zum Senden einer SMS-Nachricht verwenden. Sie müssen jedoch einige Einstellungen vornehmen. Öffnen Sie den Emulator, klicken Sie auf die letzte Schaltfläche in der rechten Navigationsleiste, um den erweiterten Steuerungsdialog zu öffnen, und wählen Sie dann die Telefonsteuerungsschaltfläche aus.
Wie im vorherigen Abschnitt müssen wir einen Ereignis-Listener erstellen, um Änderungen des Telefonstatus zu überwachen. Der Hauptunterschied besteht darin, dass wir diesmal die Erweiterung erweitern werden Rundfunkempfänger
Basisklasse, sodass wir den Status des Telefonanrufs abhören können, auch wenn die Anwendung nicht ausgeführt wird. Vergewissern Sie sich, dass Sie den Listener nicht mehr als einmal registrieren! Wir prüfen dies in Zeile 36.
import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.telephony.PhoneStateListener; import android.telephony.TelephonyManager; import android.widget.Toast; public class PhoneCallStateReceiver erweitert BroadcastReceiver private TelephonyManager mTelephonyManager; public static boolean isListening = false; @Override public void onReceive (Endgültiger Kontext, Intent Intent) 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) case TelephonyManager.CALL_STATE_IDLE: Toast.makeText (Kontext "CALL_STATE_IDLE", Toast.LENGTH_SHORT) .show (); brechen; case TelephonyManager.CALL_STATE_RINGING: Toast.makeText (Kontext "CALL_STATE_RINGING", Toast.LENGTH_SHORT) .show (); brechen; case TelephonyManager.CALL_STATE_OFFHOOK: Toast.makeText (Kontext "CALL_STATE_OFFHOOK", Toast.LENGTH_SHORT) .show (); brechen; ; if (! isListening) mTelephonyManager.listen (mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE); isListening = true;
Ein Rundfunkempfänger funktioniert nur, wenn er registriert ist. Wir müssen das Android-System über unseren Broadcast-Empfänger informieren, indem Sie ihn im registrieren AndroidManifest.xml Datei durch Anschließen unserer PhoneCallStateReceiver
Klasse zum
das beschreibt die Systemübertragung, die wir in diesem Fall empfangen möchten, PHONE_STATE
.
Für ausgehende Anrufe müssen Sie die NEW_OUTGOING_CALL
Handlungsabsicht
in dem
des Empfängers in AndroidManifest.xml.
Um die Telefonnummer des beabsichtigten abgehenden Anrufs zu erhalten, drücken Sie im onReceive (Kontext, Absicht)
Methode, wir bekommen die Nummer von der Absicht als Extra. Um zu verhindern, dass der beabsichtigte Anruf durchgeht, können wir anrufen setResultData ()
und übergeben Sie ein Nullargument. Das Ergebnisdaten
wird als die eigentliche anzurufende Nummer verwendet.
@Override public void onReceive (Endgültiger Kontext, Intent Intent) // für ausgehenden Anruf String ausgehendPhoneNo = intent.getStringExtra (Intent.EXTRA_PHONE_NUMBER) .toString (); // ausgehenden Anruf verhindern setResultData (null);
Weitere Informationen zu Broadcasts und Broadcast-Empfängern finden Sie in unserem Tutorial auf Envato Tuts +:
Für das Senden von SMS haben Sie nur zwei Möglichkeiten: Verwenden Sie die Geräte-SMS-Clientanwendung oder überspringen Sie den Client, indem Sie die SMS direkt von Ihrer App aus senden. Wir betrachten beide Szenarien und Sie können entscheiden, welches für Ihren Anwendungsfall besser ist. Beginnen wir mit dem Senden einer SMS mit dem Geräte-SMS-Client.
Zuerst müssen wir unser Hauptlayout ändern, um eine Text bearbeiten
Feld für die Nachricht und a Nachricht senden Taste.
In unserem onCreate ()
Methode in unserem Hauptaktivität
Klasse, erstellen Sie eine Absicht mit ACTION_SENDTO
als erstes Argument und a smsto:
URI als zweites Argument. Die Textnachricht ist der Wert von sms_body
extra:
//… Button sendMessageBtn = (Button) findViewById (R.id.btn_send_message); final EditText messagetEt = (EditText) findViewById (R.id.et_message); sendMessageBtn.setOnClickListener (neuer View.OnClickListener () @Override public void onClick (Ansicht)) String message = messagetEt.getText (). toString (); String phoneNo = mPhoneNoEt.getText (); TextUtils.isEmpty (Nachricht) &&! TextUtils.isEmpty (phoneNo)) Intent smsIntent = new Intent (Intent.ACTION_SENDTO, Uri.parse ("smsto:" + phoneNo)); smsIntent.putExtra ("sms_body", message); startActivity (smsIntent);); //…
Hier überwacht der SMS-Client den Status der Nachrichtenübermittlung.
Wenn Sie alle erforderlichen Felder eingegeben haben, klicken Sie auf SMS senden Die Schaltfläche öffnet den SMS-Client des Benutzers oder gibt dem Benutzer Optionen zur Auswahl einer App, falls noch keine ausgewählt wurde.
Als Nächstes sehen Sie, wie Sie die SMS direkt aus unserer Anwendung senden, anstatt den Geräte-SMS-Client zu verwenden.
Wie üblich müssen wir die Erlaubnis in registrieren AndroidManifest.xml.
Als Nächstes müssen wir für Android 6.0 (API-Ebene 23) und höher das anfordern SMS SENDEN
Erlaubnis zur Laufzeit.
Um mehr über Android-Laufzeitberechtigungen und deren Änderungen in Version 6.0 zu erfahren, lesen Sie unser Tutorial zu Envato Tuts +:
Um eine SMS zu senden, erhalten wir die Standardeinstellung SmsManager
Instanz und dann nennen Sie es sende Textnachricht()
Methode, wobei die Telefonnummer als erstes Argument und die Nachricht als zweites Argument übergeben werden:
//… final int SEND_SMS_PERMISSION_REQUEST_CODE = 111; private Button mSendMessageBtn; @Override protected void onCreate (Bundle savedInstanceState) //… mSendMessageBtn = (Schaltfläche) findViewById (R.id.btn_send_message); final EditText messagetEt = (EditText) findViewById (R.id.et_message); mSendMessageBtn.setEnabled (false); if (checkPermission (Manifest.permission.SEND_SMS)) mSendMessageBtn.setEnabled (true); else ActivityCompat.requestPermissions (dieser neue String [] Manifest.permission.SEND_SMS, SEND_SMS_PERMISSION_REQUEST_CODE); mSendMessageBtn.setOnClickListener (neuer View.OnClickListener () @Override public void onClick (Ansicht)) String message = messagetEt.getText (). toString (); String phoneNo = mPhoneNoEt.getText () (.) ! TextUtils.isEmpty (Nachricht) &&! 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, "Berechtigung verweigert", Toast.LENGTH_SHORT) .show ();); private boolean checkPermission (Zeichenfolgeberechtigung) int checkPermission = ContextCompat.checkSelfPermission (this, Berechtigung); return (checkPermission == PackageManager.PERMISSION_GRANTED); @Override public void onRequestPermissionsResult (int requestCode, @NonNull String [] -Berechtigungen, @NonNull int [] grantResults) switch (requestCode) case SEND_SMS_PERMISSION_REQUEST_CODE: if (grantResults.length> 0 & amp.) .PERMISSION_GRANTED)) mSendMessageBtn.setEnabled (true); Rückkehr; //…
Um den Lieferstatus zu überwachen, drücken Sie die SMSManager
sende Textnachricht()
Methode hat zwei optional PendingIntent
Parameter: sentIntent
und LieferungIntent
.
void sendTextMessage (String destinationAddress, String scAddress, String-Text, PendingIntent sentIntent, PendingIntent deliveryIntent)
Wenn Sie verwenden möchten sentIntent
, Achten Sie auf den Ergebniscode Aktivität.RESULT_OK
auf Erfolg oder einer von RESULT_ERROR_GENERIC_FAILURE
, RESULT_ERROR_RADIO_OFF
, und RESULT_ERROR_NULL_PDU
einen Fehler anzeigen.
Damit Ihre App mit dem Empfangen von SMS-Nachrichten vom Telefon des Benutzers beginnen kann, ist es am besten, wenn ein Broadcast-Empfänger registriert wird, der benachrichtigt werden kann, wenn eine neue SMS eingeht, auch wenn Ihre App nicht im Vordergrund ausgeführt wird.
Ergänzen Sie die RECEIVE_SMS
Erlaubnis zu AndroidManifest.xml:
Als Nächstes müssen wir prüfen, ob die App die Berechtigung hat, SMS-Nachrichten zur Laufzeit zu empfangen. Also in der Hauptaktivität
Klasse, überprüfen Sie die RECEIVE_SMS
Genehmigung. Wenn es nicht gefunden wird, fordern Sie es an.
//… @Override protected void onCreate (Bundle savedInstanceState) //… if (! CheckPermission (Manifest.permission.RECEIVE_SMS)) ActivityCompat.requestPermissions (dieser neue String [] Manifest.permission.RECEIVE_SMS, 222); //…
Wir holen jedes Objekt der SmsMessage
Klasse mit der Methode createFromPdu (Byte [] pdu)
, Übergeben einer PDU (Protokolldateneinheit). Wir fügen es dann zu unserem Nachrichtenarray hinzu.
Um API 23 und höher zu unterstützen, sollten Sie das Format String extra angeben (entweder "3gpp" für GSM / UMTS / LTE-Nachrichten im 3GPP-Format oder "3gpp2" für CDMA / LTE-Nachrichten im 3GPP2-Format)..
import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.Build; import android.os.Bundle; import android.telephony.SmsMessage; import android.widget.Toast; public class SMSReceiver erweitert BroadcastReceiver @Override public void onReceive (Kontext-Kontext, Intent-Absicht) Bundle bundle = intent.getExtras (); if (bundle! = null) Object [] pdus = (Object []) bundle.get ("pdus"); String format = bundle.getString ("format"); letzte SmsMessage [] messages = neue 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]); Zeichenfolge senderPhoneNo = messages [i] .getDisplayOriginatingAddress (); Toast.makeText (Kontext, "Nachricht" + Nachrichten [0] .getMessageBody () + ", from" + senderPhoneNo, Toast.LENGTH_SHORT) .show ();
Starten Sie nun die App, schließen Sie sie und senden Sie Ihrem emulierten Telefon eine SMS.
In diesem Lernprogramm haben Sie Folgendes gelernt:
In Android können Sie noch viel mehr mit Telefonanrufen und SMS-Nachrichten tun. Weitere Informationen finden Sie in der Dokumentation zur Android-Telefonie-API und zur SMSManager-API.
In der Zwischenzeit finden Sie einige unserer anderen Beiträge zur Android-Entwicklung!