Move preferences to its own activity, leaving a "blank" openkeychain api one
This commit is contained in:
parent
2889454d32
commit
42a971f348
6 changed files with 150 additions and 135 deletions
|
@ -61,6 +61,13 @@
|
|||
android:value="com.zeapo.pwdstore.PasswordStore" />
|
||||
</activity>
|
||||
|
||||
<activity android:name=".autofill.AutofillPreferenceActivity">
|
||||
android:parentActivityName=".PasswordStore">
|
||||
|
||||
<meta-data android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value="com.zeapo.pwdstore.PasswordStore" />
|
||||
</activity>
|
||||
|
||||
<activity android:name="net.rdrei.android.dirchooser.DirectoryChooserActivity" />
|
||||
</application>
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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<String, ?> prefApps = prefs.getAll();
|
||||
ArrayList<ApplicationInfo> 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<ApplicationInfo> 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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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<String, ?> prefApps = prefs.getAll();
|
||||
ArrayList<ApplicationInfo> 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<ApplicationInfo> 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");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ import java.util.ArrayList;
|
|||
public class AutofillRecyclerAdapter extends RecyclerView.Adapter<AutofillRecyclerAdapter.ViewHolder> {
|
||||
private ArrayList<ApplicationInfo> 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<AutofillRecycl
|
|||
}
|
||||
}
|
||||
|
||||
public AutofillRecyclerAdapter(ArrayList<ApplicationInfo> apps, PackageManager pm, AutofillActivity activity) {
|
||||
public AutofillRecyclerAdapter(ArrayList<ApplicationInfo> apps, PackageManager pm, AutofillPreferenceActivity activity) {
|
||||
this.apps = apps;
|
||||
this.pm = pm;
|
||||
this.activity = activity;
|
||||
|
|
Loading…
Reference in a new issue