GetTranslated.AI

Android SDK - Complete Integration Guide

Comprehensive guide for integrating GetTranslated.AI into your Android applications

Overview

The GetTranslated Android SDK provides real-time, AI-powered translations for Android applications. It offers seamless integration with automatic language detection, offline caching, and support for both anonymous and authenticated users.


🎯 Getting Started: To use translations in your app, you only need to:
  1. Create a project and use the CLI to translate your strings
  2. Call GetTranslated.init(getApplicationContext(), "your-ck-api-key") in your Application class

That's it! The SDK automatically handles language detection, caching, and all other functionality. Language management, dynamic strings, user authentication, callbacks, and other features are optional and only needed if you want to customize the default behavior.


Key Features

  • Real-time Translation: Get translations on-demand with automatic caching
  • Anonymous User Support: Automatic user ID generation with seamless login transition
  • Initialization Callbacks: Receive initialization status and error information via callbacks
  • Language Management: Automatic language detection based on system preferences and overrides (manual setting optional for custom selectors)
  • Offline Caching: Persistent translation cache using SharedPreferences
  • Memory Safe: Uses ApplicationContext to prevent memory leaks
  • Cross-platform: Consistent API with other GetTranslated SDKs
  • Comprehensive Logging: Configurable logging levels for debugging
  • Robust Error Handling: Detailed error codes and messages for initialization failures

Architecture

The SDK follows a singleton pattern with the following key components:

  1. GetTranslated - Main SDK class with static methods
  2. Logger - Configurable logging system
  3. StorageKeys - SharedPreferences key management
  4. LanguageDetection - Device language detection and matching
  5. NetworkRunnable - Asynchronous network operations

Installation

Prerequisites

  • Android API 21+ (Android 5.0)
  • Java 11+
  • Android Studio 4.0+

Installation

Add the SDK from Maven Central to your app/build.gradle:

dependencies {
    implementation 'ai.gettranslated:android-sdk:1.0.0'
    // ... other dependencies
}

Note: Make sure mavenCentral() is in your repositories block (it's included by default in modern Android projects).

Required Permissions

Add to your AndroidManifest.xml:

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

Quick Start

Initialization Timing

Important: The SDK should be initialized in your Application.onCreate() method, before any activities are created. This ensures that saved language preferences are applied before views are inflated, allowing Android resources to load in the correct language.

Basic Initialization

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        // Initialize GetTranslated SDK
        // This should be done in Application.onCreate() before activities are created
        GetTranslated.init(getApplicationContext(), "your-ck-api-key");
    }
}

Initialization with Callback (Recommended)

For better error handling and initialization status tracking, use the callback version:

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        // Initialize with callback to handle initialization status
        // This should be done in Application.onCreate() before activities are created
        GetTranslated.init(getApplicationContext(), "your-ck-api-key", new GetTranslated.InitCallback() {
            @Override
            public void onInitSuccess() {
                Log.d("GetTranslated", "SDK initialized successfully");
                // SDK is ready to use
            }
            
            @Override
            public void onInitError(int errorCode, String errorMessage) {
                Log.e("GetTranslated", "Initialization failed: " + errorMessage);
                // Handle initialization error
                // errorCode: HTTP status code (401, 403, 500) or 0 for network/parsing errors
            }
        });
    }
}

Activity-Level Initialization (For Language Persistence)

If you need to apply saved language preferences before views are inflated in an Activity, you can check for saved preferences early. After views are created, you can check the SDK's initialization status to update your UI:

public class MainActivity extends AppCompatActivity {
    private boolean sdkInitialized = false;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        // Apply saved language preference before inflating views
        applySavedLanguagePreference();
        
        // Initialize SDK early (before views) so language can be applied
        initializeSDK();
        
        setContentView(R.layout.activity_main);
        
        initializeViews();
        setupClickListeners();
        
