Muestra cualquiera de las keys o crea si no existen al seleccionar de Openkeychain

Estaba jugando con K9 y Openkeychain, y noté que cuando selecciono la key de la configuration de cryptography de K9, me dan 3 opciones (es decir, si solo tengo 1 key maestra): elija ninguna, elija la key maestra y elija crear una.

¿Qué pasa si quiero aplicar openkeychain y le doy al usuario la opción de seleccionar solo la key maestra, crear una si no existe ninguna y desactivarla por completo? Como podría hacerlo

Aunque el código se puede encontrar en el repository git de Openkeychain ( https://github.com/open-keychain/open-keychain ), estoy cargando el código para la class de fragment y la class de adaptador.

package org.sufficientlysecure.keychain.remote.ui; import android.accounts.AccountManager; import android.app.Activity; import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.support.v4.app.LoaderManager; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader; import android.support.v7.widget.LinearLayoutManager; import android.widget.Toast; import org.openintents.openpgp.util.OpenPgpApi; import org.openintents.openpgp.util.OpenPgpUtils; import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.pgp.KeyRing; import org.sufficientlysecure.keychain.provider.ApiDataAccessObject; import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainContract.KeyRings; import org.sufficientlysecure.keychain.remote.ui.adapter.SelectSignKeyAdapter; import org.sufficientlysecure.keychain.ui.CreateKeyActivity; import org.sufficientlysecure.keychain.ui.util.adapter.CursorAdapter; import org.sufficientlysecure.keychain.ui.base.RecyclerFragment; import org.sufficientlysecure.keychain.util.Log; public class SelectSignKeyIdListFragment extends RecyclerFragment<SelectSignKeyAdapter> implements SelectSignKeyAdapter.SelectSignKeyListener, LoaderManager.LoaderCallbacks<Cursor> { private static final String TAG=SelectSignKeyIdListFragment.class.getSimpleName(); private static final String ARG_DATA_URI = "uri"; private static final String ARG_PREF_UID = "pref_uid"; public static final String ARG_DATA = "data"; private Uri mDataUri; private Intent mResult; private String mPrefUid; private ApiDataAccessObject mApiDao; /** * Creates new instance of this fragment */ public static SelectSignKeyIdListFragment newInstance(Uri dataUri, Intent data, String prefernetworkingUserId) { SelectSignKeyIdListFragment frag = new SelectSignKeyIdListFragment(); Bundle args = new Bundle(); args.putParcelable(ARG_DATA_URI, dataUri); args.putParcelable(ARG_DATA, data); args.putString(ARG_PREF_UID, prefernetworkingUserId); frag.setArguments(args); return frag; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mApiDao = new ApiDataAccessObject(getActivity()); } /** * Define Adapter and Loader on create of Activity */ @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); mResult = getArguments().getParcelable(ARG_DATA); mPrefUid = getArguments().getString(ARG_PREF_UID); mDataUri = getArguments().getParcelable(ARG_DATA_URI); // ps : begin Log.e(TAG,"Test ... getDefaultAccountEmail :"+getDefaultAccountEmail() +" mDataUri :"+mDataUri); //ps : end // Give some text to display if there is no data. In a real // application this would come from a resource. setEmptyText(getString(R.string.list_empty)); SelectSignKeyAdapter adapter = new SelectSignKeyAdapter(getContext(), null); adapter.setListener(this); setAdapter(adapter); setLayoutManager(new LinearLayoutManager(getContext())); // Start out with a progress indicator. hideList(false); // Prepare the loader. Either re-connect with an existing one, // or start a new one. getLoaderManager().initLoader(0, null, this); } @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { Uri baseUri = KeyRings.buildUnifiedKeyRingsUri(); // These are the rows that we will retrieve. String[] projection = new String[]{ KeyRings._ID, KeyRings.MASTER_KEY_ID, KeyRings.USER_ID, KeyRings.IS_EXPIRED, KeyRings.IS_REVOKED, KeyRings.HAS_ENCRYPT, KeyRings.VERIFIED, KeyRings.HAS_ANY_SECRET, KeyRings.HAS_DUPLICATE_USER_ID, KeyRings.CREATION, KeyRings.NAME, KeyRings.EMAIL, KeyRings.COMMENT }; String selection = KeyRings.HAS_ANY_SECRET + " != 0"; String orderBy = KeyRings.USER_ID + " ASC"; // Now create and return a CursorLoader that will take care of // creating a Cursor for the data being displayed. return new CursorLoader(getActivity(), baseUri, projection, selection, null, orderBy); } private String getDefaultAccountEmail() { String email = null; try{ android.accounts.Account[] accounts = AccountManager.get(getActivity()).getAccounts(); for (android.accounts.Account account : accounts) { if (account.type.equals("com.org.prive")) { email = account.name; } else if (Constants.DEBUG && account.type.equals("org.sufficientlysecure.keychain.debug.account")) { email = account.name; } } return email; } catch (Exception ex){ Toast.makeText(this.getActivity(), "Please add an account to your device!", Toast.LENGTH_SHORT).show(); return email; } } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { // Swap the new cursor in. (The framework will take care of closing the // old cursor once we return.) getAdapter().swapCursor(CursorAdapter.KeyCursor.wrap(data)); Toast.makeText(getContext(),String.valueOf(getRecyclerView().getAdapter()),Toast.LENGTH_LONG).show(); // The list should now be shown. if (isResumed()) { showList(true); } else { showList(false); } } @Override public void onLoaderReset(Loader<Cursor> loader) { // This is called when the last Cursor provided to onLoadFinished() // above is about to be closed. We need to make sure we are no // longer using it. getAdapter().swapCursor(null); } @Override public void onDestroy() { getAdapter().setListener(null); super.onDestroy(); } @Override public void onCreateKeyDummyClicked() { OpenPgpUtils.UserId userIdSplit = KeyRing.splitUserId(mPrefUid); Intent intent = new Intent(getActivity(), CreateKeyActivity.class); intent.putExtra(CreateKeyActivity.EXTRA_NAME, userIdSplit.name); intent.putExtra(CreateKeyActivity.EXTRA_EMAIL, userIdSplit.email); getActivity().startActivityForResult(intent, SelectSignKeyIdActivity.REQUEST_CODE_CREATE_KEY); } @Override public void onSelectKeyItemClicked(long masterKeyId) { Uri allowedKeysUri = mDataUri.buildUpon() .appendPath(KeychainContract.PATH_ALLOWED_KEYS) .build(); mApiDao.addAllowedKeyIdForApp(allowedKeysUri, masterKeyId); mResult.putExtra(OpenPgpApi.EXTRA_SIGN_KEY_ID, masterKeyId); Log.d(Constants.TAG, "allowedKeyId: " + masterKeyId); Log.d(Constants.TAG, "allowedKeysUri: " + allowedKeysUri); getActivity().setResult(Activity.RESULT_OK, mResult); getActivity().finish(); } } 

La class de adaptador:

 package org.sufficientlysecure.keychain.remote.ui.adapter; import android.content.Context; import android.database.Cursor; import android.support.v4.content.ContextCompat; import android.support.v7.widget.RecyclerView; import android.text.format.DateUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import org.openintents.openpgp.util.OpenPgpUtils; import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.ui.adapter.KeyCursorAdapter; import org.sufficientlysecure.keychain.ui.util.FormattingUtils; import org.sufficientlysecure.keychain.ui.util.Highlighter; import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils; import org.sufficientlysecure.keychain.ui.util.adapter.CursorAdapter; public class SelectSignKeyAdapter extends KeyCursorAdapter<CursorAdapter.KeyCursor, RecyclerView.ViewHolder> { private static final int VIEW_TYPE_KEY = 0; private static final int VIEW_TYPE_DUMMY = 1; private SelectSignKeyListener mListener; public SelectSignKeyAdapter(Context context, Cursor cursor) { super(context, KeyCursor.wrap(cursor)); } public void setListener(SelectSignKeyListener listener) { mListener = listener; } @Override public int getItemCount() { return super.getItemCount() + 1; // received items + 1 dummy key } @Override public long getItemId(int pos) { if (pos < super.getItemCount()) { return super.getItemId(pos); } else { return RecyclerView.NO_ID; } } @Override public int getItemViewType(int position) { return position == super.getItemCount() ? VIEW_TYPE_DUMMY : VIEW_TYPE_KEY; } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { switch (viewType) { case VIEW_TYPE_KEY: return new SignKeyItemHolder(LayoutInflater.from(parent.getContext()) .inflate(R.layout.select_sign_key_item, parent, false)); case VIEW_TYPE_DUMMY: return new DummyViewHolder(LayoutInflater.from(parent.getContext()) .inflate(R.layout.select_dummy_key_item, parent, false)); default: return null; } } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { if (holder.getItemViewType() == VIEW_TYPE_KEY) { super.onBindViewHolder(holder, position); } } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, KeyCursor cursor, String query) { ((SignKeyItemHolder) holder).bind(cursor, query); } private class DummyViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { public DummyViewHolder(View itemView) { super(itemView); itemView.setClickable(true); itemView.setOnClickListener(this); } @Override public void onClick(View v) { if (mListener != null) { mListener.onCreateKeyDummyClicked(); } } } private class SignKeyItemHolder extends RecyclerView.ViewHolder implements View.OnClickListener { private TextView mUserIdText; private TextView mUserIdRestText; private TextView mCreationText; private ImageView mStatusIcon; public SignKeyItemHolder(View itemView) { super(itemView); itemView.setClickable(true); itemView.setOnClickListener(this); mUserIdText = (TextView) itemView.findViewById(R.id.select_key_item_name); mUserIdRestText = (TextView) itemView.findViewById(R.id.select_key_item_email); mCreationText = (TextView) itemView.findViewById(R.id.select_key_item_creation); mStatusIcon = (ImageView) itemView.findViewById(R.id.select_key_item_status_icon); } public void bind(KeyCursor cursor, String query) { Highlighter highlighter = new Highlighter(itemView.getContext(), query); Context context = itemView.getContext(); { // set name and stuff, common to both key types String name = cursor.getName(); String email = cursor.getEmail(); if (name != null) { mUserIdText.setText(highlighter.highlight(name)); } else { mUserIdText.setText(R.string.user_id_no_name); } if (email != null) { mUserIdRestText.setText(highlighter.highlight(email)); mUserIdRestText.setVisibility(View.VISIBLE); } else { mUserIdRestText.setVisibility(View.GONE); } } { // set edit button and status, specific by key type. Note: order is important! int textColor; if (cursor.isRevoked()) { KeyFormattingUtils.setStatusImage( context, mStatusIcon, null, KeyFormattingUtils.State.REVOKED, R.color.key_flag_gray ); itemView.setEnabled(false); mStatusIcon.setVisibility(View.VISIBLE); textColor = ContextCompat.getColor(context, R.color.key_flag_gray); } else if (cursor.isExpinetworking()) { KeyFormattingUtils.setStatusImage( context, mStatusIcon, null, KeyFormattingUtils.State.EXPIRED, R.color.key_flag_gray ); itemView.setEnabled(false); mStatusIcon.setVisibility(View.VISIBLE); textColor = ContextCompat.getColor(context, R.color.key_flag_gray); } else { itemView.setEnabled(true); mStatusIcon.setVisibility(View.GONE); textColor = FormattingUtils.getColorFromAttr(context, R.attr.colorText); } mUserIdText.setTextColor(textColor); mUserIdRestText.setTextColor(textColor); if (cursor.hasDuplicate()) { String dateTime = DateUtils.formatDateTime(context, cursor.getCreationTime(), DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_YEAR | DateUtils.FORMAT_ABBREV_MONTH); mCreationText.setText(context.getString(R.string.label_key_created, dateTime)); mCreationText.setTextColor(textColor); mCreationText.setVisibility(View.VISIBLE); } else { mCreationText.setVisibility(View.GONE); } } } @Override public void onClick(View v) { if (mListener != null) { mListener.onSelectKeyItemClicked(getItemId()); } } } public interface SelectSignKeyListener { void onCreateKeyDummyClicked(); void onSelectKeyItemClicked(long masterKeyId); } }