aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDominik Schürmann <dominik@dominikschuermann.de>2013-01-08 17:01:45 +0100
committerDominik Schürmann <dominik@dominikschuermann.de>2013-01-08 17:01:45 +0100
commit68039d3a8a0ce9b20ee426765094807112a634d7 (patch)
tree50d5f528382a89030be0c78f26e4cd7be5ca5b71
parent6cc7156fbd094265dddd66562941c90a2d9079d6 (diff)
downloadopen-keychain-68039d3a8a0ce9b20ee426765094807112a634d7.tar.gz
open-keychain-68039d3a8a0ce9b20ee426765094807112a634d7.tar.bz2
open-keychain-68039d3a8a0ce9b20ee426765094807112a634d7.zip
Improved import with preview of keyrings
-rw-r--r--APG/res/layout/import_keys.xml22
-rw-r--r--APG/res/raw/help_nfc_beam.html4
-rw-r--r--APG/res/values/strings.xml6
-rw-r--r--APG/src/org/thialfihar/android/apg/helper/PGPHelper.java4
-rw-r--r--APG/src/org/thialfihar/android/apg/helper/PGPMain.java38
-rw-r--r--APG/src/org/thialfihar/android/apg/service/ApgIntentService.java32
-rw-r--r--APG/src/org/thialfihar/android/apg/ui/ImportKeysActivity.java199
-rw-r--r--APG/src/org/thialfihar/android/apg/ui/ImportKeysListFragment.java148
-rw-r--r--APG/src/org/thialfihar/android/apg/ui/KeyListActivity.java2
-rw-r--r--APG/src/org/thialfihar/android/apg/ui/KeyServerQueryActivity.java2
-rw-r--r--APG/src/org/thialfihar/android/apg/ui/KeyServerUploadActivity.java2
-rw-r--r--APG/src/org/thialfihar/android/apg/ui/ShareNfcBeamActivity.java23
-rw-r--r--APG/src/org/thialfihar/android/apg/ui/ShareQrCodeActivity.java2
-rw-r--r--APG/src/org/thialfihar/android/apg/ui/SignKeyActivity.java4
-rw-r--r--APG/src/org/thialfihar/android/apg/ui/widget/ImportKeysListLoader.java140
-rw-r--r--APG/src/org/thialfihar/android/apg/ui/widget/KeyListAdapter.java4
-rw-r--r--README.md2
17 files changed, 451 insertions, 183 deletions
diff --git a/APG/res/layout/import_keys.xml b/APG/res/layout/import_keys.xml
index 8e107cd96..1c2dbd0c7 100644
--- a/APG/res/layout/import_keys.xml
+++ b/APG/res/layout/import_keys.xml
@@ -6,7 +6,7 @@
<LinearLayout
android:id="@+id/import_from_qr_code_footer"
- android:layout_width="fill_parent"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="vertical"
@@ -36,23 +36,27 @@
</LinearLayout>
<ScrollView
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
android:layout_above="@id/import_from_qr_code_footer"
android:fillViewport="true" >
<LinearLayout
- android:layout_width="fill_parent"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
- android:paddingLeft="10dp"
- android:paddingRight="10dp" >
+ android:paddingLeft="12dp"
+ android:paddingRight="12dp" >
- <TextView
- android:id="@+id/import_from_qr_code_content"
+ <LinearLayout
+ android:id="@+id/import_keys_list_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:text="" />
+ android:layout_marginTop="16dp"
+ android:orientation="vertical"
+ android:paddingLeft="4dp"
+ android:paddingRight="4dp" >
+ </LinearLayout>
</LinearLayout>
</ScrollView>
diff --git a/APG/res/raw/help_nfc_beam.html b/APG/res/raw/help_nfc_beam.html
index 31abb7ddb..80c79c4a3 100644
--- a/APG/res/raw/help_nfc_beam.html
+++ b/APG/res/raw/help_nfc_beam.html
@@ -8,8 +8,8 @@ And don't add newlines before or after p tags because of transifex -->
<ol>
<li>Go to your partners 'Manage Public Keyrings' and long press on the keyring you want to share.</li>
<li>Hold the two devices back to back (they have to be almost touching) and you’ll feel a vibration.</li>
-<li>After it vibrates you’ll see the content on your device turn into a card-like object with Star Trek warp speed-looking animation in the background.</li>
-<li>Tap the card and the content will then load on the other person’s device.</li>
+<li>After it vibrates you’ll see the content on your partners device turn into a card-like object with Star Trek warp speed-looking animation in the background.</li>
+<li>Tap the card and the content will then load on the your device.</li>
</ol>
</body>
</html> \ No newline at end of file
diff --git a/APG/res/values/strings.xml b/APG/res/values/strings.xml
index 531e1cd68..b5f55cdd3 100644
--- a/APG/res/values/strings.xml
+++ b/APG/res/values/strings.xml
@@ -93,7 +93,7 @@
<string name="menu_importFromQrCode">Import from QR Code</string>
<string name="menu_importFromNfc">Import from NFC</string>
<string name="menu_exportKeys">Export All Keyrings</string>
- <string name="menu_exportKey">Export Keyring</string>
+ <string name="menu_exportKey">Export To File</string>
<string name="menu_deleteKey">Delete Keyring</string>
<string name="menu_createKey">Create Keyring</string>
<string name="menu_editKey">Edit Keyring</string>
@@ -154,7 +154,7 @@
<string name="expired">expired</string>
<string name="notValid">not valid</string>
<string name="nKeyServers">%s key server(s)</string>
- <string name="fingerprint">fingerprint</string>
+ <string name="fingerprint">Fingerprint:</string>
<!-- choice_lowerCase: capitalized first word, no punctuation -->
<string name="choice_none">None</string>
@@ -232,6 +232,7 @@
<string name="qrScanImportSuccess">Successfully validated and imported keyring</string>
<string name="listInformation">Long press one entry in this list to show more options!</string>
<string name="listEmpty">This list is empty!</string>
+ <string name="nfcSuccessfull">Successfully sent keyring with NFC Beam!</string>
<!--
error_lowerCase: phrases, no punctuation, all lowercase,
@@ -266,6 +267,7 @@
<string name="error_onlyFilesAreSupported">Direct binary data without actual file in filesystem is not supported. This is only supported by ACTION_ENCRYPT_STREAM_AND_RETURN.</string>
<string name="error_jellyBeanNeeded">You need Android 4.1 alias Jelly Bean to use Androids NFC Beam feature!</string>
<string name="error_nfcNeeded">NFC is not available on your device!</string>
+ <string name="error_nothingImport">Nothing to import!</string>
<!-- progress_lowerCase: lowercase, phrases, usually ending in '…' -->
<string name="progress_done">done.</string>
diff --git a/APG/src/org/thialfihar/android/apg/helper/PGPHelper.java b/APG/src/org/thialfihar/android/apg/helper/PGPHelper.java
index fed1d2156..f7bc62d4f 100644
--- a/APG/src/org/thialfihar/android/apg/helper/PGPHelper.java
+++ b/APG/src/org/thialfihar/android/apg/helper/PGPHelper.java
@@ -351,7 +351,7 @@ public class PGPHelper {
return algorithmStr + ", " + keySize + "bit";
}
- public static String convertToHex(byte[] fp) {
+ public static String convertFingerprintToHex(byte[] fp) {
String fingerPrint = "";
for (int i = 0; i < fp.length; ++i) {
if (i != 0 && i % 10 == 0) {
@@ -382,7 +382,7 @@ public class PGPHelper {
key = secretKey.getPublicKey();
}
- return convertToHex(key.getFingerprint());
+ return convertFingerprintToHex(key.getFingerprint());
}
public static String getSmallFingerPrint(long keyId) {
diff --git a/APG/src/org/thialfihar/android/apg/helper/PGPMain.java b/APG/src/org/thialfihar/android/apg/helper/PGPMain.java
index cb4326f88..a8203d568 100644
--- a/APG/src/org/thialfihar/android/apg/helper/PGPMain.java
+++ b/APG/src/org/thialfihar/android/apg/helper/PGPMain.java
@@ -74,6 +74,7 @@ import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyDataDecryptorFactory
import org.spongycastle.openpgp.operator.jcajce.JcePublicKeyKeyEncryptionMethodGenerator;
import org.thialfihar.android.apg.provider.ProviderHelper;
import org.thialfihar.android.apg.service.ApgIntentService;
+import org.thialfihar.android.apg.ui.dialog.SetPassphraseDialogFragment;
import org.thialfihar.android.apg.util.HkpKeyServer;
import org.thialfihar.android.apg.util.InputData;
import org.thialfihar.android.apg.util.PositionAwareInputStream;
@@ -476,7 +477,7 @@ public class PGPMain {
}
public static int storeKeyRingInCache(Context context, PGPKeyRing keyring) {
- int status = Integer.MIN_VALUE; // out of bounds value (Id.retrun_value.*)
+ int status = Integer.MIN_VALUE; // out of bounds value (Id.return_value.*)
try {
if (keyring instanceof PGPSecretKeyRing) {
PGPSecretKeyRing secretKeyRing = (PGPSecretKeyRing) keyring;
@@ -538,18 +539,20 @@ public class PGPMain {
}
}
- public static Bundle importKeyRings(Context context, int type, InputData data,
+ public static Bundle importKeyRings(Context context, InputData data,
ProgressDialogUpdater progress) throws ApgGeneralException, FileNotFoundException,
PGPException, IOException {
Bundle returnData = new Bundle();
- if (type == Id.type.secret_key) {
- if (progress != null)
- progress.setProgress(R.string.progress_importingSecretKeys, 0, 100);
- } else {
- if (progress != null)
- progress.setProgress(R.string.progress_importingPublicKeys, 0, 100);
- }
+ // if (type == Id.type.secret_key) {
+ // if (progress != null)
+
+ updateProgress(progress, R.string.progress_importingSecretKeys, 0, 100);
+ // progress.setProgress(R.string.progress_importingSecretKeys, 0, 100);
+ // } else {
+ // if (progress != null)
+ // progress.setProgress(R.string.progress_importingPublicKeys, 0, 100);
+ // }
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
throw new ApgGeneralException(context.getString(R.string.error_externalStorageNotReady));
@@ -569,10 +572,10 @@ public class PGPMain {
int status = Integer.MIN_VALUE; // out of bounds value
// if this key is what we expect it to be, save it
- if ((type == Id.type.secret_key && keyring instanceof PGPSecretKeyRing)
- || (type == Id.type.public_key && keyring instanceof PGPPublicKeyRing)) {
- status = storeKeyRingInCache(context, keyring);
- }
+ // if ((type == Id.type.secret_key && keyring instanceof PGPSecretKeyRing)
+ // || (type == Id.type.public_key && keyring instanceof PGPPublicKeyRing)) {
+ status = storeKeyRingInCache(context, keyring);
+ // }
if (status == Id.return_value.error) {
throw new ApgGeneralException(context.getString(R.string.error_savingKeys));
@@ -589,9 +592,6 @@ public class PGPMain {
updateProgress(progress, (int) (100 * progressIn.position() / data.getSize()), 100);
- // TODO: needed?
- // obj = objectFactory.nextObject();
-
keyring = PGPConversionHelper.decodeKeyRing(bufferedInput);
}
} catch (EOFException e) {
@@ -652,9 +652,9 @@ public class PGPMain {
return returnData;
}
- public static Bundle getKeyRings(Context context, long[] masterKeyIds,
- OutputStream outStream, ProgressDialogUpdater progress) throws ApgGeneralException,
- FileNotFoundException, PGPException, IOException {
+ public static Bundle getKeyRings(Context context, long[] masterKeyIds, OutputStream outStream,
+ ProgressDialogUpdater progress) throws ApgGeneralException, FileNotFoundException,
+ PGPException, IOException {
Bundle returnData = new Bundle();
ArmoredOutputStream out = new ArmoredOutputStream(outStream);
diff --git a/APG/src/org/thialfihar/android/apg/service/ApgIntentService.java b/APG/src/org/thialfihar/android/apg/service/ApgIntentService.java
index e738b4193..58afa9fa8 100644
--- a/APG/src/org/thialfihar/android/apg/service/ApgIntentService.java
+++ b/APG/src/org/thialfihar/android/apg/service/ApgIntentService.java
@@ -80,13 +80,13 @@ public class ApgIntentService extends IntentService implements ProgressDialogUpd
public static final int ACTION_DELETE_FILE_SECURELY = 40;
- public static final int ACTION_IMPORT_KEY = 50;
- public static final int ACTION_EXPORT_KEY = 51;
+ public static final int ACTION_IMPORT_KEYRING = 50;
+ public static final int ACTION_EXPORT_KEYRING = 51;
- public static final int ACTION_UPLOAD_KEY = 60;
- public static final int ACTION_QUERY_KEY = 61;
+ public static final int ACTION_UPLOAD_KEYRING = 60;
+ public static final int ACTION_QUERY_KEYRING = 61;
- public static final int ACTION_SIGN_KEY = 70;
+ public static final int ACTION_SIGN_KEYRING = 70;
/* keys for data bundle */
@@ -137,7 +137,7 @@ public class ApgIntentService extends IntentService implements ProgressDialogUpd
public static final String IMPORT_INPUT_STREAM = "importInputStream";
public static final String IMPORT_FILENAME = "importFilename";
public static final String IMPORT_BYTES = "importBytes";
- public static final String IMPORT_KEY_TYPE = "importKeyType";
+ // public static final String IMPORT_KEY_TYPE = "importKeyType";
// export key
public static final String EXPORT_OUTPUT_STREAM = "exportOutputStream";
@@ -629,16 +629,16 @@ public class ApgIntentService extends IntentService implements ProgressDialogUpd
break;
- case ACTION_IMPORT_KEY:
+ case ACTION_IMPORT_KEYRING:
try {
/* Input */
int target = data.getInt(TARGET);
- int keyType = Id.type.public_key;
- if (data.containsKey(IMPORT_KEY_TYPE)) {
- keyType = data.getInt(IMPORT_KEY_TYPE);
- }
+ // int keyType = Id.type.public_key;
+ // if (data.containsKey(IMPORT_KEY_TYPE)) {
+ // keyType = data.getInt(IMPORT_KEY_TYPE);
+ // }
/* Operation */
InputStream inStream = null;
@@ -670,7 +670,7 @@ public class ApgIntentService extends IntentService implements ProgressDialogUpd
}
Bundle resultData = new Bundle();
- resultData = PGPMain.importKeyRings(this, keyType, inputData, this);
+ resultData = PGPMain.importKeyRings(this, inputData, this);
sendMessageToHandler(ApgIntentServiceHandler.MESSAGE_OKAY, resultData);
} catch (Exception e) {
@@ -679,7 +679,7 @@ public class ApgIntentService extends IntentService implements ProgressDialogUpd
break;
- case ACTION_EXPORT_KEY:
+ case ACTION_EXPORT_KEYRING:
try {
/* Input */
@@ -729,7 +729,7 @@ public class ApgIntentService extends IntentService implements ProgressDialogUpd
break;
- case ACTION_UPLOAD_KEY:
+ case ACTION_UPLOAD_KEYRING:
try {
/* Input */
@@ -756,7 +756,7 @@ public class ApgIntentService extends IntentService implements ProgressDialogUpd
break;
- case ACTION_QUERY_KEY:
+ case ACTION_QUERY_KEYRING:
try {
/* Input */
@@ -787,7 +787,7 @@ public class ApgIntentService extends IntentService implements ProgressDialogUpd
break;
- case ACTION_SIGN_KEY:
+ case ACTION_SIGN_KEYRING:
try {
/* Input */
diff --git a/APG/src/org/thialfihar/android/apg/ui/ImportKeysActivity.java b/APG/src/org/thialfihar/android/apg/ui/ImportKeysActivity.java
index be4542bbb..355214ab5 100644
--- a/APG/src/org/thialfihar/android/apg/ui/ImportKeysActivity.java
+++ b/APG/src/org/thialfihar/android/apg/ui/ImportKeysActivity.java
@@ -38,8 +38,9 @@ import org.thialfihar.android.apg.ui.dialog.DeleteFileDialogFragment;
import org.thialfihar.android.apg.ui.dialog.FileDialogFragment;
import org.thialfihar.android.apg.util.Log;
+import android.support.v4.app.FragmentManager;
+import android.support.v4.app.FragmentTransaction;
import android.view.View;
-import android.widget.TextView;
import android.widget.Toast;
import com.actionbarsherlock.app.SherlockFragmentActivity;
@@ -58,26 +59,22 @@ public class ImportKeysActivity extends SherlockFragmentActivity {
// only used by IMPORT
public static final String EXTRA_TEXT = "text";
-
- protected String mImportFilename = Constants.path.APP_DIR + "/";
+ public static final String EXTRA_KEYRING_BYTES = "keyring_bytes";
// public static final String EXTRA_KEY_ID = "keyId";
- protected String mImportData;
+ protected String mImportFilename;
+ protected byte[] mImportData;
+
protected boolean mDeleteAfterImport = false;
FileDialogFragment mFileDialog;
- private TextView mContentView;
-
- private String mScannedContent;
-
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.import_keys);
- mContentView = (TextView) findViewById(R.id.import_from_qr_code_content);
// set actionbar without home button if called from another app
OtherHelper.setActionBarBackButton(this);
@@ -116,7 +113,7 @@ public class ImportKeysActivity extends SherlockFragmentActivity {
return true;
case Id.menu.option.import_from_file:
- showImportKeysDialog();
+ showImportFromFileDialog();
return true;
case Id.menu.option.import_from_qr_code:
@@ -156,15 +153,21 @@ public class ImportKeysActivity extends SherlockFragmentActivity {
if (ACTION_IMPORT.equals(action)) {
if ("file".equals(intent.getScheme()) && intent.getDataString() != null) {
mImportFilename = intent.getData().getPath();
- } else {
- mImportData = intent.getStringExtra(EXTRA_TEXT);
+ mImportData = null;
+ } else if (extras.containsKey(EXTRA_TEXT)) {
+ mImportData = intent.getStringExtra(EXTRA_TEXT).getBytes();
+ mImportFilename = null;
+ } else if (extras.containsKey(EXTRA_KEYRING_BYTES)) {
+ mImportData = intent.getByteArrayExtra(EXTRA_KEYRING_BYTES);
+ mImportFilename = null;
}
- importKeys();
+ loadKeyListFragment();
} else if (ACTION_IMPORT_FROM_FILE.equals(action)) {
if ("file".equals(intent.getScheme()) && intent.getDataString() != null) {
mImportFilename = intent.getData().getPath();
+ mImportData = null;
}
- showImportKeysDialog();
+ showImportFromFileDialog();
} else if (ACTION_IMPORT_FROM_QR_CODE.equals(action)) {
importFromQrCode();
} else if (ACTION_IMPORT_FROM_NFC.equals(action)) {
@@ -172,6 +175,23 @@ public class ImportKeysActivity extends SherlockFragmentActivity {
}
}
+ public void loadKeyListFragment() {
+ if (mImportData != null || mImportFilename != null) {
+ // generate list of keyrings
+ FragmentManager fragmentManager = getSupportFragmentManager();
+ FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
+
+ ImportKeysListFragment listFragment = new ImportKeysListFragment();
+ Bundle args = new Bundle();
+ args.putByteArray(ImportKeysListFragment.ARG_KEYRING_BYTES, mImportData);
+ args.putString(ImportKeysListFragment.ARG_IMPORT_FILENAME, mImportFilename);
+ listFragment.setArguments(args);
+ // replace container in view with fragment
+ fragmentTransaction.replace(R.id.import_keys_list_container, listFragment);
+ fragmentTransaction.commit();
+ }
+ }
+
private void importFromQrCode() {
new IntentIntegrator(this).initiateScan();
}
@@ -186,7 +206,7 @@ public class ImportKeysActivity extends SherlockFragmentActivity {
/**
* Show to dialog from where to import keys
*/
- public void showImportKeysDialog() {
+ public void showImportFromFileDialog() {
// Message is received after file is selected
Handler returnHandler = new Handler() {
@Override
@@ -196,8 +216,11 @@ public class ImportKeysActivity extends SherlockFragmentActivity {
Bundle data = message.getData();
mImportFilename = data.getString(FileDialogFragment.MESSAGE_DATA_FILENAME);
+ Log.d(Constants.TAG, "mImportFilename: " + mImportFilename);
+
mDeleteAfterImport = data.getBoolean(FileDialogFragment.MESSAGE_DATA_CHECKED);
- importKeys();
+
+ loadKeyListFragment();
}
}
};
@@ -209,104 +232,14 @@ public class ImportKeysActivity extends SherlockFragmentActivity {
public void run() {
mFileDialog = FileDialogFragment.newInstance(messenger,
getString(R.string.title_importKeys),
- getString(R.string.specifyFileToImportFrom), mImportFilename, null,
- Id.request.filename);
+ getString(R.string.specifyFileToImportFrom), Constants.path.APP_DIR + "/",
+ null, Id.request.filename);
mFileDialog.show(getSupportFragmentManager(), "fileDialog");
}
});
}
- /**
- * Import keys with mImportData
- */
- public void importKeys() {
- Log.d(Constants.TAG, "importKeys started");
-
- // Send all information needed to service to import key in other thread
- Intent intent = new Intent(this, ApgIntentService.class);
-
- intent.putExtra(ApgIntentService.EXTRA_ACTION, ApgIntentService.ACTION_IMPORT_KEY);
-
- // fill values for this action
- Bundle data = new Bundle();
-
- // TODO
- data.putInt(ApgIntentService.IMPORT_KEY_TYPE, Id.type.secret_key);
-
- if (mImportData != null) {
- data.putInt(ApgIntentService.TARGET, ApgIntentService.TARGET_BYTES);
- data.putByteArray(ApgIntentService.IMPORT_BYTES, mImportData.getBytes());
- } else {
- data.putInt(ApgIntentService.TARGET, ApgIntentService.TARGET_FILE);
- data.putString(ApgIntentService.IMPORT_FILENAME, mImportFilename);
- }
-
- intent.putExtra(ApgIntentService.EXTRA_DATA, data);
-
- // Message is received after importing is done in ApgService
- ApgIntentServiceHandler saveHandler = new ApgIntentServiceHandler(this,
- R.string.progress_importing, ProgressDialog.STYLE_HORIZONTAL) {
- public void handleMessage(Message message) {
- // handle messages by standard ApgHandler first
- super.handleMessage(message);
-
- if (message.arg1 == ApgIntentServiceHandler.MESSAGE_OKAY) {
- // get returned data bundle
- Bundle returnData = message.getData();
-
- int added = returnData.getInt(ApgIntentService.RESULT_IMPORT_ADDED);
- int updated = returnData.getInt(ApgIntentService.RESULT_IMPORT_UPDATED);
- int bad = returnData.getInt(ApgIntentService.RESULT_IMPORT_BAD);
- String toastMessage;
- if (added > 0 && updated > 0) {
- toastMessage = getString(R.string.keysAddedAndUpdated, added, updated);
- } else if (added > 0) {
- toastMessage = getString(R.string.keysAdded, added);
- } else if (updated > 0) {
- toastMessage = getString(R.string.keysUpdated, updated);
- } else {
- toastMessage = getString(R.string.noKeysAddedOrUpdated);
- }
- Toast.makeText(ImportKeysActivity.this, toastMessage, Toast.LENGTH_SHORT)
- .show();
- if (bad > 0) {
- AlertDialog.Builder alert = new AlertDialog.Builder(ImportKeysActivity.this);
-
- alert.setIcon(android.R.drawable.ic_dialog_alert);
- alert.setTitle(R.string.warning);
- alert.setMessage(ImportKeysActivity.this.getString(
- R.string.badKeysEncountered, bad));
-
- alert.setPositiveButton(android.R.string.ok,
- new DialogInterface.OnClickListener() {
- public void onClick(DialogInterface dialog, int id) {
- dialog.cancel();
- }
- });
- alert.setCancelable(true);
- alert.create().show();
- } else if (mDeleteAfterImport) {
- // everything went well, so now delete, if that was turned on
- DeleteFileDialogFragment deleteFileDialog = DeleteFileDialogFragment
- .newInstance(mImportFilename);
- deleteFileDialog.show(getSupportFragmentManager(), "deleteDialog");
- }
- }
- };
- };
-
- // Create a new Messenger for the communication back
- Messenger messenger = new Messenger(saveHandler);
- intent.putExtra(ApgIntentService.EXTRA_MESSENGER, messenger);
-
- // show progress dialog
- saveHandler.showProgressDialog(this);
-
- // start service with intent
- startService(intent);
- }
-
// private void importAndSignOld(final long keyId, final String expectedFingerprint) {
// if (expectedFingerprint != null && expectedFingerprint.length() > 0) {
//
@@ -326,7 +259,7 @@ public class ImportKeysActivity extends SherlockFragmentActivity {
// PGPPublicKeyRing publicKeyRing = (PGPPublicKeyRing) keyring;
//
// // make sure the fingerprints match before we cache this thing
- // String actualFingerprint = PGPHelper.convertToHex(publicKeyRing
+ // String actualFingerprint = PGPHelper.convertFingerprintToHex(publicKeyRing
// .getPublicKey().getFingerprint());
// if (expectedFingerprint.equals(actualFingerprint)) {
// // store the signed key in our local cache
@@ -374,21 +307,36 @@ public class ImportKeysActivity extends SherlockFragmentActivity {
}
public void importOnClick(View view) {
- Log.d(Constants.TAG, "import key started");
+ Log.d(Constants.TAG, "Import key button clicked!");
+
+ importKeys();
+ }
+
+ /**
+ * Import keys with mImportData
+ */
+ public void importKeys() {
+ if (mImportData != null || mImportFilename != null) {
+ Log.d(Constants.TAG, "importKeys started");
- if (mScannedContent != null) {
// Send all information needed to service to import key in other thread
Intent intent = new Intent(this, ApgIntentService.class);
- intent.putExtra(ApgIntentService.EXTRA_ACTION, ApgIntentService.ACTION_IMPORT_KEY);
+ intent.putExtra(ApgIntentService.EXTRA_ACTION, ApgIntentService.ACTION_IMPORT_KEYRING);
// fill values for this action
Bundle data = new Bundle();
- data.putInt(ApgIntentService.IMPORT_KEY_TYPE, Id.type.public_key);
+ // TODO: check for key type?
+ // data.putInt(ApgIntentService.IMPORT_KEY_TYPE, Id.type.secret_key);
- data.putInt(ApgIntentService.TARGET, ApgIntentService.TARGET_BYTES);
- data.putByteArray(ApgIntentService.IMPORT_BYTES, mScannedContent.getBytes());
+ if (mImportData != null) {
+ data.putInt(ApgIntentService.TARGET, ApgIntentService.TARGET_BYTES);
+ data.putByteArray(ApgIntentService.IMPORT_BYTES, mImportData);
+ } else {
+ data.putInt(ApgIntentService.TARGET, ApgIntentService.TARGET_FILE);
+ data.putString(ApgIntentService.IMPORT_FILENAME, mImportFilename);
+ }
intent.putExtra(ApgIntentService.EXTRA_DATA, data);
@@ -435,6 +383,11 @@ public class ImportKeysActivity extends SherlockFragmentActivity {
});
alert.setCancelable(true);
alert.create().show();
+ } else if (mDeleteAfterImport) {
+ // everything went well, so now delete, if that was turned on
+ DeleteFileDialogFragment deleteFileDialog = DeleteFileDialogFragment
+ .newInstance(mImportFilename);
+ deleteFileDialog.show(getSupportFragmentManager(), "deleteDialog");
}
}
};
@@ -449,6 +402,8 @@ public class ImportKeysActivity extends SherlockFragmentActivity {
// start service with intent
startService(intent);
+ } else {
+ Toast.makeText(this, R.string.error_nothingImport, Toast.LENGTH_LONG).show();
}
}
@@ -483,9 +438,11 @@ public class ImportKeysActivity extends SherlockFragmentActivity {
data);
if (scanResult != null && scanResult.getFormatName() != null) {
- mScannedContent = scanResult.getContents();
+ // mScannedContent = scanResult.getContents();
- mContentView.setText(mScannedContent);
+ mImportData = scanResult.getContents().getBytes();
+
+ // mContentView.setText(mScannedContent);
// String[] bits = scanResult.getContents().split(",");
// if (bits.length != 2) {
// return; // dont know how to handle this. Not a valid code
@@ -505,4 +462,12 @@ public class ImportKeysActivity extends SherlockFragmentActivity {
}
}
}
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+
+ loadKeyListFragment();
+ }
+
}
diff --git a/APG/src/org/thialfihar/android/apg/ui/ImportKeysListFragment.java b/APG/src/org/thialfihar/android/apg/ui/ImportKeysListFragment.java
new file mode 100644
index 000000000..157f34c28
--- /dev/null
+++ b/APG/src/org/thialfihar/android/apg/ui/ImportKeysListFragment.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2012 Dominik Schürmann <dominik@dominikschuermann.de>
+ * Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
+ *
+ * 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.
+ */
+
+package org.thialfihar.android.apg.ui;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.thialfihar.android.apg.Constants;
+import org.thialfihar.android.apg.R;
+import org.thialfihar.android.apg.ui.widget.ImportKeysListLoader;
+import org.thialfihar.android.apg.util.Log;
+
+import com.actionbarsherlock.app.SherlockListFragment;
+
+import android.app.Activity;
+import android.os.Bundle;
+import android.support.v4.content.Loader;
+import android.support.v4.app.LoaderManager;
+import android.view.View;
+import android.widget.ListView;
+import android.widget.SimpleAdapter;
+
+public class ImportKeysListFragment extends SherlockListFragment implements
+ LoaderManager.LoaderCallbacks<List<Map<String, String>>> {
+ public static String ARG_KEYRING_BYTES = "bytes";
+ public static String ARG_IMPORT_FILENAME = "filename";
+
+ byte[] mKeyringBytes;
+ String mImportFilename;
+
+ private Activity mActivity;
+ private SimpleAdapter mAdapter;
+
+ @Override
+ public void onListItemClick(ListView listView, View view, int position, long id) {
+ // Map<String, String> item = (Map<String, String>) listView.getItemAtPosition(position);
+ // String userId = item.get(ImportKeysListLoader.MAP_ATTR_USER_ID);
+ }
+
+ /**
+ * Resume is called after rotating
+ */
+ @Override
+ public void onResume() {
+ super.onResume();
+
+ // Start out with a progress indicator.
+ setListShown(false);
+
+ // reload list
+ getLoaderManager().restartLoader(0, null, this);
+ }
+
+ /**
+ * Define Adapter and Loader on create of Activity
+ */
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+
+ mActivity = this.getActivity();
+
+ mKeyringBytes = getArguments().getByteArray(ARG_KEYRING_BYTES);
+ mImportFilename = getArguments().getString(ARG_IMPORT_FILENAME);
+
+ // register long press context menu
+ registerForContextMenu(getListView());
+
+ // Give some text to display if there is no data. In a real
+ // application this would come from a resource.
+ setEmptyText(mActivity.getString(R.string.error_nothingImport));
+
+ // Create an empty adapter we will use to display the loaded data.
+ String[] from = new String[] {};
+ int[] to = new int[] {};
+ List<Map<String, String>> data = new ArrayList<Map<String, String>>();
+ mAdapter = new SimpleAdapter(getActivity(), data, android.R.layout.two_line_list_item,
+ from, to);
+ setListAdapter(mAdapter);
+
+ // Start out with a progress indicator.
+ setListShown(false);
+
+ // Prepare the loader. Either re-connect with an existing one,
+ // or start a new one.
+ getLoaderManager().initLoader(0, null, this);
+ }
+
+ @Override
+ public Loader<List<Map<String, String>>> onCreateLoader(int id, Bundle args) {
+ return new ImportKeysListLoader(mActivity, mKeyringBytes, mImportFilename);
+ }
+
+ @Override
+ public void onLoadFinished(Loader<List<Map<String, String>>> loader,
+ List<Map<String, String>> data) {
+ // Set the new data in the adapter.
+ // for (String item : data) {
+ // mAdapter.add(item);
+ // }
+ Log.d(Constants.TAG, "data: " + data);
+ // TODO: real swapping the data to the already defined adapter doesn't work
+ // Workaround: recreate adapter!
+ // http://stackoverflow.com/questions/2356091/android-add-function-of-arrayadapter-not-working
+ // mAdapter = new ArrayAdapter<String>(mActivity, android.R.layout.two_line_list_item,
+ // data);
+
+ String[] from = new String[] { ImportKeysListLoader.MAP_ATTR_USER_ID,
+ ImportKeysListLoader.MAP_ATTR_FINGERPINT };
+ int[] to = new int[] { android.R.id.text1, android.R.id.text2 };
+ mAdapter = new SimpleAdapter(getActivity(), data, android.R.layout.two_line_list_item,
+ from, to);
+
+ mAdapter.notifyDataSetChanged();
+ setListAdapter(mAdapter);
+
+ // The list should now be shown.
+ if (isResumed()) {
+ setListShown(true);
+ } else {
+ setListShownNoAnimation(true);
+ }
+ }
+
+ @Override
+ public void onLoaderReset(Loader<List<Map<String, String>>> loader) {
+ // Clear the data in the adapter.
+ // Not available in SimpleAdapter!
+ // mAdapter.clear();
+ }
+
+}
diff --git a/APG/src/org/thialfihar/android/apg/ui/KeyListActivity.java b/APG/src/org/thialfihar/android/apg/ui/KeyListActivity.java
index bc345fe90..ac4798f7c 100644
--- a/APG/src/org/thialfihar/android/apg/ui/KeyListActivity.java
+++ b/APG/src/org/thialfihar/android/apg/ui/KeyListActivity.java
@@ -260,7 +260,7 @@ public class KeyListActivity extends SherlockFragmentActivity {
// Send all information needed to service to export key in other thread
Intent intent = new Intent(this, ApgIntentService.class);
- intent.putExtra(ApgIntentService.EXTRA_ACTION, ApgIntentService.ACTION_EXPORT_KEY);
+ intent.putExtra(ApgIntentService.EXTRA_ACTION, ApgIntentService.ACTION_EXPORT_KEYRING);
// fill values for this action
Bundle data = new Bundle();
diff --git a/APG/src/org/thialfihar/android/apg/ui/KeyServerQueryActivity.java b/APG/src/org/thialfihar/android/apg/ui/KeyServerQueryActivity.java
index 593d4e5f4..c7bcb56e5 100644
--- a/APG/src/org/thialfihar/android/apg/ui/KeyServerQueryActivity.java
+++ b/APG/src/org/thialfihar/android/apg/ui/KeyServerQueryActivity.java
@@ -169,7 +169,7 @@ public class KeyServerQueryActivity extends SherlockFragmentActivity {
// Send all information needed to service to query keys in other thread
Intent intent = new Intent(this, ApgIntentService.class);
- intent.putExtra(ApgIntentService.EXTRA_ACTION, ApgIntentService.ACTION_QUERY_KEY);
+ intent.putExtra(ApgIntentService.EXTRA_ACTION, ApgIntentService.ACTION_QUERY_KEYRING);
// fill values for this action
Bundle data = new Bundle();
diff --git a/APG/src/org/thialfihar/android/apg/ui/KeyServerUploadActivity.java b/APG/src/org/thialfihar/android/apg/ui/KeyServerUploadActivity.java
index db907ed48..f1ac05735 100644
--- a/APG/src/org/thialfihar/android/apg/ui/KeyServerUploadActivity.java
+++ b/APG/src/org/thialfihar/android/apg/ui/KeyServerUploadActivity.java
@@ -104,7 +104,7 @@ public class KeyServerUploadActivity extends SherlockFragmentActivity {
// Send all information needed to service to upload key in other thread
Intent intent = new Intent(this, ApgIntentService.class);
- intent.putExtra(ApgIntentService.EXTRA_ACTION, ApgIntentService.ACTION_UPLOAD_KEY);
+ intent.putExtra(ApgIntentService.EXTRA_ACTION, ApgIntentService.ACTION_UPLOAD_KEYRING);
// fill values for this action
Bundle data = new Bundle();
diff --git a/APG/src/org/thialfihar/android/apg/ui/ShareNfcBeamActivity.java b/APG/src/org/thialfihar/android/apg/ui/ShareNfcBeamActivity.java
index d1a1c198c..bdf5f6227 100644
--- a/APG/src/org/thialfihar/android/apg/ui/ShareNfcBeamActivity.java
+++ b/APG/src/org/thialfihar/android/apg/ui/ShareNfcBeamActivity.java
@@ -82,8 +82,6 @@ public class ShareNfcBeamActivity extends SherlockFragmentActivity implements
Toast.LENGTH_LONG).show();
finish();
} else {
- buildView();
-
// handle actions after verifying that nfc works...
handleActions(getIntent());
}
@@ -99,7 +97,7 @@ public class ShareNfcBeamActivity extends SherlockFragmentActivity implements
}
if (ACTION_SHARE_WITH_NFC.equals(action)) {
- long masterKeyId = getIntent().getExtras().getLong(EXTRA_MASTER_KEY_ID);
+ long masterKeyId = extras.getLong(EXTRA_MASTER_KEY_ID);
// get public keyring as byte array
mSharedKeyringBytes = ProviderHelper.getPublicKeyRingsAsByteArray(this,
@@ -121,10 +119,14 @@ public class ShareNfcBeamActivity extends SherlockFragmentActivity implements
NdefMessage msg = (NdefMessage) rawMsgs[0];
// record 0 contains the MIME type, record 1 is the AAR, if present
byte[] receivedKeyringBytes = msg.getRecords()[0].getPayload();
-
-
-
-// Log.d(Constants.TAG, new String());
+
+ Intent importIntent = new Intent(this, ImportKeysActivity.class);
+ importIntent.setAction(ImportKeysActivity.ACTION_IMPORT);
+ importIntent.putExtra(ImportKeysActivity.EXTRA_KEYRING_BYTES, receivedKeyringBytes);
+
+ finish();
+
+ startActivity(importIntent);
}
private void buildView() {
@@ -186,7 +188,8 @@ public class ShareNfcBeamActivity extends SherlockFragmentActivity implements
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_SENT:
- Toast.makeText(getApplicationContext(), "Message sent!", Toast.LENGTH_LONG).show();
+ Toast.makeText(getApplicationContext(), R.string.nfcSuccessfull, Toast.LENGTH_LONG)
+ .show();
break;
}
}
@@ -198,6 +201,10 @@ public class ShareNfcBeamActivity extends SherlockFragmentActivity implements
// Check to see that the Activity started due to an Android Beam
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
handleActionNdefDiscovered(getIntent());
+ } else {
+ // build view only when sending nfc, not when receiving, as it gets directly into Import
+ // activity on receiving
+ buildView();
}
}
diff --git a/APG/src/org/thialfihar/android/apg/ui/ShareQrCodeActivity.java b/APG/src/org/thialfihar/android/apg/ui/ShareQrCodeActivity.java
index 38449bf58..7d4237b80 100644
--- a/APG/src/org/thialfihar/android/apg/ui/ShareQrCodeActivity.java
+++ b/APG/src/org/thialfihar/android/apg/ui/ShareQrCodeActivity.java
@@ -49,7 +49,7 @@ public class ShareQrCodeActivity extends SherlockFragmentActivity {
}
if (ACTION_SHARE_WITH_QR_CODE.equals(action)) {
- long masterKeyId = getIntent().getExtras().getLong(EXTRA_MASTER_KEY_ID);
+ long masterKeyId = extras.getLong(EXTRA_MASTER_KEY_ID);
// get public keyring as ascii armored string
ArrayList<String> keyringArmored = ProviderHelper.getPublicKeyRingsAsArmoredString(
diff --git a/APG/src/org/thialfihar/android/apg/ui/SignKeyActivity.java b/APG/src/org/thialfihar/android/apg/ui/SignKeyActivity.java
index b970cb3d3..f8d47688c 100644
--- a/APG/src/org/thialfihar/android/apg/ui/SignKeyActivity.java
+++ b/APG/src/org/thialfihar/android/apg/ui/SignKeyActivity.java
@@ -198,7 +198,7 @@ public class SignKeyActivity extends SherlockFragmentActivity {
// Send all information needed to service to sign key in other thread
Intent intent = new Intent(this, ApgIntentService.class);
- intent.putExtra(ApgIntentService.EXTRA_ACTION, ApgIntentService.ACTION_SIGN_KEY);
+ intent.putExtra(ApgIntentService.EXTRA_ACTION, ApgIntentService.ACTION_SIGN_KEYRING);
// fill values for this action
Bundle data = new Bundle();
@@ -249,7 +249,7 @@ public class SignKeyActivity extends SherlockFragmentActivity {
// Send all information needed to service to upload key in other thread
Intent intent = new Intent(this, ApgIntentService.class);
- intent.putExtra(ApgIntentService.EXTRA_ACTION, ApgIntentService.ACTION_UPLOAD_KEY);
+ intent.putExtra(ApgIntentService.EXTRA_ACTION, ApgIntentService.ACTION_UPLOAD_KEYRING);
// fill values for this action
Bundle data = new Bundle();
diff --git a/APG/src/org/thialfihar/android/apg/ui/widget/ImportKeysListLoader.java b/APG/src/org/thialfihar/android/apg/ui/widget/ImportKeysListLoader.java
new file mode 100644
index 000000000..75a0ef06f
--- /dev/null
+++ b/APG/src/org/thialfihar/android/apg/ui/widget/ImportKeysListLoader.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
+ *
+ * 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.
+ */
+
+package org.thialfihar.android.apg.ui.widget;
+
+import java.io.BufferedInputStream;
+import java.io.ByteArrayInputStream;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.spongycastle.openpgp.PGPKeyRing;
+import org.thialfihar.android.apg.Constants;
+import org.thialfihar.android.apg.R;
+import org.thialfihar.android.apg.helper.PGPConversionHelper;
+import org.thialfihar.android.apg.helper.PGPHelper;
+import org.thialfihar.android.apg.util.InputData;
+import org.thialfihar.android.apg.util.Log;
+import org.thialfihar.android.apg.util.PositionAwareInputStream;
+
+import android.content.Context;
+import android.support.v4.content.AsyncTaskLoader;
+
+/**
+ * A custom Loader to search for bad adware apps, based on
+ * https://github.com/brosmike/AirPush-Detector. Daniel Bjorge licensed it under Apachev2 after
+ * asking him by mail.
+ */
+public class ImportKeysListLoader extends AsyncTaskLoader<List<Map<String, String>>> {
+ public static final String MAP_ATTR_USER_ID = "user_id";
+ public static final String MAP_ATTR_FINGERPINT = "fingerprint";
+
+ Context mContext;
+ List<String> mItems;
+
+ byte[] mKeyringBytes;
+ String mImportFilename;
+
+ public ImportKeysListLoader(Context context, byte[] keyringBytes, String importFilename) {
+ super(context);
+ this.mContext = context;
+ this.mKeyringBytes = keyringBytes;
+ this.mImportFilename = importFilename;
+ }
+
+ @Override
+ public List<Map<String, String>> loadInBackground() {
+ InputData inputData = null;
+ if (mKeyringBytes != null) {
+ inputData = new InputData(new ByteArrayInputStream(mKeyringBytes), mKeyringBytes.length);
+ } else {
+ try {
+ inputData = new InputData(new FileInputStream(mImportFilename),
+ mImportFilename.length());
+ } catch (FileNotFoundException e) {
+ Log.e(Constants.TAG, "Failed to init FileInputStream!", e);
+ }
+ }
+
+ return generateListOfKeyrings(inputData);
+ }
+
+ @Override
+ protected void onReset() {
+ super.onReset();
+
+ // Ensure the loader is stopped
+ onStopLoading();
+ }
+
+ @Override
+ protected void onStartLoading() {
+ forceLoad();
+ }
+
+ @Override
+ protected void onStopLoading() {
+ cancelLoad();
+ }
+
+ @Override
+ public void deliverResult(List<Map<String, String>> data) {
+ super.deliverResult(data);
+ }
+
+ /**
+ * Similar to PGPMain.importKeyRings
+ *
+ * @param keyringBytes
+ * @return
+ */
+ private ArrayList<Map<String, String>> generateListOfKeyrings(InputData inputData) {
+ ArrayList<Map<String, String>> output = new ArrayList<Map<String, String>>();
+
+ PositionAwareInputStream progressIn = new PositionAwareInputStream(
+ inputData.getInputStream());
+ // need to have access to the bufferedInput, so we can reuse it for the possible
+ // PGPObject chunks after the first one, e.g. files with several consecutive ASCII
+ // armour blocks
+ BufferedInputStream bufferedInput = new BufferedInputStream(progressIn);
+ try {
+ PGPKeyRing keyring = PGPConversionHelper.decodeKeyRing(bufferedInput);
+ while (keyring != null) {
+ String userId = PGPHelper.getMainUserId(keyring.getPublicKey());
+
+ String fingerprint = PGPHelper.convertFingerprintToHex(keyring.getPublicKey()
+ .getFingerprint());
+
+ Map<String, String> attrs = new HashMap<String, String>();
+ attrs.put(MAP_ATTR_USER_ID, userId);
+ attrs.put(MAP_ATTR_FINGERPINT, mContext.getString(R.string.fingerprint) + "\n"
+ + fingerprint);
+ output.add(attrs);
+
+ keyring = PGPConversionHelper.decodeKeyRing(bufferedInput);
+ }
+ } catch (Exception e) {
+ Log.e(Constants.TAG, "Exception", e);
+ }
+
+ return output;
+ }
+
+}
diff --git a/APG/src/org/thialfihar/android/apg/ui/widget/KeyListAdapter.java b/APG/src/org/thialfihar/android/apg/ui/widget/KeyListAdapter.java
index 1f5c3a97e..194142b28 100644
--- a/APG/src/org/thialfihar/android/apg/ui/widget/KeyListAdapter.java
+++ b/APG/src/org/thialfihar/android/apg/ui/widget/KeyListAdapter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Dominik Schürmann <dominik@dominikschuermann.de>
+ * Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -125,7 +125,7 @@ public class KeyListAdapter extends CursorTreeAdapter {
if (userId == null) {
Log.d(Constants.TAG, "userId is null!");
}
- userId.setText(context.getString(R.string.fingerprint) + ":\n" + fingerprint);
+ userId.setText(context.getString(R.string.fingerprint) + "\n" + fingerprint);
} else {
// differentiate between keys and userIds in MergeCursor
if (cursor.getColumnIndex(Keys.KEY_ID) != -1) {
diff --git a/README.md b/README.md
index 22708f8b5..07ca28f63 100644
--- a/README.md
+++ b/README.md
@@ -83,6 +83,8 @@ Android primitives to exchange data: Intent, Intent with return values, Send (al
* IMPORT_FROM_FILE
* IMPORT_FROM_QR_CODE
* IMPORT_FROM_NFC
+* SHARE_WITH_QR_CODE
+* SHARE_WITH_NFC
* EDIT_KEY
* SELECT_PUBLIC_KEYS
* SELECT_SECRET_KEY