Introduction

Android SDK 2.0 is a full re-write of the original SDK in Kotlin . The idea behind this re-write is to focus on performance, reliability and extensibility. Also, internally the SDK now uses the ViewPump library which allows you to use your own layout interceptors with our SDK. For simplicity, all examples in this documentation will be in Java . Please keep in mind that this is a beta and everything is subject to change, so let us know in the support chat if you encounter any problems or have any suggestions. Also, if you like the new version of the SDK, any positive feedback is also welcome.

Limitations

This beta is compatible with AndroidX  support library with AppCompat  coming sometime after the beta-1 release. However, depending on user feedback, AppCompat  support may not be included in the final release. Texts in custom views need to be updated programmatically (LokaliseResources class can be used to get the latest strings).

Beta 10 breaking changes

We are finalizing the specifications of the SDK 2, and this is probably the last beta build for this SDK before the full release. Please note, that since beta-10 LokaliseMenuInflater has been removed, and instead, you should use the translateToolbarItems method from LokaliseResources if you want your menu items to be translated automatically.

public class MainActivity extends AppCompatActivity {
...
private Toolbar toolbar;

@Override
protected void onCreate(Bundle savedInstanceState) {
toolbar = findViewById(R.id.toolbar);
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
((LokaliseResources) getResources()).translateToolbarItems(toolbar);
return true;
}
...
}

Also, Realm.io library has been updated to version 10, so if your project is using an old version of Realm.io, you may need to update it.

File size

Please note that the size of the new APK file may increase. To mitigate this, we recommend uploading a bundle generated by Android Studio to Google Play instead of a simple APK file. This will allow Google Play to serve only needed resources to end-user devices drastically decreasing the download size.

Getting started

Step 1: Set up your project in Lokalise

