개요
이 튜토리얼에서는 안드로이드 앱에서 SmsManager를 사용해 문자 메시지(SMS)를 전송하는 방법을 단계별로 살펴봅니다. 전화번호와 메시지 내용을 입력한 뒤 전송 버튼을 누르면 SMS가 발송되는 간단한 예제 앱을 직접 만들어 보겠습니다.
SMS 발송에는 SEND_SMS 권한이 반드시 필요하므로, 런타임 권한 요청 처리 방법까지 함께 다룹니다.
1단계 – 새 프로젝트 만들기
Android Studio를 실행하고 File ⇒ New Project를 선택한 후, 필요한 정보를 모두 입력해 새 프로젝트를 생성합니다.
2단계 – 레이아웃 작성 (activity_main.xml)
res/layout/activity_main.xml 파일에 아래 코드를 추가합니다. 전화번호 입력란, 메시지 입력란, 전송 버튼으로 구성된 세로 방향 LinearLayout 레이아웃입니다.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="4dp"
tools:context=".MainActivity">
<EditText
android:hint="Enter mobile number"
android:id="@+id/editTextNum"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<EditText
android:hint="Enter your message"
android:id="@+id/editTextMsg"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/btnSendMsg"
android:onClick="SendSMS"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Send Message"/>
</LinearLayout>
3단계 – MainActivity.java 작성
src/MainActivity.java에 아래 코드를 추가합니다. 이 코드는 먼저 SEND_SMS 권한이 부여되어 있는지 확인하고, 권한이 없으면 사용자에게 요청합니다. 이후 입력값이 비어 있는지, 숫자만 입력되었는지 검증한 뒤 SmsManager로 메시지를 전송하고 그 결과를 토스트(Toast)로 알려줍니다.
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.telephony.SmsManager;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
Button btnSend;
EditText editTextNum, editTextMsg;
private static final int PERMISSION_REQUEST = 101;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editTextNum = findViewById(R.id.editTextNum);
editTextMsg = findViewById(R.id.editTextMsg);
btnSend = findViewById(R.id.btnSendMsg);
}
public void SendSMS(View view) {
int permissionCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.SEND_SMS);
if (permissionCheck == PackageManager.PERMISSION_GRANTED){
MyMessage();
} else {
ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.SEND_SMS}, PERMISSION_REQUEST);
}
}
private void MyMessage() {
String myNumber = editTextNum.getText().toString().trim();
String myMsg = editTextMsg.getText().toString().trim();
if (myNumber.equals("") || myMsg.equals("")){
Toast.makeText(this, "Field cannot be empty", Toast.LENGTH_SHORT).show();
} else {
if (TextUtils.isDigitsOnly(myNumber)){
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(myNumber, null, myMsg, null, null);
Toast.makeText(this, "Message Sent", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Please enter the correct number", Toast.LENGTH_SHORT).show();
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PERMISSION_REQUEST) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
MyMessage();
} else {
Toast.makeText(this, "You don't have required permission to send a message", Toast.LENGTH_SHORT).show();
}
}
}
}
4단계 – 매니페스트에 권한 추가 (AndroidManifest.xml)
androidManifest.xml 파일에 아래와 같이 SEND_SMS 권한을 선언합니다. 이 권한이 선언되어 있지 않으면 앱은 SMS를 전송할 수 없습니다.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
package="app.com.sample">
<uses-permission android:name="android.permission.SEND_SMS"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
앱 실행 및 결과 확인
이제 애플리케이션을 실행해 보겠습니다. 실제 안드로이드 기기가 컴퓨터에 연결되어 있다고 가정합니다. Android Studio에서 프로젝트의 액티비티 파일 중 하나를 연 뒤, 툴바의 실행(Run)
아이콘을 클릭합니다. 기기 목록에서 본인의 모바일 기기를 선택하면, 해당 기기 화면에 아래와 같은 기본 화면이 표시됩니다.


참고: 듀얼 SIM 기기에서 특정 SIM으로 보내기
SmsManager.getDefault()는 항상 기본 SIM을 통해 메시지를 전송합니다. 듀얼 SIM 기기에서 특정 SIM을 지정해 발송하려면 Android 5.1(API 22) 이상에서 제공되는 getSmsManagerForSubscriptionId()를 활용할 수 있습니다.
SubscriptionManager subscriptionManager = getSystemService(SubscriptionManager.class);
// 첫 번째 SIM 슬롯의 subscriptionId 가져오기
int subscriptionId = subscriptionManager.getActiveSubscriptionInfoForSimSlotIndex(0).getSubscriptionId();
SmsManager smsManager = SmsManager.getSmsManagerForSubscriptionId(subscriptionId);
smsManager.sendTextMessage(myNumber, null, myMsg, null, null);
특정 SIM의 구독 정보를 읽어오려면 매니페스트에 READ_PHONE_STATE 권한도 함께 선언해야 하며, Android 6.0(API 23) 이상에서는 런타임에 해당 권한을 요청해야 한다는 점도 유의하세요.