Feral Cat

Building just because.
Android

Using the Google Translate API in your Android App

Just make an Http call!

So, I thought I’d write a quick article on using the Google Translate API in your Android app since most of the articles I found didn’t help. Article after article pointed me in the direction of this Java library which unfortunately conflicted with other dependencies in my application. I spent about two days trying to get what I thought would be an easy feature implemented and never got any closer so I switched over to making an outright Http call. By all means, this could be because I suck, but at least it is now done.

Google APIS

You’re going to need to set up payment in your Google Developer Console and you’ll have to enable the Cloud Translation API on the same dashboard. This is a paid API so be careful with your key and be sure to eventually restrict it’s usage to your app alone so some mischievous guy doesn’t come around and translate stuff on your dime. Setting up your API key shouldn’t be too complicated, so I’m not going to go over that in detail. Feel free to comment below if the detail is actually needed.

Implementing The Cloud Translation API

So you’ve gone into the cloud console, given Google free reign of your bank account, enabled the Cloud Translation API, and copied your API key somewhere safe. Let’s put it to use.

The UI

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    >
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    >
    <EditText
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:id="@+id/textInput"
        android:background="@null"/>
    <Button
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight=".25"
        android:id="@+id/translateButton"
        android:text="Translate"
        />
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:id="@+id/translation"
        />
</LinearLayout>
</android.support.constraint.ConstraintLayout>

THE XML above results in the following. We have an EditText for the input, a TextView for the output, and a button to trigger the translation. These have all been placed within a LinearLayout with a vertical orientation. Don’t forget the orientation or else nothing will show up on your screen! The height set to 0 in all of the linear layout’s children which makes layout_weight take over in each element and dynamically determine their height according to the screen. By all means this might screw me over in regards to button text if somebody has an abnormally tiny phone which might be the case because Android devices come in all shapes and sizes. But we’ll leave it as is.

Android Manifest

We need to add internet permission to our android manifest to make the http call. Paste this into your AndroidManifest.xml file.

    <uses-permission android:name="android.permission.INTERNET"/>

The entire AndroidManifest.xml file will look approximately like the following.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.googletranslateexample">
    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Libraries

You’ll also need libraries to complete the http call. Add the following line to the dependencies section of your module build.gradle file. It’ll be the gradle file with versionName and versionCode in it. Look towards the end of the document and you’ll find your dependencies section. Paste this in.

    implementation 'com.loopj.android:android-async-http:1.4.9'

Java Time

Create a new Java class and name it Http.java. This will be making the actual http call. Paste the following in it and replace “YOUR_KEY_HERE” with the key you pulled from the Google API dashboard earlier.

package com.example.googletranslateexample;

import android.util.Log;

import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;

import java.net.URLEncoder;

public class Http {
    private static final String BASE_URL = "https://translation.googleapis.com/language/translate/v2?";
    private static final String KEY = "YOUR_KEY_HERE";


    private static AsyncHttpClient client = new AsyncHttpClient();


    public static void post(String transText,String sourceLang, String destLang, AsyncHttpResponseHandler responseHandler) {
        client.get(getAbsoluteUrl(transText, sourceLang, destLang), responseHandler);
    }

    private static String makeKeyChunk(String key) {
        return "key=" + KEY;
    }

    private static String makeTransChunk(String transText) {
        String encodedText = URLEncoder.encode(transText);
        return "&amp;q=" + encodedText;
    }

    private static String langSource(String langSource) {
        return "&amp;source=" + langSource;
    }

    private static String langDest(String langDest) {
        return "&amp;target=" + langDest;

    }

    private static String getAbsoluteUrl(String transText, String sourceLang, String destLang) {
        String apiUrl = BASE_URL + makeKeyChunk(KEY) + makeTransChunk(transText) + langSource(sourceLang) + langDest(destLang);
        return apiUrl;
    }
}

This pretty much just makes a fancy url which includes your API key and sends some data to it in a format Google specifies in their API documentation. So now, you need to hook up the button to pull text from the edit text on click, send it to the api, read the returned data, and update your text view. Let’s jump over to your MainActivity which should have been automatically created when you first started the project. We’re almost there folks.

So now open up the MainActivity.java document. We’ll need to find the button to set the on click listener. If you haven’t done this before, refer to this previous article.

        Button button = findViewById(R.id.translateButton);

Define the translationTextView variable outside of the onCreate or make it final. So, make sure to have the following right before you see @Override near the start of your MainActivity.java file.

    private TextView translationTextView;

Then, on the inside of the onCreate find the translationTextView so that we can set its text later.

        translationTextView = findViewById(R.id.translation);

Now, just as an example, I will define and find the input field inside of the onCreate by writing out the following.

        final EditText input = findViewById(R.id.textInput);

So now, we’ve found all relevant views for the example. We should see the following inside of the onCreate.

        Button button = findViewById(R.id.translateButton);
        translationTextView = findViewById(R.id.translation);
        final EditText input = findViewById(R.id.textInput);

Now it’s time to set the on click listener for the button. This is just a usual listener, nothing special.

     button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String translationString = input.getText().toString();
                Http.post(translationString, "en", "es", new JsonHttpResponseHandler(){
                    @Override
                    public void onSuccess(int statusCode, Header[] headers, JSONObject response) {


                        try {
                            JSONObject serverResp = new JSONObject(response.toString());
                            JSONObject jsonObject = serverResp.getJSONObject("data");
                            JSONArray transObject = jsonObject.getJSONArray("translations");
                            JSONObject transObject2 =  transObject.getJSONObject(0);
                            translationTextView.setText(transObject2.getString("translatedText"));
                        } catch (JSONException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }

                });
            }
        });

On button click we will pull whatever is written in the input field and send that over to the Google Translate API via the Http class we wrote earlier. The Http class we wrote takes in four parameters, the translation string, the source language, the destination language, and the response handler. The source and destination languages are language codes which can be found here. Inside the onSuccess we then parse or make sense of the server response and output with the following line.

translationTextView.setText(transObject2.getString("translatedText"));

The MainActivity.java class in it’s entirety should look like the following now.

package com.example.googletranslateexample;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import com.loopj.android.http.JsonHttpResponseHandler;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import cz.msebera.android.httpclient.Header;

public class MainActivity extends AppCompatActivity {
    private TextView translationTextView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button button = findViewById(R.id.translateButton);
        translationTextView = findViewById(R.id.translation);
        final EditText input = findViewById(R.id.textInput);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String translationString = input.getText().toString();
                Http.post(translationString, "en", "es", new JsonHttpResponseHandler(){
                    @Override
                    public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
                        try {
                            JSONObject serverResp = new JSONObject(response.toString());
                            JSONObject jsonObject = serverResp.getJSONObject("data");
                            JSONArray transObject = jsonObject.getJSONArray("translations");
                            JSONObject transObject2 =  transObject.getJSONObject(0);
                            translationTextView.setText(transObject2.getString("translatedText"));
                        } catch (JSONException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                });
            }
        });
    }
}

So, that’s it folks. You’ve implemented the Google translate API! It shouldn’t have been too daunting to start using the Google Translate API in your Android app. I know I’ve glossed over a couple of topics so let me know if I incorrectly assumed they weren’t necessary and I’ll circle back around. Cheers and happy coding.

3 comments on “Using the Google Translate API in your Android App

  1. This example not work – i created this project and this error i am getting while trying to comle it

    error: incompatible types: String cannot be converted to AsyncHttpResponseHandler

Leave a Reply

Your email address will not be published. Required fields are marked *