        // Check SDK initialization status and update UI
        updateInitializationStatus();
    }
    
    private void applySavedLanguagePreference() {
        try {
            SharedPreferences prefs = getSharedPreferences(
                ai.gettranslated.sdk.Constants.PREF_KEY, Context.MODE_PRIVATE);
            String storedUserId = ai.gettranslated.sdk.StorageKeys.getStoredUserId(prefs);
            
            if (storedUserId != null) {
                String savedLang = ai.gettranslated.sdk.StorageKeys.getUserLanguageOverride(prefs, storedUserId);
                if (savedLang != null && !savedLang.isEmpty()) {
                    Locale locale = Locale.forLanguageTag(savedLang);
                    Locale.setDefault(locale);
                    Configuration config = getResources().getConfiguration();
                    config.setLocale(locale);
                    getResources().updateConfiguration(config, getResources().getDisplayMetrics());
                }
            }
        } catch (Exception e) {
            Log.e("MainActivity", "Failed to apply saved language", e);
        }
    }
    
    private void initializeSDK() {
        GetTranslated.init(getApplicationContext(), "your-ck-api-key", new GetTranslated.InitCallback() {
            @Override
            public void onInitSuccess() {
                runOnUiThread(() -> {
                    sdkInitialized = true;
                    updateUI();
                });
            }
            
            @Override
            public void onInitError(int errorCode, String errorMessage) {
                runOnUiThread(() -> {
                    sdkInitialized = false;
                    updateUI();
                });
            }
        });
    }
    
    private void updateInitializationStatus() {
        // Query SDK status after views are created
        boolean isInitialized = GetTranslated.isInitialized();
        sdkInitialized = isInitialized;
        
        if (isInitialized) {
            // Update UI to show SDK is ready
            Set<String> languages = GetTranslated.getLanguages();
            // ... update UI elements
        }
    }
}

Simple Translation

// Synchronous translation
String translated = GetTranslated.getDynamicString("Hello, World!");

// Asynchronous translation with callback
GetTranslated.getDynamicString("Hello, World!", new GetTranslated.TranslationCallback() {
    @Override
    public void onTranslationReady(String translation) {
        // Update UI on main thread
        runOnUiThread(() -> {
            textView.setText(translation);
        });
    }
    
    @Override
    public void onTranslationError(String errorMessage) {
        // Handle error
        Log.e("Translation", "Error: " + errorMessage);
    }
});

Language Management

Important: The SDK automatically sets the application language based on system preferences and any saved user overrides during initialization. You do not need to manually set the language unless you want to implement a custom language selector in your app.

The SDK's automatic language resolution follows this priority:

  1. Server language override (if provided by the server)
  2. Saved user language preference (if previously set)
  3. Device language (with smart matching to supported languages)
  4. Base language (fallback)
// Get supported languages
Set<String> languages = GetTranslated.getLanguages();

// Get current language (automatically set by SDK)
String currentLang = GetTranslated.getCurrentLanguage();

// Optional: Manually set language (only if implementing a language selector)
GetTranslated.setLanguage("es");

API Reference

Static Methods

init(Context context, String key)

Initializes the SDK with anonymous user and default logging. This version does not take a user id, and will generate a random id for tracking user state. If the SDK is already initialized, this method returns immediately without re-initializing. The callback (if provided) will be called immediately with success status.

Parameters:

  • context - Application context retrieved from getApplicationContext() in your application
  • key - The GetTranslated project client key
GetTranslated.init(getApplicationContext(), "your-ck-api-key");

init(Context context, String key, InitCallback callback)

Initializes the SDK with anonymous user, default logging, and initialization callback. This version does not take a user id, and will generate a random id for tracking user state. If the SDK is already initialized, this method returns immediately without re-initializing. The callback will be called immediately with success status.

Parameters:

  • context - Application context retrieved from getApplicationContext() in your application
  • key - The GetTranslated project client key
  • callback - Callback to receive initialization status
