공통 인텐트

인텐트를 사용하면 Intent 객체에서 실행할 작업(예: '지도 보기' 또는 '사진 찍기')을 설명하여 다른 앱에서 활동을 시작할 수 있습니다. 이런 유형의 인텐트를 암시적 인텐트라고 합니다. 시작할 앱 구성요소를 지정하는 대신 작업을 지정하고 그 작업을 수행하기 위한 약간의 데이터를 제공하기 때문입니다.

startActivity() 또는 startActivityForResult()를 호출하여 암시적 인텐트를 전달하면 시스템은 인텐트를 처리할 수 있는 앱을 찾아 인텐트를 확인하고 해당 Activity를 시작합니다. 인텐트를 처리할 수 있는 앱이 하나 이상 있는 경우, 시스템은 사용할 앱을 선택할 수 있는 대화상자를 사용자에게 표시합니다.

이 페이지에서는 일반적인 작업을 수행하는 데 사용하는 다양한 암시적 인텐트를 설명하며, 이 설명은 인텐트를 처리하는 앱의 유형별로 구성됩니다. 또한 각 섹션에서는 인텐트 필터를 만들어 앱의 작업 실행 기능을 광고하는 방법도 보여줍니다.

주의: 암시적 인텐트를 받을 수 있는 앱이 기기에 없으면 앱이 startActivity()를 호출할 때 비정상 종료됩니다. 인텐트를 수신할 앱이 있는지 먼저 확인하려면 Intent 객체에서 resolveActivity()를 호출합니다. 결과가 null이 아닌 경우, 인텐트를 처리할 수 있는 앱이 하나 이상 있다는 뜻이며 startActivity()를 호출해도 안전합니다. 결과가 null이면 해당 인텐트를 사용해서는 안 되며, 가능하면 해당 인텐트를 호출하는 기능을 비활성화해야 합니다.

인텐트나 인텐트 필터 생성 방법을 잘 모르는 경우 먼저 인텐트 및 인텐트 필터를 읽어보세요.

개발 호스트에서 이 페이지에 나열된 인텐트를 실행하는 방법을 알아보려면 Android 디버그 브리지로 인텐트 확인 섹션을 참고하세요.

Google Voice Actions

Google Voice Actions는 음성 명령에 응답하여 이 페이지에 열거된 일부 인텐트를 실행합니다. 자세한 내용은 시스템 음성 액션 시작하기를 참고하세요.

알람 시계

다음은 각 작업을 실행하는 앱의 기능을 광고하는 인텐트 필터를 만드는 데 필요한 정보를 포함하여 알람 시계 앱의 일반적인 작업입니다.

알람 만들기

Google Voice Actions

  • "오전 7시로 알람 설정해 줘"

새 알람을 만들려면 ACTION_SET_ALARM 작업을 사용하고 다음 엑스트라를 사용하여 시간과 메시지 등의 알람 세부정보를 지정합니다.

참고: Android 2.3 (API 수준 9) 이하에서는 시간, 분, 메시지 엑스트라만 사용할 수 있습니다. 그 밖의 엑스트라는 이후 버전의 플랫폼에서 사용할 수 있습니다.

작업
ACTION_SET_ALARM
데이터 URI
없음
MIME 유형
없음
추가 항목
EXTRA_HOUR
알람에서의 시입니다.
EXTRA_MINUTES
알람에서의 분.
EXTRA_MESSAGE
알람 식별을 위한 사용자 지정 메시지입니다.
EXTRA_DAYS
이 알람이 반복되는 각 요일이 포함된 ArrayList입니다. 각각의 날을 Calendar 클래스의 정수(예: MONDAY)로 선언해야 합니다.

일회성 알람에는 이 엑스트라를 지정하지 마세요.

EXTRA_RINGTONE
알람에 사용할 벨소리를 지정하는 content: URI. 벨소리를 사용하지 않으려면 VALUE_RINGTONE_SILENT를 사용합니다.

기본 벨소리를 사용하려면 이 엑스트라를 지정하지 마세요.

EXTRA_VIBRATE
이 알람에 진동을 사용할 것인지 여부를 지정하는 불리언입니다.
EXTRA_SKIP_UI
알람 설정 시 응답하는 앱이 그 UI를 건너뛰어야 하는지 여부를 지정하는 불리언입니다. 값이 true일 경우 그 앱은 확인 UI를 무시하고 지정된 알람을 설정해야 합니다.

인텐트 예:

Kotlin

fun createAlarm(message: String, hour: Int, minutes: Int) {
    val intent = Intent(AlarmClock.ACTION_SET_ALARM).apply {
        putExtra(AlarmClock.EXTRA_MESSAGE, message)
        putExtra(AlarmClock.EXTRA_HOUR, hour)
        putExtra(AlarmClock.EXTRA_MINUTES, minutes)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Java

public void createAlarm(String message, int hour, int minutes) {
    Intent intent = new Intent(AlarmClock.ACTION_SET_ALARM)
            .putExtra(AlarmClock.EXTRA_MESSAGE, message)
            .putExtra(AlarmClock.EXTRA_HOUR, hour)
            .putExtra(AlarmClock.EXTRA_MINUTES, minutes);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}
참고:

ACTION_SET_ALARM 인텐트를 호출하려면 앱에 SET_ALARM 권한이 있어야 합니다.

<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />

인텐트 필터의 예:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.SET_ALARM" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

타이머 만들기

Google Voice Actions

  • "5분 타이머 설정해 줘"

카운트다운 타이머를 만들려면 ACTION_SET_TIMER 작업을 사용하고 다음 엑스트라를 사용하여 기간 등의 타이머 세부정보를 지정합니다.

참고: 이 인텐트는 Android 4.4 (API 수준 19) 이상에서 사용할 수 있습니다.

작업
ACTION_SET_TIMER
데이터 URI
없음
MIME 유형
없음
추가 항목
EXTRA_LENGTH
타이머 길이(단위: 초)입니다.
EXTRA_MESSAGE
타이머 식별을 위한 사용자 지정 메시지입니다.
EXTRA_SKIP_UI
타이머 설정 시 응답하는 앱이 그 UI를 건너뛰어야 하는지 여부를 지정하는 불리언입니다. 값이 true일 경우 그 앱은 확인 UI를 무시하고 지정된 타이머를 시작해야 합니다.

인텐트 예:

Kotlin

fun startTimer(message: String, seconds: Int) {
    val intent = Intent(AlarmClock.ACTION_SET_TIMER).apply {
        putExtra(AlarmClock.EXTRA_MESSAGE, message)
        putExtra(AlarmClock.EXTRA_LENGTH, seconds)
        putExtra(AlarmClock.EXTRA_SKIP_UI, true)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

Java

public void startTimer(String message, int seconds) {
    Intent intent = new Intent(AlarmClock.ACTION_SET_TIMER)
            .putExtra(AlarmClock.EXTRA_MESSAGE, message)
            .putExtra(AlarmClock.EXTRA_LENGTH, seconds)
            .putExtra(AlarmClock.EXTRA_SKIP_UI, true);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}
참고:

ACTION_SET_TIMER 인텐트를 호출하려면 앱에 SET_ALARM 권한이 있어야 합니다.

<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />

인텐트 필터의 예:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.SET_TIMER" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

알람 모두 보기

알람 목록을 보려면 ACTION_SHOW_ALARMS 작업을 사용합니다.

이 인텐트를 호출하는 앱은 많지 않지만(이 인텐트는 주로 시스템 앱에서 사용됩니다), 알람 시계 기능이 있는 앱은 모두 이 인텐트 필터를 구현하고 현재의 알람을 표시함으로써 응답할 수 있습니다.

참고: 이 인텐트는 Android 4.4 (API 수준 19) 이상에서 사용할 수 있습니다.

작업
ACTION_SHOW_ALARMS
데이터 URI
없음
MIME 유형
없음

인텐트 필터의 예:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.SHOW_ALARMS" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

캘린더

일정 추가는 캘린더 앱의 일반적인 작업입니다. 다음 섹션의 정보를 사용하여 이 작업을 실행하는 앱의 기능을 광고하는 인텐트 필터를 만듭니다.

캘린더 이벤트 추가

사용자의 캘린더에 새 이벤트를 추가하려면 ACTION_INSERT 작업을 사용하고 Events.CONTENT_URI를 사용하여 데이터 URI를 지정합니다. 그런 다음 다음 엑스트라를 사용하여 다양한 이벤트 세부정보를 지정할 수 있습니다.

작업
ACTION_INSERT
데이터 URI
Events.CONTENT_URI
MIME 유형
"vnd.android.cursor.dir/event"
추가 항목
EXTRA_EVENT_ALL_DAY
종일 일정인지 여부를 지정하는 불리언입니다.
EXTRA_EVENT_BEGIN_TIME
이벤트가 시작되는 시간 (Epoch 이후부터의 밀리초).
EXTRA_EVENT_END_TIME
이벤트의 종료 시간 (Epoch 이후부터의 밀리초).
TITLE
이벤트 제목입니다.
DESCRIPTION
이벤트 설명입니다.
EVENT_LOCATION
이벤트 위치입니다.
EXTRA_EMAIL
초대된 사람들을 명시하는, 콤마로 분리된 이메일 주소 목록입니다.

CalendarContract.EventsColumns 클래스에 정의된 상수를 사용해서 그 밖에 많은 이벤트 정보를 지정할 수 있습니다.

인텐트 예:

Kotlin

fun addEvent(title: String, location: String, begin: Long, end: Long) {
    val intent = Intent(Intent.ACTION_INSERT).apply {
        data = Events.CONTENT_URI
        putExtra(Events.TITLE, title)
        putExtra(Events.EVENT_LOCATION, location)
        putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, begin)
        putExtra(CalendarContract.EXTRA_EVENT_END_TIME, end)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

자바

public void addEvent(String title, String location, long begin, long end) {
    Intent intent = new Intent(Intent.ACTION_INSERT)
            .setData(Events.CONTENT_URI)
            .putExtra(Events.TITLE, title)
            .putExtra(Events.EVENT_LOCATION, location)
            .putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, begin)
            .putExtra(CalendarContract.EXTRA_EVENT_END_TIME, end);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

인텐트 필터의 예:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.INSERT" />
        <data android:mimeType="vnd.android.cursor.dir/event" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

카메라

다음은 카메라 앱의 일반적인 작업과 각 작업을 실행하는 앱의 기능을 광고하는 인텐트 필터를 만드는 데 필요한 정보를 보여줍니다.

사진이나 동영상 찍어 반환하기

카메라 앱을 열고 결과물인 사진이나 동영상을 받으려면 ACTION_IMAGE_CAPTURE 또는 ACTION_VIDEO_CAPTURE 작업을 사용합니다. 또한 EXTRA_OUTPUT 엑스트라에서 카메라가 사진이나 동영상을 저장할 URI 위치도 지정합니다.

작업
ACTION_IMAGE_CAPTURE 또는
ACTION_VIDEO_CAPTURE
데이터 URI 스키마
없음
MIME 유형
없음
추가 항목
EXTRA_OUTPUT
카메라 앱이 사진이나 동영상 파일을 저장하는 URI 위치 (Uri 객체로서).

카메라 앱이 액티비티에 포커스를 성공적으로 반환하면(즉, 앱이 onActivityResult() 콜백을 수신하면) EXTRA_OUTPUT 값으로 지정한 URI에서 사진이나 동영상에 액세스할 수 있습니다.

참고: ACTION_IMAGE_CAPTURE를 사용하여 사진을 찍을 때 카메라가 사진의 축소된 사본(썸네일)을 결과 Intent에 반환할 수 있습니다. 이는 "data"라는 이름의 엑스트라 필드에 Bitmap로 저장됩니다.

인텐트 예:

Kotlin

const val REQUEST_IMAGE_CAPTURE = 1
val locationForPhotos: Uri = ...

fun capturePhoto(targetFilename: String) {
    val intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE).apply {
        putExtra(MediaStore.EXTRA_OUTPUT, Uri.withAppendedPath(locationForPhotos, targetFilename))
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivityForResult(intent, REQUEST_IMAGE_CAPTURE)
    }
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
    if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == Activity.RESULT_OK) {
        val thumbnail: Bitmap = data.getParcelableExtra("data")
        // Do other work with full size photo saved in locationForPhotos.
        ...
    }
}

자바

static final int REQUEST_IMAGE_CAPTURE = 1;
static final Uri locationForPhotos;

public void capturePhoto(String targetFilename) {
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    intent.putExtra(MediaStore.EXTRA_OUTPUT,
            Uri.withAppendedPath(locationForPhotos, targetFilename));
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
        Bitmap thumbnail = data.getParcelableExtra("data");
        // Do other work with full size photo saved in locationForPhotos.
        ...
    }
}

Android 12 (API 수준 31) 이상에서 이를 수행하려면 다음 인텐트 예시를 참고하세요.

인텐트 예:

Kotlin

val REQUEST_IMAGE_CAPTURE = 1

private fun dispatchTakePictureIntent() {
    val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
    try {
        startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE)
    } catch (e: ActivityNotFoundException) {
        // Display error state to the user.
    }
}

자바

static final int REQUEST_IMAGE_CAPTURE = 1;

private void dispatchTakePictureIntent() {
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    try {
        startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
    } catch (ActivityNotFoundException e) {
        // Display error state to the user.
    }
}
</section></div>

출력 위치에 적절한 Uri를 만드는 방법을 비롯하여 이 인텐트를 사용하여 사진을 찍는 방법에 관한 자세한 내용은 Take photos 또는 Take videos를 참고하세요.

인텐트 필터의 예:

<activity ...>
    <intent-filter>
        <action android:name="android.media.action.IMAGE_CAPTURE" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

이 인텐트를 처리할 때 호출한 액티비티는 들어오는 Intent에서 EXTRA_OUTPUT 엑스트라를 확인한 다음, 이 엑스트라로 지정한 위치에 촬영한 이미지나 동영상을 저장하고, 압축된 썸네일을 "data"라는 엑스트라에 포함하는 IntentsetResult()를 호출합니다.

정지 영상 모드에서 카메라 앱 시작하기

Google Voice Actions

  • "사진 찍어 줘"

카메라를 정지 이미지 모드로 열려면 INTENT_ACTION_STILL_IMAGE_CAMERA 작업을 사용합니다.

작업
INTENT_ACTION_STILL_IMAGE_CAMERA
데이터 URI 스키마
없음
MIME 유형
없음
추가 항목
없음

인텐트 예:

Kotlin

private fun dispatchTakePictureIntent() {
    val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
    try {
        startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE)
    } catch (e: ActivityNotFoundException) {
        // Display error state to the user.
    }
}

자바

public void capturePhoto(String targetFilename) {
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    intent.putExtra(MediaStore.EXTRA_OUTPUT,
            Uri.withAppendedPath(locationForPhotos, targetFilename));
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
    }
}

인텐트 필터의 예:

<activity ...>
    <intent-filter>
        <action android:name="android.media.action.STILL_IMAGE_CAMERA" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

동영상 모드에서 카메라 앱 시작하기

Google Voice Actions

  • "동영상 녹화해 줘"

카메라 앱을 동영상 모드로 열려면 INTENT_ACTION_VIDEO_CAMERA 작업을 사용합니다.

작업
INTENT_ACTION_VIDEO_CAMERA
데이터 URI 스키마
없음
MIME 유형
없음
추가 항목
없음

인텐트 예:

Kotlin

fun capturePhoto() {
    val intent = Intent(MediaStore.INTENT_ACTION_VIDEO_CAMERA)
    if (intent.resolveActivity(packageManager) != null) {
        startActivityForResult(intent, REQUEST_IMAGE_CAPTURE)
    }
}

자바

public void capturePhoto() {
    Intent intent = new Intent(MediaStore.INTENT_ACTION_VIDEO_CAMERA);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
    }
}

인텐트 필터의 예:

<activity ...>
    <intent-filter>
        <action android:name="android.media.action.VIDEO_CAMERA" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

연락처/피플 앱

다음은 연락처 관리 앱의 일반적인 작업과 각 작업을 실행하는 앱의 기능을 광고하는 인텐트 필터를 만드는 데 필요한 정보를 보여줍니다.

연락처 선택

사용자가 연락처를 선택하고 앱에 모든 연락처 정보에 액세스 권한을 주려면 ACTION_PICK 작업을 사용하고 MIME 유형을 Contacts.CONTENT_TYPE로 지정합니다.

onActivityResult() 콜백에 전달된 결과 Intent에는 선택한 연락처를 가리키는 content: URI가 포함됩니다. 이 응답은 앱에 READ_CONTACTS 권한이 포함되어 있지 않더라도 연락처 제공자 API를 사용하여 임시로 해당 연락처를 읽도록 허가합니다.

도움말: 연락처 정보에서 전화번호나 이메일 주소 등 특정 부분에만 액세스할 필요가 있다면, 특정 연락처 데이터를 선택하는 방법에 관한 다음 섹션을 참고하세요.

작업
ACTION_PICK
데이터 URI 스키마
없음
MIME 유형
Contacts.CONTENT_TYPE

인텐트 예:

Kotlin

const val REQUEST_SELECT_CONTACT = 1

fun selectContact() {
    val intent = Intent(Intent.ACTION_PICK).apply {
        type = ContactsContract.Contacts.CONTENT_TYPE
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivityForResult(intent, REQUEST_SELECT_CONTACT)
    }
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
    if (requestCode == REQUEST_SELECT_CONTACT && resultCode == RESULT_OK) {
        val contactUri: Uri = data.data
        // Do something with the selected contact at contactUri.
        //...
    }
}

자바

