From 2889454d324c9d210cafc51b47b7645cdd8abb26 Mon Sep 17 00:00:00 2001 From: Matthew Wong Date: Mon, 10 Aug 2015 13:11:42 -0400 Subject: More tweaks of dialog dismissal behaviour --- .../java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java (limited to 'app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java') diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java new file mode 100644 index 00000000..6f212149 --- /dev/null +++ b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java @@ -0,0 +1,4 @@ +package com.zeapo.pwdstore.autofill; + +public class AutofillPreferenceActivity { +} -- cgit v1.2.3 From 42a971f348b8c512db4603f4ca0b31c436651225 Mon Sep 17 00:00:00 2001 From: Matthew Wong Date: Mon, 10 Aug 2015 13:28:15 -0400 Subject: Move preferences to its own activity, leaving a "blank" openkeychain api one --- app/src/main/AndroidManifest.xml | 7 ++ .../java/com/zeapo/pwdstore/UserPreference.java | 6 +- .../zeapo/pwdstore/autofill/AutofillActivity.java | 127 ------------------- .../zeapo/pwdstore/autofill/AutofillFragment.java | 4 +- .../autofill/AutofillPreferenceActivity.java | 137 ++++++++++++++++++++- .../pwdstore/autofill/AutofillRecyclerAdapter.java | 4 +- 6 files changed, 150 insertions(+), 135 deletions(-) (limited to 'app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java') diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3ddc04e8..a6ffa791 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -61,6 +61,13 @@ android:value="com.zeapo.pwdstore.PasswordStore" /> + + android:parentActivityName=".PasswordStore"> + + + + diff --git a/app/src/main/java/com/zeapo/pwdstore/UserPreference.java b/app/src/main/java/com/zeapo/pwdstore/UserPreference.java index e2a9e5a7..cb2d2881 100644 --- a/app/src/main/java/com/zeapo/pwdstore/UserPreference.java +++ b/app/src/main/java/com/zeapo/pwdstore/UserPreference.java @@ -17,7 +17,7 @@ import android.widget.Toast; import com.google.common.base.Function; import com.google.common.base.Joiner; import com.google.common.collect.Iterables; -import com.zeapo.pwdstore.autofill.AutofillActivity; +import com.zeapo.pwdstore.autofill.AutofillPreferenceActivity; import com.zeapo.pwdstore.crypto.PgpHandler; import com.zeapo.pwdstore.git.GitActivity; import com.zeapo.pwdstore.utils.PasswordRepository; @@ -187,9 +187,9 @@ public class UserPreference extends AppCompatActivity { findPreference("autofill_apps").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { @Override public boolean onPreferenceClick(Preference preference) { - Intent intent = new Intent(callingActivity, AutofillActivity.class); + Intent intent = new Intent(callingActivity, AutofillPreferenceActivity.class); startActivity(intent); - return false; + return true; } }); } diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillActivity.java b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillActivity.java index 2d538504..5a097d07 100644 --- a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillActivity.java +++ b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillActivity.java @@ -1,48 +1,22 @@ package com.zeapo.pwdstore.autofill; -import android.app.DialogFragment; import android.app.PendingIntent; -import android.content.Context; import android.content.Intent; import android.content.IntentSender; -import android.content.SharedPreferences; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.database.Cursor; -import android.database.MatrixCursor; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; -import android.support.v7.widget.LinearLayoutManager; -import android.support.v7.widget.RecyclerView; import android.util.Log; -import android.view.View; -import android.view.WindowManager; -import android.widget.ImageView; -import android.widget.SearchView; -import android.widget.SimpleCursorAdapter; -import android.widget.TextView; - -import com.zeapo.pwdstore.R; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; // blank activity started by service for calling startIntentSenderForResult public class AutofillActivity extends AppCompatActivity { public static final int REQUEST_CODE_DECRYPT_AND_VERIFY = 9913; - private RecyclerView recyclerView; - AutofillRecyclerAdapter recyclerAdapter; // let fragment have access - private RecyclerView.LayoutManager layoutManager; - @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Intent intent = getIntent(); Bundle extras = intent.getExtras(); - // if called by service just for startIntentSenderForResult if (extras != null) { try { PendingIntent pi = intent.getExtras().getParcelable("pending_intent"); @@ -54,108 +28,7 @@ public class AutofillActivity extends AppCompatActivity { } catch (IntentSender.SendIntentException e) { Log.e(AutofillService.Constants.TAG, "SendIntentException", e); } - return; - } - // otherwise if called from settings - setContentView(R.layout.autofill_recycler_view); - recyclerView = (RecyclerView) findViewById(R.id.autofill_recycler); - - layoutManager = new LinearLayoutManager(this); - recyclerView.setLayoutManager(layoutManager); - - // apps for which the user has custom settings should be in the recycler - final PackageManager pm = getPackageManager(); - SharedPreferences prefs - = getSharedPreferences("autofill", Context.MODE_PRIVATE); - Map prefApps = prefs.getAll(); - ArrayList apps = new ArrayList<>(); - for (String packageName : prefApps.keySet()) { - try { - apps.add(pm.getApplicationInfo(packageName, 0)); - } catch (PackageManager.NameNotFoundException e) { - // remove invalid entries (from uninstalled apps?) - SharedPreferences.Editor editor = prefs.edit(); - editor.remove(packageName).apply(); - } } - recyclerAdapter = new AutofillRecyclerAdapter(apps, pm, this); - recyclerView.setAdapter(recyclerAdapter); - - // show the search bar by default but don't open the keyboard - getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); - final SearchView searchView = (SearchView) findViewById(R.id.app_search); - searchView.clearFocus(); - - // create search suggestions of apps with icons & names - final SimpleCursorAdapter.ViewBinder viewBinder = new SimpleCursorAdapter.ViewBinder() { - @Override - public boolean setViewValue(View view, Cursor cursor, int columnIndex) { - if (view instanceof TextView) { - ((TextView) view).setText(cursor.getString(columnIndex)); - } else if (view instanceof ImageView) { - try { - ((ImageView) view).setImageDrawable(pm.getApplicationIcon(cursor.getString(columnIndex))); - } catch (PackageManager.NameNotFoundException e) { - e.printStackTrace(); - return false; - } - } - return true; - } - }; - - final List allApps = pm.getInstalledApplications(0); - searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { - @Override - public boolean onQueryTextSubmit(String query) { - return false; - } - - @Override - public boolean onQueryTextChange(String newText) { - // should be a better/faster way to do this? - MatrixCursor matrixCursor = new MatrixCursor(new String[]{"_id", "package", "label"}); - for (ApplicationInfo applicationInfo : allApps) { - // exclude apps that already have settings; the search is just for adding - if (applicationInfo.loadLabel(pm).toString().toLowerCase().contains(newText.toLowerCase()) - && !recyclerAdapter.contains(applicationInfo.packageName)) { - matrixCursor.addRow(new Object[]{0, applicationInfo.packageName, applicationInfo.loadLabel(pm)}); - } - } - SimpleCursorAdapter simpleCursorAdapter = new SimpleCursorAdapter(AutofillActivity.this - , R.layout.app_list_item, matrixCursor, new String[]{"package", "label"} - , new int[]{android.R.id.icon1, android.R.id.text1}, 0); - simpleCursorAdapter.setViewBinder(viewBinder); - searchView.setSuggestionsAdapter(simpleCursorAdapter); - return false; - } - }); - - searchView.setOnSuggestionListener(new SearchView.OnSuggestionListener() { - @Override - public boolean onSuggestionSelect(int position) { - return false; - } - - @Override - public boolean onSuggestionClick(int position) { - Cursor cursor = searchView.getSuggestionsAdapter().getCursor(); - String packageName = cursor.getString(1); - String appName = cursor.getString(2); - - // similar to what happens in ViewHolder.onClick but position -1 - DialogFragment df = new AutofillFragment(); - Bundle args = new Bundle(); - args.putString("packageName", packageName); - args.putString("appName", appName); - args.putInt("position", -1); - df.setArguments(args); - df.show(getFragmentManager(), "autofill_dialog"); - return false; - } - }); - - setTitle("Autofill Apps"); } @Override diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillFragment.java b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillFragment.java index c1d75acd..b85dec6a 100644 --- a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillFragment.java +++ b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillFragment.java @@ -25,9 +25,9 @@ public class AutofillFragment extends DialogFragment { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); - // this fragment is only created from the settings page (AutofillActivity) + // this fragment is only created from the settings page (AutofillPreferenceActivity) // need to interact with the recyclerAdapter which is a member of activity - final AutofillActivity callingActivity = (AutofillActivity) getActivity(); + final AutofillPreferenceActivity callingActivity = (AutofillPreferenceActivity) getActivity(); LayoutInflater inflater = callingActivity.getLayoutInflater(); final View view = inflater.inflate(R.layout.fragment_autofill, null); diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java index 6f212149..9dac9a07 100644 --- a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java +++ b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java @@ -1,4 +1,139 @@ package com.zeapo.pwdstore.autofill; -public class AutofillPreferenceActivity { +import android.app.DialogFragment; +import android.content.Context; +import android.content.SharedPreferences; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.database.Cursor; +import android.database.MatrixCursor; +import android.os.Bundle; +import android.os.PersistableBundle; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.View; +import android.view.WindowManager; +import android.widget.ImageView; +import android.widget.SearchView; +import android.widget.SimpleCursorAdapter; +import android.widget.TextView; + +import com.zeapo.pwdstore.R; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class AutofillPreferenceActivity extends AppCompatActivity { + + private RecyclerView recyclerView; + AutofillRecyclerAdapter recyclerAdapter; // let fragment have access + private RecyclerView.LayoutManager layoutManager; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // otherwise if called from settings + setContentView(R.layout.autofill_recycler_view); + recyclerView = (RecyclerView) findViewById(R.id.autofill_recycler); + + layoutManager = new LinearLayoutManager(this); + recyclerView.setLayoutManager(layoutManager); + + // apps for which the user has custom settings should be in the recycler + final PackageManager pm = getPackageManager(); + SharedPreferences prefs + = getSharedPreferences("autofill", Context.MODE_PRIVATE); + Map prefApps = prefs.getAll(); + ArrayList apps = new ArrayList<>(); + for (String packageName : prefApps.keySet()) { + try { + apps.add(pm.getApplicationInfo(packageName, 0)); + } catch (PackageManager.NameNotFoundException e) { + // remove invalid entries (from uninstalled apps?) + SharedPreferences.Editor editor = prefs.edit(); + editor.remove(packageName).apply(); + } + } + recyclerAdapter = new AutofillRecyclerAdapter(apps, pm, this); + recyclerView.setAdapter(recyclerAdapter); + + // show the search bar by default but don't open the keyboard + getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); + final SearchView searchView = (SearchView) findViewById(R.id.app_search); + searchView.clearFocus(); + + // create search suggestions of apps with icons & names + final SimpleCursorAdapter.ViewBinder viewBinder = new SimpleCursorAdapter.ViewBinder() { + @Override + public boolean setViewValue(View view, Cursor cursor, int columnIndex) { + if (view instanceof TextView) { + ((TextView) view).setText(cursor.getString(columnIndex)); + } else if (view instanceof ImageView) { + try { + ((ImageView) view).setImageDrawable(pm.getApplicationIcon(cursor.getString(columnIndex))); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + return false; + } + } + return true; + } + }; + + final List allApps = pm.getInstalledApplications(0); + searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { + @Override + public boolean onQueryTextSubmit(String query) { + return false; + } + + @Override + public boolean onQueryTextChange(String newText) { + // should be a better/faster way to do this? + MatrixCursor matrixCursor = new MatrixCursor(new String[]{"_id", "package", "label"}); + for (ApplicationInfo applicationInfo : allApps) { + // exclude apps that already have settings; the search is just for adding + if (applicationInfo.loadLabel(pm).toString().toLowerCase().contains(newText.toLowerCase()) + && !recyclerAdapter.contains(applicationInfo.packageName)) { + matrixCursor.addRow(new Object[]{0, applicationInfo.packageName, applicationInfo.loadLabel(pm)}); + } + } + SimpleCursorAdapter simpleCursorAdapter = new SimpleCursorAdapter(AutofillPreferenceActivity.this + , R.layout.app_list_item, matrixCursor, new String[]{"package", "label"} + , new int[]{android.R.id.icon1, android.R.id.text1}, 0); + simpleCursorAdapter.setViewBinder(viewBinder); + searchView.setSuggestionsAdapter(simpleCursorAdapter); + return false; + } + }); + + searchView.setOnSuggestionListener(new SearchView.OnSuggestionListener() { + @Override + public boolean onSuggestionSelect(int position) { + return false; + } + + @Override + public boolean onSuggestionClick(int position) { + Cursor cursor = searchView.getSuggestionsAdapter().getCursor(); + String packageName = cursor.getString(1); + String appName = cursor.getString(2); + + // similar to what happens in ViewHolder.onClick but position -1 + DialogFragment df = new AutofillFragment(); + Bundle args = new Bundle(); + args.putString("packageName", packageName); + args.putString("appName", appName); + args.putInt("position", -1); + df.setArguments(args); + df.show(getFragmentManager(), "autofill_dialog"); + return false; + } + }); + + setTitle("Autofill Apps"); + } } diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillRecyclerAdapter.java b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillRecyclerAdapter.java index eff94c51..b43f5d6e 100644 --- a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillRecyclerAdapter.java +++ b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillRecyclerAdapter.java @@ -20,7 +20,7 @@ import java.util.ArrayList; public class AutofillRecyclerAdapter extends RecyclerView.Adapter { private ArrayList apps; private PackageManager pm; - private AutofillActivity activity; + private AutofillPreferenceActivity activity; public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { public View view; @@ -50,7 +50,7 @@ public class AutofillRecyclerAdapter extends RecyclerView.Adapter apps, PackageManager pm, AutofillActivity activity) { + public AutofillRecyclerAdapter(ArrayList apps, PackageManager pm, AutofillPreferenceActivity activity) { this.apps = apps; this.pm = pm; this.activity = activity; -- cgit v1.2.3 From 7c41795ded9aff01c46cc798687e62736d2233e7 Mon Sep 17 00:00:00 2001 From: Matthew Wong Date: Mon, 10 Aug 2015 16:58:28 -0400 Subject: Open settings from password fill dialog --- .../zeapo/pwdstore/autofill/AutofillActivity.java | 5 ++- .../autofill/AutofillPreferenceActivity.java | 40 ++++++++++++++-------- .../pwdstore/autofill/AutofillRecyclerAdapter.java | 26 ++++++-------- .../zeapo/pwdstore/autofill/AutofillService.java | 8 +++-- app/src/main/res/layout/app_list_item.xml | 9 ++--- 5 files changed, 49 insertions(+), 39 deletions(-) (limited to 'app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java') diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillActivity.java b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillActivity.java index 5a097d07..d8e50ebd 100644 --- a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillActivity.java +++ b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillActivity.java @@ -14,12 +14,11 @@ public class AutofillActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - Intent intent = getIntent(); - Bundle extras = intent.getExtras(); + Bundle extras = getIntent().getExtras(); if (extras != null) { try { - PendingIntent pi = intent.getExtras().getParcelable("pending_intent"); + PendingIntent pi = extras.getParcelable("pending_intent"); if (pi == null) { return; } diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java index 9dac9a07..89d3474e 100644 --- a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java +++ b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java @@ -8,7 +8,6 @@ import android.content.pm.PackageManager; import android.database.Cursor; import android.database.MatrixCursor; import android.os.Bundle; -import android.os.PersistableBundle; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; @@ -22,6 +21,8 @@ import android.widget.TextView; import com.zeapo.pwdstore.R; import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; import java.util.List; import java.util.Map; @@ -57,6 +58,12 @@ public class AutofillPreferenceActivity extends AppCompatActivity { editor.remove(packageName).apply(); } } + Collections.sort(apps, new Comparator() { + @Override + public int compare(ApplicationInfo lhs, ApplicationInfo rhs) { + return lhs.loadLabel(pm).toString().compareTo(rhs.loadLabel(pm).toString()); + } + }); recyclerAdapter = new AutofillRecyclerAdapter(apps, pm, this); recyclerView.setAdapter(recyclerAdapter); @@ -95,9 +102,7 @@ public class AutofillPreferenceActivity extends AppCompatActivity { // should be a better/faster way to do this? MatrixCursor matrixCursor = new MatrixCursor(new String[]{"_id", "package", "label"}); for (ApplicationInfo applicationInfo : allApps) { - // exclude apps that already have settings; the search is just for adding - if (applicationInfo.loadLabel(pm).toString().toLowerCase().contains(newText.toLowerCase()) - && !recyclerAdapter.contains(applicationInfo.packageName)) { + if (applicationInfo.loadLabel(pm).toString().toLowerCase().contains(newText.toLowerCase())) { matrixCursor.addRow(new Object[]{0, applicationInfo.packageName, applicationInfo.loadLabel(pm)}); } } @@ -121,19 +126,26 @@ public class AutofillPreferenceActivity extends AppCompatActivity { Cursor cursor = searchView.getSuggestionsAdapter().getCursor(); String packageName = cursor.getString(1); String appName = cursor.getString(2); - - // similar to what happens in ViewHolder.onClick but position -1 - DialogFragment df = new AutofillFragment(); - Bundle args = new Bundle(); - args.putString("packageName", packageName); - args.putString("appName", appName); - args.putInt("position", -1); - df.setArguments(args); - df.show(getFragmentManager(), "autofill_dialog"); - return false; + showDialog(packageName, appName); + return true; } }); setTitle("Autofill Apps"); + + Bundle extras = getIntent().getExtras(); + if (extras != null) { + showDialog(extras.getString("packageName"), extras.getString("appName")); + } + } + + public void showDialog(String packageName, String appName) { + DialogFragment df = new AutofillFragment(); + Bundle args = new Bundle(); + args.putString("packageName", packageName); + args.putString("appName", appName); + args.putInt("position", recyclerAdapter.getPosition(packageName)); + df.setArguments(args); + df.show(getFragmentManager(), "autofill_dialog"); } } diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillRecyclerAdapter.java b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillRecyclerAdapter.java index b43f5d6e..26680152 100644 --- a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillRecyclerAdapter.java +++ b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillRecyclerAdapter.java @@ -40,13 +40,7 @@ public class AutofillRecyclerAdapter extends RecyclerView.Adapter + android:paddingRight="8dp" + android:gravity="center_vertical"> + android:layout_width="24dp" + android:layout_height="24dp"/> Date: Tue, 11 Aug 2015 18:32:16 -0400 Subject: Add 'automatically match by default' setting; respect it & per-app settings when creating autofill dialog --- .../zeapo/pwdstore/autofill/AutofillFragment.java | 9 +++++++-- .../autofill/AutofillPreferenceActivity.java | 4 ++++ .../pwdstore/autofill/AutofillRecyclerAdapter.java | 7 ++++++- .../com/zeapo/pwdstore/autofill/AutofillService.java | 20 ++++++++++++++++++-- app/src/main/res/xml/preference.xml | 5 +++++ 5 files changed, 40 insertions(+), 5 deletions(-) (limited to 'app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java') diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillFragment.java b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillFragment.java index 3e00edfb..ea4b0a2f 100644 --- a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillFragment.java +++ b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillFragment.java @@ -3,6 +3,7 @@ package com.zeapo.pwdstore.autofill; import android.app.Activity; import android.content.DialogInterface; import android.content.Intent; +import android.preference.PreferenceManager; import android.support.v7.app.AlertDialog; import android.app.Dialog; import android.app.DialogFragment; @@ -39,9 +40,14 @@ public class AutofillFragment extends DialogFragment { String appName = getArguments().getString("appName"); builder.setTitle(appName); + + // when an app is added for the first time, the radio button selection should reflect + // the autofill_default setting: hence, defValue + SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(callingActivity); + String defValue = settings.getBoolean("autofill_default", true) ? "first" : "never"; SharedPreferences prefs = getActivity().getApplicationContext().getSharedPreferences("autofill", Context.MODE_PRIVATE); - String preference = prefs.getString(packageName, "first"); + String preference = prefs.getString(packageName, defValue); switch (preference) { case "first": ((RadioButton) view.findViewById(R.id.first)).toggle(); @@ -57,7 +63,6 @@ public class AutofillFragment extends DialogFragment { View.OnClickListener matchPassword = new View.OnClickListener() { @Override public void onClick(View v) { - // TODO figure out UI for this Intent intent = new Intent(getActivity(), PasswordStore.class); intent.putExtra("matchWith", true); startActivityForResult(intent, MATCH_WITH); diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java index 89d3474e..10684f45 100644 --- a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java +++ b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java @@ -8,6 +8,7 @@ import android.content.pm.PackageManager; import android.database.Cursor; import android.database.MatrixCursor; import android.os.Bundle; +import android.preference.PreferenceManager; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; @@ -100,6 +101,7 @@ public class AutofillPreferenceActivity extends AppCompatActivity { @Override public boolean onQueryTextChange(String newText) { // should be a better/faster way to do this? + // TODO do this async probably. it lags. MatrixCursor matrixCursor = new MatrixCursor(new String[]{"_id", "package", "label"}); for (ApplicationInfo applicationInfo : allApps) { if (applicationInfo.loadLabel(pm).toString().toLowerCase().contains(newText.toLowerCase())) { @@ -147,5 +149,7 @@ public class AutofillPreferenceActivity extends AppCompatActivity { args.putInt("position", recyclerAdapter.getPosition(packageName)); df.setArguments(args); df.show(getFragmentManager(), "autofill_dialog"); + + // TODO if called from dialog 'Settings' button, should activity finish at OK? } } diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillRecyclerAdapter.java b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillRecyclerAdapter.java index 1b5e63b7..bd2835e5 100644 --- a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillRecyclerAdapter.java +++ b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillRecyclerAdapter.java @@ -4,6 +4,7 @@ import android.content.Context; import android.content.SharedPreferences; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; +import android.preference.PreferenceManager; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; @@ -59,9 +60,13 @@ public class AutofillRecyclerAdapter extends RecyclerView.Adapter(); + items.add(PasswordItem.newPassword(file.getName(), file)); + } if (items.isEmpty()) { return; } diff --git a/app/src/main/res/xml/preference.xml b/app/src/main/res/xml/preference.xml index 9a42bb3e..44e38916 100644 --- a/app/src/main/res/xml/preference.xml +++ b/app/src/main/res/xml/preference.xml @@ -76,6 +76,11 @@ android:key="autofill_apps" android:summary="Customize autofill settings for specific apps." android:title="Per-app settings"/> + -- cgit v1.2.3 From f4c0ee607e909caaacf52367901652ea89b16581 Mon Sep 17 00:00:00 2001 From: Matthew Wong Date: Tue, 11 Aug 2015 19:56:32 -0400 Subject: Multi-select deletion of apps in settings page --- .../autofill/AutofillPreferenceActivity.java | 2 - .../pwdstore/autofill/AutofillRecyclerAdapter.java | 92 +++++++++++++++++++++- .../main/res/drawable/autofill_row_background.xml | 5 ++ app/src/main/res/layout/autofill_row_layout.xml | 2 +- 4 files changed, 96 insertions(+), 5 deletions(-) create mode 100644 app/src/main/res/drawable/autofill_row_background.xml (limited to 'app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java') diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java index 10684f45..54f0ade4 100644 --- a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java +++ b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java @@ -8,7 +8,6 @@ import android.content.pm.PackageManager; import android.database.Cursor; import android.database.MatrixCursor; import android.os.Bundle; -import android.preference.PreferenceManager; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; @@ -149,7 +148,6 @@ public class AutofillPreferenceActivity extends AppCompatActivity { args.putInt("position", recyclerAdapter.getPosition(packageName)); df.setArguments(args); df.show(getFragmentManager(), "autofill_dialog"); - // TODO if called from dialog 'Settings' button, should activity finish at OK? } } diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillRecyclerAdapter.java b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillRecyclerAdapter.java index bd2835e5..14530879 100644 --- a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillRecyclerAdapter.java +++ b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillRecyclerAdapter.java @@ -5,8 +5,11 @@ import android.content.SharedPreferences; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.preference.PreferenceManager; +import android.support.v7.view.ActionMode; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; @@ -15,13 +18,19 @@ import android.widget.TextView; import com.zeapo.pwdstore.R; import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.Set; +import java.util.TreeSet; public class AutofillRecyclerAdapter extends RecyclerView.Adapter { private ArrayList apps; private PackageManager pm; private AutofillPreferenceActivity activity; + private final Set selectedItems; + private ActionMode actionMode; - public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { + public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener { public View view; public TextView name; public TextView secondary; @@ -35,11 +44,30 @@ public class AutofillRecyclerAdapter extends RecyclerView.Adapter(Collections.reverseOrder()); } @Override @@ -80,6 +109,8 @@ public class AutofillRecyclerAdapter extends RecyclerView.Adapter + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/autofill_row_layout.xml b/app/src/main/res/layout/autofill_row_layout.xml index 3f94a8ad..354f9181 100644 --- a/app/src/main/res/layout/autofill_row_layout.xml +++ b/app/src/main/res/layout/autofill_row_layout.xml @@ -3,7 +3,7 @@ android:orientation="vertical" android:layout_width="match_parent" android:layout_height="64dp" - android:background="@color/grey_white_1000"> + android:background="@drawable/autofill_row_background"> Date: Wed, 12 Aug 2015 07:02:19 -0400 Subject: Settings page dividers --- .../autofill/AutofillPreferenceActivity.java | 3 +- .../pwdstore/autofill/DividerItemDecoration.java | 105 +++++++++++++++++++++ 2 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/com/zeapo/pwdstore/autofill/DividerItemDecoration.java (limited to 'app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java') diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java index 54f0ade4..abf1f320 100644 --- a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java +++ b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java @@ -42,7 +42,8 @@ public class AutofillPreferenceActivity extends AppCompatActivity { layoutManager = new LinearLayoutManager(this); recyclerView.setLayoutManager(layoutManager); - + recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST)); + // apps for which the user has custom settings should be in the recycler final PackageManager pm = getPackageManager(); SharedPreferences prefs diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/DividerItemDecoration.java b/app/src/main/java/com/zeapo/pwdstore/autofill/DividerItemDecoration.java new file mode 100644 index 00000000..bd5ec9de --- /dev/null +++ b/app/src/main/java/com/zeapo/pwdstore/autofill/DividerItemDecoration.java @@ -0,0 +1,105 @@ +package com.zeapo.pwdstore.autofill; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.View; + +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +public class DividerItemDecoration extends RecyclerView.ItemDecoration { + + private static final int[] ATTRS = new int[]{ + android.R.attr.listDivider + }; + + public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL; + + public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL; + + private Drawable mDivider; + + private int mOrientation; + + public DividerItemDecoration(Context context, int orientation) { + final TypedArray a = context.obtainStyledAttributes(ATTRS); + mDivider = a.getDrawable(0); + a.recycle(); + setOrientation(orientation); + } + + public void setOrientation(int orientation) { + if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) { + throw new IllegalArgumentException("invalid orientation"); + } + mOrientation = orientation; + } + + @Override + public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) { + if (mOrientation == VERTICAL_LIST) { + drawVertical(c, parent); + } else { + drawHorizontal(c, parent); + } + } + + public void drawVertical(Canvas c, RecyclerView parent) { + final int left = parent.getPaddingLeft(); + final int right = parent.getWidth() - parent.getPaddingRight(); + + final int childCount = parent.getChildCount(); + for (int i = 0; i < childCount; i++) { + final View child = parent.getChildAt(i); + final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child + .getLayoutParams(); + final int top = child.getBottom() + params.bottomMargin; + final int bottom = top + mDivider.getIntrinsicHeight(); + mDivider.setBounds(left, top, right, bottom); + mDivider.draw(c); + } + } + + public void drawHorizontal(Canvas c, RecyclerView parent) { + final int top = parent.getPaddingTop(); + final int bottom = parent.getHeight() - parent.getPaddingBottom(); + + final int childCount = parent.getChildCount(); + for (int i = 0; i < childCount; i++) { + final View child = parent.getChildAt(i); + final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child + .getLayoutParams(); + final int left = child.getRight() + params.rightMargin; + final int right = left + mDivider.getIntrinsicHeight(); + mDivider.setBounds(left, top, right, bottom); + mDivider.draw(c); + } + } + + @Override + public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { + if (mOrientation == VERTICAL_LIST) { + outRect.set(0, 0, 0, mDivider.getIntrinsicHeight()); + } else { + outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0); + } + } +} + -- cgit v1.2.3 From ec07e1eea69a69e9579ddfb44fdbee3535bcf6ad Mon Sep 17 00:00:00 2001 From: Matthew Wong Date: Thu, 13 Aug 2015 15:18:47 -0400 Subject: Preference activity overhaul --- .../zeapo/pwdstore/autofill/AutofillFragment.java | 31 +++-- .../autofill/AutofillPreferenceActivity.java | 122 ++++++------------- .../pwdstore/autofill/AutofillRecyclerAdapter.java | 132 ++++----------------- .../zeapo/pwdstore/autofill/AutofillService.java | 3 +- app/src/main/res/layout/autofill_recycler_view.xml | 11 +- app/src/main/res/layout/autofill_row_layout.xml | 5 +- app/src/main/res/layout/fragment_autofill.xml | 15 ++- app/src/main/res/menu/autofill_preference.xml | 12 ++ app/src/main/res/xml/preference.xml | 2 +- 9 files changed, 108 insertions(+), 225 deletions(-) create mode 100644 app/src/main/res/menu/autofill_preference.xml (limited to 'app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java') diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillFragment.java b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillFragment.java index ea4b0a2f..c2a30ffe 100644 --- a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillFragment.java +++ b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillFragment.java @@ -3,7 +3,7 @@ package com.zeapo.pwdstore.autofill; import android.app.Activity; import android.content.DialogInterface; import android.content.Intent; -import android.preference.PreferenceManager; +import android.content.pm.PackageManager; import android.support.v7.app.AlertDialog; import android.app.Dialog; import android.app.DialogFragment; @@ -40,15 +40,20 @@ public class AutofillFragment extends DialogFragment { String appName = getArguments().getString("appName"); builder.setTitle(appName); + try { + // since we can't (easily?) pass the drawable as an argument + builder.setIcon(callingActivity.getPackageManager().getApplicationIcon(packageName)); + } catch (PackageManager.NameNotFoundException e) { + e.printStackTrace(); + } - // when an app is added for the first time, the radio button selection should reflect - // the autofill_default setting: hence, defValue - SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(callingActivity); - String defValue = settings.getBoolean("autofill_default", true) ? "first" : "never"; SharedPreferences prefs = getActivity().getApplicationContext().getSharedPreferences("autofill", Context.MODE_PRIVATE); - String preference = prefs.getString(packageName, defValue); + String preference = prefs.getString(packageName, ""); switch (preference) { + case "": + ((RadioButton) view.findViewById(R.id.use_default)).toggle(); + break; case "first": ((RadioButton) view.findViewById(R.id.first)).toggle(); break; @@ -77,6 +82,9 @@ public class AutofillFragment extends DialogFragment { public void onClick(DialogInterface dialog, int which) { RadioGroup radioGroup = (RadioGroup) view.findViewById(R.id.autofill_radiogroup); switch (radioGroup.getCheckedRadioButtonId()) { + case R.id.use_default: + editor.remove(packageName); + break; case R.id.first: editor.putString(packageName, "first"); break; @@ -90,10 +98,10 @@ public class AutofillFragment extends DialogFragment { } editor.apply(); int position = getArguments().getInt("position"); - if (position == -1) { - callingActivity.recyclerAdapter.add(packageName); - } else { - callingActivity.recyclerAdapter.notifyItemChanged(position); + callingActivity.recyclerAdapter.notifyItemChanged(position); + + if (getArguments().getBoolean("finish")) { + callingActivity.finish(); } } }); @@ -105,7 +113,8 @@ public class AutofillFragment extends DialogFragment { public void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode == Activity.RESULT_OK) { ((EditText) getDialog().findViewById(R.id.matched)).setText(data.getStringExtra("path")); + } else { + ((RadioButton) getDialog().findViewById(R.id.use_default)).toggle(); } - } } diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java index abf1f320..91131956 100644 --- a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java +++ b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java @@ -1,22 +1,17 @@ package com.zeapo.pwdstore.autofill; import android.app.DialogFragment; -import android.content.Context; -import android.content.SharedPreferences; -import android.content.pm.ApplicationInfo; +import android.content.Intent; import android.content.pm.PackageManager; -import android.database.Cursor; -import android.database.MatrixCursor; +import android.content.pm.ResolveInfo; import android.os.Bundle; +import android.support.v4.view.MenuItemCompat; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; -import android.view.View; -import android.view.WindowManager; -import android.widget.ImageView; -import android.widget.SearchView; -import android.widget.SimpleCursorAdapter; -import android.widget.TextView; +import android.support.v7.widget.SearchView; +import android.view.Menu; +import android.view.MenuItem; import com.zeapo.pwdstore.R; @@ -24,7 +19,6 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; -import java.util.Map; public class AutofillPreferenceActivity extends AppCompatActivity { @@ -43,102 +37,62 @@ public class AutofillPreferenceActivity extends AppCompatActivity { layoutManager = new LinearLayoutManager(this); recyclerView.setLayoutManager(layoutManager); recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST)); - - // apps for which the user has custom settings should be in the recycler + + Intent intent = new Intent(Intent.ACTION_MAIN); + intent.addCategory(Intent.CATEGORY_LAUNCHER); + List allApps = getPackageManager().queryIntentActivities(intent, 0); final PackageManager pm = getPackageManager(); - SharedPreferences prefs - = getSharedPreferences("autofill", Context.MODE_PRIVATE); - Map prefApps = prefs.getAll(); - ArrayList apps = new ArrayList<>(); - for (String packageName : prefApps.keySet()) { - try { - apps.add(pm.getApplicationInfo(packageName, 0)); - } catch (PackageManager.NameNotFoundException e) { - // remove invalid entries (from uninstalled apps?) - SharedPreferences.Editor editor = prefs.edit(); - editor.remove(packageName).apply(); - } - } - Collections.sort(apps, new Comparator() { + Collections.sort(allApps, new Comparator() { @Override - public int compare(ApplicationInfo lhs, ApplicationInfo rhs) { + public int compare(ResolveInfo lhs, ResolveInfo rhs) { return lhs.loadLabel(pm).toString().compareTo(rhs.loadLabel(pm).toString()); } }); - recyclerAdapter = new AutofillRecyclerAdapter(apps, pm, this); + recyclerAdapter = new AutofillRecyclerAdapter(new ArrayList<>(allApps), pm, this); recyclerView.setAdapter(recyclerAdapter); - // show the search bar by default but don't open the keyboard - getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); - final SearchView searchView = (SearchView) findViewById(R.id.app_search); - searchView.clearFocus(); + setTitle("Autofill Apps"); - // create search suggestions of apps with icons & names - final SimpleCursorAdapter.ViewBinder viewBinder = new SimpleCursorAdapter.ViewBinder() { - @Override - public boolean setViewValue(View view, Cursor cursor, int columnIndex) { - if (view instanceof TextView) { - ((TextView) view).setText(cursor.getString(columnIndex)); - } else if (view instanceof ImageView) { - try { - ((ImageView) view).setImageDrawable(pm.getApplicationIcon(cursor.getString(columnIndex))); - } catch (PackageManager.NameNotFoundException e) { - e.printStackTrace(); - return false; - } - } - return true; - } - }; + Bundle extras = getIntent().getExtras(); + if (extras != null) { + recyclerView.scrollToPosition(recyclerAdapter.getPosition(extras.getString("packageName"))); + showDialog(extras.getString("packageName"), extras.getString("appName")); + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.autofill_preference, menu); + MenuItem searchItem = menu.findItem(R.id.action_search); + SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem); - final List allApps = pm.getInstalledApplications(0); searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override - public boolean onQueryTextSubmit(String query) { - return false; + public boolean onQueryTextSubmit(String s) { + return true; } @Override - public boolean onQueryTextChange(String newText) { - // should be a better/faster way to do this? - // TODO do this async probably. it lags. - MatrixCursor matrixCursor = new MatrixCursor(new String[]{"_id", "package", "label"}); - for (ApplicationInfo applicationInfo : allApps) { - if (applicationInfo.loadLabel(pm).toString().toLowerCase().contains(newText.toLowerCase())) { - matrixCursor.addRow(new Object[]{0, applicationInfo.packageName, applicationInfo.loadLabel(pm)}); - } - } - SimpleCursorAdapter simpleCursorAdapter = new SimpleCursorAdapter(AutofillPreferenceActivity.this - , R.layout.app_list_item, matrixCursor, new String[]{"package", "label"} - , new int[]{android.R.id.icon1, android.R.id.text1}, 0); - simpleCursorAdapter.setViewBinder(viewBinder); - searchView.setSuggestionsAdapter(simpleCursorAdapter); - return false; + public boolean onQueryTextChange(String s) { + return true; } }); - searchView.setOnSuggestionListener(new SearchView.OnSuggestionListener() { + // When using the support library, the setOnActionExpandListener() method is + // static and accepts the MenuItem object as an argument + MenuItemCompat.setOnActionExpandListener(searchItem, new MenuItemCompat.OnActionExpandListener() { @Override - public boolean onSuggestionSelect(int position) { - return false; + public boolean onMenuItemActionCollapse(MenuItem item) { + return true; } @Override - public boolean onSuggestionClick(int position) { - Cursor cursor = searchView.getSuggestionsAdapter().getCursor(); - String packageName = cursor.getString(1); - String appName = cursor.getString(2); - showDialog(packageName, appName); + public boolean onMenuItemActionExpand(MenuItem item) { return true; } }); - - setTitle("Autofill Apps"); - - Bundle extras = getIntent().getExtras(); - if (extras != null) { - showDialog(extras.getString("packageName"), extras.getString("appName")); - } + return super.onCreateOptionsMenu(menu); } public void showDialog(String packageName, String appName) { diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillRecyclerAdapter.java b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillRecyclerAdapter.java index 14530879..7c735f18 100644 --- a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillRecyclerAdapter.java +++ b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillRecyclerAdapter.java @@ -2,14 +2,11 @@ package com.zeapo.pwdstore.autofill; import android.content.Context; import android.content.SharedPreferences; -import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; -import android.preference.PreferenceManager; +import android.content.pm.ResolveInfo; import android.support.v7.view.ActionMode; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; @@ -18,19 +15,14 @@ import android.widget.TextView; import com.zeapo.pwdstore.R; import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.Set; -import java.util.TreeSet; public class AutofillRecyclerAdapter extends RecyclerView.Adapter { - private ArrayList apps; + private ArrayList apps; private PackageManager pm; private AutofillPreferenceActivity activity; - private final Set selectedItems; private ActionMode actionMode; - public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, View.OnLongClickListener { + public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { public View view; public TextView name; public TextView secondary; @@ -44,38 +36,19 @@ public class AutofillRecyclerAdapter extends RecyclerView.Adapter apps, PackageManager pm, AutofillPreferenceActivity activity) { + public AutofillRecyclerAdapter(ArrayList apps, PackageManager pm, AutofillPreferenceActivity activity) { this.apps = apps; this.pm = pm; this.activity = activity; - this.selectedItems = new TreeSet<>(Collections.reverseOrder()); } @Override @@ -87,30 +60,33 @@ public class AutofillRecyclerAdapter extends RecyclerView.Adapter - - + android:layout_height="match_parent"> + android:id="@+id/secondary_text" + android:textColor="@color/grey_600"/> diff --git a/app/src/main/res/layout/fragment_autofill.xml b/app/src/main/res/layout/fragment_autofill.xml index 6ad44a0d..e5534f41 100644 --- a/app/src/main/res/layout/fragment_autofill.xml +++ b/app/src/main/res/layout/fragment_autofill.xml @@ -13,11 +13,18 @@ android:layout_height="wrap_content" android:id="@+id/autofill_radiogroup" > + @@ -29,7 +36,7 @@ android:id="@+id/match" android:layout_gravity="center_vertical" android:checked="false" - android:layout_marginTop="8dp"/> + /> + /> diff --git a/app/src/main/res/menu/autofill_preference.xml b/app/src/main/res/menu/autofill_preference.xml new file mode 100644 index 00000000..77ce95f4 --- /dev/null +++ b/app/src/main/res/menu/autofill_preference.xml @@ -0,0 +1,12 @@ + + + + \ No newline at end of file diff --git a/app/src/main/res/xml/preference.xml b/app/src/main/res/xml/preference.xml index 44e38916..e8ba80cc 100644 --- a/app/src/main/res/xml/preference.xml +++ b/app/src/main/res/xml/preference.xml @@ -79,7 +79,7 @@ -- cgit v1.2.3 From ac533d83aab29005f70c97ed939a6d6f2e13aa16 Mon Sep 17 00:00:00 2001 From: Matthew Wong Date: Thu, 13 Aug 2015 21:16:10 -0400 Subject: Preference activity up & back behaviour. Especially when opened with 'Settings' dialog button --- app/src/main/AndroidManifest.xml | 8 +++---- .../autofill/AutofillPreferenceActivity.java | 26 ++++++++++++++++++++-- .../zeapo/pwdstore/autofill/AutofillService.java | 2 +- 3 files changed, 29 insertions(+), 7 deletions(-) (limited to 'app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java') diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a6ffa791..ecd106cd 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -54,18 +54,18 @@ android:resource="@xml/autofill_config" /> - + + android:value="com.zeapo.pwdstore.PasswordStore" /> - + + android:value="com.zeapo.pwdstore.PasswordStore" /> diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java index 91131956..6f507fa5 100644 --- a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java +++ b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java @@ -5,6 +5,8 @@ import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.Bundle; +import android.support.v4.app.NavUtils; +import android.support.v4.app.TaskStackBuilder; import android.support.v4.view.MenuItemCompat; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.LinearLayoutManager; @@ -26,11 +28,12 @@ public class AutofillPreferenceActivity extends AppCompatActivity { AutofillRecyclerAdapter recyclerAdapter; // let fragment have access private RecyclerView.LayoutManager layoutManager; + private boolean recreate; + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - // otherwise if called from settings setContentView(R.layout.autofill_recycler_view); recyclerView = (RecyclerView) findViewById(R.id.autofill_recycler); @@ -53,8 +56,10 @@ public class AutofillPreferenceActivity extends AppCompatActivity { setTitle("Autofill Apps"); + recreate = false; Bundle extras = getIntent().getExtras(); if (extras != null) { + recreate = true; recyclerView.scrollToPosition(recyclerAdapter.getPosition(extras.getString("packageName"))); showDialog(extras.getString("packageName"), extras.getString("appName")); } @@ -94,6 +99,24 @@ public class AutofillPreferenceActivity extends AppCompatActivity { }); return super.onCreateOptionsMenu(menu); } + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + // in service, we CLEAR_TASK. then we set the recreate flag. + // something of a hack, but w/o CLEAR_TASK, behaviour was unpredictable + case android.R.id.home: + Intent upIntent = NavUtils.getParentActivityIntent(this); + if (recreate) { + TaskStackBuilder.create(this) + .addNextIntentWithParentStack(upIntent) + .startActivities(); + } else { + NavUtils.navigateUpTo(this, upIntent); + } + return true; + } + return super.onOptionsItemSelected(item); + } public void showDialog(String packageName, String appName) { DialogFragment df = new AutofillFragment(); @@ -103,6 +126,5 @@ public class AutofillPreferenceActivity extends AppCompatActivity { args.putInt("position", recyclerAdapter.getPosition(packageName)); df.setArguments(args); df.show(getFragmentManager(), "autofill_dialog"); - // TODO if called from dialog 'Settings' button, should activity finish at OK? } } diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillService.java b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillService.java index 1b8ff740..688e22fc 100644 --- a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillService.java +++ b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillService.java @@ -158,7 +158,7 @@ public class AutofillService extends AccessibilityService { public void onClick(DialogInterface dialog, int which) { // the user will have to return to the app themselves. Intent intent = new Intent(AutofillService.this, AutofillPreferenceActivity.class); - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); intent.putExtra("packageName", info.getPackageName()); intent.putExtra("appName", appName); startActivity(intent); -- cgit v1.2.3 From ca45e739dadbacfe76ccce3e2c79b308d292061a Mon Sep 17 00:00:00 2001 From: Matthew Wong Date: Fri, 14 Aug 2015 00:35:00 -0400 Subject: Async populate the app list --- .../autofill/AutofillPreferenceActivity.java | 64 +++++++++++++++------- .../pwdstore/autofill/AutofillRecyclerAdapter.java | 7 ++- app/src/main/res/layout/autofill_recycler_view.xml | 18 ++++-- 3 files changed, 62 insertions(+), 27 deletions(-) (limited to 'app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java') diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java index 6f507fa5..788442a0 100644 --- a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java +++ b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java @@ -4,6 +4,7 @@ import android.app.DialogFragment; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import android.os.AsyncTask; import android.os.Bundle; import android.support.v4.app.NavUtils; import android.support.v4.app.TaskStackBuilder; @@ -14,6 +15,7 @@ import android.support.v7.widget.RecyclerView; import android.support.v7.widget.SearchView; import android.view.Menu; import android.view.MenuItem; +import android.view.View; import com.zeapo.pwdstore.R; @@ -28,6 +30,8 @@ public class AutofillPreferenceActivity extends AppCompatActivity { AutofillRecyclerAdapter recyclerAdapter; // let fragment have access private RecyclerView.LayoutManager layoutManager; + private PackageManager pm; + private boolean recreate; @Override @@ -41,27 +45,47 @@ public class AutofillPreferenceActivity extends AppCompatActivity { recyclerView.setLayoutManager(layoutManager); recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST)); - Intent intent = new Intent(Intent.ACTION_MAIN); - intent.addCategory(Intent.CATEGORY_LAUNCHER); - List allApps = getPackageManager().queryIntentActivities(intent, 0); - final PackageManager pm = getPackageManager(); - Collections.sort(allApps, new Comparator() { - @Override - public int compare(ResolveInfo lhs, ResolveInfo rhs) { - return lhs.loadLabel(pm).toString().compareTo(rhs.loadLabel(pm).toString()); - } - }); - recyclerAdapter = new AutofillRecyclerAdapter(new ArrayList<>(allApps), pm, this); - recyclerView.setAdapter(recyclerAdapter); + pm = getPackageManager(); + + new populateTask().execute(); setTitle("Autofill Apps"); + } + + private class populateTask extends AsyncTask> { + @Override + protected void onPreExecute() { + findViewById(R.id.progress_bar).setVisibility(View.VISIBLE); + } - recreate = false; - Bundle extras = getIntent().getExtras(); - if (extras != null) { - recreate = true; - recyclerView.scrollToPosition(recyclerAdapter.getPosition(extras.getString("packageName"))); - showDialog(extras.getString("packageName"), extras.getString("appName")); + @Override + protected List doInBackground(Void... params) { + Intent intent = new Intent(Intent.ACTION_MAIN); + intent.addCategory(Intent.CATEGORY_LAUNCHER); + List allApps = pm.queryIntentActivities(intent, 0); + Collections.sort(allApps, new Comparator() { + @Override + public int compare(ResolveInfo lhs, ResolveInfo rhs) { + return lhs.loadLabel(pm).toString().compareTo(rhs.loadLabel(pm).toString()); + } + }); + return allApps; + } + + @Override + protected void onPostExecute(List allApps) { + findViewById(R.id.progress_bar).setVisibility(View.GONE); + + recyclerAdapter = new AutofillRecyclerAdapter(new ArrayList<>(allApps), pm, AutofillPreferenceActivity.this); + recyclerView.setAdapter(recyclerAdapter); + + recreate = false; + Bundle extras = getIntent().getExtras(); + if (extras != null) { + recreate = true; + recyclerView.scrollToPosition(recyclerAdapter.getPosition(extras.getString("packageName"))); + showDialog(extras.getString("packageName"), extras.getString("appName")); + } } } @@ -75,11 +99,12 @@ public class AutofillPreferenceActivity extends AppCompatActivity { searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { @Override public boolean onQueryTextSubmit(String s) { - return true; + return false; } @Override public boolean onQueryTextChange(String s) { + recyclerAdapter.filter(s); return true; } }); @@ -99,6 +124,7 @@ public class AutofillPreferenceActivity extends AppCompatActivity { }); return super.onCreateOptionsMenu(menu); } + @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillRecyclerAdapter.java b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillRecyclerAdapter.java index 7c735f18..485ef288 100644 --- a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillRecyclerAdapter.java +++ b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillRecyclerAdapter.java @@ -4,7 +4,6 @@ import android.content.Context; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; -import android.support.v7.view.ActionMode; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; @@ -20,7 +19,6 @@ public class AutofillRecyclerAdapter extends RecyclerView.Adapter apps; private PackageManager pm; private AutofillPreferenceActivity activity; - private ActionMode actionMode; public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { public View view; @@ -61,7 +59,7 @@ public class AutofillRecyclerAdapter extends RecyclerView.Adapter - + - \ No newline at end of file + + + \ No newline at end of file -- cgit v1.2.3 From b260a19be7172ad34487669a02c3002bc234b3b2 Mon Sep 17 00:00:00 2001 From: Matthew Wong Date: Fri, 14 Aug 2015 01:43:40 -0400 Subject: App filtering --- .../autofill/AutofillPreferenceActivity.java | 36 +++++-------------- .../pwdstore/autofill/AutofillRecyclerAdapter.java | 42 +++++++++++++++++++--- 2 files changed, 46 insertions(+), 32 deletions(-) (limited to 'app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java') diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java index 788442a0..1170d7b7 100644 --- a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java +++ b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java @@ -19,9 +19,6 @@ import android.view.View; import com.zeapo.pwdstore.R; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Comparator; import java.util.List; public class AutofillPreferenceActivity extends AppCompatActivity { @@ -52,31 +49,25 @@ public class AutofillPreferenceActivity extends AppCompatActivity { setTitle("Autofill Apps"); } - private class populateTask extends AsyncTask> { + private class populateTask extends AsyncTask { @Override protected void onPreExecute() { findViewById(R.id.progress_bar).setVisibility(View.VISIBLE); } @Override - protected List doInBackground(Void... params) { + protected Void doInBackground(Void... params) { Intent intent = new Intent(Intent.ACTION_MAIN); intent.addCategory(Intent.CATEGORY_LAUNCHER); List allApps = pm.queryIntentActivities(intent, 0); - Collections.sort(allApps, new Comparator() { - @Override - public int compare(ResolveInfo lhs, ResolveInfo rhs) { - return lhs.loadLabel(pm).toString().compareTo(rhs.loadLabel(pm).toString()); - } - }); - return allApps; + recyclerAdapter = new AutofillRecyclerAdapter(allApps, pm, AutofillPreferenceActivity.this); + return null; } @Override - protected void onPostExecute(List allApps) { + protected void onPostExecute(Void aVoid) { findViewById(R.id.progress_bar).setVisibility(View.GONE); - recyclerAdapter = new AutofillRecyclerAdapter(new ArrayList<>(allApps), pm, AutofillPreferenceActivity.this); recyclerView.setAdapter(recyclerAdapter); recreate = false; @@ -104,24 +95,13 @@ public class AutofillPreferenceActivity extends AppCompatActivity { @Override public boolean onQueryTextChange(String s) { - recyclerAdapter.filter(s); + if (recyclerAdapter != null) { + recyclerAdapter.filter(s); + } return true; } }); - // When using the support library, the setOnActionExpandListener() method is - // static and accepts the MenuItem object as an argument - MenuItemCompat.setOnActionExpandListener(searchItem, new MenuItemCompat.OnActionExpandListener() { - @Override - public boolean onMenuItemActionCollapse(MenuItem item) { - return true; - } - - @Override - public boolean onMenuItemActionExpand(MenuItem item) { - return true; - } - }); return super.onCreateOptionsMenu(menu); } diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillRecyclerAdapter.java b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillRecyclerAdapter.java index 485ef288..2162b53d 100644 --- a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillRecyclerAdapter.java +++ b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillRecyclerAdapter.java @@ -4,7 +4,9 @@ import android.content.Context; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import android.support.v7.util.SortedList; import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.util.SortedListAdapterCallback; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -14,9 +16,11 @@ import android.widget.TextView; import com.zeapo.pwdstore.R; import java.util.ArrayList; +import java.util.List; public class AutofillRecyclerAdapter extends RecyclerView.Adapter { - private ArrayList apps; + private SortedList apps; + private ArrayList allApps; private PackageManager pm; private AutofillPreferenceActivity activity; @@ -43,8 +47,26 @@ public class AutofillRecyclerAdapter extends RecyclerView.Adapter apps, PackageManager pm, AutofillPreferenceActivity activity) { - this.apps = apps; + public AutofillRecyclerAdapter(List allApps, final PackageManager pm, AutofillPreferenceActivity activity) { + SortedList.Callback callback = new SortedListAdapterCallback(this) { + @Override + public int compare(ResolveInfo o1, ResolveInfo o2) { + return o1.loadLabel(pm).toString().compareTo(o2.loadLabel(pm).toString()); + } + + @Override + public boolean areContentsTheSame(ResolveInfo oldItem, ResolveInfo newItem) { + return oldItem.loadLabel(pm).toString().equals(newItem.loadLabel(pm).toString()); + } + + @Override + public boolean areItemsTheSame(ResolveInfo item1, ResolveInfo item2) { + return item1.loadLabel(pm).toString().equals(item2.loadLabel(pm).toString()); + } + }; + this.apps = new SortedList<>(ResolveInfo.class, callback); + this.apps.addAll(allApps); + this.allApps = new ArrayList<>(allApps); this.pm = pm; this.activity = activity; } @@ -102,6 +124,18 @@ public class AutofillRecyclerAdapter extends RecyclerView.Adapter Date: Fri, 14 Aug 2015 13:31:23 -0400 Subject: Load icons & labels async beforehand as well --- .../pwdstore/autofill/AutofillPreferenceActivity.java | 12 +++++++++++- .../zeapo/pwdstore/autofill/AutofillRecyclerAdapter.java | 15 +++++++++++---- 2 files changed, 22 insertions(+), 5 deletions(-) (limited to 'app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java') diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java index 1170d7b7..16867bcd 100644 --- a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java +++ b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillPreferenceActivity.java @@ -4,6 +4,7 @@ import android.app.DialogFragment; import android.content.Intent; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import android.graphics.drawable.Drawable; import android.os.AsyncTask; import android.os.Bundle; import android.support.v4.app.NavUtils; @@ -13,12 +14,14 @@ import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.SearchView; +import android.util.Pair; import android.view.Menu; import android.view.MenuItem; import android.view.View; import com.zeapo.pwdstore.R; +import java.util.HashMap; import java.util.List; public class AutofillPreferenceActivity extends AppCompatActivity { @@ -60,7 +63,14 @@ public class AutofillPreferenceActivity extends AppCompatActivity { Intent intent = new Intent(Intent.ACTION_MAIN); intent.addCategory(Intent.CATEGORY_LAUNCHER); List allApps = pm.queryIntentActivities(intent, 0); - recyclerAdapter = new AutofillRecyclerAdapter(allApps, pm, AutofillPreferenceActivity.this); + + HashMap> iconMap = new HashMap<>(allApps.size()); + for (ResolveInfo app : allApps) { + iconMap.put(app.activityInfo.packageName + , Pair.create(app.loadIcon(pm), app.loadLabel(pm).toString())); + } + + recyclerAdapter = new AutofillRecyclerAdapter(allApps, iconMap, pm, AutofillPreferenceActivity.this); return null; } diff --git a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillRecyclerAdapter.java b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillRecyclerAdapter.java index 2162b53d..01916650 100644 --- a/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillRecyclerAdapter.java +++ b/app/src/main/java/com/zeapo/pwdstore/autofill/AutofillRecyclerAdapter.java @@ -4,9 +4,11 @@ import android.content.Context; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; +import android.graphics.drawable.Drawable; import android.support.v7.util.SortedList; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.util.SortedListAdapterCallback; +import android.util.Pair; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -16,11 +18,13 @@ import android.widget.TextView; import com.zeapo.pwdstore.R; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; public class AutofillRecyclerAdapter extends RecyclerView.Adapter { private SortedList apps; private ArrayList allApps; + private HashMap> iconMap; private PackageManager pm; private AutofillPreferenceActivity activity; @@ -47,11 +51,12 @@ public class AutofillRecyclerAdapter extends RecyclerView.Adapter allApps, final PackageManager pm, AutofillPreferenceActivity activity) { + public AutofillRecyclerAdapter(List allApps, HashMap> iconMap + , final PackageManager pm, AutofillPreferenceActivity activity) { SortedList.Callback callback = new SortedListAdapterCallback(this) { @Override public int compare(ResolveInfo o1, ResolveInfo o2) { - return o1.loadLabel(pm).toString().compareTo(o2.loadLabel(pm).toString()); + return o1.loadLabel(pm).toString().toLowerCase().compareTo(o2.loadLabel(pm).toString().toLowerCase()); } @Override @@ -67,6 +72,7 @@ public class AutofillRecyclerAdapter extends RecyclerView.Adapter(ResolveInfo.class, callback); this.apps.addAll(allApps); this.allApps = new ArrayList<>(allApps); + this.iconMap = new HashMap<>(iconMap); this.pm = pm; this.activity = activity; } @@ -81,10 +87,11 @@ public class AutofillRecyclerAdapter extends RecyclerView.Adapter