GetTranslated.init(getApplicationContext(), "your-ck-api-key", new GetTranslated.InitCallback() {
    @Override
    public void onInitSuccess() {
        // SDK initialized successfully
    }
    
    @Override
    public void onInitError(int errorCode, String errorMessage) {
        // Handle initialization error
    }
});

init(Context context, String key, String userId)

Initializes the SDK with specific user ID and default logging. If the SDK is already initialized, this method returns immediately without re-initializing. The callback (if provided) will be called immediately with success status.

Parameters:

  • context - Application context retrieved from getApplicationContext() in your application
  • key - The GetTranslated project client key
  • userId - User id for tracking user state and language overrides. This can be any data format you'd like.
GetTranslated.init(getApplicationContext(), "your-ck-api-key", "user-123");

init(Context context, String key, String userId, InitCallback callback)

Initializes the SDK with specific user ID, default logging, and initialization callback. If the SDK is already initialized, this method returns immediately without re-initializing. The callback will be called immediately with success status.

Parameters:

  • context - Application context retrieved from getApplicationContext() in your application
  • key - The GetTranslated project client key
  • userId - User id for tracking user state and language overrides. This can be any data format you'd like.
  • callback - Callback to receive initialization status
GetTranslated.init(getApplicationContext(), "your-ck-api-key", "user-123", new GetTranslated.InitCallback() {
    @Override
    public void onInitSuccess() {
        // SDK initialized successfully
    }
    
    @Override
    public void onInitError(int errorCode, String errorMessage) {
        // Handle initialization error
    }
});

init(Context context, String key, String userId, Logger.LogLevel logLevel)

Initializes the SDK with specific user ID and logging level.

Parameters:

  • context - Application context retrieved from getApplicationContext() in your application
  • key - The GetTranslated project client key
  • userId - User id for tracking user state and language overrides. This can be any data format you'd like (can be null for anonymous).
  • logLevel - Log level for SDK logging
GetTranslated.init(getApplicationContext(), "your-ck-api-key", "user-123", Logger.LogLevel.DEBUG);

init(Context context, String key, String userId, Logger.LogLevel logLevel, InitCallback callback)

Initializes the SDK with specific user ID, logging level, and initialization callback.

Parameters:

  • context - Application context retrieved from getApplicationContext() in your application
  • key - The GetTranslated project client key
  • userId - User id for tracking user state and language overrides. This can be any data format you'd like (can be null for anonymous).
  • logLevel - Log level for SDK logging
  • callback - Callback to receive initialization status
GetTranslated.init(getApplicationContext(), "your-ck-api-key", "user-123", 
    Logger.LogLevel.DEBUG, new GetTranslated.InitCallback() {
        @Override
        public void onInitSuccess() {
            // SDK initialized successfully
        }
        
        @Override
        public void onInitError(int errorCode, String errorMessage) {
            // Handle initialization error
        }
    });

login(String userId)

Used to change the user id after the SDK has been initialized. The SDK will re-initialize automatically. Supported languages are preserved during re-initialization to prevent UI flicker. If re-initialization fails, the SDK instance is cleared and a RuntimeException is thrown.

Parameters:

  • userId - New user ID

Throws:

  • IllegalArgumentException - if userId is null or empty
  • IllegalStateException - if GetTranslated SDK has not been initialized
  • RuntimeException - if re-initialization fails after login
GetTranslated.login("user-123");

login(String userId, InitCallback callback)

Used to change the user id after the SDK has been initialized. The SDK will re-initialize automatically. Supported languages are preserved during re-initialization to prevent UI flicker. If re-initialization fails, the SDK instance is cleared, the error callback is called, and a RuntimeException is thrown.

Parameters:

  • userId - New user ID
  • callback - Optional callback to receive re-initialization status

Throws:

  • IllegalArgumentException - if userId is null or empty
  • IllegalStateException - if GetTranslated SDK has not been initialized
  • RuntimeException - if re-initialization fails after login
