DEV Community

Piotr Chmielowski
Piotr Chmielowski

Posted on

Opening Google Translate from your Android application

In this post I'll demonstrate how to programatically open Google Translate from another Android application and pass text to translate.

As an example I'll use a screen which displays some text and provides a "translate" button:

Screen with text

Here is the source code:

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            TranslateTestTheme {
                MainScreen(
                    title = "Dog",
                    body = dogDescription,
                    onTranslateClick = { openGoogleTranslate(dogDescription) },
                )
            }
        }
    }
}

@Composable
private fun MainScreen(
    title: String,
    body: String,
    onTranslateClick: () -> Unit,
) {
    Scaffold(
        topBar = {
            TopAppBar(
                title = { Text(text = title) },
                actions = {
                    IconButton(onClick = onTranslateClick) {
                        Icon(Icons.Default.GTranslate, contentDescription = "Translate")
                    }
                }
            )
        },
        content = {
            Text(
                text = body,
                style = MaterialTheme.typography.body2,
                modifier = Modifier.padding(16.dp),
            )
        },
    )
}
Enter fullscreen mode Exit fullscreen mode

The key part is following callback: onTranslateClick = { openGoogleTranslate(dogDescription) }.

Launching Google Translate with Intent.ACTION_PROCESS_TEXT

Let's take a look at the openGoogleTranslate method:

fun Context.openGoogleTranslate(text: String) {
    val intent = Intent()
        .setAction(Intent.ACTION_PROCESS_TEXT)
        .setType("text/plain")
        .putExtra(Intent.EXTRA_PROCESS_TEXT, text)
        .putExtra(Intent.EXTRA_PROCESS_TEXT_READONLY, true)
    startActivity(intent)
}
Enter fullscreen mode Exit fullscreen mode

It opens any Activity which is registered with Intent.ACTION_PROCESS_TEXT intent filter. As Google Translate app provides such Activity, it is one of the candidates to be opened when mentioned method is called.

It is important to remember, however, that some users have no Google Translate application installed. Some users also have on their devices more applications that handle Intent.ACTION_PROCESS_TEXT.

In the second case, Android prompts the following dialog:

Image description

In case of no application to handle the intent installed, ActivityNotFoundException will be thrown on startActivity invocation. This case can be handled by try/catch block:

try {
    startActivity(intent)
} catch (e: ActivityNotFoundException) {
    // TODO: Show error
}
Enter fullscreen mode Exit fullscreen mode

Checking if Google Translate is installed

It would be nice to display the "translate" button only if Google Translate is installed. Following code can be use to check its existence:

fun Context.queryProcessTextActivities(): List<ResolveInfo> {
    val intent = Intent()
        .setAction(Intent.ACTION_PROCESS_TEXT)
        .setType("text/plain")
    return packageManager.queryIntentActivities(intent, 0)
}

fun Context.isGoogleTranslateInstalled() = queryProcessTextActivities()
    .any { it.activityInfo.packageName == "com.google.android.apps.translate" }
Enter fullscreen mode Exit fullscreen mode

In order to make queryIntentActivities work correctly on all Android versions, the following fragment should be added to AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
    <application ...>
        ...
    </application>
    <queries>
        <intent>
            <action android:name="android.intent.action.PROCESS_TEXT" />
            <data android:mimeType="text/plain" />
        </intent>
    </queries>
</manifest>
Enter fullscreen mode Exit fullscreen mode

Launching Google Translate directly

We can also make sure that - if it is installed - Google Translate will be launched, regardless if there are other applications to handle intent or not.

To do so, the following code can be used:

fun Context.queryProcessTextActivities(): List<ResolveInfo> {
    val intent = Intent()
        .setAction(Intent.ACTION_PROCESS_TEXT)
        .setType("text/plain")
    return packageManager.queryIntentActivities(intent, 0)
}

fun Context.googleTranslateActivityInfo() = queryProcessTextActivities()
    .firstOrNull { it.activityInfo.packageName == "com.google.android.apps.translate" }
    ?.activityInfo

fun Context.openGoogleTranslate(activity: ActivityInfo, text: String) {
    val intent = Intent()
        .setAction(Intent.ACTION_PROCESS_TEXT)
        .setType("text/plain")
        .putExtra(Intent.EXTRA_PROCESS_TEXT, text)
        .putExtra(Intent.EXTRA_PROCESS_TEXT_READONLY, true)
        // Following line makes sure only Google Translate app will be launched
        .setClassName(activity.packageName, activity.name)
    try {
        startActivity(intent)
    } catch (e: ActivityNotFoundException) {
        // TODO: Show error
    }
}
Enter fullscreen mode Exit fullscreen mode

You can find complete Kotlin code under this link: https://gist.github.com/pchmielowski/d236f06f168c05efa3f5b26f1e2f0af9

Top comments (0)