If you have not yet done so, add a new project in Lokalise, upload any source language files you may have (or just add keys directly in Lokalise's editor if you are building a new app). Take note of the project ID, which can be found in project settings and usually looks like this:

3281927757690217f560f6.71199070

Step 2: Generate the bundle

Go to the Downloads page in Lokalise, select "Lokalise Android SDK" as the format and click the Build only button to generate the bundle. You will be automatically taken to the bundle versions management page in project settings. Leave the switches as they are for now. See details the in Managing bundles section.

Make sure to always include the latest strings in your project when releasing the app.

Step 3: Include Lokalise SDK in your project

First you need to add https://maven.lokalise.com to your top level .gradle file:

allprojects {
    repositories {
        ...
        maven {
            url "https://maven.lokalise.com"
        }
    }
}


After that, add the SDK to your application module level .gradle file (note that it is now sdk) instead of ota-sdk:

dependencies {
    ...
    implementation('com.lokalise.android:sdk:2.0.0-beta-10') {
        transitive = true
    }
}


If you are using ProGuard, add the following rules (please note, that it is now com.):

-keep class com.lokalise.** { *; }
-dontwarn com.lokalise.*
-keep @interface io.realm.annotations.RealmModule { *; }
-keep class io.realm.annotations.RealmModule { *; }

Depending on your ProGuard settings you may also need to include the rules for the Gson library.


Also, if you are using DexGuard, you will need to specify these additional rules:

-keepresources string/**
-keepresources string-array/**
-keepresources plurals/**

Step 4: Initialise the SDK

For this step you will need your SDK token (generate a token in project settings > General tab) and the Project ID of the desired project (obtained in the project settings). In your main Application class include the following code:

public class MyApplication extends Application {
    ...
    @Override
    public void onCreate() {
        super.onCreate();
        // It is important init right after the "super.onCreate()"
        Lokalise.init(this, "<sdk token>", "<project id>">);
   
        // Add this only if you want to use pre-release bundles
        Lokalise.setPreRelease(true);
       
        // Fetch the latest translations from Lokalise (can be called anywhere)
        Lokalise.updateTranslations();
    }
    ...
}


We will need to inject the Lokalise SDK into the Activity context as well and translate the menu items using a method from LokaliseResources. To do so, we recommend you create a base Activity class and extend all your activities from it. Add the following code into your activity:

public class MainActivity extends AppCompatActivity {
    ...
private Toolbar toolbar;

@Override
protected void onCreate(Bundle savedInstanceState) {
toolbar = findViewById(R.id.toolbar);
}

    @Override
    protected void attachBaseContext(Context newBase) {
        // Inject the Lokalise SDK into the activity context
        super.attachBaseContext(LokaliseContextWrapper.wrap(newBase));
    }

@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
((LokaliseResources) getResources()).translateToolbarItems(toolbar);
return true;
}
    ...


That's it! You are ready to go!

Usage

Updating translations

There is no need to update your code, refer to the keys as usual:

...
<TextView
    android:id="@+id/test"
    android:text="@string/hello_world"
    ... />
...


Or from code:

TextView test = (TextView) findViewById(R.id.test);
test.setText(R.string.hello_world);


Or if you need to get latest translations from parts of the application where Context is not overridden (e.g. inside custom views), you can use the LokaliseResources class directly:

LokaliseResources lokaliseResources = new LokaliseResources(context);
String myString = lokaliseResources.getString(R.string.hello_world);

Changing application locale

If you need to change the locale of your application manually, use the Lokalise.setLocale(<Language ISO e.g. "en">, <Region ISO e.g. "GB">) method. 

There is no need for custom locale changing code or context wrappers, simply call this method and restart the Activity.

Dynamically adding keys

Sometimes you need to add new strings without recompiling the application. 

After adding a new key via the Lokalise interface and creating a new Android SDK bundle, you can refer to the new key by name using the following code:

...
LokaliseResources resources = new LokaliseResources(context);
String newKey = resources.getString("new_key_name");
if(newKey != null) {
    // do something with the new value
}

Please note that there is no guarantee that the key will exist when you request it, since you can pass any key name to the method, so make sure to check whether the returned value is null.

Callbacks

If you need to know when Lokalise is done downloading a new translation bundle, there are several options.

LokaliseCallback

The simplest way is to use the LokaliseCallback interface:

LokaliseCallback myCallback = new LokaliseCallback() {
    @Override
    public void onUpdated(long oldBundleId, long newBundleId) {
       
    }

    @Override
    public void onUpdateFailed(LokaliseUpdateError error) {

    }

    @Override
    public void onUpdateNoNeeded() {

    }
});

Lokalise.addCallback(myCallback);


If you need to remove a callback, simply use Lokalise.removeCallback(myCallback);

Broadcast receiver

You can also receive notifications about bundle updates via Broadcast receiver:

...
IntentFilter myIntentFilter = new IntentFilter();
myIntentFilter.addAction(LokaliseDefines.INTENT_TRANSLATIONS_UPDATED);
myIntentFilter.addAction(LokaliseDefines.INTENT_TRANSLATION_UPDATE_FAILED);
myIntentFilter.addAction(LokaliseDefines.INTENT_TRANSLATION_UPDATE_NOT_NEEDED);

BroadcastReceiver myReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if(action.equals(LokaliseDefines.INTENT_TRANSLATIONS_UPDATED)) {
            long oldBundleId = intent.getLongExtra(LokaliseDefines.EXTRA_BUNDLE_VERSION_OLD, 0);
            long newBundleId = intent.getLongExtra(LokaliseDefines.EXTRA_BUNDLE_VERSION_NEW, 0);

            //Do something
        } else if(action.equals(LokaliseDefines.INTENT_TRANSLATION_UPDATE_FAILED)) {
            LokaliseUpdateError error = (LokaliseUpdateError) intent.getSerializableExtra(LokaliseDefines.EXTRA_UPDATE_ERROR);

            //Do something
        } else if(action.equals(LokaliseDefines.INTENT_TRANSLATION_UPDATE_NOT_NEEDED)) {
            //Do something
        }
    }
};

@Override
protected void onResume() {
    super.onResume();
    registerReceiver(myReceiver, myIntentFilter);
}

@Override
protected void onPause() {
    super.onPause();
    unregisterReceiver(myReceiver);
}
...

Compatibility with ViewPump

If you are using ViewPump in your project, you can pass a list of interceptors to the Lokalise.init()  method. 

...
List<Interceptor> postInterceptors = new ArrayList<>();
List<Interceptor> preInterceptors = new ArrayList<>();

Lokalise.init(this, "<sdk token>", "<project id>">, postInterceptors, preInterceptors);
...

Please note, that you need to use the LokaliseContextWrapper instead of the ViewPumpContextWrapper in order for everything to work.

Managing bundles

Publishing changes

Lokalise supports production and prerelease versions of the bundle and lets you keep different versions of each bundle. 

When the bundle is generated, it will take you to the project settings / Lokalise Android SDK section. Turn on the relevant switch before the bundle to publish it to production or prerelease.

Hit Save changes to apply.

Bundle freeze

Lokalise offers the option to freeze a particular bundle on a particular app version. As you can see in the screenshot below the "Test_01" bundle is assigned to the apps with a build from 0 to 6 and the newest bundle is assigned to the apps with a build from 7 to 12. This feature is supported in the Lokalise Android SDK 1.3 and up.

Mobile SDK insights

We provide comprehensive usage stats on the project's Statistics page. The reports include:

  • Daily unique users (range)
  • Daily requests (range)
  • App languages (all time)
  • Device languages (all time)
  • Device - App language pairs (all time)
  • App languages (weekly comparison)
  • Monthly active users
Did this answer your question?