From c772a2dbfef87a7c58d21a49d2a5a8edd0342fc3 Mon Sep 17 00:00:00 2001 From: Darcy Wong Date: Fri, 20 Dec 2019 15:35:28 +0700 Subject: [PATCH] chore(android): Refactor HelpFile as utility --- .../kmea/KeyboardInfoActivity.java | 63 +------------ .../kmea/KeyboardSettingsActivity.java | 27 ++---- .../com/tavultesoft/kmea/util/HelpFile.java | 89 +++++++++++++++++++ 3 files changed, 99 insertions(+), 80 deletions(-) create mode 100644 android/KMEA/app/src/main/java/com/tavultesoft/kmea/util/HelpFile.java diff --git a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/KeyboardInfoActivity.java b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/KeyboardInfoActivity.java index a6fd61f124..84eccb725f 100644 --- a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/KeyboardInfoActivity.java +++ b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/KeyboardInfoActivity.java @@ -4,16 +4,11 @@ package com.tavultesoft.kmea; -import java.io.File; -import java.io.FileFilter; import java.util.ArrayList; import java.util.HashMap; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; -import androidx.core.content.FileProvider; -import android.content.ClipData; -import android.content.ClipDescription; import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; @@ -33,8 +28,8 @@ import android.widget.SimpleAdapter; import android.widget.TextView; import android.widget.Toast; -import com.tavultesoft.kmea.util.FileUtils; import com.tavultesoft.kmea.util.FileProviderUtils; +import com.tavultesoft.kmea.util.HelpFile; import com.tavultesoft.kmea.util.MapCompat; import com.tavultesoft.kmea.util.QRCodeUtil; @@ -128,67 +123,15 @@ public final class KeyboardInfoActivity extends AppCompatActivity { @Override public void onItemClick(AdapterView parent, View view, int position, long id) { if (position == 1) { - Intent i = new Intent(Intent.ACTION_VIEW); - if (customHelpLink != null) { // Display local welcome.htm help file, including associated assets - if (FileUtils.isWelcomeFile(customHelpLink) && ! KMManager.isTestMode()) { - File customHelp = new File(new File(customHelpLink).getAbsolutePath()); - i.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - // Starting with Android N, you can't pass file:// to intents, so we use FileProvider - try { - final String authority = FileProviderUtils.getAuthority(context); - Uri contentUri = FileProvider.getUriForFile( - context, authority, customHelp); - i.setDataAndType(contentUri, "text/html"); + Intent i = HelpFile.toActionView(context, customHelpLink, packageID); - // Grant read permission to all the files in the package so embedded assets can be viewed - ClipData clipData = new ClipData(null, - new String[] { - ClipDescription.MIMETYPE_TEXT_HTML, - "text/css", - "image/gif", - "image/jpeg", - "image/png" - }, new ClipData.Item(contentUri)); - - // Exclude html help files and JS files. Treat rest of the files as assets - FileFilter _fileFilter = new FileFilter() { - @Override - public boolean accept(File pathname) { - String name = pathname.getName(); - if (pathname.isFile() && (FileUtils.isReadmeFile(name) || - FileUtils.isWelcomeFile(name) || FileUtils.hasJavaScriptExtension(name))) { - return false; - } - return true; - } - }; - - File packageDir = new File( - context.getDir("data", Context.MODE_PRIVATE), "packages" + File.separator + packageID + File.separator); - File[] files = packageDir.listFiles(_fileFilter); - for(File assetFile : files) { - Uri assetUri = FileProvider.getUriForFile( - context, authority, assetFile); - clipData.addItem(new ClipData.Item(assetUri)); - } - - // Associate assets in clipData to the intent - i.setClipData(clipData); - } catch (NullPointerException e) { - String message = "FileProvider undefined in app to load" + customHelp.toString(); - Toast.makeText(context, message, Toast.LENGTH_LONG).show(); - Log.e("KeyboardInfoActivity", message); - } - } - else { - i.setData(Uri.parse(customHelpLink)); - } if (FileProviderUtils.exists(context)|| KMManager.isTestMode()) { startActivity(i); } } else { + Intent i = new Intent(Intent.ACTION_VIEW); i.setData(Uri.parse(helpUrlStr)); startActivity(i); } diff --git a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/KeyboardSettingsActivity.java b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/KeyboardSettingsActivity.java index 2e9ed67fd5..6921b86dcb 100644 --- a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/KeyboardSettingsActivity.java +++ b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/KeyboardSettingsActivity.java @@ -33,6 +33,7 @@ import android.widget.Toast; import com.tavultesoft.kmea.util.FileUtils; import com.tavultesoft.kmea.util.FileProviderUtils; +import com.tavultesoft.kmea.util.HelpFile; import com.tavultesoft.kmea.util.MapCompat; import com.tavultesoft.kmea.util.QRCodeUtil; @@ -140,33 +141,19 @@ public final class KeyboardSettingsActivity extends AppCompatActivity { // "Help" link clicked if (itemTitle.equals(getString(R.string.help_link))) { - Intent i = new Intent(Intent.ACTION_VIEW); - if (customHelpLink != null) { - if (FileUtils.isWelcomeFile(customHelpLink)) { - File customHelp = new File(new File(customHelpLink).getAbsolutePath()); - i.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); - // Starting with Android N, you can't pass file:// to intents, so we use FileProvider - try { - Uri contentUri = FileProvider.getUriForFile( - context, authority, customHelp); - i.setDataAndType(contentUri, "text/html"); - } catch (NullPointerException e) { - String message = "FileProvider undefined in app to load" + customHelp.toString(); - Toast.makeText(context, message, Toast.LENGTH_LONG).show(); - Log.e("TAG", message); - } - } - else { - i.setData(Uri.parse(customHelpLink)); - } - if (FileProviderUtils.exists(context)) { + // Display local welcome.htm help file, including associated assets + Intent i = HelpFile.toActionView(context, customHelpLink, packageID); + + if (FileProviderUtils.exists(context) || KMManager.isTestMode()) { startActivity(i); } } else { + Intent i = new Intent(Intent.ACTION_VIEW); i.setData(Uri.parse(helpUrlStr)); startActivity(i); } + // "Uninstall Keyboard" clicked } else if (itemTitle.equals(getString(R.string.uninstall_keyboard))) { // Uninstall selected keyboard diff --git a/android/KMEA/app/src/main/java/com/tavultesoft/kmea/util/HelpFile.java b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/util/HelpFile.java new file mode 100644 index 0000000000..47a1d27436 --- /dev/null +++ b/android/KMEA/app/src/main/java/com/tavultesoft/kmea/util/HelpFile.java @@ -0,0 +1,89 @@ +package com.tavultesoft.kmea.util; + +import android.content.ClipData; +import android.content.ClipDescription; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.util.Log; +import android.widget.Toast; + +import androidx.core.content.FileProvider; + +import com.tavultesoft.kmea.KMManager; +import com.tavultesoft.kmea.util.FileProviderUtils; +import com.tavultesoft.kmea.util.FileUtils; + +import java.io.File; +import java.io.FileFilter; + + +public final class HelpFile { + private static final String TAG = "HelpFile"; + private static final String[] ASSET_MIME_TYPES = { + ClipDescription.MIMETYPE_TEXT_HTML, + "text/css", + "image/gif", + "image/jpeg", + "image/png"}; + + /** + * Utility to pass a help file and all associated assets to an Intent for Intent.ACTION_VIEW + * @param context + * @param helpFile Full path string of the html file to view + * @param packageID String of the package ID + * @return Intent + */ + public static Intent toActionView(Context context, String helpFile, String packageID) { + Intent i = new Intent(Intent.ACTION_VIEW); + + if (FileUtils.isWelcomeFile(helpFile) && ! KMManager.isTestMode()) { + File customHelp = new File(new File(helpFile).getAbsolutePath()); + i.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + // Starting with Android N, you can't pass file:// to intents, so we use FileProvider + try { + final String authority = FileProviderUtils.getAuthority(context); + Uri contentUri = FileProvider.getUriForFile( + context, authority, customHelp); + i.setDataAndType(contentUri, "text/html"); + + // Grant read permission to all the files in the package so embedded assets can be viewed + ClipData clipData = new ClipData(null, ASSET_MIME_TYPES, new ClipData.Item(contentUri)); + + // Exclude html help files and JS files. Treat rest of the files as assets + FileFilter _fileFilter = new FileFilter() { + @Override + public boolean accept(File pathname) { + String name = pathname.getName(); + if (pathname.isFile() && (FileUtils.isReadmeFile(name) || + FileUtils.isWelcomeFile(name) || FileUtils.hasJavaScriptExtension(name))) { + return false; + } + return true; + } + }; + + String base = helpFile.contains("packages") ? "packages" : "models"; + File packageDir = new File( + context.getDir("data", Context.MODE_PRIVATE), base + File.separator + packageID + File.separator); + File[] files = packageDir.listFiles(_fileFilter); + for(File assetFile : files) { + Uri assetUri = FileProvider.getUriForFile( + context, authority, assetFile); + clipData.addItem(new ClipData.Item(assetUri)); + } + + // Associate assets in clipData to the intent + i.setClipData(clipData); + } catch (NullPointerException e) { + String message = "FileProvider undefined in app to load" + customHelp.toString(); + Toast.makeText(context, message, Toast.LENGTH_LONG).show(); + Log.e(TAG, message); + } + } else { + i.setData(Uri.parse(helpFile)); + } + return i; + } + +} \ No newline at end of file