mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-11-27 19:22:14 -05:00
implemented secret keys without passphrase
This commit is contained in:
parent
4793cd1c25
commit
4eebeede2b
@ -25,15 +25,14 @@
|
|||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="fill_parent"
|
android:layout_height="fill_parent"
|
||||||
android:fillViewport="true"
|
android:fillViewport="true" >
|
||||||
android:paddingLeft="10dp"
|
|
||||||
android:paddingRight="10dp" >
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:padding="4dp" >
|
android:paddingLeft="10dp"
|
||||||
|
android:paddingRight="10dp" >
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="fill_parent"
|
android:layout_width="fill_parent"
|
||||||
|
@ -98,7 +98,7 @@
|
|||||||
<string name="menu_keyServer">Key Server</string>
|
<string name="menu_keyServer">Key Server</string>
|
||||||
<string name="menu_updateKey">Update</string>
|
<string name="menu_updateKey">Update</string>
|
||||||
<string name="menu_exportKeyToServer">Export To Server</string>
|
<string name="menu_exportKeyToServer">Export To Server</string>
|
||||||
<string name="menu_share">Share</string>
|
<string name="menu_share">Share with QR Code</string>
|
||||||
<string name="menu_scanQRCode">Scan QR Code</string>
|
<string name="menu_scanQRCode">Scan QR Code</string>
|
||||||
<string name="menu_signKey">Sign Key</string>
|
<string name="menu_signKey">Sign Key</string>
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@ import org.apg.ui.widget.KeyEditor;
|
|||||||
import org.apg.ui.widget.SectionView;
|
import org.apg.ui.widget.SectionView;
|
||||||
import org.apg.ui.widget.UserIdEditor;
|
import org.apg.ui.widget.UserIdEditor;
|
||||||
import org.apg.util.IterableIterator;
|
import org.apg.util.IterableIterator;
|
||||||
|
import org.apg.util.Utils;
|
||||||
import org.spongycastle.bcpg.ArmoredInputStream;
|
import org.spongycastle.bcpg.ArmoredInputStream;
|
||||||
import org.spongycastle.bcpg.ArmoredOutputStream;
|
import org.spongycastle.bcpg.ArmoredOutputStream;
|
||||||
import org.spongycastle.bcpg.BCPGOutputStream;
|
import org.spongycastle.bcpg.BCPGOutputStream;
|
||||||
@ -155,6 +156,7 @@ public class Apg {
|
|||||||
public static final String EXTRA_BINARY = "binary";
|
public static final String EXTRA_BINARY = "binary";
|
||||||
public static final String EXTRA_KEY_SERVERS = "keyServers";
|
public static final String EXTRA_KEY_SERVERS = "keyServers";
|
||||||
public static final String EXTRA_EXPECTED_FINGERPRINT = "expectedFingerprint";
|
public static final String EXTRA_EXPECTED_FINGERPRINT = "expectedFingerprint";
|
||||||
|
public static final String EXTRA_NO_PASSPHRASE = "noPassphrase";
|
||||||
|
|
||||||
public static final String AUTHORITY = DataProvider.AUTHORITY;
|
public static final String AUTHORITY = DataProvider.AUTHORITY;
|
||||||
|
|
||||||
@ -374,18 +376,6 @@ public class Apg {
|
|||||||
return secretKey;
|
return secretKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static long getNumDaysBetween(GregorianCalendar first, GregorianCalendar second) {
|
|
||||||
GregorianCalendar tmp = new GregorianCalendar();
|
|
||||||
tmp.setTime(first.getTime());
|
|
||||||
long numDays = (second.getTimeInMillis() - first.getTimeInMillis()) / 1000 / 86400;
|
|
||||||
tmp.add(Calendar.DAY_OF_MONTH, (int) numDays);
|
|
||||||
while (tmp.before(second)) {
|
|
||||||
tmp.add(Calendar.DAY_OF_MONTH, 1);
|
|
||||||
++numDays;
|
|
||||||
}
|
|
||||||
return numDays;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void buildSecretKey(Activity context, SectionView userIdsView,
|
public static void buildSecretKey(Activity context, SectionView userIdsView,
|
||||||
SectionView keysView, String oldPassPhrase, String newPassPhrase,
|
SectionView keysView, String oldPassPhrase, String newPassPhrase,
|
||||||
ProgressDialogUpdater progress) throws Apg.GeneralException, NoSuchProviderException,
|
ProgressDialogUpdater progress) throws Apg.GeneralException, NoSuchProviderException,
|
||||||
@ -509,7 +499,7 @@ public class Apg {
|
|||||||
GregorianCalendar creationDate = new GregorianCalendar();
|
GregorianCalendar creationDate = new GregorianCalendar();
|
||||||
creationDate.setTime(getCreationDate(masterKey));
|
creationDate.setTime(getCreationDate(masterKey));
|
||||||
GregorianCalendar expiryDate = keyEditor.getExpiryDate();
|
GregorianCalendar expiryDate = keyEditor.getExpiryDate();
|
||||||
long numDays = getNumDaysBetween(creationDate, expiryDate);
|
long numDays = Utils.getNumDaysBetween(creationDate, expiryDate);
|
||||||
if (numDays <= 0) {
|
if (numDays <= 0) {
|
||||||
throw new GeneralException(
|
throw new GeneralException(
|
||||||
context.getString(R.string.error_expiryMustComeAfterCreation));
|
context.getString(R.string.error_expiryMustComeAfterCreation));
|
||||||
@ -517,8 +507,10 @@ public class Apg {
|
|||||||
hashedPacketsGen.setKeyExpirationTime(true, numDays * 86400);
|
hashedPacketsGen.setKeyExpirationTime(true, numDays * 86400);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (progress != null)
|
if (progress != null) {
|
||||||
progress.setProgress(R.string.progress_buildingMasterKeyRing, 30, 100);
|
progress.setProgress(R.string.progress_buildingMasterKeyRing, 30, 100);
|
||||||
|
}
|
||||||
|
|
||||||
PGPKeyRingGenerator keyGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION,
|
PGPKeyRingGenerator keyGen = new PGPKeyRingGenerator(PGPSignature.POSITIVE_CERTIFICATION,
|
||||||
masterKeyPair, mainUserId, PGPEncryptedData.CAST5, newPassPhrase.toCharArray(),
|
masterKeyPair, mainUserId, PGPEncryptedData.CAST5, newPassPhrase.toCharArray(),
|
||||||
hashedPacketsGen.generate(), unhashedPacketsGen.generate(), new SecureRandom(),
|
hashedPacketsGen.generate(), unhashedPacketsGen.generate(), new SecureRandom(),
|
||||||
@ -558,7 +550,7 @@ public class Apg {
|
|||||||
GregorianCalendar creationDate = new GregorianCalendar();
|
GregorianCalendar creationDate = new GregorianCalendar();
|
||||||
creationDate.setTime(getCreationDate(masterKey));
|
creationDate.setTime(getCreationDate(masterKey));
|
||||||
GregorianCalendar expiryDate = keyEditor.getExpiryDate();
|
GregorianCalendar expiryDate = keyEditor.getExpiryDate();
|
||||||
long numDays = getNumDaysBetween(creationDate, expiryDate);
|
long numDays = Utils.getNumDaysBetween(creationDate, expiryDate);
|
||||||
if (numDays <= 0) {
|
if (numDays <= 0) {
|
||||||
throw new GeneralException(
|
throw new GeneralException(
|
||||||
context.getString(R.string.error_expiryMustComeAfterCreation));
|
context.getString(R.string.error_expiryMustComeAfterCreation));
|
||||||
@ -2202,7 +2194,7 @@ public class Apg {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} catch (NameNotFoundException e) {
|
} catch (NameNotFoundException e) {
|
||||||
// unpossible!
|
// impossible!
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2216,7 +2208,7 @@ public class Apg {
|
|||||||
VERSION = pi.versionName;
|
VERSION = pi.versionName;
|
||||||
return VERSION;
|
return VERSION;
|
||||||
} catch (NameNotFoundException e) {
|
} catch (NameNotFoundException e) {
|
||||||
// unpossible!
|
// impossible!
|
||||||
return "0.0.0";
|
return "0.0.0";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ import android.app.Dialog;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.DialogInterface.OnClickListener;
|
import android.content.DialogInterface.OnClickListener;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
@ -86,7 +87,7 @@ public class AskForSecretKeyPassPhrase {
|
|||||||
alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
activity.removeDialog(Id.dialog.pass_phrase);
|
activity.removeDialog(Id.dialog.pass_phrase);
|
||||||
String passPhrase = "" + input.getText();
|
String passPhrase = input.getText().toString();
|
||||||
long keyId;
|
long keyId;
|
||||||
if (secretKey != null) {
|
if (secretKey != null) {
|
||||||
try {
|
try {
|
||||||
@ -116,6 +117,23 @@ public class AskForSecretKeyPassPhrase {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// check if the key has no passphrase
|
||||||
|
if (secretKey != null) {
|
||||||
|
try {
|
||||||
|
Log.d("APG", "check if key has no passphrase...");
|
||||||
|
PGPPrivateKey testKey = secretKey.extractPrivateKey("".toCharArray(),
|
||||||
|
new BouncyCastleProvider());
|
||||||
|
if (testKey != null) {
|
||||||
|
Log.d("APG", "Key has no passphrase!");
|
||||||
|
|
||||||
|
cb.passPhraseCallback(secretKey.getKeyID(), null);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} catch (PGPException e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
return alert.create();
|
return alert.create();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -118,15 +118,11 @@ public class DecryptActivity extends BaseActivity {
|
|||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
|
|
||||||
if (mDecryptEnabled) {
|
if (mDecryptEnabled) {
|
||||||
menu.add(1, Id.menu.option.decrypt, 0, mDecryptString)
|
menu.add(1, Id.menu.option.decrypt, 0, mDecryptString).setShowAsAction(
|
||||||
// .setIcon(R.drawable.ic_menu_encrypt)
|
|
||||||
.setShowAsAction(
|
|
||||||
MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
|
MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
|
||||||
}
|
}
|
||||||
if (mReplyEnabled) {
|
if (mReplyEnabled) {
|
||||||
menu.add(1, Id.menu.option.reply, 1, mReplyString)
|
menu.add(1, Id.menu.option.reply, 1, mReplyString).setShowAsAction(
|
||||||
// .setIcon(R.drawable.ic_menu_decrypt)
|
|
||||||
.setShowAsAction(
|
|
||||||
MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
|
MenuItem.SHOW_AS_ACTION_ALWAYS | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,9 +271,8 @@ public class DecryptActivity extends BaseActivity {
|
|||||||
// replace non breakable spaces
|
// replace non breakable spaces
|
||||||
textData = textData.replaceAll("\\xa0", " ");
|
textData = textData.replaceAll("\\xa0", " ");
|
||||||
mMessage.setText(textData);
|
mMessage.setText(textData);
|
||||||
mDecryptString = getString(R.string.btn_verify);
|
|
||||||
// mDecryptButton.setText(R.string.btn_verify);
|
|
||||||
|
|
||||||
|
mDecryptString = getString(R.string.btn_verify);
|
||||||
// build new action bar
|
// build new action bar
|
||||||
invalidateOptionsMenu();
|
invalidateOptionsMenu();
|
||||||
} else {
|
} else {
|
||||||
@ -399,8 +394,6 @@ public class DecryptActivity extends BaseActivity {
|
|||||||
|
|
||||||
if (mSource.getCurrentView().getId() == R.id.sourceMessage
|
if (mSource.getCurrentView().getId() == R.id.sourceMessage
|
||||||
&& (mMessage.getText().length() > 0 || mData != null || mContentUri != null)) {
|
&& (mMessage.getText().length() > 0 || mData != null || mContentUri != null)) {
|
||||||
// mDecryptButton.performClick();
|
|
||||||
// TODO: why was it performClick()???
|
|
||||||
decryptClicked();
|
decryptClicked();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,6 @@ import android.app.Dialog;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
@ -49,7 +48,6 @@ import android.widget.CheckBox;
|
|||||||
import android.widget.CompoundButton;
|
import android.widget.CompoundButton;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.TableRow;
|
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
import android.widget.CompoundButton.OnCheckedChangeListener;
|
import android.widget.CompoundButton.OnCheckedChangeListener;
|
||||||
|
|
||||||
@ -72,6 +70,8 @@ public class EditKeyActivity extends BaseActivity {
|
|||||||
|
|
||||||
private Button mChangePassPhrase;
|
private Button mChangePassPhrase;
|
||||||
|
|
||||||
|
private CheckBox mNoPassphrase;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
menu.add(1, Id.menu.option.cancel, 0, R.string.btn_doNotSave).setShowAsAction(
|
menu.add(1, Id.menu.option.cancel, 0, R.string.btn_doNotSave).setShowAsAction(
|
||||||
@ -152,6 +152,14 @@ public class EditKeyActivity extends BaseActivity {
|
|||||||
if (extras.containsKey(Apg.EXTRA_USER_IDS)) {
|
if (extras.containsKey(Apg.EXTRA_USER_IDS)) {
|
||||||
userIds.add(extras.getString(Apg.EXTRA_USER_IDS));
|
userIds.add(extras.getString(Apg.EXTRA_USER_IDS));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if userId is given, prefill the fields
|
||||||
|
if (extras.containsKey(Apg.EXTRA_NO_PASSPHRASE)) {
|
||||||
|
boolean noPassphrase = extras.getBoolean(Apg.EXTRA_NO_PASSPHRASE);
|
||||||
|
if (noPassphrase) {
|
||||||
|
mCurrentPassPhrase = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mChangePassPhrase = (Button) findViewById(R.id.edit_key_btn_change_pass_phrase);
|
mChangePassPhrase = (Button) findViewById(R.id.edit_key_btn_change_pass_phrase);
|
||||||
@ -162,12 +170,15 @@ public class EditKeyActivity extends BaseActivity {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// disable passphrase when no passphrase checkobox is checked!
|
// disable passphrase when no passphrase checkobox is checked!
|
||||||
final CheckBox noPassphrase = (CheckBox) findViewById(R.id.edit_key_no_passphrase);
|
mNoPassphrase = (CheckBox) findViewById(R.id.edit_key_no_passphrase);
|
||||||
noPassphrase.setOnCheckedChangeListener(new OnCheckedChangeListener() {
|
mNoPassphrase.setOnCheckedChangeListener(new OnCheckedChangeListener() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||||
if (isChecked) {
|
if (isChecked) {
|
||||||
|
// remove passphrase
|
||||||
|
mNewPassPhrase = null;
|
||||||
|
|
||||||
mChangePassPhrase.setVisibility(View.GONE);
|
mChangePassPhrase.setVisibility(View.GONE);
|
||||||
} else {
|
} else {
|
||||||
mChangePassPhrase.setVisibility(View.VISIBLE);
|
mChangePassPhrase.setVisibility(View.VISIBLE);
|
||||||
@ -194,6 +205,12 @@ public class EditKeyActivity extends BaseActivity {
|
|||||||
mCurrentPassPhrase = "";
|
mCurrentPassPhrase = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mCurrentPassPhrase.equals("")) {
|
||||||
|
// check "no passphrase" checkbox and remove button
|
||||||
|
mNoPassphrase.setChecked(true);
|
||||||
|
mChangePassPhrase.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
updatePassPhraseButtonText();
|
updatePassPhraseButtonText();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,9 +221,15 @@ public class EditKeyActivity extends BaseActivity {
|
|||||||
return ((KeyEditor) mKeys.getEditors().getChildAt(0)).getValue().getKeyID();
|
return ((KeyEditor) mKeys.getEditors().getChildAt(0)).getValue().getKeyID();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean havePassPhrase() {
|
public boolean isPassphraseSet() {
|
||||||
return (!mCurrentPassPhrase.equals(""))
|
if (mNoPassphrase.isChecked()) {
|
||||||
|| (mNewPassPhrase != null && !mNewPassPhrase.equals(""));
|
return true;
|
||||||
|
} else if ((!mCurrentPassPhrase.equals(""))
|
||||||
|
|| (mNewPassPhrase != null && !mNewPassPhrase.equals(""))) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -215,7 +238,7 @@ public class EditKeyActivity extends BaseActivity {
|
|||||||
case Id.dialog.new_pass_phrase: {
|
case Id.dialog.new_pass_phrase: {
|
||||||
AlertDialog.Builder alert = new AlertDialog.Builder(this);
|
AlertDialog.Builder alert = new AlertDialog.Builder(this);
|
||||||
|
|
||||||
if (havePassPhrase()) {
|
if (isPassphraseSet()) {
|
||||||
alert.setTitle(R.string.title_changePassPhrase);
|
alert.setTitle(R.string.title_changePassPhrase);
|
||||||
} else {
|
} else {
|
||||||
alert.setTitle(R.string.title_setPassPhrase);
|
alert.setTitle(R.string.title_setPassPhrase);
|
||||||
@ -266,7 +289,7 @@ public class EditKeyActivity extends BaseActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void saveClicked() {
|
private void saveClicked() {
|
||||||
if (!havePassPhrase()) {
|
if (!isPassphraseSet()) {
|
||||||
Toast.makeText(this, R.string.setAPassPhrase, Toast.LENGTH_SHORT).show();
|
Toast.makeText(this, R.string.setAPassPhrase, Toast.LENGTH_SHORT).show();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -333,7 +356,7 @@ public class EditKeyActivity extends BaseActivity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updatePassPhraseButtonText() {
|
private void updatePassPhraseButtonText() {
|
||||||
mChangePassPhrase.setText(havePassPhrase() ? R.string.btn_changePassPhrase
|
mChangePassPhrase.setText(isPassphraseSet() ? R.string.btn_changePassPhrase
|
||||||
: R.string.btn_setPassPhrase);
|
: R.string.btn_setPassPhrase);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,15 +49,13 @@ public class SecretKeyListActivity extends KeyListActivity implements OnChildCli
|
|||||||
@Override
|
@Override
|
||||||
public boolean onCreateOptionsMenu(Menu menu) {
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
menu.add(3, Id.menu.option.search, 0, R.string.menu_search)
|
menu.add(3, Id.menu.option.search, 0, R.string.menu_search)
|
||||||
.setIcon(R.drawable.ic_menu_search)
|
.setIcon(R.drawable.ic_menu_search).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
|
||||||
.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
|
menu.add(1, Id.menu.option.create, 1, R.string.menu_createKey).setShowAsAction(
|
||||||
menu.add(1, Id.menu.option.create, 1, R.string.menu_createKey)
|
|
||||||
.setShowAsAction(
|
|
||||||
MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
|
MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
|
||||||
menu.add(0, Id.menu.option.import_keys, 2, R.string.menu_importKeys)
|
menu.add(0, Id.menu.option.import_keys, 2, R.string.menu_importKeys).setShowAsAction(
|
||||||
.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
|
MenuItem.SHOW_AS_ACTION_NEVER | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
|
||||||
menu.add(0, Id.menu.option.export_keys, 3, R.string.menu_exportKeys)
|
menu.add(0, Id.menu.option.export_keys, 3, R.string.menu_exportKeys).setShowAsAction(
|
||||||
.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
|
MenuItem.SHOW_AS_ACTION_NEVER | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -114,7 +112,6 @@ public class SecretKeyListActivity extends KeyListActivity implements OnChildCli
|
|||||||
long keyId = ((KeyListAdapter) mList.getExpandableListAdapter())
|
long keyId = ((KeyListAdapter) mList.getExpandableListAdapter())
|
||||||
.getGroupId(mSelectedItem);
|
.getGroupId(mSelectedItem);
|
||||||
String msg = keyId + "," + Apg.getFingerPrint(keyId);
|
String msg = keyId + "," + Apg.getFingerPrint(keyId);
|
||||||
;
|
|
||||||
|
|
||||||
new IntentIntegrator(this).shareText(msg);
|
new IntentIntegrator(this).shareText(msg);
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,8 @@ package org.apg.util;
|
|||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.GregorianCalendar;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
@ -51,4 +53,23 @@ public class Utils {
|
|||||||
return stream.toString();
|
return stream.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the number if days between two dates
|
||||||
|
*
|
||||||
|
* @param first
|
||||||
|
* @param second
|
||||||
|
* @return number of days
|
||||||
|
*/
|
||||||
|
public static long getNumDaysBetween(GregorianCalendar first, GregorianCalendar second) {
|
||||||
|
GregorianCalendar tmp = new GregorianCalendar();
|
||||||
|
tmp.setTime(first.getTime());
|
||||||
|
long numDays = (second.getTimeInMillis() - first.getTimeInMillis()) / 1000 / 86400;
|
||||||
|
tmp.add(Calendar.DAY_OF_MONTH, (int) numDays);
|
||||||
|
while (tmp.before(second)) {
|
||||||
|
tmp.add(Calendar.DAY_OF_MONTH, 1);
|
||||||
|
++numDays;
|
||||||
|
}
|
||||||
|
return numDays;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user