mirror of
https://github.com/keymanapp/keyman.git
synced 2026-09-17 21:27:40 +00:00
feat(android): Add API for checking Chrome version
This commit is contained in:
parent
fc2d0ccd4d
commit
ca2a7c2ef4
9 changed files with 193 additions and 48 deletions
|
|
@ -24,7 +24,7 @@ import com.tavultesoft.kmea.BaseActivity;
|
|||
import com.tavultesoft.kmea.KMManager;
|
||||
import com.tavultesoft.kmea.util.KMPLink;
|
||||
import com.tavultesoft.kmea.util.KMString;
|
||||
import com.tavultesoft.kmea.util.WebViewUtil;
|
||||
import com.tavultesoft.kmea.util.WebViewUtils;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
|
@ -166,7 +166,7 @@ public class KMPBrowserActivity extends BaseActivity {
|
|||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
WebViewUtil.cleanup(webView);
|
||||
WebViewUtils.cleanup(webView);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -40,6 +40,8 @@ import com.keyman.android.DownloadIntentService;
|
|||
import com.tavultesoft.kmea.util.KMLog;
|
||||
import com.tavultesoft.kmea.util.KMPLink;
|
||||
import com.tavultesoft.kmea.util.KMString;
|
||||
import com.tavultesoft.kmea.util.WebViewUtils;
|
||||
import com.tavultesoft.kmea.util.WebViewUtils.EngineModeType;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.ProgressDialog;
|
||||
|
|
@ -197,6 +199,7 @@ public class MainActivity extends BaseActivity implements OnKeyboardEventListene
|
|||
textView.setTextSize((float) textSize);
|
||||
textView.setSelection(textView.getText().length());
|
||||
|
||||
checkChromeVersion();
|
||||
CheckInstallReferrer.checkGooglePlayInstallReferrer(this, context);
|
||||
checkGetStarted();
|
||||
}
|
||||
|
|
@ -764,6 +767,24 @@ public class MainActivity extends BaseActivity implements OnKeyboardEventListene
|
|||
KMManager.setMaySendCrashReport(maySendCrashReport);
|
||||
}
|
||||
|
||||
private void checkChromeVersion() {
|
||||
if (WebViewUtils.getEngineModeType(context,"") != EngineModeType.ENGINE_MODE_TYPE_FULL) {
|
||||
// Notify minimum Chrome version needed
|
||||
String message = "Minimum Chrome version 57 needed for Keyman.";
|
||||
//KMLog.LogError(TAG, message);
|
||||
Toast.makeText(getApplicationContext(), message,
|
||||
Toast.LENGTH_LONG).show();
|
||||
|
||||
// Launch PlayStore to update Chrome
|
||||
try {
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=com.android.chrome"));
|
||||
startActivity(intent);
|
||||
} catch (android.content.ActivityNotFoundException e) {
|
||||
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/apps/details?id=com.android.chome")));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Uri requestPermissionIntentUri;
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import com.stepstone.stepper.StepperLayout;
|
|||
import com.stepstone.stepper.VerificationError;
|
||||
import com.tavultesoft.kmea.packages.PackageProcessor;
|
||||
import com.tavultesoft.kmea.util.FileUtils;
|
||||
import com.tavultesoft.kmea.util.WebViewUtil;
|
||||
import com.tavultesoft.kmea.util.WebViewUtils;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.os.Bundle;
|
||||
|
|
@ -137,7 +137,7 @@ public class WebViewFragment extends Fragment implements BlockingStep {
|
|||
@Override
|
||||
public void onPageFinished(WebView view, String url) {
|
||||
// Inject a meta viewport tag into the head of the file if it doesn't exist
|
||||
WebViewUtil.injectViewport(view);
|
||||
WebViewUtils.injectViewport(view);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,10 @@
|
|||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<queries>
|
||||
<!-- Permission needed to query for Chrome version -->
|
||||
<package android:name="com.android.chrome" />
|
||||
</queries>
|
||||
|
||||
<application
|
||||
android:theme="@style/AppTheme" >
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ import com.tavultesoft.kmea.packages.PackageProcessor;
|
|||
import com.tavultesoft.kmea.util.FileProviderUtils;
|
||||
import com.tavultesoft.kmea.util.FileUtils;
|
||||
import com.tavultesoft.kmea.util.HelpFile;
|
||||
import com.tavultesoft.kmea.util.WebViewUtil;
|
||||
import com.tavultesoft.kmea.util.WebViewUtils;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
|
|
@ -144,7 +144,7 @@ public class KMHelpFileActivity extends BaseActivity {
|
|||
@Override
|
||||
public void onPageFinished(WebView view, String url) {
|
||||
// Inject a meta viewport tag into the head of the file if it doesn't exist
|
||||
WebViewUtil.injectViewport(view);
|
||||
WebViewUtils.injectViewport(view);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -167,7 +167,7 @@ public class KMHelpFileActivity extends BaseActivity {
|
|||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
WebViewUtil.cleanup(webView);
|
||||
WebViewUtils.cleanup(webView);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ import com.tavultesoft.kmea.util.FileUtils;
|
|||
import com.tavultesoft.kmea.util.KMLog;
|
||||
import com.tavultesoft.kmea.util.KMString;
|
||||
import com.tavultesoft.kmea.util.MapCompat;
|
||||
import com.tavultesoft.kmea.util.WebViewUtils;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
|
|
@ -367,6 +368,15 @@ public final class KMManager {
|
|||
return appVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Keyman Engine mode based on the Chrome version
|
||||
* @param aContext
|
||||
* @return WebViewUtils.EngineModeType
|
||||
*/
|
||||
public static WebViewUtils.EngineModeType getEngineMode(Context aContext) {
|
||||
return WebViewUtils.getEngineModeType(aContext, "");
|
||||
}
|
||||
|
||||
// Check if a keyboard namespace is reserved
|
||||
public static boolean isReservedNamespace(String packageID) {
|
||||
if (packageID.equals(KMDefault_UndefinedPackageID)) {
|
||||
|
|
|
|||
|
|
@ -1,41 +0,0 @@
|
|||
/**
|
||||
* Copyright (C) 2021 SIL International. All rights reserved.
|
||||
*/
|
||||
package com.tavultesoft.kmea.util;
|
||||
|
||||
import android.view.ViewGroup;
|
||||
import android.webkit.WebView;
|
||||
|
||||
public final class WebViewUtil {
|
||||
// Inject a meta viewport tag into the head of the file if it doesn't exist
|
||||
public static void injectViewport(WebView webView) {
|
||||
if (webView != null) {
|
||||
webView.loadUrl(
|
||||
"javascript:(function() {" +
|
||||
"if(document.head && !document.querySelectorAll('meta[name=viewport]').length) {"+
|
||||
"let meta=document.createElement('meta');"+
|
||||
"meta.name='viewport';"+
|
||||
"meta.content='width=device-width, initial-scale=1';"+
|
||||
"document.head.appendChild(meta);"+
|
||||
"}"+
|
||||
"})()"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Blank the webView and destroy completely
|
||||
// Reference: https://stackoverflow.com/questions/17418503/destroy-webview-in-android/17458577#17458577
|
||||
public static void cleanup(WebView webView) {
|
||||
if (webView != null) {
|
||||
webView.loadUrl("about:blank");
|
||||
ViewGroup viewGroup = (ViewGroup) webView.getParent();
|
||||
if (viewGroup != null) {
|
||||
viewGroup.removeView(webView);
|
||||
}
|
||||
webView.removeAllViews();
|
||||
webView.destroy();
|
||||
webView = null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
/**
|
||||
* Keyman is copyright (C) SIL International. MIT License.
|
||||
*/
|
||||
package com.tavultesoft.kmea.util;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.view.ViewGroup;
|
||||
import android.webkit.WebView;
|
||||
import com.tavultesoft.kmea.util.KMLog;
|
||||
|
||||
public final class WebViewUtils {
|
||||
public static final String TAG = "WebViewUtils";
|
||||
|
||||
// Keyman Engine functionality based on Chrome version
|
||||
public enum EngineModeType {
|
||||
ENGINE_MODE_TYPE_DISABLED, // WebView doesn't support touch keyboard features
|
||||
ENGINE_MODE_TYPE_DEGRADED, // WebView supports touch keyboards but not LDML keyboards
|
||||
ENGINE_MODE_TYPE_FULL; // WebView supports touch keyboards and LDML keyboards
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Keyman Engine mode based on the Chrome version.
|
||||
* @param context - The context
|
||||
* @param chromeVersion - String of the device's Chrome version.
|
||||
* If not provided, the device's Chrome version is queried
|
||||
* @return EngineModeType
|
||||
*/
|
||||
public static EngineModeType getEngineModeType(Context context, String chromeVersion) {
|
||||
if (context == null) {
|
||||
return EngineModeType.ENGINE_MODE_TYPE_DISABLED;
|
||||
}
|
||||
if (chromeVersion == null || chromeVersion.isEmpty()) {
|
||||
chromeVersion = getChromeVersion(context);
|
||||
}
|
||||
|
||||
if (FileUtils.compareVersions(chromeVersion, "57.0") == FileUtils.VERSION_GREATER) {
|
||||
return EngineModeType.ENGINE_MODE_TYPE_FULL;
|
||||
} else if (FileUtils.compareVersions(chromeVersion, "37.0") == FileUtils.VERSION_GREATER) {
|
||||
return EngineModeType.ENGINE_MODE_TYPE_DEGRADED;
|
||||
}
|
||||
|
||||
return EngineModeType.ENGINE_MODE_TYPE_DISABLED;
|
||||
}
|
||||
|
||||
// Inject a meta viewport tag into the head of the file if it doesn't exist
|
||||
public static void injectViewport(WebView webView) {
|
||||
if (webView != null) {
|
||||
webView.loadUrl(
|
||||
"javascript:(function() {" +
|
||||
"if(document.head && !document.querySelectorAll('meta[name=viewport]').length) {"+
|
||||
"let meta=document.createElement('meta');"+
|
||||
"meta.name='viewport';"+
|
||||
"meta.content='width=device-width, initial-scale=1';"+
|
||||
"document.head.appendChild(meta);"+
|
||||
"}"+
|
||||
"})()"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Blank the webView and destroy completely
|
||||
// Reference: https://stackoverflow.com/questions/17418503/destroy-webview-in-android/17458577#17458577
|
||||
public static void cleanup(WebView webView) {
|
||||
if (webView != null) {
|
||||
webView.loadUrl("about:blank");
|
||||
ViewGroup viewGroup = (ViewGroup) webView.getParent();
|
||||
if (viewGroup != null) {
|
||||
viewGroup.removeView(webView);
|
||||
}
|
||||
webView.removeAllViews();
|
||||
webView.destroy();
|
||||
webView = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Chrome version. Returns empty string if Chrome not installed.
|
||||
* @param context - The context
|
||||
* @return String
|
||||
*/
|
||||
private static String getChromeVersion(Context context) {
|
||||
if (context == null) {
|
||||
return "";
|
||||
}
|
||||
try {
|
||||
PackageInfo pInfo;
|
||||
pInfo = context.getPackageManager().getPackageInfo("com.android.chrome", PackageManager.GET_ACTIVITIES);
|
||||
if (pInfo != null) {
|
||||
return pInfo.versionName;
|
||||
}
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
KMLog.LogInfo(TAG, "Chrome not installed");
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/**
|
||||
* Keyman is copyright (C) SIL International. MIT License.
|
||||
*/
|
||||
package com.tavultesoft.kmea.util;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.robolectric.RobolectricTestRunner;
|
||||
import com.tavultesoft.kmea.util.WebViewUtils;
|
||||
|
||||
@RunWith(RobolectricTestRunner.class)
|
||||
public class WebViewUtilsTest {
|
||||
private Context context = null;
|
||||
|
||||
@Before
|
||||
public void getContext() {
|
||||
context = ApplicationProvider.getApplicationContext();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_ChromeEmpty_EngineModeTypeDisabled() {
|
||||
String chromeVersion = "";
|
||||
Assert.assertEquals(WebViewUtils.getEngineModeType(context, chromeVersion),
|
||||
WebViewUtils.EngineModeType.ENGINE_MODE_TYPE_DISABLED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_Chrome36_EngineModeTypeDisabled() {
|
||||
String chromeVersion = "36.0";
|
||||
Assert.assertEquals(WebViewUtils.getEngineModeType(context, chromeVersion),
|
||||
WebViewUtils.EngineModeType.ENGINE_MODE_TYPE_DISABLED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_Chrome57_EngineModeTypeDegraded() {
|
||||
String chromeVersion = "57.0";
|
||||
Assert.assertEquals(WebViewUtils.getEngineModeType(context, chromeVersion),
|
||||
WebViewUtils.EngineModeType.ENGINE_MODE_TYPE_DEGRADED);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_Chrome58_EngineModeTypeFull() {
|
||||
String chromeVersion = "58.0";
|
||||
Assert.assertEquals(WebViewUtils.getEngineModeType(context, chromeVersion),
|
||||
WebViewUtils.EngineModeType.ENGINE_MODE_TYPE_FULL);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue