Skip to content

Background Database Update

Since sorisdk 4.2.2, you can update the audio recognition database in the background using the new updateDatabase method. This feature allows you to keep your audio recognition material up-to-date without interrupting the recognition process.

Overview

The SORIAudioRecognizer.shared().updateDatabase(context) method enables you to update the audio recognition database from the server at any time, regardless of whether audio recognition is currently running. This is particularly useful for devices that run audio recognition continuously for extended periods.

For example, when new audio material is added to the server while audio recognition is active, calling this method will allow you to immediately use the new audio material without restarting the recognition process.

Manual Database Update

You can manually update the database at any time by calling the updateDatabase method:

kotlin
val updateResult = SORIAudioRecognizer.shared().updateDatabase(this)

if (updateResult.success) {
    if (updateResult.updateAvailable) {
        Log.i("SORI", "Database updated successfully to version: ${updateResult.currentVersion}")
    } else {
        Log.d("SORI", "Database is already up to date (version: ${updateResult.currentVersion})")
    }
} else {
    Log.e("SORI", "Database update failed: ${updateResult.errorMessage}")
}
java
SORIUpdateResult updateResult = SORIAudioRecognizer.shared().updateDatabase(this);

if (updateResult.getSuccess()) {
    if (updateResult.getUpdateAvailable()) {
        Log.i("SORI", "Database updated successfully to version: " + updateResult.getCurrentVersion());
    } else {
        Log.d("SORI", "Database is already up to date (version: " + updateResult.getCurrentVersion() + ")");
    }
} else {
    Log.e("SORI", "Database update failed: " + updateResult.getErrorMessage());
}

Periodic Background Updates with WorkManager

For automatic periodic updates, you can use Android's WorkManager to schedule background database updates. This approach ensures that your audio recognition database stays current without manual intervention.

Setting Up Periodic Updates

Add the following code to your MainActivity.kt or MainActivity.java file to set up periodic database updates:

kotlin
private fun setupPeriodicDatabaseUpdate() {
    val constraints = Constraints.Builder()
        .setRequiredNetworkType(NetworkType.CONNECTED)
        .build()

    val workRequest = PeriodicWorkRequestBuilder<UpdateDatabaseWorker>(2, TimeUnit.HOURS)
        .setConstraints(constraints)
        .build()

    WorkManager.getInstance(this).enqueueUniquePeriodicWork(
        "UpdateSORIDatabase",
        ExistingPeriodicWorkPolicy.KEEP,
        workRequest
    )

    Log.d("SORI", "Periodic database update scheduled every 2 hours")
}
java
private void setupPeriodicDatabaseUpdate() {
    Constraints constraints = new Constraints.Builder()
        .setRequiredNetworkType(NetworkType.CONNECTED)
        .build();

    PeriodicWorkRequest workRequest = new PeriodicWorkRequest.Builder(
            UpdateDatabaseWorker.class, 2, TimeUnit.HOURS)
        .setConstraints(constraints)
        .build();

    WorkManager.getInstance(this).enqueueUniquePeriodicWork(
        "UpdateSORIDatabase",
        ExistingPeriodicWorkPolicy.KEEP,
        workRequest
    );

    Log.d("SORI", "Periodic database update scheduled every 2 hours");
}

Battery Optimization

Setting the worker to run too frequently can negatively impact Android vitals such as battery consumption. We recommend using intervals of 2 hours or more to maintain optimal device performance.

Creating the Worker Class

Create a new file UpdateDatabaseWorker.kt or UpdateDatabaseWorker.java in your project with the following implementation:

kotlin
package com.iplateia.soriexample

import android.content.Context
import android.util.Log
import androidx.work.CoroutineWorker
import androidx.work.WorkerParameters
import com.iplateia.sorisdk.SORIAudioRecognizer

/**
 * Worker class that periodically updates the SORI audio recognition database.
 * This worker runs every 2 hours to check for and download new audiopack updates.
 */