GetTranslated.login("user-123", new GetTranslated.InitCallback() {
    @Override
    public void onInitSuccess() {
        // Login and re-initialization successful
        // Supported languages are preserved during re-initialization
    }
    
    @Override
    public void onInitError(int errorCode, String errorMessage) {
        // Login re-initialization failed
    }
});

logout()

Logout and return to anonymous user (re-initializes with anonymous user information). Clears user-specific preferences and re-initializes with a new anonymous user ID. The SDK will re-initialize automatically. Supported languages are preserved during re-initialization. Note: Language overrides, translation cache, and sync data are preserved for potential future logins with the same user ID. If re-initialization fails, the SDK instance is cleared and a RuntimeException is thrown.

Throws:

  • IllegalStateException - if GetTranslated SDK has not been initialized
  • RuntimeException - if re-initialization fails after logout
GetTranslated.logout();

logout(InitCallback callback)

Logout and return to anonymous user (re-initializes with anonymous user information). Clears user-specific preferences and re-initializes with a new anonymous user ID. The SDK will re-initialize automatically. Supported languages are preserved during re-initialization. Note: Language overrides, translation cache, and sync data are preserved for potential future logins with the same user ID. If re-initialization fails, the SDK instance is cleared, the error callback is called, and a RuntimeException is thrown.

Parameters:

  • callback - Optional callback to receive re-initialization status

Throws:

  • IllegalStateException - if GetTranslated SDK has not been initialized
  • RuntimeException - if re-initialization fails after logout
GetTranslated.logout(new GetTranslated.InitCallback() {
    @Override
    public void onInitSuccess() {
        // Logout and re-initialization successful
        // Supported languages are preserved during re-initialization
    }
    
    @Override
    public void onInitError(int errorCode, String errorMessage) {
        // Logout re-initialization failed
    }
});

setLanguage(String languageCode)

Programmatically override the app language. Note: This is optional - the SDK automatically sets the language based on system preferences and saved overrides during initialization. Only use this method if you want to implement a custom language selector in your app.

This is a no-op if not initialized or if languageCode is not one of the values returned by getLanguages(). The language preference is saved immediately and will persist across app restarts.

Parameters:

  • languageCode - The 2 character ISO language code to set (e.g., "en", "es", "fr")

Note: Language changes may require an app restart or activity recreation to fully take effect for Android resources. Dynamic translations via getDynamicString() take effect immediately.

// Optional: Only needed if implementing a language selector
GetTranslated.setLanguage("es");

getLanguages()

Returns the set of languages supported by the current project.

Returns: Set<String> - The Set of supported languages, or an empty set if not initialized.

Set<String> languages = GetTranslated.getLanguages();
// Returns: ["en", "es", "fr", "de", ...]

getCurrentLanguage()

Returns the current language code being used by the SDK.

Returns: String - The current language code (e.g., "en", "es", "fr"), or "en" if not initialized.

String currentLang = GetTranslated.getCurrentLanguage();
// Returns: "en" or "es" etc.

isInitialized()

Returns whether the SDK has been successfully initialized.

Returns: boolean - true if the SDK is initialized and ready to use, false otherwise.

Use Case: Useful for checking initialization status when initializing early (before views are created) and updating UI after views are created.

boolean isInitialized = GetTranslated.isInitialized();
if (isInitialized) {
    // SDK is ready to use
    Set<String> languages = GetTranslated.getLanguages();
}

getDynamicString(String text)

Returns a translated version of the requested dynamic string based on the user's language setting. This method is for translating strings that are not known at build time (e.g., server messages, user-generated content). This method call will never block and will return the original string in a few cases:

  1. The user's language is the default app language
  2. This string has not been seen before and there is no translation yet available. If this use case is important to handle, use the version of this function that takes a TranslationCallback.
  3. There is an error fetching a translation

Parameters:

  • text - The string to translate

Returns: String - A translated version of the string, or the original string in certain cases

String translation = GetTranslated.getDynamicString("Hello, World!");

getDynamicString(String text, TranslationCallback callback)

