Opening Google Translate from your Android application
Tags: android
Published: 2021-11-24 16:34:45

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xi2qxqilpalckyn42x4q.png)

Here is the source code:

```kotlin
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),
            )
        },
    )
}
```

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:
```kotlin
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)
}
```

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hgtm5932mlyrfrvgmcm8.png)

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:

```kotlin
try {
    startActivity(intent)
} catch (e: ActivityNotFoundException) {
    // TODO: Show error
}
```

## 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:

```kotlin
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" }
```

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

```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>
```

## 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:
```kotlin
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
    }
}
```

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