6월 3일의 ⁠#Android11: 베타 버전 출시 행사에 참여하세요.

최근 쿼리 제안 추가

Android 검색 대화상자 또는 검색 위젯을 사용할 때 최근 검색어를 기반으로 추천 검색어를 제공할 수 있습니다. 예를 들어 사용자가 이전에 '강아지'를 검색한 적이 있는 경우 동일한 쿼리를 입력하기 시작하면 이 쿼리가 추천 검색어로 표시됩니다. 그림 1은 최근 추천 검색어가 표시된 검색 대화상자의 예를 보여줍니다.

시작하기 전에 애플리케이션에서 기본 검색을 위한 검색 대화상자나 검색 위젯을 구현해야 합니다. 아직 확인하지 않은 경우 검색 인터페이스 만들기를 참고하세요.

기본 사항

그림 1. 최근 추천 검색어가 표시된 검색 대화상자 스크린샷

최근 추천 검색어는 단순히 저장된 검색어입니다. 사용자가 추천 검색어 중 하나를 선택하면 검색 활동은 이 추천 검색어가 있는 ACTION_SEARCH 인텐트를 기존에 처리하고 있는 검색어로 수신합니다(검색 인터페이스 만들기 설명 참고).

최근 추천 검색어를 제공하려면 다음을 따라야 합니다.

  • 검색 인터페이스 만들기의 설명대로 검색 활동을 구현합니다.
  • SearchRecentSuggestionsProvider를 확장하는 콘텐츠 제공자를 만들어 애플리케이션 manifest에서 선언합니다.
  • 추천 검색어를 제공하는 콘텐츠 제공자에 관한 정보로 검색 가능한 구성을 수정합니다.
  • 검색이 실행될 때마다 콘텐츠 제공자에 쿼리를 저장합니다.

Android 시스템은 검색 대화상자를 표시하는 것처럼 대화상자 또는 검색 위젯 아래에 추천 검색어도 표시합니다. 시스템에서 추천 검색어를 가져올 수 있는 소스를 제공하기만 하면 됩니다.

시스템에서 활동이 검색 활동임을 식별하고 추천 검색어를 제공하면 사용자가 쿼리를 입력하기 시작할 때 다음 절차가 진행됩니다.

  1. 시스템이 검색어 텍스트(지금까지 입력된 모든 텍스트)를 가져와서 추천 검색어가 포함된 콘텐츠 제공자에 쿼리를 실행합니다.
  2. 콘텐츠 제공자가 검색어 텍스트와 일치하는 모든 추천 검색어를 가리키는 Cursor를 반환합니다.
  3. 시스템에서 Cursor가 제공한 추천 검색어 목록이 표시됩니다.

최근 추천 검색어가 표시되면 다음과 같은 결과가 발생할 수 있습니다.

  • 사용자가 다른 키를 입력하거나 임의의 방식으로 쿼리를 변경하면 위의 단계가 반복되고 추천 검색어 목록이 업데이트됩니다.
  • 사용자가 검색을 실행하면 추천 검색어가 무시되고 검색이 일반 ACTION_SEARCH 인텐트를 사용하여 검색 활동에 전달됩니다.
  • 사용자가 추천 검색어를 선택하면 추천된 텍스트를 쿼리로 사용하여 ACTION_SEARCH 인텐트가 검색 활동에 전달됩니다.

콘텐츠 제공자에 관해 확장하는 SearchRecentSuggestionsProvider 클래스가 위에서 설명한 작업을 자동으로 처리하므로 작성할 코드가 거의 없습니다.

콘텐츠 제공자 만들기

최근 추천 검색어에 필요한 콘텐츠 제공자는 SearchRecentSuggestionsProvider의 구현이어야 합니다. 이 클래스는 거의 모든 작업을 자동으로 처리합니다. 코드 한 줄을 실행하는 클래스 생성자를 작성하기만 하면 됩니다.

예를 들어 최근 추천 검색어용 콘텐츠 제공자의 전체 구현은 다음과 같습니다.

Kotlin

    class MySuggestionProvider : SearchRecentSuggestionsProvider() {
        init {
            setupSuggestions(AUTHORITY, MODE)
        }

        companion object {
            const val AUTHORITY = "com.example.MySuggestionProvider"
            const val MODE: Int = SearchRecentSuggestionsProvider.DATABASE_MODE_QUERIES
        }
    }
    

자바

    public class MySuggestionProvider extends SearchRecentSuggestionsProvider {
        public final static String AUTHORITY = "com.example.MySuggestionProvider";
        public final static int MODE = DATABASE_MODE_QUERIES;

        public MySuggestionProvider() {
            setupSuggestions(AUTHORITY, MODE);
        }
    }
    

