From 66f4353c3eb333008285cfb7f10a4ae42c8d63a3 Mon Sep 17 00:00:00 2001 From: J-Jamet Date: Wed, 14 Mar 2018 14:37:50 +0100 Subject: [PATCH 01/56] Fix ActivityNotFound for AutoFill Service #37 --- .../settings/NestedSettingsFragment.java | 14 +++++++++++--- app/src/main/res/values-fr/strings.xml | 1 + app/src/main/res/values/strings.xml | 1 + 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/keepassdroid/settings/NestedSettingsFragment.java b/app/src/main/java/com/keepassdroid/settings/NestedSettingsFragment.java index 25c7538f2..2f27c461e 100644 --- a/app/src/main/java/com/keepassdroid/settings/NestedSettingsFragment.java +++ b/app/src/main/java/com/keepassdroid/settings/NestedSettingsFragment.java @@ -19,6 +19,7 @@ */ package com.keepassdroid.settings; +import android.content.ActivityNotFoundException; import android.content.Intent; import android.content.DialogInterface; import android.content.res.Resources; @@ -204,7 +205,14 @@ public void onClick(DialogInterface dialog, @Override public boolean onPreferenceClick(Preference preference) { if (((SwitchPreference) preference).isChecked()) { - startEnableService(); + try { + startEnableService(); + } catch (ActivityNotFoundException e) { + String error = getString(R.string.error_autofill_enable_service); + ((SwitchPreference) preference).setChecked(false); + Log.d(getClass().getName(), error, e); + Toast.makeText(getContext(), error, Toast.LENGTH_SHORT).show(); + } } else { disableService(); } @@ -221,11 +229,11 @@ private void disableService() { } @RequiresApi(api = Build.VERSION_CODES.O) - private void startEnableService() { + private void startEnableService() throws ActivityNotFoundException{ if (autofillManager != null && !autofillManager.hasEnabledAutofillServices()) { Intent intent = new Intent(Settings.ACTION_REQUEST_SET_AUTOFILL_SERVICE); intent.setData(Uri.parse("package:com.example.android.autofill.service")); - Log.d(getClass().getName(), "enableService(): intent="+ intent); + Log.d(getClass().getName(), "enableService(): intent=" + intent); startActivityForResult(intent, REQUEST_CODE_AUTOFILL); } else { Log.d(getClass().getName(), "Sample service already enabled."); diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 33b9ea30d..c6916e212 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -96,6 +96,7 @@ A field name is required for each string. Le titre est obligatoire. Entrez un entier positif pour la longueur du champ + Le service de remplissage automatique ne peut être activé. Nom du champ Valeur Fichier non trouvé. diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b9e164162..4079e8e18 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -94,6 +94,7 @@ A field name is required for each string. A title is required. Enter a positive integer on length field + Autofill service can\'t be enabled. Field Name Field value File not found. From 4cc7d1e74df11c7e5691dc31ee4ffe9daef41564 Mon Sep 17 00:00:00 2001 From: J-Jamet Date: Wed, 14 Mar 2018 16:52:40 +0100 Subject: [PATCH 02/56] Fix ActivityNotFound in FilePicker #37 --- .../fileselect/BrowserDialog.java | 81 ++++-------- .../com/keepassdroid/view/KeyFileHelper.java | 125 ++++++++++-------- app/src/main/res/layout/browser_install.xml | 28 ++-- app/src/main/res/values-ca/strings.xml | 4 +- app/src/main/res/values-cs/strings.xml | 4 +- app/src/main/res/values-da/strings.xml | 4 +- app/src/main/res/values-de/strings.xml | 4 +- app/src/main/res/values-el/strings.xml | 4 +- app/src/main/res/values-es/strings.xml | 4 +- app/src/main/res/values-eu/strings.xml | 4 +- app/src/main/res/values-fi/strings.xml | 4 +- app/src/main/res/values-fr/strings.xml | 4 +- app/src/main/res/values-hu/strings.xml | 4 +- app/src/main/res/values-it/strings.xml | 4 +- app/src/main/res/values-iw/strings.xml | 4 +- app/src/main/res/values-ja/strings.xml | 4 +- app/src/main/res/values-lv/strings.xml | 4 +- app/src/main/res/values-nl/strings.xml | 4 +- app/src/main/res/values-nn/strings.xml | 4 +- app/src/main/res/values-pl/strings.xml | 4 +- app/src/main/res/values-pt-rBR/strings.xml | 4 +- app/src/main/res/values-pt-rPT/strings.xml | 4 +- app/src/main/res/values-ru/strings.xml | 4 +- app/src/main/res/values-sk/strings.xml | 4 +- app/src/main/res/values-sv/strings.xml | 4 +- app/src/main/res/values-uk/strings.xml | 4 +- app/src/main/res/values-zh-rCN/strings.xml | 4 +- app/src/main/res/values-zh-rTW/strings.xml | 4 +- app/src/main/res/values/donottranslate.xml | 4 +- app/src/main/res/values/strings.xml | 4 +- 30 files changed, 165 insertions(+), 177 deletions(-) diff --git a/app/src/main/java/com/keepassdroid/fileselect/BrowserDialog.java b/app/src/main/java/com/keepassdroid/fileselect/BrowserDialog.java index c3ca14f2b..aa93f2717 100644 --- a/app/src/main/java/com/keepassdroid/fileselect/BrowserDialog.java +++ b/app/src/main/java/com/keepassdroid/fileselect/BrowserDialog.java @@ -20,69 +20,42 @@ package com.keepassdroid.fileselect; import android.app.Dialog; -import android.content.Context; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.v4.app.DialogFragment; +import android.support.v7.app.AlertDialog; +import android.view.LayoutInflater; import android.view.View; import android.widget.Button; -import com.kunzisoft.keepass.R; import com.keepassdroid.utils.Util; +import com.kunzisoft.keepass.R; -public class BrowserDialog extends Dialog { - - public BrowserDialog(Context context) { - super(context); - } +public class BrowserDialog extends DialogFragment { + @NonNull @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.browser_install); - setTitle(R.string.file_browser); - - Button cancel = (Button) findViewById(R.id.cancel); - cancel.setOnClickListener(new View.OnClickListener() { - - public void onClick(View v) { - BrowserDialog.this.cancel(); - } - }); - - Button market = (Button) findViewById(R.id.install_market); - market.setOnClickListener(new View.OnClickListener() { - - public void onClick(View v) { - Util.gotoUrl(getContext(), R.string.oi_filemanager_market); - BrowserDialog.this.cancel(); - } - }); - if (!isMarketInstalled()) { - market.setVisibility(View.GONE); - } - - Button web = (Button) findViewById(R.id.install_web); - web.setOnClickListener(new View.OnClickListener() { - - public void onClick(View v) { - Util.gotoUrl(getContext(), R.string.oi_filemanager_web); - BrowserDialog.this.cancel(); - } + public Dialog onCreateDialog(Bundle savedInstanceState) { + AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + // Get the layout inflater + LayoutInflater inflater = getActivity().getLayoutInflater(); + View root = inflater.inflate(R.layout.browser_install, null); + builder.setView(root) + .setNegativeButton(R.string.cancel, (dialog, id) -> { }); + + Button market = root.findViewById(R.id.install_market); + market.setOnClickListener((view) -> { + Util.gotoUrl(getContext(), R.string.filemanager_play_store); + dismiss(); }); - } - - private boolean isMarketInstalled() { - PackageManager pm = getContext().getPackageManager(); - - try { - pm.getPackageInfo("com.android.vending", 0); - } catch (NameNotFoundException e) { - return false; - } - - return true; - + + Button web = root.findViewById(R.id.install_web); + web.setOnClickListener(view -> { + Util.gotoUrl(getContext(), R.string.filemanager_f_droid); + dismiss(); + }); + + return builder.create(); } } diff --git a/app/src/main/java/com/keepassdroid/view/KeyFileHelper.java b/app/src/main/java/com/keepassdroid/view/KeyFileHelper.java index 779e1a993..10fc77f04 100644 --- a/app/src/main/java/com/keepassdroid/view/KeyFileHelper.java +++ b/app/src/main/java/com/keepassdroid/view/KeyFileHelper.java @@ -20,11 +20,12 @@ package com.keepassdroid.view; import android.app.Activity; -import android.content.ActivityNotFoundException; import android.content.ContentResolver; import android.content.Intent; import android.net.Uri; +import android.os.Build; import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentActivity; import android.util.Log; import android.view.View; @@ -35,11 +36,15 @@ import com.keepassdroid.utils.Interaction; import com.keepassdroid.utils.UriUtil; +import javax.annotation.Nullable; + import static android.app.Activity.RESULT_OK; public class KeyFileHelper { - public static final int GET_CONTENT = 25745; + private static final String TAG = "KeyFileHelper"; + + private static final int GET_CONTENT = 25745; private static final int OPEN_DOC = 25845; private static final int FILE_BROWSE = 25645; @@ -66,34 +71,53 @@ public class OpenFileOnClickViewListener implements View.OnClickListener { @Override public void onClick(View v) { - if (StorageAF.useStorageFramework(activity)) { - Intent i = new Intent(StorageAF.ACTION_OPEN_DOCUMENT); - i.addCategory(Intent.CATEGORY_OPENABLE); - i.setType("*/*"); - i.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION| - Intent.FLAG_GRANT_WRITE_URI_PERMISSION| - Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); - if(fragment != null) - fragment.startActivityForResult(i, OPEN_DOC); - else - activity.startActivityForResult(i, OPEN_DOC); - } else { - Intent i = new Intent(Intent.ACTION_GET_CONTENT); - i.addCategory(Intent.CATEGORY_OPENABLE); - i.setType("*/*"); - - try { - if(fragment != null) - fragment.startActivityForResult(i, GET_CONTENT); - else - activity.startActivityForResult(i, GET_CONTENT); - } catch (ActivityNotFoundException|SecurityException e) { - lookForOpenIntentsFilePicker(dataUri.onRequestIntentFilePicker()); + try { + if (StorageAF.useStorageFramework(activity)) { + openActivityWithActionOpenDocument(); + } else { + openActivityWithActionGetContent(); } + } catch (Exception e) { + Log.e(TAG,"Enable to start the file picker activity", e); + + // Open File picker if can't open activity + Uri uri = null; + if (dataUri != null) + uri = dataUri.onRequestIntentFilePicker(); + if(lookForOpenIntentsFilePicker(uri)) + showBrowserDialog(); } } } + private void openActivityWithActionOpenDocument() { + Intent i = new Intent(StorageAF.ACTION_OPEN_DOCUMENT); + i.addCategory(Intent.CATEGORY_OPENABLE); + i.setType("*/*"); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { + i.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | + Intent.FLAG_GRANT_WRITE_URI_PERMISSION | + Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION); + } else { + i.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | + Intent.FLAG_GRANT_WRITE_URI_PERMISSION); + } + if (fragment != null) + fragment.startActivityForResult(i, OPEN_DOC); + else + activity.startActivityForResult(i, OPEN_DOC); + } + + private void openActivityWithActionGetContent() { + Intent i = new Intent(Intent.ACTION_GET_CONTENT); + i.addCategory(Intent.CATEGORY_OPENABLE); + i.setType("*/*"); + if(fragment != null) + fragment.startActivityForResult(i, GET_CONTENT); + else + activity.startActivityForResult(i, GET_CONTENT); + } + public OpenFileOnClickViewListener getOpenFileOnClickViewListener() { return new OpenFileOnClickViewListener(null); } @@ -102,49 +126,46 @@ public OpenFileOnClickViewListener getOpenFileOnClickViewListener(ClickDataUriCa return new OpenFileOnClickViewListener(dataUri); } - private void lookForOpenIntentsFilePicker(Uri dataUri) { - if (Interaction.isIntentAvailable(activity, Intents.OPEN_INTENTS_FILE_BROWSE)) { - Intent i = new Intent(Intents.OPEN_INTENTS_FILE_BROWSE); - - // Get file path parent if possible - try { + private boolean lookForOpenIntentsFilePicker(@Nullable Uri dataUri) { + boolean showBrowser = false; + try { + if (Interaction.isIntentAvailable(activity, Intents.OPEN_INTENTS_FILE_BROWSE)) { + Intent i = new Intent(Intents.OPEN_INTENTS_FILE_BROWSE); + // Get file path parent if possible if (dataUri != null && dataUri.toString().length() > 0 && dataUri.getScheme().equals("file")) { i.setData(dataUri); - //i.setData(Uri.parse("file://" + mDbUri.getPath())); - /* - TODO Verify Intent File Picker - File keyfile = new File(mDbUri.getPath()); - File parent = keyfile.getParentFile(); - if (parent != null) { - i.setData(Uri.parse("file://" + parent.getAbsolutePath())); - } - */ } else { Log.w(getClass().getName(), "Unable to read the URI"); } - } catch (Exception e) { - // Ignore - Log.w(getClass().getName(), "Unable to read the URI " + e.getMessage()); - } - - try { if(fragment != null) fragment.startActivityForResult(i, FILE_BROWSE); else activity.startActivityForResult(i, FILE_BROWSE); - } catch (ActivityNotFoundException e) { - showBrowserDialog(); + } else { + showBrowser = true; } - } else { - showBrowserDialog(); + } catch (Exception e) { + Log.w(TAG, "Enable to start OPEN_INTENTS_FILE_BROWSE", e); + showBrowser = true; } + return showBrowser; } + /** + * Show Browser dialog to select file picker app + */ private void showBrowserDialog() { - BrowserDialog browserDialog = new BrowserDialog(activity); - browserDialog.show(); + try { + BrowserDialog browserDialog = new BrowserDialog(); + if (fragment != null && fragment.getFragmentManager() != null) + browserDialog.show(fragment.getFragmentManager(), "browserDialog"); + else if (activity.getFragmentManager() != null) + browserDialog.show(((FragmentActivity) activity).getSupportFragmentManager(), "browserDialog"); + } catch (Exception e) { + Log.e(TAG, "Can't open BrowserDialog", e); + } } /** diff --git a/app/src/main/res/layout/browser_install.xml b/app/src/main/res/layout/browser_install.xml index 8b7d2d306..21c95df98 100644 --- a/app/src/main/res/layout/browser_install.xml +++ b/app/src/main/res/layout/browser_install.xml @@ -17,36 +17,30 @@ You should have received a copy of the GNU General Public License along with KeePass DX. If not, see . --> - + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:text="@string/browser_intall_text" + android:layout_marginBottom="12dp" /> + android:layout_width="match_parent" + android:layout_height="match_parent" + android:gravity="center_horizontal" + android:orientation="vertical">