Sending SMS
SmsManager
and implic Intent
.With
SmsManager
, the message will immediately sent and user can't customizing it any more. This process will perform with this code:
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage("[destination_phone_number]", null, "[sms_content]", null, null);
However, through Intent
, System will call the built-in SMS application in OS and through it, you can preview and edit the phone number or SMS content:
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.putExtra("address", "[destination_phone_number]");
intent.putExtra("sms_body", "[sms_message]");
intent.setData(Uri.parse("smsto:" + "[destination_phone_number]"));
intent.setType("vnd.android-dir/mms-sms");
startActivity(intent);
SEND_SMS
permission in AndroidManifest.xml
:
<uses-permission android:name="android.permission.SEND_SMS" />
Intent
. Firstly, create a simple layout like this:
activity_sms.xml
In programmatically code, we will call the default built-in SMS app to send data after click the <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".SMSActivity">
<EditText
android:id="@+id/txt_phone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:hint="Enter Phone Number"
android:inputType="phone"/>
<EditText
android:id="@+id/sms_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Enter SMS"/>
<Button
android:id="@+id/btnSendSMS"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="Send Sms" />
</LinearLayout>
Button
:
SMSActivity.java
After running this activity, we can see this result:package info.devexchanges.telephony;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class SMSActivity extends AppCompatActivity {
private Button btnSend;
private EditText txtPhoneNumber;
private EditText txtMessageContent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sms);
btnSend = (Button) findViewById(R.id.btnSendSMS);
txtPhoneNumber = (EditText) findViewById(R.id.txt_phone);
txtMessageContent = (EditText) findViewById(R.id.sms_content);
btnSend.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
sendSMSMessage();
}
});
}
protected void sendSMSMessage() {
String phoneNo = txtPhoneNumber.getText().toString().trim();
String message = txtMessageContent.getText().toString().trim();
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.putExtra("address", phoneNo);
intent.putExtra("sms_body", message);
intent.setData(Uri.parse("smsto:" + phoneNo));
intent.setType("vnd.android-dir/mms-sms");
startActivity(intent);
}
}
Filling content on
EditTexts
, click "Send SMS", you will be redirected to SMS application. You can edit the message and phone number before sending it here:Making a phone call
Intent.ACTION_DIAL
or directly call by using Intent.ACTION_CALL
.With the first case, it's seem so simple, with
Intent.ACTION_DIAL
, we can go to the "dial srceen" of Android OS. Suppose we have a simple layout contains only 1 Button
and 1 EditText
like this:
activity_call.xml
Layout preview:<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="@dimen/activity_horizontal_margin">
<EditText
android:id="@+id/txt_phone"
android:hint="Input a phone number here"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="phone" />
<Button
android:id="@+id/btn_call"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Call" />
</LinearLayout>
Put some programmatically code to handling button event (redirect user to "dial screen" with input phone number:
DialingActivity.java
Running this activity, input a phone number to the package info.devexchanges.telephony;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class DialingActivity extends AppCompatActivity {
private Button btnCall;
private EditText txtPhone;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_call);
txtPhone = (EditText) findViewById(R.id.txt_phone);
btnCall = (Button)findViewById(R.id.btn_call);
btnCall.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (txtPhone.getText().toString().trim().equals("")) {
Toast.makeText(DialingActivity.this, "Please input a phone number", Toast.LENGTH_SHORT).show();
} else {
String uri = "tel:"+ txtPhone.getText().toString();
Intent dialIntent = new Intent(Intent.ACTION_DIAL, Uri.parse(uri));
startActivity(dialIntent);
}
}
});
}
}
EditText
:Click "Call", we will see the soft phone keyboard, you still can customizing the phone number here:
When make a call directly from programmatically code, although the
Intent
is sufficient for the phone call, in some cases we want to monitor the phone state. In such situations, we use PhoneStateListener
and TelephonyManager
classes. In this example we create our own PhoneStateListener
, in order to handle some states of the phone call. More specifically, in the state CALL_STATE_IDLE
, we want to return to our application’s main activity after the end of the call. For that reason we create a suitable Intent, as you can see in the code below:
CallingActivity.java
With this approach, we need package info.devexchanges.telephony;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class CallingActivity extends AppCompatActivity {
private Button btnCall;
private EditText txtPhone;
private final static String TAG = CallingActivity.class.getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_call);
txtPhone = (EditText) findViewById(R.id.txt_phone);
btnCall = (Button) findViewById(R.id.btn_call);
// add PhoneStateListener for monitoring
CustomPhoneListener phoneListener = new CustomPhoneListener();
TelephonyManager telephonyManager =
(TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
// receive notifications of telephony state changes
telephonyManager.listen(phoneListener,PhoneStateListener.LISTEN_CALL_STATE);
btnCall.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (txtPhone.getText().toString().trim().equals("")) {
Toast.makeText(CallingActivity.this, "Please input a phone number", Toast.LENGTH_SHORT).show();
} else {
try {
String uri = "tel:" + txtPhone.getText().toString();
Intent callIntent = new Intent(Intent.ACTION_CALL, Uri.parse(uri));
if (ActivityCompat.checkSelfPermission(CallingActivity.this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
return;
}
startActivity(callIntent);
} catch (Exception e) {
Toast.makeText(getApplicationContext(), "Your call has failed...", Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
}
});
}
private class CustomPhoneListener extends PhoneStateListener {
private boolean onCall = false;
@Override
public void onCallStateChanged(int state, String incomingNumber) {
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:
// phone ringing...
Log.i(TAG, "Destination phone is ringing, please wait...");
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
// one call exists that is dialing, active, or on hold
Log.i(TAG, "on Calling...");
//because user answers the incoming call
onCall = true;
break;
case TelephonyManager.CALL_STATE_IDLE:
// in initialization of the class and at the end of phone call
// detect flag from CALL_STATE_OFFHOOK
if (onCall) {
Log.i(TAG, "Restarting app after a call...!");
// restart our application
Intent restart = getBaseContext().getPackageManager().getLaunchIntentForPackage(getBaseContext().getPackageName());
restart.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(restart);
onCall = false;
}
break;
default:
break;
}
}
}
}
CALL_PHONE
and READ_PHONE_STATE
permissions in AndroidManifest.xml
:
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
Conclusions
Intent
. Further, you can learn by yourself the way to listen for incoming messages by BroadcastReceiver
. Finally, click the button below to view demo project on @Github.