Returns a translated version of the requested dynamic string based on the user's language setting. The behavior of the return value from this function is identical to the other getDynamicString method, however the TranslationCallback enables the application to be notified when a translation is available (this may require a network request depending on whether or not it has been previously cached).

Parameters:

  • text - The string to translate
  • callback - A callback to notify the application when a translation is available. One of onTranslationReady or onTranslationError is guaranteed to be called.

Returns: String - A translated version of the string, or the original string in certain cases

GetTranslated.getDynamicString("Hello, World!", new GetTranslated.TranslationCallback() {
    @Override
    public void onTranslationReady(String translation) {
        // Handle successful translation
    }
    
    @Override
    public void onTranslationError(String errorMessage) {
        // Handle error
    }
});

InitCallback Interface

public interface InitCallback {
    /**
     * Called when SDK initialization succeeds.
     */
    void onInitSuccess();

    /**
     * Called if there is an error during SDK initialization.
     *
     * @param errorCode The HTTP error code (e.g., 401, 403, 500), or 0 for network/parsing errors
     * @param errorMessage A description of the error
     */
    void onInitError(int errorCode, String errorMessage);
}

Error Code Reference:

  • 0 - Network error or parsing error
  • 401 - Unauthorized (invalid API key)
  • 403 - Forbidden (API key lacks required permissions)
  • 500 - Server error

TranslationCallback Interface

public interface TranslationCallback {
    /**
     * Called when the requested translation is available.
     *
     * @param translation The requested translation
     */
    void onTranslationReady(String translation);

    /**
     * Called if there is an error completing the translation request.
     *
     * @param errorMessage A description of the error
     */
    void onTranslationError(String errorMessage);
}

Logger Class

// Log Levels
public enum LogLevel {
    ERROR(0),    // Only error messages
    WARN(1),     // Warning and error messages (default)
    INFO(2),     // Informational, warning, and error messages
    DEBUG(3),    // Debug, info, warning, and error messages
    VERBOSE(4);  // All messages
}

// Initialize logger
Logger.init(Logger.LogLevel.DEBUG, true, false);

// Log messages
Logger.logInfo("Your message");
Logger.logError("Error occurred", exception);
Logger.logDebug("Debug information", data);
Logger.logWarn("Warning message");
Logger.logVerbose("Verbose information");

Advanced Usage

Custom Logging Configuration

// Initialize with custom logging
Logger.init(Logger.LogLevel.VERBOSE, true, false);

// Or configure after initialization
Logger logger = Logger.getInstance();
logger.setLevel(Logger.LogLevel.DEBUG);

Error Handling Strategies

1. Graceful Fallback

public String getTranslationSafely(String text) {
    try {
        return GetTranslated.getDynamicString(text);
    } catch (Exception e) {
        Logger.logError("Translation failed", e);
        return text; // Return original text as fallback
    }
}

2. Callback with Retry

public void translateWithRetry(String text, int maxRetries) {
    GetTranslated.getDynamicString(text, new GetTranslated.TranslationCallback() {
        @Override
        public void onTranslationReady(String translation) {
            // Success - update UI
            updateUI(translation);
        }
        
        @Override
        public void onTranslationError(String errorMessage) {
            if (maxRetries > 0) {
                // Retry with exponential backoff
                new Handler().postDelayed(() -> {
                    translateWithRetry(text, maxRetries - 1);
                }, 1000 * (4 - maxRetries)); // 1s, 2s, 3s delays
            } else {
                // Final failure - show fallback
                updateUI(text);
            }
        }
    });
}

User Management Patterns

1. Anonymous to Authenticated Flow

public class UserManager {
    private static final String PREFS_NAME = "user_prefs";
    private static final String USER_ID_KEY = "user_id";
    
