Search code examples
androidandroid-gradle-pluginandroid-contentprovider

How to use gradle placeholder applicationId in xml to make unique contentProvider authority


I have the following searchable xml declaration:

<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:label="@string/app_name"
    android:voiceSearchMode="showVoiceSearchButton"
    android:includeInGlobalSearch="true"
    android:searchMode="queryRewriteFromText"
    android:searchSuggestAuthority="com.mypackage.MyRecentSuggestionsProvider"
    android:searchSuggestSelection=" ?"
    android:hint="@string/search_hint">

</searchable>

now here is the contentProvider itself:

package com.mypackage.contentProviders

import android.content.SearchRecentSuggestionsProvider
import com.mypackage.BuildConfig
     class MySuggestionsProvider : SearchRecentSuggestionsProvider() {

        val AUTHORITY = BuildConfig.APPLICATION_ID + ".MySuggestionsProvider"
        val MODE = SearchRecentSuggestionsProvider.DATABASE_MODE_QUERIES

       init{
            setupSuggestions(AUTHORITY, MODE)
        }
    }

now the issue is i have 3 flavors in gradle so the line in the contentProvider class that defines the authority is using the application ID to make it unique so that all 3 flavors can exist on the device at the same time. as i recall, two apps cannot have duplicate authorities.

Now onto my problem:i do not want to override searchable.xml in every flavor just to declare another authority for each. i would rather do something like this:

<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:label="@string/app_name"
    android:voiceSearchMode="showVoiceSearchButton"
    android:includeInGlobalSearch="true"
    android:searchMode="queryRewriteFromText"
    android:searchSuggestAuthority="{applicationId}.MyRecentSuggestionsProvider"
    android:searchSuggestSelection=" ?"
    android:hint="@string/search_hint">

</searchable>

we do this often for the android manifest as a placeholder. is there anyway i do not have to create different xml declarations of for the content provider and instead somehow make it unique per flavor ?


Solution

  • Manifest placeholders do not work in resources. However, you can:

    • Use resValue in Gradle to define different values for a string resource based on flavor, then have android:searchSuggestAuthority refer to that string resource

    • Have source sets for each flavor, define a string resource in each of those, then have android:searchSuggestAuthority refer to that string resource

    • Have source sets for each flavor, and have different copies of searchable.xml in each, which is what you are trying to avoid