class UpdateDatabaseWorker(
    context: Context,
    params: WorkerParameters
) : CoroutineWorker(context, params) {

    companion object {
        private const val TAG = "UpdateDatabaseWorker"
    }

    override suspend fun doWork(): Result {
        return try {
            Log.d(TAG, "Starting periodic database update check")
            
            // Get the SORI recognizer instance
            val recognizer = SORIAudioRecognizer.shared()
            
            // Perform the database update
            val updateResult = recognizer.updateDatabase(applicationContext)
            
            if (updateResult.success) {
                if (updateResult.updateAvailable) {
                    Log.i(TAG, "Database updated successfully to version: ${updateResult.currentVersion}")
                } else {
                    Log.d(TAG, "Database is already up to date (version: ${updateResult.currentVersion})")
                }
                Result.success()
            } else {
                Log.e(TAG, "Database update failed: ${updateResult.errorMessage}")
                // Return retry for temporary failures, success for permanent failures
                if (updateResult.errorMessage?.contains("Authentication failed") == true) {
                    Result.failure() // Don't retry authentication failures
                } else {
                    Result.retry() // Retry for network issues, etc.
                }
            }
        } catch (e: Exception) {
            Log.e(TAG, "Unexpected error during database update", e)
            Result.retry()
        }
    }
}
java
package com.iplateia.soriexample;

import android.content.Context;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.work.Worker;
import androidx.work.WorkerParameters;
import com.iplateia.sorisdk.SORIAudioRecognizer;
import com.iplateia.sorisdk.SORIUpdateResult;

/**
 * Worker class that periodically updates the SORI audio recognition database.
 * This worker runs every 2 hours to check for and download new audiopack updates.
 */
public class UpdateDatabaseWorker extends Worker {
    private static final String TAG = "UpdateDatabaseWorker";

    public UpdateDatabaseWorker(@NonNull Context context, @NonNull WorkerParameters params) {
        super(context, params);
    }

    @NonNull
    @Override
    public Result doWork() {
        try {
            Log.d(TAG, "Starting periodic database update check");
            
            // Get the SORI recognizer instance
            SORIAudioRecognizer recognizer = SORIAudioRecognizer.shared();
            
            // Perform the database update
            SORIUpdateResult updateResult = recognizer.updateDatabase(getApplicationContext());
            
            if (updateResult.getSuccess()) {
                if (updateResult.getUpdateAvailable()) {
                    Log.i(TAG, "Database updated successfully to version: " + updateResult.getCurrentVersion());
                } else {
                    Log.d(TAG, "Database is already up to date (version: " + updateResult.getCurrentVersion() + ")");
                }
                return Result.success();
            } else {
                Log.e(TAG, "Database update failed: " + updateResult.getErrorMessage());
                // Return retry for temporary failures, success for permanent failures
                String errorMessage = updateResult.getErrorMessage();
                if (errorMessage != null && errorMessage.contains("Authentication failed")) {
                    return Result.failure(); // Don't retry authentication failures
                } else {
                    return Result.retry(); // Retry for network issues, etc.
                }
            }
        } catch (Exception e) {
            Log.e(TAG, "Unexpected error during database update", e);
            return Result.retry();
        }
    }
}

Adding WorkManager Dependencies

Make sure to add the WorkManager dependency to your build.gradle file:

groovy
dependencies {
    implementation "androidx.work:work-runtime-ktx:2.9.0" // For Kotlin
    // or
    implementation "androidx.work:work-runtime:2.9.0" // For Java
}
kotlin
dependencies {
    implementation("androidx.work:work-runtime-ktx:2.9.0") // For Kotlin
    // or
    implementation("androidx.work:work-runtime:2.9.0") // For Java
}

Initialization

Call the setupPeriodicDatabaseUpdate() method in your MainActivity.onCreate() method or in your application's initialization code:

kotlin
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    
    // ... your existing code ...
    
    // Set up periodic database updates
    setupPeriodicDatabaseUpdate()
}
java
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    
    // ... your existing code ...
    
    // Set up periodic database updates
    setupPeriodicDatabaseUpdate();
}

Best Practices

  1. Network Constraints: Always set network constraints to ensure updates only occur when connected to avoid unnecessary data usage.

  2. Error Handling: Implement proper error handling to distinguish between temporary network issues (retry) and permanent failures (don't retry).

  3. Logging: Include appropriate logging to monitor the update process and diagnose any issues.

  4. Update Frequency: Consider your users' battery life and data usage when setting the update frequency. We recommend intervals of 2 hours or more.

  5. User Experience: Since database updates happen in the background, consider providing users with information about when the database was last updated if relevant to your app's UX.

Troubleshooting

If you encounter issues with background updates:

  1. Check Network Connectivity: Ensure the device has a stable internet connection.
  2. Verify API Credentials: Ensure your API key and secret are correctly configured.
  3. Review Logs: Check the logs for specific error messages that can help identify the issue.
  4. WorkManager Constraints: Verify that your WorkManager constraints are appropriate for your use case.

API Reference

For detailed information about the updateDatabase method and its return values, please refer to the API Reference.