setupSuggestions() 호출은 검색 권한 및 데이터베이스 모드의 이름을 전달합니다. 검색 권한은 임의의 고유 문자열일 수 있지만 콘텐츠 제공자의 정규화된 이름(패키지 이름 다음에 제공자의 클래스 이름 사용 - 예: 'com.example.MySuggestionProvider')을 사용하는 것이 좋습니다. 데이터베이스 모드는 DATABASE_MODE_QUERIES를 포함해야 하며 선택사항으로 추천 검색어 표에 각 추천 검색어와 함께 두 번째 텍스트 줄을 제공할 수 있는 또 하나의 열을 추가하는 DATABASE_MODE_2LINES를 포함할 수 있습니다. 다음은 각 추천 검색어에 두 줄을 제공하려는 경우의 예입니다.

Kotlin

    const val MODE: Int = DATABASE_MODE_QUERIES or DATABASE_MODE_2LINES
    

자바

    public final static int MODE = DATABASE_MODE_QUERIES | DATABASE_MODE_2LINES;
    

이제 애플리케이션 manifest에서 SearchRecentSuggestionsProvider 클래스에(그리고 검색 가능한 구성에) 사용된 것과 동일한 권한 문자열을 사용해 콘텐츠 제공자를 선언합니다. 예를 들어 다음과 같습니다.

    <application>
        <provider android:name=".MySuggestionProvider"
                  android:authorities="com.example.MySuggestionProvider" />
        ...
    </application>
    

검색 가능한 구성 수정하기

추천 검색어 제공자를 사용하도록 시스템을 구성하려면 검색 가능한 구성 파일의 <searchable> 요소에 android:searchSuggestAuthorityandroid:searchSuggestSelection 속성을 추가해야 합니다. 예를 들어 다음과 같습니다.

    <?xml version="1.0" encoding="utf-8"?>
    <searchable xmlns:android="http://schemas.android.com/apk/res/android"
        android:label="@string/app_label"
        android:hint="@string/search_hint"
        android:searchSuggestAuthority="com.example.MySuggestionProvider"
        android:searchSuggestSelection=" ?" >
    </searchable>
    

android:searchSuggestAuthority의 값은 콘텐츠 제공자에 사용된 권한과 정확하게 일치하는 콘텐츠 제공자의 정규화된 이름이어야 합니다(위 예의 AUTHORITY 문자열).

android:searchSuggestSelection의 값은 공백 뒤에 나오는 단일 물음표(" ?")여야 하며 단순히 SQLite 선택 인수의 자리표시자(사용자가 입력하는 쿼리 텍스트로 자동으로 대체됨)입니다.

쿼리 저장하기

최근 쿼리 모음을 채우려면 검색 활동에 수신된 각 쿼리를 SearchRecentSuggestionsProvider에 추가합니다. 이렇게 하려면 검색 활동이 쿼리를 수신할 때마다 SearchRecentSuggestions 인스턴스를 만들고 saveRecentQuery()를 호출합니다. 예를 들어 활동의 onCreate() 메서드 중에 쿼리를 저장할 수 있는 방법은 다음과 같습니다.

Kotlin

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main)

        if (Intent.ACTION_SEARCH == intent.action) {
            intent.getStringExtra(SearchManager.QUERY)?.also { query ->
                SearchRecentSuggestions(this, MySuggestionProvider.AUTHORITY, MySuggestionProvider.MODE)
                        .saveRecentQuery(query, null)
            }
        }
    }
    

자바

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        Intent intent  = getIntent();

        if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
            String query = intent.getStringExtra(SearchManager.QUERY);
            SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this,
                    MySuggestionProvider.AUTHORITY, MySuggestionProvider.MODE);
            suggestions.saveRecentQuery(query, null);
        }
    }
    

SearchRecentSuggestionsProvider 생성자에는 콘텐츠 제공자가 선언한 것과 동일한 권한 및 데이터베이스 모드가 필요합니다.

saveRecentQuery() 메서드는 검색어 문자열을 첫 번째 매개변수로 사용하고 선택사항으로 두 번째 문자열을 추천 검색어의 두 번째 줄(또는 null)로 포함합니다. 두 번째 매개변수는 DATABASE_MODE_2LINES로 추천 검색어에 두 줄 모드를 사용 설정한 경우에만 사용됩니다. 두 줄 모드를 사용 설정한 경우 시스템에서 일치하는 추천 검색어를 찾을 때 이 두 번째 줄에 관해서도 쿼리 텍스트의 일치 여부를 비교합니다.

추천 데이터 지우기

사용자의 개인정보 보호를 위해 사용자가 최근 추천 검색어를 지울 수 있는 방법을 항상 제공해야 합니다. 쿼리 기록을 지우려면 clearHistory()를 호출합니다. 예를 들어 다음과 같습니다.

Kotlin

    SearchRecentSuggestions(this, HelloSuggestionsProvider.AUTHORITY, HelloSuggestionsProvider.MODE)
            .clearHistory()
    

자바

    SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this,
            HelloSuggestionProvider.AUTHORITY, HelloSuggestionProvider.MODE);
    suggestions.clearHistory();
    

'검색 기록 지우기' 메뉴 항목, 환경설정 항목, 버튼 중에서 선택하여 위 예를 실행합니다. 사용자가 검색 기록을 삭제하기를 원하는지 확인하는 확인 대화상자도 제공해야 합니다.