    public void loginUser(String userId) {
        // Use callback to handle re-initialization after login
        GetTranslated.login(userId, new GetTranslated.InitCallback() {
            @Override
            public void onInitSuccess() {
                // Login and re-initialization successful
                // Supported languages are preserved during re-initialization
                saveUserId(userId);
                notifyLoginSuccess();
            }
            
            @Override
            public void onInitError(int errorCode, String errorMessage) {
                Logger.logError("Login re-initialization failed: " + errorMessage, null);
                notifyLoginError(errorMessage);
            }
        });
    }
    
    public void logoutUser() {
        // Use callback to handle re-initialization after logout
        GetTranslated.logout(new GetTranslated.InitCallback() {
            @Override
            public void onInitSuccess() {
                // Logout and re-initialization successful
                // Supported languages are preserved during re-initialization
                clearUserId();
                notifyLogoutSuccess();
            }
            
            @Override
            public void onInitError(int errorCode, String errorMessage) {
                Logger.logError("Logout re-initialization failed: " + errorMessage, null);
            }
        });
    }
}

Performance Optimization

1. Batch Translation Loading

public class TranslationLoader {
    private final List<String> pendingTranslations = new ArrayList<>();
    private final Handler handler = new Handler(Looper.getMainLooper());
    private Runnable batchRunnable;
    
    public void loadTranslation(String text) {
        pendingTranslations.add(text);
        
        // Cancel previous batch if exists
        if (batchRunnable != null) {
            handler.removeCallbacks(batchRunnable);
        }
        
        // Schedule batch processing
        batchRunnable = this::processBatch;
        handler.postDelayed(batchRunnable, 100); // 100ms delay
    }
    
    private void processBatch() {
        List<String> batch = new ArrayList<>(pendingTranslations);
        pendingTranslations.clear();
        
        for (String text : batch) {
            GetTranslated.getDynamicString(text, new GetTranslated.TranslationCallback() {
                @Override
                public void onTranslationReady(String translation) {
                    notifyTranslationReady(text, translation);
                }
                
                @Override
                public void onTranslationError(String errorMessage) {
                    notifyTranslationError(text, errorMessage);
                }
            });
        }
    }
}

Migration Guides

From Other Translation Libraries

From Android's Built-in Localization

Before (Android Resources):

// Old way with string resources
String text = getString(R.string.hello_world);

After (GetTranslated):

// New way with dynamic translation
String text = GetTranslated.getDynamicString("Hello, World!");

From Google Translate API

Before (Google Translate):

Translate translate = TranslateOptions.getDefaultInstance().getService();
Translation translation = translate.translate("Hello", Translate.TranslateOption.targetLanguage("es"));
String result = translation.getTranslatedText();

After (GetTranslated):

GetTranslated.getDynamicString("Hello", new GetTranslated.TranslationCallback() {
    @Override
    public void onTranslationReady(String translation) {
        // Use translation
    }
    
    @Override
    public void onTranslationError(String errorMessage) {
        // Handle error
    }
});

Best Practices

1. Initialization

  • Always use ApplicationContext: Prevents memory leaks
  • Initialize early: In Application.onCreate() before activities are created
  • Handle errors: Wrap initialization in try-catch
  • For language persistence: Initialize in Application.onCreate() or apply saved language in Activity.onCreate() before setContentView()
public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        try {
            // Initialize in Application.onCreate() to ensure saved language
            // preferences are applied before any activities are created
            GetTranslated.init(getApplicationContext(), "your-ck-api-key", 
                new GetTranslated.InitCallback() {
                    @Override
                    public void onInitSuccess() {
                        Log.d("App", "SDK initialized successfully");
                    }
                    
                    @Override
                    public void onInitError(int errorCode, String errorMessage) {
                        Log.e("App", "SDK initialization failed: " + errorMessage);
                    }
                });
        } catch (Exception e) {
            Logger.logError("SDK initialization failed", e);
        }
    }
}

Important: Initializing in Application.onCreate() ensures that:

  • Saved language preferences are restored before any activities are created
  • Android resources load in the correct language from the start
  • The SDK is ready before your app's UI is displayed

