mirror of
https://github.com/keymanapp/keyman.git
synced 2026-09-24 08:37:42 +00:00
feat(android/app): Use api for downloading associated dictionary
This commit is contained in:
parent
ce8c502191
commit
0f17062ad2
4 changed files with 203 additions and 17 deletions
|
|
@ -26,7 +26,7 @@ import com.tavultesoft.kmea.KeyboardEventHandler.OnKeyboardDownloadEventListener
|
|||
import com.tavultesoft.kmea.KeyboardEventHandler.OnKeyboardEventListener;
|
||||
import com.tavultesoft.kmea.cloud.CloudApiTypes;
|
||||
import com.tavultesoft.kmea.cloud.CloudDownloadMgr;
|
||||
import com.tavultesoft.kmea.cloud.impl.CloudLexicalPackageDownloadCallback;
|
||||
import com.tavultesoft.kmea.cloud.impl.CloudLexicalModelMetaDataDownloadCallback;
|
||||
import com.tavultesoft.kmea.data.CloudRepository;
|
||||
import com.tavultesoft.kmea.data.Dataset;
|
||||
import com.tavultesoft.kmea.data.Keyboard;
|
||||
|
|
@ -997,25 +997,25 @@ public class MainActivity extends AppCompatActivity implements OnKeyboardEventLi
|
|||
repo = CloudRepository.shared.fetchDataset(context);
|
||||
}
|
||||
|
||||
// Check if associated model is available in the cloud, and that it's not already installed
|
||||
LexicalModel modelInfo = CloudRepository.shared.getAssociatedLexicalModel(context, languageID);
|
||||
if ((modelInfo != null) && (KMManager.getAssociatedLexicalModel(languageID) == null)) {
|
||||
String modelID = modelInfo.getLexicalModelID();
|
||||
String url = modelInfo.getUpdateKMP();
|
||||
if (url != null) {
|
||||
ArrayList<CloudApiTypes.CloudApiParam> _params = new ArrayList<>();
|
||||
_params.add(new CloudApiTypes.CloudApiParam(
|
||||
CloudApiTypes.ApiTarget.LexicalModelPackage, url));
|
||||
// Check if associated model is not already installed
|
||||
if (KMManager.getAssociatedLexicalModel(languageID) == null) {
|
||||
String _downloadid = CloudLexicalModelMetaDataDownloadCallback.createDownloadId(languageID);
|
||||
CloudLexicalModelMetaDataDownloadCallback _callback = new CloudLexicalModelMetaDataDownloadCallback();
|
||||
|
||||
// Check if model is already queued to download
|
||||
String _downloadid= CloudLexicalPackageDownloadCallback.createDownloadId(modelID);
|
||||
if(!CloudDownloadMgr.getInstance().alreadyDownloadingData(_downloadid)) {
|
||||
KMKeyboardDownloaderActivity.downloadLexicalModel(context, modelID, _params);
|
||||
}
|
||||
}
|
||||
Toast.makeText(context,
|
||||
context.getString(R.string.query_associated_model),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
|
||||
ArrayList<CloudApiTypes.CloudApiParam> aPreparedCloudApiParams = new ArrayList<>();
|
||||
String url = CloudRepository.prepareLexicalModelQuery(languageID);
|
||||
aPreparedCloudApiParams.add(new CloudApiTypes.CloudApiParam(
|
||||
CloudApiTypes.ApiTarget.KeyboardLexicalModels, url).setType(CloudApiTypes.JSONType.Array));
|
||||
|
||||
CloudDownloadMgr.getInstance().executeAsDownload(
|
||||
context, _downloadid, null, _callback,
|
||||
aPreparedCloudApiParams.toArray(new CloudApiTypes.CloudApiParam[0]));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,178 @@
|
|||
/**
|
||||
* Copyright (C) 2020 SIL International. All rights reserved.
|
||||
*/
|
||||
package com.tavultesoft.kmea.cloud.impl;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.tavultesoft.kmea.R;
|
||||
import com.tavultesoft.kmea.cloud.CloudApiTypes;
|
||||
import com.tavultesoft.kmea.cloud.CloudDataJsonUtil;
|
||||
import com.tavultesoft.kmea.cloud.CloudDownloadMgr;
|
||||
import com.tavultesoft.kmea.cloud.ICloudDownloadCallback;
|
||||
import com.tavultesoft.kmea.util.KMLog;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Start the lexical model download when lexical model metadata is downloaded.
|
||||
*/
|
||||
public class CloudLexicalModelMetaDataDownloadCallback implements ICloudDownloadCallback<Void,
|
||||
List<CloudLexicalModelMetaDataDownloadCallback.MetaDataResult>>
|
||||
{
|
||||
/**
|
||||
* the metadata result and all necessary downloads which should be started
|
||||
*/
|
||||
static class MetaDataResult
|
||||
{
|
||||
CloudApiTypes.CloudApiReturns returnjson;
|
||||
CloudApiTypes.CloudApiParam params;
|
||||
//HashMap<String,String> keyboardInfo;
|
||||
String additionalDownloadid;
|
||||
List<CloudApiTypes.CloudApiParam> additionalDownloads;
|
||||
}
|
||||
|
||||
private static final String TAG = "CloudLMMetaDldCb";
|
||||
|
||||
/**
|
||||
* Additional Cloud API parameter: language id.
|
||||
*/
|
||||
public static final String PARAM_LANG_ID = "lang_id";
|
||||
/**
|
||||
* Additional Cloud API parameter: lexical model id.
|
||||
*/
|
||||
public static final String PARAM_LM_ID = "lm_id";
|
||||
|
||||
@Override
|
||||
public void initializeContext(Context context) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<CloudLexicalModelMetaDataDownloadCallback.MetaDataResult> extractCloudResultFromDownloadSet(
|
||||
CloudApiTypes.CloudDownloadSet<Void, List<CloudLexicalModelMetaDataDownloadCallback.MetaDataResult>> aDownload) {
|
||||
|
||||
List<CloudLexicalModelMetaDataDownloadCallback.MetaDataResult> _result = new ArrayList<>(aDownload.getSingleDownloads().size());
|
||||
|
||||
for (CloudApiTypes.SingleCloudDownload _d : aDownload.getSingleDownloads()) {
|
||||
|
||||
CloudApiTypes.CloudApiReturns _json_result = CloudDataJsonUtil.retrieveJsonFromDownload(_d);
|
||||
|
||||
if (_json_result != null) {
|
||||
|
||||
CloudLexicalModelMetaDataDownloadCallback.MetaDataResult _data = new CloudLexicalModelMetaDataDownloadCallback.MetaDataResult();
|
||||
_data.returnjson = _json_result;
|
||||
_data.params = _d.getCloudParams();
|
||||
_result.add(_data); // Null if offline.
|
||||
}
|
||||
}
|
||||
return _result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyCloudDownloadToModel(Context aContext, Void aModel, List<CloudLexicalModelMetaDataDownloadCallback.MetaDataResult> aCloudResult) {
|
||||
if (aCloudResult.isEmpty()) {
|
||||
String msg = aContext.getString(R.string.catalog_unavailable);
|
||||
Toast.makeText(aContext, msg, Toast.LENGTH_SHORT).show();
|
||||
KMLog.LogError(TAG, "Could not reach server");
|
||||
return;
|
||||
}
|
||||
|
||||
processCloudResults(aContext, aCloudResult);
|
||||
|
||||
startDownloads(aContext, aCloudResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the keyboard data and lexical model download.
|
||||
* @param aContext the context
|
||||
* @param aMetaDataResult the meta data result
|
||||
*/
|
||||
private void startDownloads(Context aContext, List<MetaDataResult> aMetaDataResult) {
|
||||
for(MetaDataResult _r:aMetaDataResult)
|
||||
{
|
||||
if(_r.additionalDownloads!=null)
|
||||
{
|
||||
if(_r.returnjson.target== CloudApiTypes.ApiTarget.KeyboardLexicalModels) {
|
||||
if( CloudDownloadMgr.getInstance().alreadyDownloadingData(_r.additionalDownloadid))
|
||||
{
|
||||
Toast.makeText(aContext,
|
||||
aContext.getString(R.string.dictionary_download_is_running_in_background),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
continue;
|
||||
}
|
||||
CloudLexicalPackageDownloadCallback _callback = new CloudLexicalPackageDownloadCallback();
|
||||
|
||||
Toast.makeText(aContext,
|
||||
aContext.getString(R.string.dictionary_download_start_in_background),
|
||||
Toast.LENGTH_SHORT).show();
|
||||
|
||||
CloudDownloadMgr.getInstance().executeAsDownload(aContext,
|
||||
_r.additionalDownloadid, null, _callback,
|
||||
_r.additionalDownloads.toArray(new CloudApiTypes.CloudApiParam[0]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* process the meta data result and prepare the additional downloads.
|
||||
* @param aContext the context
|
||||
* @param aMetaDataResult the meta data results
|
||||
*/
|
||||
private void processCloudResults(Context aContext, List<MetaDataResult> aMetaDataResult) {
|
||||
for(MetaDataResult _r:aMetaDataResult) {
|
||||
if (_r.returnjson.target== CloudApiTypes.ApiTarget.Keyboard) {
|
||||
//handleKeyboardMetaData(_r);
|
||||
}
|
||||
if(_r.returnjson.target== CloudApiTypes.ApiTarget.KeyboardLexicalModels) {
|
||||
JSONArray lmData = _r.returnjson.jsonArray;
|
||||
if (lmData != null && lmData.length() > 0) {
|
||||
try {
|
||||
JSONObject modelInfo = lmData.getJSONObject(0);
|
||||
|
||||
if (modelInfo.has("packageFilename") && modelInfo.has("id")) {
|
||||
String _modelID = modelInfo.getString("id");
|
||||
ArrayList<CloudApiTypes.CloudApiParam> urls = new ArrayList<>();
|
||||
urls.add(new CloudApiTypes.CloudApiParam(
|
||||
CloudApiTypes.ApiTarget.LexicalModelPackage,
|
||||
modelInfo.getString("packageFilename")));
|
||||
_r.additionalDownloadid = CloudLexicalPackageDownloadCallback.createDownloadId(_modelID);
|
||||
_r.additionalDownloads= urls;
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
KMLog.LogException(TAG, "Error parsing lexical model from api.keyman.com. ", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_r.returnjson.target == CloudApiTypes.ApiTarget.PackageVersion) {
|
||||
JSONObject pkgData = _r.returnjson.jsonObject;
|
||||
|
||||
if (pkgData != null) {
|
||||
List<Bundle> updateBundles = new ArrayList<>();
|
||||
CloudDataJsonUtil.processKeyboardPackageUpdateJSON(aContext, pkgData, updateBundles);
|
||||
CloudDataJsonUtil.processLexicalModelPackageUpdateJSON(aContext, pkgData, updateBundles);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* create a download id for the lexical model metadata.
|
||||
* @param aLanguageId the language id
|
||||
* @return the result
|
||||
*/
|
||||
public static String createDownloadId(String aLanguageId)
|
||||
{
|
||||
return "metadata_" + aLanguageId;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -42,6 +42,7 @@ public class CloudRepository {
|
|||
|
||||
public static final String API_MODEL_QUERY = "?q";
|
||||
public static final String API_MODEL_FORMATSTR = "https://%s/model%s";
|
||||
public static final String API_MODEL_LANGUAGE_FORMATSTR = "https://%s/model?q=bcp47:%s";
|
||||
public static final String API_PACKAGE_VERSION_FORMATSTR = "https://%s/package-version?platform=android%s%s";
|
||||
|
||||
private Dataset memCachedDataset;
|
||||
|
|
@ -225,6 +226,11 @@ public class CloudRepository {
|
|||
/* do what's possible here, rather than in the Task */
|
||||
}
|
||||
|
||||
public static String prepareLexicalModelQuery(String languageID) {
|
||||
String lexicalURL = String.format(API_MODEL_LANGUAGE_FORMATSTR, getHost(), languageID);
|
||||
return lexicalURL;
|
||||
}
|
||||
|
||||
/**
|
||||
* initialize the data set from cache on startup of the application
|
||||
* (not used until keyboard update is implemented)
|
||||
|
|
|
|||
|
|
@ -102,6 +102,8 @@
|
|||
<string name="keyboard_qr_code" comment="QR Code description">
|
||||
Scan this code to load this\nkeyboard on another device</string>
|
||||
|
||||
<!-- Context: Query for associated dictionary -->
|
||||
<string name="query_associated_model" comment="Check if there's an available dictionary to download">Checking for associated dictionary to download</string>
|
||||
|
||||
<!-- Context: Model Updates -->
|
||||
<string name="confirm_download_model" comment="Confirmation to download a dictionary update">Would you like to download the latest version of this dictionary?</string>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue