private void shareKey(Uri dataUri, boolean fingerprintOnly) {
    String content;
    if (fingerprintOnly) {
      byte[] fingerprintBlob = ProviderHelper.getFingerprint(this, dataUri);
      String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob, false);

      content = Constants.FINGERPRINT_SCHEME + ":" + fingerprint;
    } else {
      // get public keyring as ascii armored string
      long masterKeyId = ProviderHelper.getMasterKeyId(this, dataUri);
      ArrayList<String> keyringArmored =
          ProviderHelper.getKeyRingsAsArmoredString(this, dataUri, new long[] {masterKeyId});

      content = keyringArmored.get(0);

      // Android will fail with android.os.TransactionTooLargeException if key is too big
      // see http://www.lonestarprod.com/?p=34
      if (content.length() >= 86389) {
        Toast.makeText(getApplicationContext(), R.string.key_too_big_for_sharing, Toast.LENGTH_LONG)
            .show();
        return;
      }
    }

    // let user choose application
    Intent sendIntent = new Intent(Intent.ACTION_SEND);
    sendIntent.putExtra(Intent.EXTRA_TEXT, content);
    sendIntent.setType("text/plain");
    startActivity(
        Intent.createChooser(sendIntent, getResources().getText(R.string.action_share_key_with)));
  }
  public void drawPublicKey() {
    PGPPublicKeyRing pubring = ProviderHelper.getPGPPublicKeyRingByMasterKeyId(this, mPubKeyId);

    if (pubring != null) {
      PGPPublicKey key = PgpKeyHelper.getMasterKey(pubring);
      String masterKeyIdHex = PgpKeyHelper.convertKeyIdToHex(mPubKeyId);

      // get relevant UI elements
      TextView keyIdHex = (TextView) findViewById(R.id.public_key_master_key_hex);
      TextView keyUserId = (TextView) findViewById(R.id.public_key_user_id);
      TextView keyUserIdRest = (TextView) findViewById(R.id.public_key_user_id_rest);

      if (key != null) {
        String userId = PgpKeyHelper.getMainUserIdSafe(this, key);

        String[] userIdSplit = PgpKeyHelper.splitUserId(userId);
        String userName, userEmail;

        if (userIdSplit[0] != null) {
          userName = userIdSplit[0];
        } else {
          userName = getResources().getString(R.string.user_id_no_name);
        }

        if (userIdSplit[1] != null) {
          userEmail = userIdSplit[1];
        } else {
          userEmail = getResources().getString(R.string.error_user_id_no_email);
        }

        keyIdHex.setText(masterKeyIdHex);

        keyUserId.setText(userName);
        keyUserIdRest.setText(userEmail);
        keyUserId.setVisibility(View.VISIBLE);
        keyUserIdRest.setVisibility(View.VISIBLE);
      } else {
        Log.e(Constants.TAG, "this shouldn't happen. key == 0!");
        finish();
        return;
      }
    } else {
      Log.e(Constants.TAG, "this shouldn't happen. pubring == 0!");
      finish();
      return;
    }
  }
  private void updateFromKeyserver(Uri dataUri, ProviderHelper providerHelper)
      throws ProviderHelper.NotFoundException {
    byte[] blob =
        (byte[])
            providerHelper.getGenericData(
                KeychainContract.KeyRings.buildUnifiedKeyRingUri(dataUri),
                KeychainContract.Keys.FINGERPRINT,
                ProviderHelper.FIELD_TYPE_BLOB);
    String fingerprint = PgpKeyHelper.convertFingerprintToHex(blob);

    Intent queryIntent = new Intent(getActivity(), ImportKeysActivity.class);
    queryIntent.setAction(ImportKeysActivity.ACTION_IMPORT_KEY_FROM_KEYSERVER_AND_RETURN_RESULT);
    queryIntent.putExtra(ImportKeysActivity.EXTRA_FINGERPRINT, fingerprint);

    startActivityForResult(queryIntent, 0);
  }
  /**
   * If an Intent gives a signatureMasterKeyId and/or encryptionMasterKeyIds, preselect those!
   *
   * @param preselectedSignatureKeyId
   * @param preselectedEncryptionKeyIds
   */
  private void preselectKeys(
      long preselectedSignatureKeyId,
      long[] preselectedEncryptionKeyIds,
      ProviderHelper providerHelper) {
    if (preselectedSignatureKeyId != 0) {
      // TODO: don't use bouncy castle objects!
      try {
        PGPSecretKeyRing keyRing =
            providerHelper.getPGPSecretKeyRingWithKeyId(preselectedSignatureKeyId);

        PGPSecretKey masterKey = keyRing.getSecretKey();
        if (masterKey != null) {
          PGPSecretKey signKey = PgpKeyHelper.getFirstSigningSubkey(keyRing);
          if (signKey != null) {
            setSignatureKeyId(masterKey.getKeyID());
          }
        }
      } catch (ProviderHelper.NotFoundException e) {
        Log.e(Constants.TAG, "key not found!", e);
      }
    }

    if (preselectedEncryptionKeyIds != null) {
      Vector<Long> goodIds = new Vector<Long>();
      for (int i = 0; i < preselectedEncryptionKeyIds.length; ++i) {
        // TODO One query per selected key?! wtf
        try {
          long id =
              providerHelper.getMasterKeyId(
                  KeyRings.buildUnifiedKeyRingsFindBySubkeyUri(
                      Long.toString(preselectedEncryptionKeyIds[i])));
          goodIds.add(id);
        } catch (ProviderHelper.NotFoundException e) {
          Log.e(Constants.TAG, "key not found!", e);
        }
      }
      if (goodIds.size() > 0) {
        long[] keyIds = new long[goodIds.size()];
        for (int i = 0; i < goodIds.size(); ++i) {
          keyIds[i] = goodIds.get(i);
        }
        setEncryptionKeyIds(keyIds);
      }
    }
  }
  private void updateView() {
    if (mEncryptionKeyIds == null || mEncryptionKeyIds.length == 0) {
      mSelectKeysButton.setText(getString(R.string.select_keys_button_default));
    } else {
      mSelectKeysButton.setText(
          getResources()
              .getQuantityString(
                  R.plurals.select_keys_button,
                  mEncryptionKeyIds.length,
                  mEncryptionKeyIds.length));
    }

    if (mSecretKeyId == Constants.key.none) {
      mSign.setChecked(false);
      mMainUserId.setText("");
      mMainUserIdRest.setText("");
    } else {
      // See if we can get a user_id from a unified query
      String[] userId;
      try {
        String userIdResult =
            (String)
                mProviderHelper.getUnifiedData(
                    mSecretKeyId, KeyRings.USER_ID, ProviderHelper.FIELD_TYPE_STRING);
        userId = PgpKeyHelper.splitUserId(userIdResult);
      } catch (ProviderHelper.NotFoundException e) {
        userId = null;
      }
      if (userId != null && userId[0] != null) {
        mMainUserId.setText(userId[0]);
      } else {
        mMainUserId.setText(getResources().getString(R.string.user_id_no_name));
      }
      if (userId != null && userId[1] != null) {
        mMainUserIdRest.setText(userId[1]);
      } else {
        mMainUserIdRest.setText("");
      }
      mSign.setChecked(true);
    }
  }
  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.)
    switch (loader.getId()) {
      case LOADER_ID_KEYRING:
        if (data.moveToFirst()) {
          // get name, email, and comment from USER_ID
          String[] mainUserId = PgpKeyHelper.splitUserId(data.getString(KEYRING_INDEX_USER_ID));
          if (mainUserId[0] != null) {
            getActivity().setTitle(mainUserId[0]);
            mName.setText(mainUserId[0]);
          } else {
            getActivity().setTitle(R.string.user_id_no_name);
            mName.setText(R.string.user_id_no_name);
          }
          mEmail.setText(mainUserId[1]);
          mComment.setText(mainUserId[2]);
        }

        break;
      case LOADER_ID_USER_IDS:
        mUserIdsAdapter.swapCursor(data);
        break;
      case LOADER_ID_KEYS:
        // the first key here is our master key
        if (data.moveToFirst()) {
          // get key id from MASTER_KEY_ID
          long keyId = data.getLong(KEYS_INDEX_KEY_ID);
          String keyIdStr = PgpKeyHelper.convertKeyIdToHex(keyId);
          mKeyId.setText(keyIdStr);

          // get creation date from CREATION
          if (data.isNull(KEYS_INDEX_CREATION)) {
            mCreation.setText(R.string.none);
          } else {
            Date creationDate = new Date(data.getLong(KEYS_INDEX_CREATION) * 1000);

            mCreation.setText(
                DateFormat.getDateFormat(getActivity().getApplicationContext())
                    .format(creationDate));
          }

          // get expiry date from EXPIRY
          if (data.isNull(KEYS_INDEX_EXPIRY)) {
            mExpiry.setText(R.string.none);
          } else {
            Date expiryDate = new Date(data.getLong(KEYS_INDEX_EXPIRY) * 1000);

            mExpiry.setText(
                DateFormat.getDateFormat(getActivity().getApplicationContext()).format(expiryDate));
          }

          String algorithmStr =
              PgpKeyHelper.getAlgorithmInfo(
                  data.getInt(KEYS_INDEX_ALGORITHM), data.getInt(KEYS_INDEX_KEY_SIZE));
          mAlgorithm.setText(algorithmStr);

          byte[] fingerprintBlob = data.getBlob(KEYS_INDEX_FINGERPRINT);
          if (fingerprintBlob == null) {
            // FALLBACK for old database entries
            fingerprintBlob = ProviderHelper.getFingerprint(getActivity(), mDataUri);
          }
          String fingerprint = PgpKeyHelper.convertFingerprintToHex(fingerprintBlob, true);

          mFingerprint.setText(OtherHelper.colorizeFingerprint(fingerprint));
        }

        mKeysAdapter.swapCursor(data);
        break;

      default:
        break;
    }
  }
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.certify_key_activity);

    final ActionBar actionBar = getSupportActionBar();
    actionBar.setDisplayShowTitleEnabled(true);
    actionBar.setDisplayHomeAsUpEnabled(false);
    actionBar.setHomeButtonEnabled(false);

    mSelectKeyFragment =
        (SelectSecretKeyLayoutFragment)
            getSupportFragmentManager().findFragmentById(R.id.sign_key_select_key_fragment);
    mSelectKeyFragment.setCallback(this);
    mSelectKeyFragment.setFilterCertify(true);

    mSelectKeyserverSpinner = (Spinner) findViewById(R.id.sign_key_keyserver);
    ArrayAdapter<String> adapter =
        new ArrayAdapter<String>(
            this,
            android.R.layout.simple_spinner_item,
            Preferences.getPreferences(this).getKeyServers());
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    mSelectKeyserverSpinner.setAdapter(adapter);

    mUploadKeyCheckbox = (CheckBox) findViewById(R.id.sign_key_upload_checkbox);
    if (!mUploadKeyCheckbox.isChecked()) {
      mSelectKeyserverSpinner.setEnabled(false);
    } else {
      mSelectKeyserverSpinner.setEnabled(true);
    }

    mUploadKeyCheckbox.setOnCheckedChangeListener(
        new OnCheckedChangeListener() {

          @Override
          public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            if (!isChecked) {
              mSelectKeyserverSpinner.setEnabled(false);
            } else {
              mSelectKeyserverSpinner.setEnabled(true);
            }
          }
        });

    mSignButton = (BootstrapButton) findViewById(R.id.sign_key_sign_button);
    mSignButton.setOnClickListener(
        new OnClickListener() {

          @Override
          public void onClick(View v) {
            if (mPubKeyId != 0) {
              if (mMasterKeyId == 0) {
                mSelectKeyFragment.setError(getString(R.string.select_key_to_sign));
              } else {
                initiateSigning();
              }
            }
          }
        });

    mDataUri = getIntent().getData();
    if (mDataUri == null) {
      Log.e(Constants.TAG, "Intent data missing. Should be Uri of key!");
      finish();
      return;
    }

    PGPPublicKeyRing signKey = (PGPPublicKeyRing) ProviderHelper.getPGPKeyRing(this, mDataUri);

    if (signKey != null) {
      mPubKeyId = PgpKeyHelper.getMasterKey(signKey).getKeyID();
      drawPublicKey();
    }
    if (mPubKeyId == 0) {
      Log.e(Constants.TAG, "this shouldn't happen. KeyId == 0!");
      finish();
      return;
    }
  }