2. Translation Usage

  • Use callbacks for UI updates: Prevents blocking the main thread
  • Provide fallbacks: Always have a fallback for failed translations
  • Cache translations: The SDK caches automatically, but you can add your own layer
public void updateText(String originalText) {
    GetTranslated.getDynamicString(originalText, new GetTranslated.TranslationCallback() {
        @Override
        public void onTranslationReady(String translation) {
            runOnUiThread(() -> {
                textView.setText(translation);
            });
        }
        
        @Override
        public void onTranslationError(String errorMessage) {
            runOnUiThread(() -> {
                textView.setText(originalText); // Fallback
            });
        }
    });
}

3. Language Management

Automatic Language Detection: The SDK automatically sets the application language during initialization based on system preferences and saved overrides. You only need to manually set the language if implementing a custom language selector.

  • Check language support: Verify language is supported before setting
  • Persist user preferences: Save language choices in SharedPreferences
  • Handle language changes: Update UI when language changes
// Example: Implementing a custom language selector (optional)
public void setLanguageSafely(String languageCode) {
    Set<String> supportedLanguages = GetTranslated.getLanguages();
    if (supportedLanguages.contains(languageCode)) {
        GetTranslated.setLanguage(languageCode);
        saveLanguagePreference(languageCode);
    } else {
        Logger.logWarn("Language not supported: " + languageCode);
    }
}

Troubleshooting

Common Issues

❌ "Not initialized" Error

Problem: Calling SDK methods before initialization

Solution: Make sure to call GetTranslated.init() before using other methods

❌ Memory Leaks

Problem: Using activity context instead of application context

Solution: Always use getApplicationContext() instead of activity context

❌ Translations Not Updating

Problem: Not handling language changes properly

Solution: Update UI after language change and re-translate texts

❌ Network Errors

Problem: Not handling network failures

Solution: Implement proper error handling with fallbacks and retry logic

❌ Language Not Persisting After Restart

Problem: Language preference is set but app loads in default language after restart

Solution: Ensure SDK initialization happens before views are inflated. Initialize in Application.onCreate() or check for saved language preference in Activity.onCreate() before setContentView(). This ensures Android resources load in the correct language.

❌ Language Changes Not Taking Effect

Problem: Language is changed but UI still shows old language

Solution: Language changes may require an activity restart or app restart to fully take effect, especially for Android resources. For dynamic translations, the change takes effect immediately. After changing language, you may need to recreate the activity with recreate() or restart the app.

Debug Mode

Enable debug logging to troubleshoot issues:

// Enable debug logging
GetTranslated.init(getApplicationContext(), "your-ck-api-key", null, Logger.LogLevel.DEBUG);

// Or configure logging separately
Logger.init(Logger.LogLevel.VERBOSE, true, false);

Examples

Complete App Example

public class MainActivity extends AppCompatActivity {
    private static final String API_KEY = "your-ck-api-key";
    private static final String TAG = "MainActivity";
    
    private TextView welcomeText;
    private TextView descriptionText;
    private Button languageButton;
    private Button translateButton;
    private EditText customTextInput;
    private TextView customTranslationText;
    
