Merge pull request #1992 from keymanapp/android-file-browser

[Android] Use file browser to navigate to install local .kmp files
This commit is contained in:
Darcy Wong 2019-08-29 18:32:09 -05:00 • committed by GitHub
commit 76cebc85be
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 63 additions and 16 deletions

View file

@ -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));

View file

@ -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);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 313 B

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="@dimen/preference_icon"
android:layout_height="@dimen/preference_icon"
android:src="@drawable/ic_folder_open" />

View file

@ -14,7 +14,7 @@
app:showAsAction="always"
android:title="@string/action_web"
android:icon="@drawable/ic_light_action_web" />
<item
android:id="@+id/action_text_size"
app:showAsAction="always"

View file

@ -14,7 +14,7 @@
app:showAsAction="always"
android:title="@string/action_web"
android:icon="@drawable/ic_light_action_web" />
<item
android:id="@+id/action_text_size"
app:showAsAction="always"

View file

@ -5,6 +5,7 @@
<string name="action_share" translatable="false">Share</string>
<string name="action_web" translatable="false">Web Browser</string>
<string name="action_file_browser" translatable="false">File Browser</string>
<string name="action_text_size" translatable="false">Text Size</string>
<string name="action_overflow" translatable="false">More</string>
<string name="action_clear_text" translatable="false">Clear Text</string>

View file

@ -12,6 +12,7 @@
<string name="title_keyboard" translatable="false">Keyboard</string>
<string name="title_add_language" translatable="false">Add New Language</string>
<string name="title_add_keyboard" translatable="false">Add New Keyboard</string>
<string name="title_add_keyboard_from_device" translatable="false">Add Keyboard from Device</string>
<string name="title_languages_settings" translatable="false">Installed Languages</string>
<string name="title_language_settings" translatable="false">%s Settings</string>

View file

@ -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)