diff --git a/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/KeymanSettingsFragment.java b/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/KeymanSettingsFragment.java
index ccf851b0fa..676ab7bbd0 100644
--- a/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/KeymanSettingsFragment.java
+++ b/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/KeymanSettingsFragment.java
@@ -2,6 +2,7 @@ package com.tavultesoft.kmapro;
import android.content.Context;
import android.content.Intent;
+import android.net.Uri;
import android.os.Bundle;
import android.provider.Settings;
import android.view.inputmethod.InputMethodManager;
@@ -19,7 +20,7 @@ public class KeymanSettingsFragment extends PreferenceFragmentCompat {
private static final String TAG = "SettingsFragment";
private static Context context;
- private Preference languagesPreference;
+ private Preference languagesPreference, addKeyboardFromDevice;
private CheckBoxPreference setSystemKeyboardPreference;
private CheckBoxPreference setDefaultKeyboardPreference;
@@ -40,6 +41,24 @@ public class KeymanSettingsFragment extends PreferenceFragmentCompat {
languagesIntent.putExtra(KMManager.KMKey_DisplayKeyboardSwitcher, false);
languagesPreference.setIntent(languagesIntent);
+ // Launch System file browser for user to navigate to local .kmp files
+ // Using generic "Add keyboard" title even though this can also install lexical model .kmp's.
+ addKeyboardFromDevice = new Preference(context);
+ addKeyboardFromDevice.setTitle(getString(R.string.title_add_keyboard_from_device));
+ addKeyboardFromDevice.setWidgetLayoutResource(R.layout.preference_file_browser_layout);
+ addKeyboardFromDevice.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
+ @Override
+ public boolean onPreferenceClick(Preference preference) {
+ Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
+ intent.addCategory(Intent.CATEGORY_OPENABLE);
+ intent.putExtra("android.content.extra.SHOW_ADVANCED", false);
+ // Unfortunately, we can't filter for a "kmp" mime type
+ intent.setType("*/*");
+ startActivityForResult(intent, MainActivity.READ_REQUEST_CODE);
+ return false;
+ }
+ });
+
/*
Automatically does the following:
SharedPreferences.Editor editor = prefs.edit();
@@ -92,6 +111,8 @@ public class KeymanSettingsFragment extends PreferenceFragmentCompat {
setDefaultKeyboardPreference.setOnPreferenceChangeListener(checkBlocker);
screen.addPreference(languagesPreference);
+ screen.addPreference(addKeyboardFromDevice);
+
screen.addPreference(setSystemKeyboardPreference);
screen.addPreference(setDefaultKeyboardPreference);
@@ -132,6 +153,16 @@ public class KeymanSettingsFragment extends PreferenceFragmentCompat {
// .update() on our behalf.
}
+
+ public void onActivityResult(int requestCode, int resultCode, Intent returnIntent) {
+ // Handle kmp file selected from file browser
+ if ((requestCode == MainActivity.READ_REQUEST_CODE) && (returnIntent != null)) {
+ String kmpFilename = returnIntent.getDataString();
+ Uri data = Uri.parse(kmpFilename);
+ MainActivity.useLocalKMP(this.getContext(), data);
+ }
+ }
+
public void update() {
setSystemKeyboardPreference.setChecked(SystemIMESettings.isEnabledAsSystemKB(context));
setDefaultKeyboardPreference.setChecked(SystemIMESettings.isDefaultKB(context));
diff --git a/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/MainActivity.java b/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/MainActivity.java
index d5219d4868..4e1f6bd466 100644
--- a/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/MainActivity.java
+++ b/android/KMAPro/kMAPro/src/main/java/com/tavultesoft/kmapro/MainActivity.java
@@ -75,10 +75,12 @@ import android.widget.SeekBar;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity implements OnKeyboardEventListener, OnKeyboardDownloadEventListener,
- ActivityCompat.OnRequestPermissionsResultCallback {
+ ActivityCompat.OnRequestPermissionsResultCallback {
+ public static Context context;
// Fields used for installing kmp packages
private static final int PERMISSION_REQUEST_STORAGE = 0;
+ public static final int READ_REQUEST_CODE = 42;
Uri data;
private static final String TAG = "MainActivity";
@@ -132,6 +134,7 @@ public class MainActivity extends AppCompatActivity implements OnKeyboardEventLi
protected void onCreate(Bundle savedInstanceState) {
setTheme(R.style.AppTheme);
super.onCreate(savedInstanceState);
+ context = this;
resultReceiver = new DownloadResultReceiver(new Handler());
mFirebaseAnalytics = FirebaseAnalytics.getInstance(this);
@@ -619,7 +622,7 @@ public class MainActivity extends AppCompatActivity implements OnKeyboardEventLi
// Request for storage permission
if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission has been granted. Resume task needing this permission
- useLocalKMP(data);
+ useLocalKMP(context, data);
} else {
// Permission request denied
String message = "Storage permission request was denied. Unable to install keyboard package";
@@ -634,14 +637,14 @@ public class MainActivity extends AppCompatActivity implements OnKeyboardEventLi
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) ==
PackageManager.PERMISSION_GRANTED) {
- useLocalKMP(data);
+ useLocalKMP(context, data);
} else {
// Permission is missing and must be requested
requestStoragePermission();
}
} else {
// Permission automatically granted on older Android versions
- useLocalKMP(data);
+ useLocalKMP(context, data);
}
}
@@ -664,7 +667,8 @@ public class MainActivity extends AppCompatActivity implements OnKeyboardEventLi
}
}
- private void useLocalKMP(Uri data) {
+ // TODO: Move this to KMEA during Keyman 13.0 refactoring
+ public static void useLocalKMP(Context context, Uri data) {
String filename = "";
String cacheKMPFilename = "";
File cacheKMPFile = null;
@@ -675,13 +679,13 @@ public class MainActivity extends AppCompatActivity implements OnKeyboardEventLi
switch (data.getScheme().toLowerCase()) {
case "content":
// DownloadManager passes a path "/document/number" so we need to extract the .kmp filename
- Cursor cursor = getContentResolver().query(data, null, null, null, null);
+ Cursor cursor = context.getContentResolver().query(data, null, null, null, null);
cursor.moveToFirst();
int nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
filename = cursor.getString(nameIndex);
isKMP = FileUtils.hasKeymanPackageExtension(filename);
cacheKMPFilename = filename;
- inputFile = getContentResolver().openInputStream(data);
+ inputFile = context.getContentResolver().openInputStream(data);
break;
case "file":
@@ -695,21 +699,22 @@ public class MainActivity extends AppCompatActivity implements OnKeyboardEventLi
if (isKMP) {
// Copy KMP to app cache
- cacheKMPFile = new File(MainActivity.this.getCacheDir().toString(), cacheKMPFilename);
+ cacheKMPFile = new File(context.getCacheDir().toString(), cacheKMPFilename);
if (cacheKMPFile.exists()) {
cacheKMPFile.delete();
}
FileUtils.copy(inputFile, new FileOutputStream(cacheKMPFile));
} else {
- String noKeyboardsInstalledMessage = " is not a valid keyboard package file.\nNo keyboards were installed.";
- Toast.makeText(getApplicationContext(),
+ String noKeyboardsInstalledMessage = " is not a valid Keyman package file.\n" +
+ "No keyboards/dictionaries were installed.";
+ Toast.makeText(context,
filename + noKeyboardsInstalledMessage, Toast.LENGTH_LONG).show();
}
} catch (Exception e) {
String message = "Access denied to " + filename +
".\nCheck Android Settings --> Apps --> Keyman to grant storage permissions";
- Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();
+ Toast.makeText(context, message, Toast.LENGTH_LONG).show();
Log.e(TAG, "Unable to copy " + filename + " to app cache");
return;
}
@@ -717,9 +722,9 @@ public class MainActivity extends AppCompatActivity implements OnKeyboardEventLi
if (cacheKMPFile != null) {
bundle.putString("kmpFile", cacheKMPFile.getAbsolutePath());
- Intent packageIntent = new Intent(getApplicationContext(), PackageActivity.class);
+ Intent packageIntent = new Intent(context, PackageActivity.class);
packageIntent.putExtras(bundle);
- startActivity(packageIntent);
+ context.startActivity(packageIntent);
}
}
diff --git a/android/KMAPro/kMAPro/src/main/res/drawable-hdpi/ic_folder_open.png b/android/KMAPro/kMAPro/src/main/res/drawable-hdpi/ic_folder_open.png
new file mode 100644
index 0000000000..4f90c63104
Binary files /dev/null and b/android/KMAPro/kMAPro/src/main/res/drawable-hdpi/ic_folder_open.png differ
diff --git a/android/KMAPro/kMAPro/src/main/res/drawable-mdpi/ic_folder_open.png b/android/KMAPro/kMAPro/src/main/res/drawable-mdpi/ic_folder_open.png
new file mode 100644
index 0000000000..4f90c63104
Binary files /dev/null and b/android/KMAPro/kMAPro/src/main/res/drawable-mdpi/ic_folder_open.png differ
diff --git a/android/KMAPro/kMAPro/src/main/res/drawable-xhdpi/ic_folder_open.png b/android/KMAPro/kMAPro/src/main/res/drawable-xhdpi/ic_folder_open.png
new file mode 100644
index 0000000000..f55b92e9ba
Binary files /dev/null and b/android/KMAPro/kMAPro/src/main/res/drawable-xhdpi/ic_folder_open.png differ
diff --git a/android/KMAPro/kMAPro/src/main/res/drawable-xxhdpi/ic_folder_open.png b/android/KMAPro/kMAPro/src/main/res/drawable-xxhdpi/ic_folder_open.png
new file mode 100644
index 0000000000..1eb3365e09
Binary files /dev/null and b/android/KMAPro/kMAPro/src/main/res/drawable-xxhdpi/ic_folder_open.png differ
diff --git a/android/KMAPro/kMAPro/src/main/res/drawable-xxxhdpi/ic_folder_open.png b/android/KMAPro/kMAPro/src/main/res/drawable-xxxhdpi/ic_folder_open.png
new file mode 100644
index 0000000000..e6faa991f4
Binary files /dev/null and b/android/KMAPro/kMAPro/src/main/res/drawable-xxxhdpi/ic_folder_open.png differ
diff --git a/android/KMAPro/kMAPro/src/main/res/layout/preference_file_browser_layout.xml b/android/KMAPro/kMAPro/src/main/res/layout/preference_file_browser_layout.xml
new file mode 100644
index 0000000000..9483748278
--- /dev/null
+++ b/android/KMAPro/kMAPro/src/main/res/layout/preference_file_browser_layout.xml
@@ -0,0 +1,5 @@
+
+
diff --git a/android/KMAPro/kMAPro/src/main/res/menu-land/main.xml b/android/KMAPro/kMAPro/src/main/res/menu-land/main.xml
index 892a1f24ec..6cb3ec10a3 100644
--- a/android/KMAPro/kMAPro/src/main/res/menu-land/main.xml
+++ b/android/KMAPro/kMAPro/src/main/res/menu-land/main.xml
@@ -14,7 +14,7 @@
app:showAsAction="always"
android:title="@string/action_web"
android:icon="@drawable/ic_light_action_web" />
-
+
-
+
- Share
Web Browser
+ File Browser
Text Size
More
Clear Text
diff --git a/android/KMEA/app/src/main/res/values/strings.xml b/android/KMEA/app/src/main/res/values/strings.xml
index 698fc4c9f7..4756b8bd9c 100644
--- a/android/KMEA/app/src/main/res/values/strings.xml
+++ b/android/KMEA/app/src/main/res/values/strings.xml
@@ -12,6 +12,7 @@
Keyboard
Add New Language
Add New Keyboard
+ Add Keyboard from Device
Installed Languages
%s Settings
diff --git a/android/history.md b/android/history.md
index 44dd6ff0ac..3bfd484b14 100644
--- a/android/history.md
+++ b/android/history.md
@@ -3,6 +3,10 @@
## 13.0 alpha
* Start version 13.0
+## 2019-08-30 12.0.4081 beta
+* New Feature:
+ * Allow user to "Add keyboard from local device" from Settings menu (#1992)
+
## 2019-08-27 12.0.4080 beta
* Fix menu icon and text alignment (#1999)