static final int REQUEST_SELECT_CONTACT = 1;

public void selectContact() {
    Intent intent = new Intent(Intent.ACTION_PICK);
    intent.setType(ContactsContract.Contacts.CONTENT_TYPE);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(intent, REQUEST_SELECT_CONTACT);
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_SELECT_CONTACT && resultCode == RESULT_OK) {
        Uri contactUri = data.getData();
        // Do something with the selected contact at contactUri.
        ...
    }
}

연락처 URI를 생성한 후 연락처 세부정보를 검색하는 방법에 대해서는 연락처 세부정보 검색을 참고하세요.

이 인텐트를 사용하여 연락처 URI를 검색할 때는 일반적으로 표시 이름, 연락처에 별표표시 여부와 같은 연락처의 기본 세부정보를 읽기 위한 READ_CONTACTS 권한이 필요하지 않습니다. 하지만 특정 연락처에 관한 더 구체적인 데이터(예: 전화번호 또는 이메일 주소)를 읽으려면 READ_CONTACTS 권한이 필요합니다.

특정 연락처 데이터 선택

사용자가 연락처에서 전화번호, 이메일 주소 또는 기타 데이터 유형 등의 특정 정보만 선택할 수 있도록 하려면 ACTION_PICK 작업을 사용하고 MIME 유형으로 다음 콘텐츠 유형 중 하나를 지정합니다. 예를 들어 연락처의 전화번호를 얻으려면 CommonDataKinds.Phone.CONTENT_TYPE을 지정합니다.

참고: 특정 연락처에 관한 특정 정보를 보려면 대부분의 경우 앱에 READ_CONTACTS 권한이 있어야 합니다.

연락처에서 한 가지 유형의 데이터만 검색해야 하는 경우 ContactsContract.CommonDataKinds 클래스의 CONTENT_TYPE를 사용하는 이 기법이 앞 섹션에서 설명한 Contacts.CONTENT_TYPE를 사용하는 것보다 효율적입니다. 이 결과를 사용하면 연락처 제공자에 더 복잡한 쿼리를 실행하지 않고도 원하는 데이터에 직접 액세스할 수 있습니다.

onActivityResult() 콜백에 전달된 결과 Intent에는 선택한 연락처 데이터를 가리키는 content: URI가 포함됩니다. 이 응답은 앱에 READ_CONTACTS 권한이 포함되어 있지 않더라도, 임시로 해당 연락처 데이터를 읽도록 허가합니다.

작업
ACTION_PICK
데이터 URI 스키마
없음
MIME 유형
CommonDataKinds.Phone.CONTENT_TYPE
연락처에서 전화번호를 골라냅니다.
CommonDataKinds.Email.CONTENT_TYPE
연락처에서 이메일 주소를 골라냅니다.
CommonDataKinds.StructuredPostal.CONTENT_TYPE
우편 주소가 있는 연락처 중에서 선택합니다.

아니면 ContactsContract에서 많은 CONTENT_TYPE 값 중 하나를 골라냅니다.

인텐트 예:

Kotlin

const val REQUEST_SELECT_PHONE_NUMBER = 1

fun selectContact() {
    // Start an activity for the user to pick a phone number from contacts.
    val intent = Intent(Intent.ACTION_PICK).apply {
        type = CommonDataKinds.Phone.CONTENT_TYPE
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivityForResult(intent, REQUEST_SELECT_PHONE_NUMBER)
    }
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
    if (requestCode == REQUEST_SELECT_PHONE_NUMBER && resultCode == Activity.RESULT_OK) {
        // Get the URI and query the content provider for the phone number.
        val contactUri: Uri = data.data
        val projection: Array<String> = arrayOf(CommonDataKinds.Phone.NUMBER)
        contentResolver.query(contactUri, projection, null, null, null).use { cursor ->
            // If the cursor returned is valid, get the phone number.
            if (cursor.moveToFirst()) {
                val numberIndex = cursor.getColumnIndex(CommonDataKinds.Phone.NUMBER)
                val number = cursor.getString(numberIndex)
                // Do something with the phone number.
                ...
            }
        }
    }
}

자바

static final int REQUEST_SELECT_PHONE_NUMBER = 1;

public void selectContact() {
    // Start an activity for the user to pick a phone number from contacts.
    Intent intent = new Intent(Intent.ACTION_PICK);
    intent.setType(CommonDataKinds.Phone.CONTENT_TYPE);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(intent, REQUEST_SELECT_PHONE_NUMBER);
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_SELECT_PHONE_NUMBER && resultCode == RESULT_OK) {
        // Get the URI and query the content provider for the phone number.
        Uri contactUri = data.getData();
        String[] projection = new String[]{CommonDataKinds.Phone.NUMBER};
        Cursor cursor = getContentResolver().query(contactUri, projection,
                null, null, null);
        // If the cursor returned is valid, get the phone number.
        if (cursor != null && cursor.moveToFirst()) {
            int numberIndex = cursor.getColumnIndex(CommonDataKinds.Phone.NUMBER);
            String number = cursor.getString(numberIndex);
            // Do something with the phone number.
            //...
        }
    }
}

연락처 보기

알고 있는 연락처의 세부정보를 표시하려면 ACTION_VIEW 작업을 사용하고, content: URI를 가지고 연락처를 인텐트 데이터로 지정합니다.

연락처의 URI를 검색하는 데는 주로 두 가지 방법이 사용됩니다.

  • 앞 섹션에 나온 ACTION_PICK 작업에서 반환된 연락처 URI를 사용합니다. 이 접근 방식에는 앱 권한이 필요하지 않습니다.
  • 연락처 목록 검색에 설명된 대로 모든 연락처 목록에 직접 액세스합니다. 이 접근 방식에는 READ_CONTACTS 권한이 필요합니다.
작업
ACTION_VIEW
데이터 URI 스키마
content:<URI>
MIME 유형
없음 이 유형은 연락처 URI에서 추론됩니다.

인텐트 예:

Kotlin

fun viewContact(contactUri: Uri) {
    val intent = Intent(Intent.ACTION_VIEW, contactUri)
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

자바

public void viewContact(Uri contactUri) {
    Intent intent = new Intent(Intent.ACTION_VIEW, contactUri);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

기존 연락처 편집

알고 있는 연락처를 수정하려면 ACTION_EDIT 작업을 사용하고, content: URI가 있는 연락처를 인텐트 데이터로 지정합니다. 그리고 ContactsContract.Intents.Insert의 상수에서 지정한 엑스트라에 알려진 연락처 정보를 포함합니다.

연락처의 URI를 검색하는 데는 주로 두 가지 방법이 사용됩니다.

  • 앞 섹션에 나온 ACTION_PICK 작업에서 반환된 연락처 URI를 사용합니다. 이 접근 방식에는 앱 권한이 필요하지 않습니다.
  • 연락처 목록 검색에 설명된 대로 모든 연락처 목록에 직접 액세스합니다. 이 접근 방식에는 READ_CONTACTS 권한이 필요합니다.
작업
ACTION_EDIT
데이터 URI 스키마
content:<URI>
MIME 유형
이 유형은 연락처 URI에서 추론됩니다.
추가 항목
ContactsContract.Intents.Insert에서 정의한 하나 이상의 부가정보. 연락처 정보 필드를 채울 수 있습니다.

인텐트 예:

Kotlin

fun editContact(contactUri: Uri, email: String) {
    val intent = Intent(Intent.ACTION_EDIT).apply {
        data = contactUri
        putExtra(ContactsContract.Intents.Insert.EMAIL, email)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

자바

public void editContact(Uri contactUri, String email) {
    Intent intent = new Intent(Intent.ACTION_EDIT);
    intent.setData(contactUri);
    intent.putExtra(Intents.Insert.EMAIL, email);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

연락처를 수정하는 방법에 관한 자세한 내용은 인텐트를 사용하여 연락처 수정을 참고하세요.

연락처 삽입

새 연락처를 삽입하려면 ACTION_INSERT 작업을 사용하고 MIME 유형으로 Contacts.CONTENT_TYPE를 지정합니다. 그리고 ContactsContract.Intents.Insert의 상수에서 지정한 엑스트라에 알고 있는 연락처 정보를 포함합니다.

작업
ACTION_INSERT
데이터 URI 스키마
없음
MIME 유형
Contacts.CONTENT_TYPE
추가 항목
ContactsContract.Intents.Insert에 정의된 하나 이상의 엑스트라.

인텐트 예:

Kotlin

fun insertContact(name: String, email: String) {
    val intent = Intent(Intent.ACTION_INSERT).apply {
        type = ContactsContract.Contacts.CONTENT_TYPE
        putExtra(ContactsContract.Intents.Insert.NAME, name)
        putExtra(ContactsContract.Intents.Insert.EMAIL, email)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

자바

public void insertContact(String name, String email) {
    Intent intent = new Intent(Intent.ACTION_INSERT);
    intent.setType(Contacts.CONTENT_TYPE);
    intent.putExtra(Intents.Insert.NAME, name);
    intent.putExtra(Intents.Insert.EMAIL, email);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

연락처 삽입에 대한 자세한 내용은 인텐트를 사용하여 연락처 수정을 참고하세요.

이메일

선택적 첨부파일이 있는 이메일을 작성하는 것은 이메일 앱에서 일반적인 작업입니다. 다음 섹션의 정보를 사용하여 이 작업을 실행하는 앱의 기능을 광고하는 인텐트 필터를 만듭니다.

선택적 첨부 파일이 있는 이메일 작성

이메일을 작성하려면 첨부 파일을 포함할 것인지에 따라 다음 작업 중 하나를 사용하고, 나열된 추가 키를 사용하여 받는 사람이나 제목 등의 이메일 세부정보를 포함합니다.

작업
ACTION_SENDTO (첨부파일이 없음) 또는
ACTION_SEND (첨부파일이 하나) 또는
ACTION_SEND_MULTIPLE (첨부파일이 여러 개)
데이터 URI 스키마
없음
MIME 유형
"text/plain"
"*/*"
추가 항목
Intent.EXTRA_EMAIL
모든 '받는 사람' 이메일 주소의 문자열 배열입니다.
Intent.EXTRA_CC
모든 '참조' 수신자 이메일 주소의 문자열 배열입니다.
Intent.EXTRA_BCC
모든 'BCC' 수신자 이메일 주소의 문자열 배열입니다.
Intent.EXTRA_SUBJECT
이메일 제목 문자열입니다.
Intent.EXTRA_TEXT
이메일 본문 문자열.
Intent.EXTRA_STREAM
첨부파일을 가리키는 Uri입니다. ACTION_SEND_MULTIPLE 작업을 사용하는 경우에는 대신 여러 개의 Uri 객체가 포함된 ArrayList입니다.

인텐트 예:

Kotlin

fun composeEmail(addresses: Array<String>, subject: String, attachment: Uri) {
    val intent = Intent(Intent.ACTION_SEND).apply {
        type = "*/*"
        putExtra(Intent.EXTRA_EMAIL, addresses)
        putExtra(Intent.EXTRA_SUBJECT, subject)
        putExtra(Intent.EXTRA_STREAM, attachment)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

자바

public void composeEmail(String[] addresses, String subject, Uri attachment) {
    Intent intent = new Intent(Intent.ACTION_SEND);
    intent.setType("*/*");
    intent.putExtra(Intent.EXTRA_EMAIL, addresses);
    intent.putExtra(Intent.EXTRA_SUBJECT, subject);
    intent.putExtra(Intent.EXTRA_STREAM, attachment);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

이메일 앱에서만 이 인텐트가 처리되고 문자 메시지 앱이나 소셜 앱에서는 처리되지 않도록 하려면 다음 예와 같이 ACTION_SENDTO 작업을 사용하고 "mailto:" 데이터 구성표를 포함합니다.

Kotlin

fun composeEmail(addresses: Array<String>, subject: String) {
    val intent = Intent(Intent.ACTION_SENDTO).apply {
        data = Uri.parse("mailto:") // Only email apps handle this.
        putExtra(Intent.EXTRA_EMAIL, addresses)
        putExtra(Intent.EXTRA_SUBJECT, subject)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

자바

public void composeEmail(String[] addresses, String subject) {
    Intent intent = new Intent(Intent.ACTION_SENDTO);
    intent.setData(Uri.parse("mailto:")); // Only email apps handle this.
    intent.putExtra(Intent.EXTRA_EMAIL, addresses);
    intent.putExtra(Intent.EXTRA_SUBJECT, subject);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

인텐트 필터의 예:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <data android:type="*/*" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
    <intent-filter>
        <action android:name="android.intent.action.SENDTO" />
        <data android:scheme="mailto" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

파일 저장

다음은 각 작업을 실행하는 앱의 기능을 광고하는 인텐트 필터를 만드는 데 필요한 정보를 포함하여 파일 저장소 앱의 일반적인 작업입니다.

특정 유형의 파일 검색

사용자가 문서나 사진 등의 파일을 선택하고 앱에 그 참조를 반환하도록 요청하려면 ACTION_GET_CONTENT 작업을 사용하고 원하는 MIME 유형을 지정합니다. 앱에 반환된 파일 참조는 액티비티의 현재 수명 주기에만 일시적으로 존재하므로 나중에 여기에 액세스하려면 나중에 읽을 수 있는 사본을 가져와야 합니다.

이 인텐트를 사용하면 사용자가 프로세스에서 새 파일을 만들 수도 있습니다. 예를 들어 사용자는 기존 사진을 선택하는 대신 카메라로 새 사진을 캡처할 수 있습니다.

onActivityResult() 메서드에 전달된 결과 인텐트에는 이 파일을 가리키는 URI가 있는 데이터가 포함됩니다. 이 URI는 http: URI, file: URI, content: URI 등과 같이 무엇이든 가능합니다. 그러나 선택할 수 있는 파일을 콘텐츠 제공자 (content: URI)에서 액세스할 수 있는 파일과 openFileDescriptor()를 통해 파일 스트림으로서 이용할 수 있는 파일만으로 제한하고 싶다면 인텐트에 CATEGORY_OPENABLE 카테고리를 추가합니다.

Android 4.3 (API 수준 18) 이상에서는 인텐트에 EXTRA_ALLOW_MULTIPLE를 추가하고 true로 설정하여 사용자가 여러 파일을 선택하도록 할 수도 있습니다. 그러면 getClipData()에서 반환한 ClipData 객체에서 선택된 각 파일에 액세스할 수 있습니다.

작업
ACTION_GET_CONTENT
데이터 URI 스키마
없음
MIME 유형
사용자가 선택해야 하는 파일 유형에 해당하는 MIME 유형입니다.
추가 항목
EXTRA_ALLOW_MULTIPLE
사용자가 한 번에 파일을 한 개 이상 선택할 수 있는지의 여부를 선언하는 불리언 값입니다.
EXTRA_LOCAL_ONLY
반환된 파일을 원격 서비스에서 다운로드해야 하는 대신 기기에서 직접 열 수 있어야 하는지의 여부를 선언하는 불리언 값입니다.
카테고리 (선택사항)
CATEGORY_OPENABLE
openFileDescriptor()로 열어 파일 스트림으로 나타낼 수 있는, "열 수 있는" 파일만 반환합니다.

사진을 가져오는 인텐트 예시:

Kotlin

const val REQUEST_IMAGE_GET = 1

fun selectImage() {
    val intent = Intent(Intent.ACTION_GET_CONTENT).apply {
        type = "image/*"
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivityForResult(intent, REQUEST_IMAGE_GET)
    }
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
    if (requestCode == REQUEST_IMAGE_GET && resultCode == Activity.RESULT_OK) {
        val thumbnail: Bitmap = data.getParcelableExtra("data")
        val fullPhotoUri: Uri = data.data
        // Do work with photo saved at fullPhotoUri.
        ...
    }
}

자바

static final int REQUEST_IMAGE_GET = 1;

public void selectImage() {
    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
    intent.setType("image/*");
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(intent, REQUEST_IMAGE_GET);
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_IMAGE_GET && resultCode == RESULT_OK) {
        Bitmap thumbnail = data.getParcelable("data");
        Uri fullPhotoUri = data.getData();
        // Do work with photo saved at fullPhotoUri.
        ...
    }
}

사진을 돌려주는 예시 인텐트 필터:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.GET_CONTENT" />
        <data android:type="image/*" />
        <category android:name="android.intent.category.DEFAULT" />
        <!-- The OPENABLE category declares that the returned file is accessible
             from a content provider that supports OpenableColumns
             and ContentResolver.openFileDescriptor(). -->
        <category android:name="android.intent.category.OPENABLE" />
    </intent-filter>
</activity>

특정 유형의 파일 열기

ACTION_GET_CONTENT 작업을 사용하여 앱에 가져와야 하는 파일의 사본을 검색하는 대신, Android 4.4 이상에서는 ACTION_OPEN_DOCUMENT 작업을 사용하고 MIME 유형을 지정함으로써 다른 앱에서 관리하는 파일 열기를 요청할 수 있습니다. 또한 사용자가 앱에서 쓰기가 가능한 새 문서를 만들 수 있도록 하려면 ACTION_CREATE_DOCUMENT 작업을 대신 사용하세요.

예를 들어 기존 PDF 문서를 선택하는 대신 ACTION_CREATE_DOCUMENT 인텐트를 사용하면 사용자가 문서의 저장소를 관리하는 다른 앱 내에서 새 문서를 만들 위치를 선택할 수 있습니다. 그러면 앱이 새 문서를 작성할 수 있는 URI 위치를 받게 됩니다.

ACTION_GET_CONTENT 작업에서 onActivityResult() 메서드에 전달된 인텐트는 어떤 유형의 URI라도 반환할 수 있지만 ACTION_OPEN_DOCUMENTACTION_CREATE_DOCUMENT의 결과 인텐트는 항상 선택된 파일을 DocumentsProvider가 지원하는 content: URI로 지정합니다. openFileDescriptor()로 파일을 열고 DocumentsContract.Document의 열을 사용하여 세부정보를 쿼리할 수 있습니다.

반환된 URI는 앱에 장기적 파일 읽기 권한을 부여합니다(쓰기 권한도 가능할 수 있음). ACTION_OPEN_DOCUMENT 작업은 특히 기존의 파일을 앱에 복사해오지 않고 읽고 싶을 때, 또는 파일을 그 자리에서 열어 편집하고 싶을 때 유용합니다.

사용자가 인텐트에 EXTRA_ALLOW_MULTIPLE을 추가하고 true로 설정하여 여러 파일을 선택하도록 할 수도 있습니다. 사용자가 한 개의 항목만 선택하면 getData()에서 그 항목을 검색할 수 있습니다. 사용자가 항목을 두 개 이상 선택하는 경우에는 getData()가 null을 반환하므로, 대신 getClipData()에서 반환한 ClipData 객체에서 각 항목을 검색해야 합니다.

참고: 인텐트는 MIME 유형을 지정해야 하며 CATEGORY_OPENABLE 카테고리를 선언해야 합니다. 적절한 경우 EXTRA_MIME_TYPES 엑스트라를 사용하여 MIME 유형 배열을 추가하여 MIME 유형을 둘 이상 지정할 수 있습니다. 이 경우 setType()에서 기본 MIME 유형을 "*/*"로 설정해야 합니다.

작업
ACTION_OPEN_DOCUMENT 또는
ACTION_CREATE_DOCUMENT
데이터 URI 스키마
없음
MIME 유형
사용자가 선택해야 하는 파일 유형에 해당하는 MIME 유형입니다.
추가 항목
EXTRA_MIME_TYPES
앱에서 요구되는 파일 유형에 해당하는 MIME 유형의 배열입니다. 이 엑스트라를 사용할 때는 setType()에서 기본 MIME 유형을 "*/*"로 설정해야 합니다.
EXTRA_ALLOW_MULTIPLE
사용자가 한 번에 파일을 두 개 이상 선택할 수 있는지를 선언하는 불리언 값입니다.
EXTRA_TITLE
ACTION_CREATE_DOCUMENT와 함께 사용하여 최초 파일 이름을 지정합니다.
EXTRA_LOCAL_ONLY
반환된 파일을 원격 서비스에서 다운로드해야 하는 대신 기기에서 직접 열 수 있어야 하는지의 여부를 선언하는 불리언 값입니다.
카테고리
CATEGORY_OPENABLE
openFileDescriptor()로 열어 파일 스트림으로 나타낼 수 있는, "열 수 있는" 파일만 반환합니다.

사진을 가져오는 인텐트 예시:

Kotlin

const val REQUEST_IMAGE_OPEN = 1

fun selectImage2() {
    val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
        type = "image/*"
        addCategory(Intent.CATEGORY_OPENABLE)
    }
    // Only the system receives the ACTION_OPEN_DOCUMENT, so no need to test.
    startActivityForResult(intent, REQUEST_IMAGE_OPEN)
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
    if (requestCode == REQUEST_IMAGE_OPEN && resultCode == Activity.RESULT_OK) {
        val fullPhotoUri: Uri = data.data
        // Do work with full size photo saved at fullPhotoUri.
        ...
    }
}

자바

static final int REQUEST_IMAGE_OPEN = 1;

public void selectImage() {
    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
    intent.setType("image/*");
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    // Only the system receives the ACTION_OPEN_DOCUMENT, so no need to test.
    startActivityForResult(intent, REQUEST_IMAGE_OPEN);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_IMAGE_OPEN && resultCode == RESULT_OK) {
        Uri fullPhotoUri = data.getData();
        // Do work with full size photo saved at fullPhotoUri.
        ...
    }
}

서드 파티 앱은 ACTION_OPEN_DOCUMENT 작업이 있는 인텐트에 응답할 수 없습니다. 그 대신 시스템이 이 인텐트를 받아 다양한 앱에서 이용할 수 있는 파일들을 모두 통합 사용자 인터페이스에 표시합니다.

이 UI에 앱의 파일을 제공하고 다른 앱이 열 수 있도록 하려면 다음 예와 같이 DocumentsProvider를 구현하고 PROVIDER_INTERFACE("android.content.action.DOCUMENTS_PROVIDER")용 인텐트 필터를 포함해야 합니다.

<provider ...
    android:grantUriPermissions="true"
    android:exported="true"
    android:permission="android.permission.MANAGE_DOCUMENTS">
    <intent-filter>
        <action android:name="android.content.action.DOCUMENTS_PROVIDER" />
    </intent-filter>
</provider>

앱이 관리하는 파일을 다른 앱에서 열 수 있게 하는 방법에 대한 자세한 내용은 저장소 액세스 프레임워크를 사용하여 파일 열기를 참고하세요.

오프라인 액션

자동차 호출은 일반적인 로컬 작업입니다. 다음 섹션의 정보를 사용하여 이 작업을 실행하는 앱의 기능을 광고하는 인텐트 필터를 만듭니다.

택시 호출

Google Voice Actions

  • "택시 불러 줘"
  • "차 좀 불러주세요"

(Wear OS 전용)

택시를 부르려면 ACTION_RESERVE_TAXI_RESERVATION 작업을 사용합니다.

참고: 앱은 이 작업을 완료하기 전에 사용자에게 확인을 요청해야 합니다.

작업
ACTION_RESERVE_TAXI_RESERVATION
데이터 URI
없음
MIME 유형
없음
추가 항목
없음

인텐트 예:

Kotlin

fun callCar() {
    val intent = Intent(ReserveIntents.ACTION_RESERVE_TAXI_RESERVATION)
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

자바

public void callCar() {
    Intent intent = new Intent(ReserveIntents.ACTION_RESERVE_TAXI_RESERVATION);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

인텐트 필터의 예:

<activity ...>
    <intent-filter>
        <action android:name="com.google.android.gms.actions.RESERVE_TAXI_RESERVATION" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

지도

지도 앱에서는 지도에 위치를 표시하는 것이 일반적인 작업입니다. 다음 섹션의 정보를 사용하여 이 작업을 실행하는 앱의 기능을 광고하는 인텐트 필터를 만듭니다.

지도상에 위치 표시하기

지도를 열려면 ACTION_VIEW 작업을 사용하고 다음 스키마 중 하나로 인텐트 데이터에 위치 정보를 지정합니다.

작업
ACTION_VIEW
데이터 URI 스키마
geo:latitude,longitude
주어진 경도와 위도의 맵을 표시합니다.

예: "geo:47.6,-122.3"

geo:latitude,longitude?z=zoom
주어진 경도와 위도의 맵을 특정 확대/축소 수준에서 표시합니다. 확대/축소 수준이 1이면 지구 전체가 주어진 lat,lng을 중심으로 표시됩니다. 가장 높은(가장 가까운) 확대/축소 수준은 23입니다.

예: "geo:47.6,-122.3?z=11"

geo:0,0?q=lat,lng(label)
주어진 경도와 위도의 맵을 문자열 레이블과 함께 표시합니다.

예: "geo:0,0?q=34.99,-106.61(Treasure)"

geo:0,0?q=my+street+address
'내 상세 주소' 위치를 표시합니다. 특정 주소나 위치 쿼리일 수 있습니다.

예: "geo:0,0?q=1600+Amphitheatre+Parkway%2C+CA"

참고: geo URI에 전달된 모든 문자열은 인코딩되어야 합니다. 예를 들어 1st & Pike, Seattle 문자열은 1st%20%26%20Pike%2C%20Seattle가 됩니다. 문자열의 공백은 %20로 인코딩되거나 더하기 기호 (+)로 대체됩니다.

MIME 유형
없음

인텐트 예:

Kotlin

fun showMap(geoLocation: Uri) {
    val intent = Intent(Intent.ACTION_VIEW).apply {
        data = geoLocation
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

자바

public void showMap(Uri geoLocation) {
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setData(geoLocation);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

인텐트 필터의 예:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <data android:scheme="geo" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

음악 또는 동영상

다음은 음악 및 동영상 앱의 일반적인 작업과 각 작업을 실행하는 앱의 기능을 광고하는 인텐트 필터를 만드는 데 필요한 정보를 보여줍니다.

미디어 파일 재생

음악 파일을 재생하려면 ACTION_VIEW 작업을 사용하고 인텐트 데이터에 파일의 URI 위치를 지정합니다.

작업
ACTION_VIEW
데이터 URI 스키마
file:<URI>
content:<URI>
http:<URL>
MIME 유형
"audio/*"
"application/ogg"
"application/x-ogg"
"application/itunes"
또는 앱에서 요구하는 다른 유형.

인텐트 예:

Kotlin

fun playMedia(file: Uri) {
    val intent = Intent(Intent.ACTION_VIEW).apply {
        data = file
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

자바

public void playMedia(Uri file) {
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setData(file);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

인텐트 필터의 예:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <data android:type="audio/*" />
        <data android:type="application/ogg" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

검색어 기반 음악 재생

Google Voice Actions

  • "마이클 잭슨의 billie jean을 들려주세요"

검색어를 바탕으로 음악을 재생하려면 INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH 인텐트를 사용합니다. 앱이 사용자의 음성 명령에 응답하여 이 인텐트를 실행하고 음악을 재생할 수 있습니다. 이 인텐트를 수신하는 앱은 인벤토리에서 주어진 쿼리와 일치하는 콘텐츠를 검색하여 해당 콘텐츠를 재생하기 시작합니다.

이 인텐트에는 원하는 검색 모드를 지정하는 EXTRA_MEDIA_FOCUS 문자열 엑스트라를 포함합니다. 예를 들어, 검색 모드는 아티스트 이름으로 검색할 것인지 노래 제목으로 검색할 것인지 지정할 수 있습니다.

작업
INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH
데이터 URI 스키마
없음
MIME 유형
없음
추가 항목
MediaStore.EXTRA_MEDIA_FOCUS(필수 항목)

검색 모드를 나타냅니다. 사용자가 특정 아티스트, 앨범, 노래 또는 재생목록 중 무엇을 찾고 있는지 지정합니다. 대부분의 검색 모드는 추가 엑스트라를 취합니다. 예를 들어 사용자가 특정 노래를 듣는 데 관심이 있다면 인텐트에 노래 제목, 아티스트, 앨범, 이 세 가지의 엑스트라가 더 있어야 합니다. 이 인텐트는 각 EXTRA_MEDIA_FOCUS 값에 대해 다음과 같은 검색 모드를 지원합니다.

기타 - "vnd.android.cursor.item/*"

아무 음악이나 재생합니다. 수신 앱은 임의의 선택으로 현명하게, 이를테면 사용자가 마지막으로 들은 재생목록 등의 음악을 재생합니다.

추가적인 엑스트라:

  • QUERY (필수): 빈 문자열입니다. 이 엑스트라는 이전 버전과의 호환성을 위해 항상 제공됩니다. 검색 모드에 대해 알지 못하는 기존 앱은 이 인텐트를 비구조화된 검색으로 처리할 수 있습니다.

구조화되지 않음 - "vnd.android.cursor.item/*"

비구조화된 검색어로부터 특정 노래, 앨범 또는 장르를 재생합니다. 앱이 사용자가 듣기 원하는 콘텐츠 유형을 식별할 수 없을 때 이 검색 모드로 인텐트를 생성할 수 있습니다. 가능하면 더 구체적인 검색 모드를 사용하세요.

추가적인 엑스트라:

  • QUERY (필수): 아티스트, 앨범, 노래 제목 또는 장르 중 임의의 조합을 포함하는 문자열입니다.

장르 - Audio.Genres.ENTRY_CONTENT_TYPE

특정 장르의 음악을 재생합니다.

추가적인 엑스트라:

  • "android.intent.extra.genre" (필수) - 장르입니다.
  • QUERY (필수): 장르입니다. 이 엑스트라는 항상 이전 버전과의 호환성을 위해 제공됩니다. 검색 모드에 대해 알지 못하는 기존 앱은 이 인텐트를 비구조화된 검색으로 처리할 수 있습니다.

아티스트 - Audio.Artists.ENTRY_CONTENT_TYPE

특정 아티스트의 음악을 재생합니다.

추가적인 엑스트라:

  • EXTRA_MEDIA_ARTIST (필수): 아티스트입니다.
  • "android.intent.extra.genre": 장르입니다.
  • QUERY (필수): 아티스트나 장르로 이루어진 조합을 포함하는 문자열입니다. 이 엑스트라는 이전 버전과의 호환성을 위해 항상 제공됩니다. 검색 모드에 대해 알지 못하는 기존 앱은 이 인텐트를 비구조화된 검색으로 처리할 수 있습니다.

앨범 - Audio.Albums.ENTRY_CONTENT_TYPE

특정 앨범의 음악을 재생합니다.

추가적인 엑스트라:

  • EXTRA_MEDIA_ALBUM (필수): 앨범입니다.
  • EXTRA_MEDIA_ARTIST: 아티스트입니다.
  • "android.intent.extra.genre": 장르입니다.
  • QUERY (필수): 앨범이나 아티스트로 이루어진 조합을 포함하는 문자열입니다. 이 엑스트라는 항상 이전 버전과의 호환성을 위해 제공됩니다. 검색 모드에 대해 알지 못하는 기존 앱은 이 인텐트를 비구조화된 검색으로 처리할 수 있습니다.

노래 - "vnd.android.cursor.item/audio"

특정 노래를 재생합니다.

추가적인 엑스트라:

  • EXTRA_MEDIA_ALBUM: 앨범입니다.
  • EXTRA_MEDIA_ARTIST: 아티스트입니다.
  • "android.intent.extra.genre": 장르입니다.
  • EXTRA_MEDIA_TITLE (필수): 노래 제목입니다.
  • QUERY (필수): 앨범, 아티스트, 장르 또는 제목 중 임의의 조합을 포함하는 문자열입니다. 이 추가 항목은 항상 이전 버전과의 호환성을 위해 제공됩니다. 검색 모드에 대해 알지 못하는 기존 앱은 이 인텐트를 비구조화된 검색으로 처리할 수 있습니다.

재생목록 - Audio.Playlists.ENTRY_CONTENT_TYPE

특정 재생목록이나 추가 엑스트라에서 지정한 일부 기준에 부합하는 재생목록을 재생합니다.

추가적인 엑스트라:

  • EXTRA_MEDIA_ALBUM: 앨범입니다.
  • EXTRA_MEDIA_ARTIST: 아티스트입니다.
  • "android.intent.extra.genre": 장르입니다.
  • "android.intent.extra.playlist": 재생목록입니다.
  • EXTRA_MEDIA_TITLE: 재생목록의 기반이 되는 노래 제목입니다.
  • QUERY (필수): 앨범, 아티스트, 장르, 재생목록 또는 제목 중 임의의 조합을 포함하는 문자열입니다. 이 엑스트라는 이전 버전과의 호환성을 위해 항상 제공됩니다. 검색 모드에 대해 알지 못하는 기존 앱은 이 인텐트를 비구조화된 검색으로 처리할 수 있습니다.

인텐트 예:

사용자가 특정 아티스트의 노래를 듣기 원할 경우, 검색 앱이 다음 인텐트를 생성할 수 있습니다.

Kotlin

fun playSearchArtist(artist: String) {
    val intent = Intent(MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH).apply {
        putExtra(MediaStore.EXTRA_MEDIA_FOCUS, MediaStore.Audio.Artists.ENTRY_CONTENT_TYPE)
        putExtra(MediaStore.EXTRA_MEDIA_ARTIST, artist)
        putExtra(SearchManager.QUERY, artist)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

자바

public void playSearchArtist(String artist) {
    Intent intent = new Intent(MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH);
    intent.putExtra(MediaStore.EXTRA_MEDIA_FOCUS,
                    MediaStore.Audio.Artists.ENTRY_CONTENT_TYPE);
    intent.putExtra(MediaStore.EXTRA_MEDIA_ARTIST, artist);
    intent.putExtra(SearchManager.QUERY, artist);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

인텐트 필터의 예:

<activity ...>
    <intent-filter>
        <action android:name="android.media.action.MEDIA_PLAY_FROM_SEARCH" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

활동에서 이 인텐트를 처리할 때 들어오는 Intent에서 EXTRA_MEDIA_FOCUS 엑스트라의 값을 확인하여 검색 모드를 결정합니다. 액티비티에서 검색 모드가 확인되면 해당 검색 모드에 대해 추가적인 엑스트라의 값을 읽습니다. 앱은 이 정보를 사용하여 인벤토리 내에서 검색을 수행한 다음, 검색어에 일치하는 콘텐츠를 재생할 수 있습니다. 예를 들면 다음과 같습니다.

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    ...
    if (intent.action.compareTo(MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH) == 0) {

        val mediaFocus: String? = intent.getStringExtra(MediaStore.EXTRA_MEDIA_FOCUS)
        val query: String? = intent.getStringExtra(SearchManager.QUERY)

        // Some of these extras might not be available depending on the search mode.
        val album: String? = intent.getStringExtra(MediaStore.EXTRA_MEDIA_ALBUM)
        val artist: String? = intent.getStringExtra(MediaStore.EXTRA_MEDIA_ARTIST)
        val genre: String? = intent.getStringExtra("android.intent.extra.genre")
        val playlist: String? = intent.getStringExtra("android.intent.extra.playlist")
        val title: String? = intent.getStringExtra(MediaStore.EXTRA_MEDIA_TITLE)

        // Determine the search mode and use the corresponding extras.
        when {
            mediaFocus == null -> {
                // 'Unstructured' search mode (backward compatible)
                playUnstructuredSearch(query)
            }
            mediaFocus.compareTo("vnd.android.cursor.item/*") == 0 -> {
                if (query?.isNotEmpty() == true) {
                    // 'Unstructured' search mode.
                    playUnstructuredSearch(query)
                } else {
                    // 'Any' search mode.
                    playResumeLastPlaylist()
                }
            }
            mediaFocus.compareTo(MediaStore.Audio.Genres.ENTRY_CONTENT_TYPE) == 0 -> {
                // 'Genre' search mode.
                playGenre(genre)
            }
            mediaFocus.compareTo(MediaStore.Audio.Artists.ENTRY_CONTENT_TYPE) == 0 -> {
                // 'Artist' search mode.
                playArtist(artist, genre)
            }
            mediaFocus.compareTo(MediaStore.Audio.Albums.ENTRY_CONTENT_TYPE) == 0 -> {
                // 'Album' search mode.
                playAlbum(album, artist)
            }
            mediaFocus.compareTo("vnd.android.cursor.item/audio") == 0 -> {
                // 'Song' search mode.
                playSong(album, artist, genre, title)
            }
            mediaFocus.compareTo(MediaStore.Audio.Playlists.ENTRY_CONTENT_TYPE) == 0 -> {
                // 'Playlist' search mode.
                playPlaylist(album, artist, genre, playlist, title)
            }
        }
    }
}

자바

protected void onCreate(Bundle savedInstanceState) {
    //...
    Intent intent = this.getIntent();
    if (intent.getAction().compareTo(MediaStore.INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH) == 0) {

        String mediaFocus = intent.getStringExtra(MediaStore.EXTRA_MEDIA_FOCUS);
        String query = intent.getStringExtra(SearchManager.QUERY);

        // Some of these extras might not be available depending on the search mode.
        String album = intent.getStringExtra(MediaStore.EXTRA_MEDIA_ALBUM);
        String artist = intent.getStringExtra(MediaStore.EXTRA_MEDIA_ARTIST);
        String genre = intent.getStringExtra("android.intent.extra.genre");
        String playlist = intent.getStringExtra("android.intent.extra.playlist");
        String title = intent.getStringExtra(MediaStore.EXTRA_MEDIA_TITLE);

        // Determine the search mode and use the corresponding extras.
        if (mediaFocus == null) {
            // 'Unstructured' search mode (backward compatible).
            playUnstructuredSearch(query);

        } else if (mediaFocus.compareTo("vnd.android.cursor.item/*") == 0) {
            if (query.isEmpty()) {
                // 'Any' search mode.
                playResumeLastPlaylist();
            } else {
                // 'Unstructured' search mode.
                playUnstructuredSearch(query);
            }

        } else if (mediaFocus.compareTo(MediaStore.Audio.Genres.ENTRY_CONTENT_TYPE) == 0) {
            // 'Genre' search mode.
            playGenre(genre);

        } else if (mediaFocus.compareTo(MediaStore.Audio.Artists.ENTRY_CONTENT_TYPE) == 0) {
            // 'Artist' search mode.
            playArtist(artist, genre);

        } else if (mediaFocus.compareTo(MediaStore.Audio.Albums.ENTRY_CONTENT_TYPE) == 0) {
            // 'Album' search mode.
            playAlbum(album, artist);

        } else if (mediaFocus.compareTo("vnd.android.cursor.item/audio") == 0) {
            // 'Song' search mode.
            playSong(album, artist, genre, title);

        } else if (mediaFocus.compareTo(MediaStore.Audio.Playlists.ENTRY_CONTENT_TYPE) == 0) {
            // 'Playlist' search mode.
            playPlaylist(album, artist, genre, playlist, title);
        }
    }
}

새 메모

메모 작성은 메모 앱에서 일반적으로 수행하는 작업입니다. 다음 섹션의 정보를 사용하여 이 작업을 실행하는 앱의 기능을 광고하는 인텐트 필터를 만듭니다.

메모 만들기

새 메모를 만들려면 ACTION_CREATE_NOTE 작업을 사용하고 다음 엑스트라를 사용하여 제목, 텍스트 등의 메모 세부정보를 지정합니다.

참고: 앱은 이 작업을 완료하기 전에 사용자에게 확인을 요청해야 합니다.

작업
ACTION_CREATE_NOTE
데이터 URI 스키마
없음
MIME 유형
PLAIN_TEXT_TYPE
"*/*"
추가 항목
EXTRA_NAME
노트의 제목이나 주제를 나타내는 문자열입니다.
EXTRA_TEXT
노트의 텍스트를 나타내는 문자열입니다.

인텐트 예:

Kotlin

fun createNote(subject: String, text: String) {
    val intent = Intent(NoteIntents.ACTION_CREATE_NOTE).apply {
        putExtra(NoteIntents.EXTRA_NAME, subject)
        putExtra(NoteIntents.EXTRA_TEXT, text)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

자바

public void createNote(String subject, String text) {
    Intent intent = new Intent(NoteIntents.ACTION_CREATE_NOTE)
            .putExtra(NoteIntents.EXTRA_NAME, subject)
            .putExtra(NoteIntents.EXTRA_TEXT, text);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

인텐트 필터의 예:

<activity ...>
    <intent-filter>
        <action android:name="com.google.android.gms.actions.CREATE_NOTE" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:mimeType="*/*" />
    </intent-filter>
</activity>

전화

전화 걸기는 휴대전화 앱에서 흔히 하는 작업입니다. 다음 섹션의 정보를 사용하여 이 작업을 실행하는 앱의 기능을 광고하는 인텐트 필터를 만듭니다.

전화 걸기

전화 앱을 열어 번호를 누르려면 ACTION_DIAL 작업을 사용하고 다음 URI 구성표를 사용하여 전화번호를 지정합니다. 전화 앱을 열면 전화번호가 표시되며 사용자가 Call 버튼을 탭해야 통화를 시작할 수 있습니다.

Google Voice Actions

  • "555-5555로 전화해 줘"
  • "call bob"
  • "음성사서함에 전화하기"

직접 전화를 걸려면 ACTION_CALL 작업을 사용하고 다음 URI 구성표를 사용하여 전화번호를 지정합니다. 전화 앱이 열리면 전화 통화가 시작됩니다. 사용자는 통화 버튼을 탭하지 않아도 됩니다.

ACTION_CALL 작업은 매니페스트 파일에 CALL_PHONE 권한을 추가해야 합니다.

<uses-permission android:name="android.permission.CALL_PHONE" />
작업
  • ACTION_DIAL - 다이얼러나 전화 앱을 엽니다.
  • ACTION_CALL - 전화 걸기 (CALL_PHONE 권한 필요)
데이터 URI 스키마
  • tel:<phone-number>
  • voicemail:<phone-number>
MIME 유형
없음

유효한 전화번호는 IETF RFC 3966에 정의되어 있는 것들입니다. 올바른 예는 다음과 같습니다.

  • tel:2125551212
  • tel:(212) 555 1212

전화 앱의 다이얼러는 전화번호와 같은 구성표를 정규화하는 데 적합합니다. 따라서 설명한 구성표는 Uri.parse() 메서드에서 반드시 필요한 것은 아닙니다. 그러나 구성표를 시도해보지 않았거나 그것을 처리할 수 있을지 확신이 서지 않는다면 Uri.fromParts() 메서드를 대신 사용하세요.

인텐트 예:

Kotlin

fun dialPhoneNumber(phoneNumber: String) {
    val intent = Intent(Intent.ACTION_DIAL).apply {
        data = Uri.parse("tel:$phoneNumber")
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

자바

public void dialPhoneNumber(String phoneNumber) {
    Intent intent = new Intent(Intent.ACTION_DIAL);
    intent.setData(Uri.parse("tel:" + phoneNumber));
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

다음은 검색 앱의 일반적인 작업과 각 작업을 실행하는 앱의 기능을 광고하는 인텐트 필터를 만드는 데 필요한 정보를 보여줍니다.

특정 앱을 사용한 검색

Google Voice Actions

  • "myvideoapp에서 고양이 동영상 검색해 줘"

앱 컨텍스트 내에 검색을 지원하려면 다음 인텐트 필터 예와 같이 SEARCH_ACTION 작업으로 앱에서 인텐트 필터를 선언합니다.

참고: 앱 검색에는 SEARCH_ACTION를 사용하지 않는 것이 좋습니다. 대신 GET_THING 작업을 구현하여 Google 어시스턴트의 인앱 검색을 위한 내장 지원을 활용하세요. 자세한 내용은 Google 어시스턴트 앱 액션 문서를 참고하세요.

작업
"com.google.android.gms.actions.SEARCH_ACTION"
Google Voice Actions에서의 검색어를 지원합니다.
추가 항목
QUERY
검색어를 포함하고 있는 문자열입니다.

인텐트 필터의 예:

<activity android:name=".SearchActivity">
    <intent-filter>
        <action android:name="com.google.android.gms.actions.SEARCH_ACTION"/>
        <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>
</activity>

웹 검색하기

웹 검색을 시작하려면 ACTION_WEB_SEARCH 작업을 사용하고 SearchManager.QUERY 엑스트라에서 검색 문자열을 지정합니다.

작업
ACTION_WEB_SEARCH
데이터 URI 스키마
없음
MIME 유형
없음
추가 항목
SearchManager.QUERY
검색 문자열입니다.

인텐트 예:

Kotlin

fun searchWeb(query: String) {
    val intent = Intent(Intent.ACTION_WEB_SEARCH).apply {
        putExtra(SearchManager.QUERY, query)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

자바

public void searchWeb(String query) {
    Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
    intent.putExtra(SearchManager.QUERY, query);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

설정

앱이 사용자에게 무엇인가 변경할 것을 요구할 때 시스템 설정 앱에서 화면을 열려면 다음 인텐트 작업 중 하나를 사용하세요.

작업
ACTION_SETTINGS
ACTION_WIRELESS_SETTINGS
ACTION_AIRPLANE_MODE_SETTINGS
ACTION_WIFI_SETTINGS
ACTION_APN_SETTINGS
ACTION_BLUETOOTH_SETTINGS
ACTION_DATE_SETTINGS
ACTION_LOCALE_SETTINGS
ACTION_INPUT_METHOD_SETTINGS
ACTION_DISPLAY_SETTINGS
ACTION_SECURITY_SETTINGS
ACTION_LOCATION_SOURCE_SETTINGS
ACTION_INTERNAL_STORAGE_SETTINGS
ACTION_MEMORY_CARD_SETTINGS

사용 가능한 추가 설정 화면은 Settings 문서를 참고하세요 .

데이터 URI 스키마
없음
MIME 유형
없음

인텐트 예:

Kotlin

fun openWifiSettings() {
    val intent = Intent(Settings.ACTION_WIFI_SETTINGS)
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

자바

public void openWifiSettings() {
    Intent intent = new Intent(Settings.ACTION_WIFI_SETTINGS);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

문자 메시지

첨부 파일이 있는 SMS/MMS 메시지를 작성하는 것은 문자 메시지 앱에서 일반적인 작업입니다. 다음 섹션의 정보를 사용하여 이 작업을 실행하는 앱의 기능을 광고하는 인텐트 필터를 만듭니다.

첨부 파일이 있는 SMS/MMS 메시지 작성

SMS 또는 MMS 문자 메시지를 시작하려면 다음 인텐트 작업 중 하나를 사용하고 다음 엑스트라 키를 사용하여 전화번호, 제목, 메시지 본문 등의 메시지 세부정보를 지정합니다.

작업
ACTION_SENDTO 또는
ACTION_SEND 또는
ACTION_SEND_MULTIPLE
데이터 URI 스키마
sms:<phone_number>
smsto:<phone_number>
mms:<phone_number>
mmsto:<phone_number>

이러한 구성표는 모두 동일한 방식으로 처리됩니다.

MIME 유형
"text/plain"
"image/*"
"video/*"
추가 항목
"subject"
메시지 제목 문자열 (일반적으로 MMS에만 해당)
"sms_body"
문자 메시지 문자열입니다.
EXTRA_STREAM
첨부할 이미지나 동영상을 가리키는 Uri입니다. ACTION_SEND_MULTIPLE 작업을 사용하는 경우 이 부가정보는 첨부할 이미지 또는 동영상을 가리키는 Uri 객체의 ArrayList입니다.

인텐트 예:

Kotlin

fun composeMmsMessage(message: String, attachment: Uri) {
    val intent = Intent(Intent.ACTION_SENDTO).apply {
        type = HTTP.PLAIN_TEXT_TYPE
        putExtra("sms_body", message)
        putExtra(Intent.EXTRA_STREAM, attachment)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

자바

public void composeMmsMessage(String message, Uri attachment) {
    Intent intent = new Intent(Intent.ACTION_SENDTO);
    intent.setType(HTTP.PLAIN_TEXT_TYPE);
    intent.putExtra("sms_body", message);
    intent.putExtra(Intent.EXTRA_STREAM, attachment);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

이 인텐트가 다른 이메일 앱이나 소셜 앱이 아닌 문자 메시지 앱에서만 처리되도록 하려면 다음 예와 같이 ACTION_SENDTO 작업을 사용하고 "smsto:" 데이터 구성표를 포함합니다.

Kotlin

fun composeMmsMessage(message: String, attachment: Uri) {
    val intent = Intent(Intent.ACTION_SEND).apply {
        data = Uri.parse("smsto:")  // Only SMS apps respond to this.
        putExtra("sms_body", message)
        putExtra(Intent.EXTRA_STREAM, attachment)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

자바

public void composeMmsMessage(String message, Uri attachment) {
    Intent intent = new Intent(Intent.ACTION_SEND);
    intent.setData(Uri.parse("smsto:"));  // Only SMS apps respond to this.
    intent.putExtra("sms_body", message);
    intent.putExtra(Intent.EXTRA_STREAM, attachment);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

인텐트 필터의 예:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <data android:type="text/plain" />
        <data android:type="image/*" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

참고: SMS/MMS 메시지 앱을 개발하는 중이라면, Android 4.4 이상에서 기본 SMS 앱으로 이용할 수 있도록 하기 위해서는 여러 가지 추가 작업에 대해 인텐트 필터를 구현해야 합니다. 자세한 내용은 Telephony의 문서를 참고하세요.

웹브라우저

웹 URL을 로드하는 것은 웹브라우저 앱의 일반적인 작업입니다. 다음 섹션의 정보를 사용하여 이 작업을 실행하는 앱의 기능을 광고하는 인텐트 필터를 만듭니다.

웹 URL 로드

Google Voice Actions

  • "example.com 열어 줘"

웹페이지를 열려면 ACTION_VIEW 작업을 사용하고 인텐트 데이터에서 웹 URL을 지정합니다.

작업
ACTION_VIEW
데이터 URI 스키마
http:<URL>
https:<URL>
MIME 유형
"text/plain"
"text/html"
"application/xhtml+xml"
"application/vnd.wap.xhtml+xml"

인텐트 예:

Kotlin

fun openWebPage(url: String) {
    val webpage: Uri = Uri.parse(url)
    val intent = Intent(Intent.ACTION_VIEW, webpage)
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}

자바

public void openWebPage(String url) {
    Uri webpage = Uri.parse(url);
    Intent intent = new Intent(Intent.ACTION_VIEW, webpage);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

인텐트 필터의 예:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <!-- Include the host attribute if you want your app to respond
             only to URLs with your app's domain. -->
        <data android:scheme="http" android:host="www.example.com" />
        <category android:name="android.intent.category.DEFAULT" />
        <!-- The BROWSABLE category is required to get links from web pages. -->
        <category android:name="android.intent.category.BROWSABLE" />
    </intent-filter>
</activity>

도움말: Android 앱이 여러분의 웹사이트와 비슷한 기능을 제공한다면, 해당 웹사이트를 가리키는 URL에 대한 인텐트 필터를 포함하세요. 그러면 사용자가 여러분의 앱을 설치한 경우, 이메일이나 여러분의 웹사이트를 가리키는 다른 웹페이지의 링크가 여러분의 웹 페이지가 아니라 Android 앱에서 열립니다. Android App Links 처리에서 자세히 알아보세요.

Android 12(API 수준 31)부터 일반 웹 인텐트는 앱이 웹 인텐트에 포함된 특정 도메인에 관해 승인된 경우에만 앱의 활동으로 확인됩니다. 앱이 도메인에 관해 승인되지 않으면 웹 인텐트는 대신 사용자의 기본 브라우저 앱으로 확인됩니다.

Android 디버그 브리지로 인텐트 확인

앱이 지원하려는 인텐트에 응답하는지 확인하려면 다음과 같이 adb 도구를 사용하여 특정 인텐트를 실행할 수 있습니다.

  1. Android 기기를 개발용으로 설정하거나 가상 기기를 사용하세요.
  2. 지원하고자 하는 인텐트를 처리하는 앱 버전을 설치하세요.
  3. adb를 사용하여 인텐트를 실행합니다.
    adb shell am start -a <ACTION> -t <MIME_TYPE> -d <DATA> \
      -e <EXTRA_NAME> <EXTRA_VALUE> -n <ACTIVITY>
    

    예를 들면 다음과 같습니다.

    adb shell am start -a android.intent.action.DIAL \
      -d tel:555-5555 -n org.example.MyApp/.MyActivity
    
  4. 필요한 인텐트 필터를 정의했다면 인텐트를 처리합니다.

자세한 내용은 셸 명령어 실행을 참고하세요.