    private String[] sampleTexts = {
        "Welcome to our app!",
        "This is a sample translation app.",
        "Tap the buttons to test translations."
    };
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        initializeViews();
        setupClickListeners();
        initializeSDK();
    }
    
    private void initializeViews() {
        welcomeText = findViewById(R.id.welcomeText);
        descriptionText = findViewById(R.id.descriptionText);
        languageButton = findViewById(R.id.languageButton);
        translateButton = findViewById(R.id.translateButton);
        customTextInput = findViewById(R.id.customTextInput);
        customTranslationText = findViewById(R.id.customTranslationText);
    }
    
    private void setupClickListeners() {
        languageButton.setOnClickListener(v -> switchLanguage());
        translateButton.setOnClickListener(v -> translateCustomText());
    }
    
    private void initializeSDK() {
        try {
            GetTranslated.init(getApplicationContext(), API_KEY, null, Logger.LogLevel.DEBUG);
            loadTranslations();
        } catch (Exception e) {
            Logger.logError("SDK initialization failed", e);
            showError("Failed to initialize translation service");
        }
    }
    
    private void loadTranslations() {
        // Load sample texts
        for (int i = 0; i < sampleTexts.length; i++) {
            final int index = i;
            GetTranslated.getDynamicString(sampleTexts[i], new GetTranslated.TranslationCallback() {
                @Override
                public void onTranslationReady(String translation) {
                    runOnUiThread(() -> updateSampleText(index, translation));
                }
                
                @Override
                public void onTranslationError(String errorMessage) {
                    Logger.logError("Translation failed for: " + sampleTexts[index], errorMessage);
                }
            });
        }
    }
    
    private void updateSampleText(int index, String translation) {
        switch (index) {
            case 0:
                welcomeText.setText(translation);
                break;
            case 1:
                descriptionText.setText(translation);
                break;
        }
    }
    
    private void switchLanguage() {
        String currentLang = GetTranslated.getCurrentLanguage();
        String newLang = "en".equals(currentLang) ? "es" : "en";
        
        try {
            GetTranslated.setLanguage(newLang);
            loadTranslations(); // Re-translate all texts
            updateLanguageButton();
        } catch (Exception e) {
            Logger.logError("Language switch failed", e);
            showError("Failed to switch language");
        }
    }
    
    private void updateLanguageButton() {
        String currentLang = GetTranslated.getCurrentLanguage();
        String buttonText = "en".equals(currentLang) ? "Switch to Spanish" : "Switch to English";
        languageButton.setText(buttonText);
    }
    
    private void translateCustomText() {
        String text = customTextInput.getText().toString().trim();
        if (text.isEmpty()) {
            showError("Please enter text to translate");
            return;
        }
        
        customTranslationText.setText("Translating...");
        
        GetTranslated.getDynamicString(text, new GetTranslated.TranslationCallback() {
            @Override
            public void onTranslationReady(String translation) {
                runOnUiThread(() -> {
                    customTranslationText.setText(translation);
                });
            }
            
            @Override
            public void onTranslationError(String errorMessage) {
                runOnUiThread(() -> {
                    customTranslationText.setText("Translation failed: " + errorMessage);
                });
            }
        });
    }
    
    private void showError(String message) {
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
    }
}

Translation Service Example

public class TranslationService {
    private static TranslationService instance;
    private final Map<String, String> cache = new HashMap<>();
    private final List<TranslationListener> listeners = new ArrayList<>();
    
    public interface TranslationListener {
        void onTranslationReady(String original, String translation);
        void onTranslationError(String original, String error);
    }
    
    public static TranslationService getInstance() {
        if (instance == null) {
            instance = new TranslationService();
        }
        return instance;
    }
    
    public void addListener(TranslationListener listener) {
        listeners.add(listener);
    }
    
    public void removeListener(TranslationListener listener) {
        listeners.remove(listener);
    }
    
    public void translate(String text) {
        if (cache.containsKey(text)) {
            notifyTranslationReady(text, cache.get(text));
            return;
        }
        
        GetTranslated.getDynamicString(text, new GetTranslated.TranslationCallback() {
            @Override
            public void onTranslationReady(String translation) {
                cache.put(text, translation);
                notifyTranslationReady(text, translation);
            }
            
            @Override
            public void onTranslationError(String errorMessage) {
                notifyTranslationError(text, errorMessage);
            }
        });
    }
    
    public void translateBatch(List<String> texts) {
        for (String text : texts) {
            translate(text);
        }
    }
    
    public void clearCache() {
        cache.clear();
    }
    
    private void notifyTranslationReady(String original, String translation) {
        for (TranslationListener listener : listeners) {
            listener.onTranslationReady(original, translation);
        }
    }
    
    private void notifyTranslationError(String original, String error) {
        for (TranslationListener listener : listeners) {
            listener.onTranslationError(original, error);
        }
    }
}