mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-11-14 12:55:08 -05:00
externalized import, export, started working on qr code import
This commit is contained in:
parent
5cd51b2ad0
commit
45d760008c
63
org_apg/res/layout/import_from_qr_code.xml
Normal file
63
org_apg/res/layout/import_from_qr_code.xml
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerHorizontal="true" >
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/import_from_qr_code_footer"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingLeft="10dp"
|
||||||
|
android:paddingRight="10dp" >
|
||||||
|
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/import_from_qr_code_import"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/import_from_qr_code_import" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/import_from_qr_code_import_sign_and_upload"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/import_from_qr_code_import_sign_and_upload" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/import_from_qr_code_scan_again"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/import_from_qr_code_scan_again" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/import_from_qr_code_finish"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/import_from_qr_code_finish" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<ScrollView
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="fill_parent"
|
||||||
|
android:layout_above="@id/import_from_qr_code_footer"
|
||||||
|
android:fillViewport="true" >
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingLeft="10dp"
|
||||||
|
android:paddingRight="10dp" >
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/import_from_qr_code_content"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="" />
|
||||||
|
</LinearLayout>
|
||||||
|
</ScrollView>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
@ -34,7 +34,7 @@
|
|||||||
<string name="title_keyServerPreference">Key Server Preference</string>
|
<string name="title_keyServerPreference">Key Server Preference</string>
|
||||||
<string name="title_changePassPhrase">Change Passphrase</string>
|
<string name="title_changePassPhrase">Change Passphrase</string>
|
||||||
<string name="title_setPassPhrase">Set Passphrase</string>
|
<string name="title_setPassPhrase">Set Passphrase</string>
|
||||||
<string name="title_sendEmail">"Send Mail..."</string>
|
<string name="title_sendEmail">"Send Mail…"</string>
|
||||||
<string name="title_encryptToFile">Encrypt To File</string>
|
<string name="title_encryptToFile">Encrypt To File</string>
|
||||||
<string name="title_decryptToFile">Decrypt To File</string>
|
<string name="title_decryptToFile">Decrypt To File</string>
|
||||||
<string name="title_importKeys">Import Keys</string>
|
<string name="title_importKeys">Import Keys</string>
|
||||||
@ -100,7 +100,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 with QR Code</string>
|
<string name="menu_share">Share public key 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>
|
||||||
|
|
||||||
@ -173,10 +173,10 @@
|
|||||||
<string name="dsa">DSA</string>
|
<string name="dsa">DSA</string>
|
||||||
<string name="elgamal">ElGamal</string>
|
<string name="elgamal">ElGamal</string>
|
||||||
<string name="rsa">RSA</string>
|
<string name="rsa">RSA</string>
|
||||||
<string name="filemanager_titleOpen">Open...</string>
|
<string name="filemanager_titleOpen">Open…</string>
|
||||||
<string name="filemanager_titleSave">Save As...</string>
|
<string name="filemanager_titleSave">Save As…</string>
|
||||||
<string name="filemanager_titleEncrypt">Select File To Encrypt...</string>
|
<string name="filemanager_titleEncrypt">Select File To Encrypt…</string>
|
||||||
<string name="filemanager_titleDecrypt">Select File To Decrypt...</string>
|
<string name="filemanager_titleDecrypt">Select File To Decrypt…</string>
|
||||||
<string name="filemanager_btnOpen">Open</string>
|
<string name="filemanager_btnOpen">Open</string>
|
||||||
<string name="filemanager_btnSave">Save</string>
|
<string name="filemanager_btnSave">Save</string>
|
||||||
<string name="warning">Warning</string>
|
<string name="warning">Warning</string>
|
||||||
@ -260,41 +260,41 @@
|
|||||||
<string name="error_savingKeys">error saving some key(s)</string>
|
<string name="error_savingKeys">error saving some key(s)</string>
|
||||||
<string name="error_couldNotExtractPrivateKey">could not extract private key</string>
|
<string name="error_couldNotExtractPrivateKey">could not extract private key</string>
|
||||||
|
|
||||||
<!-- progress_lowerCase: lowercase, phrases, usually ending in '...' -->
|
<!-- progress_lowerCase: lowercase, phrases, usually ending in '…' -->
|
||||||
<string name="progress_done">done.</string>
|
<string name="progress_done">done.</string>
|
||||||
<string name="progress_initializing">initializing...</string>
|
<string name="progress_initializing">initializing…</string>
|
||||||
<string name="progress_saving">saving...</string>
|
<string name="progress_saving">saving…</string>
|
||||||
<string name="progress_importing">importing...</string>
|
<string name="progress_importing">importing…</string>
|
||||||
<string name="progress_exporting">exporting...</string>
|
<string name="progress_exporting">exporting…</string>
|
||||||
<string name="progress_generating">generating key, this can take a while...</string>
|
<string name="progress_generating">generating key, this can take a while…</string>
|
||||||
<string name="progress_buildingKey">building key...</string>
|
<string name="progress_buildingKey">building key…</string>
|
||||||
<string name="progress_preparingMasterKey">preparing master key...</string>
|
<string name="progress_preparingMasterKey">preparing master key…</string>
|
||||||
<string name="progress_certifyingMasterKey">certifying master key...</string>
|
<string name="progress_certifyingMasterKey">certifying master key…</string>
|
||||||
<string name="progress_buildingMasterKeyRing">building master key ring...</string>
|
<string name="progress_buildingMasterKeyRing">building master key ring…</string>
|
||||||
<string name="progress_addingSubKeys">adding sub keys...</string>
|
<string name="progress_addingSubKeys">adding sub keys…</string>
|
||||||
<string name="progress_savingKeyRing">saving key ring...</string>
|
<string name="progress_savingKeyRing">saving key ring…</string>
|
||||||
<string name="progress_importingSecretKeys">importing secret keys...</string>
|
<string name="progress_importingSecretKeys">importing secret keys…</string>
|
||||||
<string name="progress_importingPublicKeys">importing public keys...</string>
|
<string name="progress_importingPublicKeys">importing public keys…</string>
|
||||||
<string name="progress_reloadingKeys">reloading keys...</string>
|
<string name="progress_reloadingKeys">reloading keys…</string>
|
||||||
<string name="progress_exportingKey">exporting key...</string>
|
<string name="progress_exportingKey">exporting key…</string>
|
||||||
<string name="progress_exportingKeys">exporting keys...</string>
|
<string name="progress_exportingKeys">exporting keys…</string>
|
||||||
<string name="progress_extractingSignatureKey">extracting signature key...</string>
|
<string name="progress_extractingSignatureKey">extracting signature key…</string>
|
||||||
<string name="progress_extractingKey">extracting key...</string>
|
<string name="progress_extractingKey">extracting key…</string>
|
||||||
<string name="progress_preparingStreams">preparing streams...</string>
|
<string name="progress_preparingStreams">preparing streams…</string>
|
||||||
<string name="progress_encrypting">encrypting data...</string>
|
<string name="progress_encrypting">encrypting data…</string>
|
||||||
<string name="progress_decrypting">decrypting data...</string>
|
<string name="progress_decrypting">decrypting data…</string>
|
||||||
<string name="progress_preparingSignature">preparing signature...</string>
|
<string name="progress_preparingSignature">preparing signature…</string>
|
||||||
<string name="progress_generatingSignature">generating signature...</string>
|
<string name="progress_generatingSignature">generating signature…</string>
|
||||||
<string name="progress_processingSignature">processing signature...</string>
|
<string name="progress_processingSignature">processing signature…</string>
|
||||||
<string name="progress_verifyingSignature">verifying signature...</string>
|
<string name="progress_verifyingSignature">verifying signature…</string>
|
||||||
<string name="progress_signing">signing...</string>
|
<string name="progress_signing">signing…</string>
|
||||||
<string name="progress_readingData">reading data...</string>
|
<string name="progress_readingData">reading data…</string>
|
||||||
<string name="progress_findingKey">finding key...</string>
|
<string name="progress_findingKey">finding key…</string>
|
||||||
<string name="progress_decompressingData">decompressing data...</string>
|
<string name="progress_decompressingData">decompressing data…</string>
|
||||||
<string name="progress_verifyingIntegrity">verifying integrity...</string>
|
<string name="progress_verifyingIntegrity">verifying integrity…</string>
|
||||||
<string name="progress_deletingSecurely">deleting \'%s\' securely...</string>
|
<string name="progress_deletingSecurely">deleting \'%s\' securely…</string>
|
||||||
<string name="progress_querying">querying...</string>
|
<string name="progress_querying">querying…</string>
|
||||||
<string name="progress_queryingServer">querying %s...</string>
|
<string name="progress_queryingServer">querying %s…</string>
|
||||||
|
|
||||||
<!-- permission strings -->
|
<!-- permission strings -->
|
||||||
<string name="permission_read_key_details_label">Read key details from APG.</string>
|
<string name="permission_read_key_details_label">Read key details from APG.</string>
|
||||||
@ -316,7 +316,7 @@
|
|||||||
<string name="slow">slow</string>
|
<string name="slow">slow</string>
|
||||||
<string name="very_slow">very slow</string>
|
<string name="very_slow">very slow</string>
|
||||||
|
|
||||||
<!-- APG Fork -->
|
<!-- APG 2.0 -->
|
||||||
|
|
||||||
|
|
||||||
<!-- Dashboard -->
|
<!-- Dashboard -->
|
||||||
@ -333,4 +333,11 @@
|
|||||||
<string name="help_tab_about">About</string>
|
<string name="help_tab_about">About</string>
|
||||||
<string name="help_about_version">Version:</string>
|
<string name="help_about_version">Version:</string>
|
||||||
|
|
||||||
|
<!-- Import from QR Code -->
|
||||||
|
|
||||||
|
<string name="import_from_qr_code_import">Import key (only locally)</string>
|
||||||
|
<string name="import_from_qr_code_import_sign_and_upload">Import, Sign, and upload key</string>
|
||||||
|
<string name="import_from_qr_code_scan_again">Scan qr code again</string>
|
||||||
|
<string name="import_from_qr_code_finish">Finish</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
@ -16,6 +16,9 @@
|
|||||||
|
|
||||||
package org.thialfihar.android.apg;
|
package org.thialfihar.android.apg;
|
||||||
|
|
||||||
|
import java.security.Security;
|
||||||
|
|
||||||
|
import org.spongycastle.jce.provider.BouncyCastleProvider;
|
||||||
import org.thialfihar.android.apg.helper.PGPMain;
|
import org.thialfihar.android.apg.helper.PGPMain;
|
||||||
import org.thialfihar.android.apg.service.PassphraseCacheService;
|
import org.thialfihar.android.apg.service.PassphraseCacheService;
|
||||||
|
|
||||||
@ -23,6 +26,10 @@ import android.app.Application;
|
|||||||
|
|
||||||
public class ApgApplication extends Application {
|
public class ApgApplication extends Application {
|
||||||
|
|
||||||
|
static {
|
||||||
|
Security.addProvider(new BouncyCastleProvider());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate() {
|
public void onCreate() {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
|
@ -35,7 +35,7 @@ public final class Id {
|
|||||||
public static final int edit = 0x21070003;
|
public static final int edit = 0x21070003;
|
||||||
public static final int update = 0x21070004;
|
public static final int update = 0x21070004;
|
||||||
public static final int exportToServer = 0x21070005;
|
public static final int exportToServer = 0x21070005;
|
||||||
public static final int share = 0x21070006;
|
public static final int share_qr_code = 0x21070006;
|
||||||
public static final int signKey = 0x21070007;
|
public static final int signKey = 0x21070007;
|
||||||
|
|
||||||
public static final class option {
|
public static final class option {
|
||||||
|
@ -86,6 +86,7 @@ public class OtherHelper {
|
|||||||
*/
|
*/
|
||||||
public static void logDebugBundle(Bundle bundle, String bundleName) {
|
public static void logDebugBundle(Bundle bundle, String bundleName) {
|
||||||
if (Constants.DEBUG) {
|
if (Constants.DEBUG) {
|
||||||
|
if (bundle != null) {
|
||||||
Set<String> ks = bundle.keySet();
|
Set<String> ks = bundle.keySet();
|
||||||
Iterator<String> iterator = ks.iterator();
|
Iterator<String> iterator = ks.iterator();
|
||||||
|
|
||||||
@ -102,6 +103,9 @@ public class OtherHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Log.d(Constants.TAG, "------------------------------");
|
Log.d(Constants.TAG, "------------------------------");
|
||||||
|
} else {
|
||||||
|
Log.d(Constants.TAG, "Bundle " + bundleName + ": null");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
package org.thialfihar.android.apg.helper;
|
package org.thialfihar.android.apg.helper;
|
||||||
|
|
||||||
|
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.Calendar;
|
||||||
@ -24,6 +25,7 @@ import java.util.Date;
|
|||||||
import java.util.GregorianCalendar;
|
import java.util.GregorianCalendar;
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
|
import org.spongycastle.bcpg.ArmoredOutputStream;
|
||||||
import org.spongycastle.bcpg.sig.KeyFlags;
|
import org.spongycastle.bcpg.sig.KeyFlags;
|
||||||
import org.spongycastle.openpgp.PGPKeyRing;
|
import org.spongycastle.openpgp.PGPKeyRing;
|
||||||
import org.spongycastle.openpgp.PGPObjectFactory;
|
import org.spongycastle.openpgp.PGPObjectFactory;
|
||||||
@ -34,8 +36,10 @@ import org.spongycastle.openpgp.PGPSecretKeyRing;
|
|||||||
import org.spongycastle.openpgp.PGPSignature;
|
import org.spongycastle.openpgp.PGPSignature;
|
||||||
import org.spongycastle.openpgp.PGPSignatureSubpacketVector;
|
import org.spongycastle.openpgp.PGPSignatureSubpacketVector;
|
||||||
import org.spongycastle.openpgp.PGPUtil;
|
import org.spongycastle.openpgp.PGPUtil;
|
||||||
|
import org.thialfihar.android.apg.Constants;
|
||||||
import org.thialfihar.android.apg.R;
|
import org.thialfihar.android.apg.R;
|
||||||
import org.thialfihar.android.apg.util.IterableIterator;
|
import org.thialfihar.android.apg.util.IterableIterator;
|
||||||
|
import org.thialfihar.android.apg.util.Log;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
|
||||||
@ -186,7 +190,7 @@ public class PGPHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static PGPPublicKey getEncryptPublicKey(long masterKeyId) {
|
public static PGPPublicKey getEncryptPublicKey(long masterKeyId) {
|
||||||
//TODO: externalize getSecretKeyRing from PGPWrapper into a DatabaseHelper
|
// TODO: externalize getSecretKeyRing from PGPWrapper into a DatabaseHelper
|
||||||
PGPPublicKeyRing keyRing = PGPMain.getPublicKeyRing(masterKeyId);
|
PGPPublicKeyRing keyRing = PGPMain.getPublicKeyRing(masterKeyId);
|
||||||
if (keyRing == null) {
|
if (keyRing == null) {
|
||||||
return null;
|
return null;
|
||||||
@ -199,7 +203,7 @@ public class PGPHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static PGPSecretKey getSigningKey(long masterKeyId) {
|
public static PGPSecretKey getSigningKey(long masterKeyId) {
|
||||||
//TODO: externalize getSecretKeyRing from PGPWrapper into a DatabaseHelper
|
// TODO: externalize getSecretKeyRing from PGPWrapper into a DatabaseHelper
|
||||||
PGPSecretKeyRing keyRing = PGPMain.getSecretKeyRing(masterKeyId);
|
PGPSecretKeyRing keyRing = PGPMain.getSecretKeyRing(masterKeyId);
|
||||||
if (keyRing == null) {
|
if (keyRing == null) {
|
||||||
return null;
|
return null;
|
||||||
@ -380,12 +384,42 @@ public class PGPHelper {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getPubkeyAsArmoredString(long keyId) {
|
||||||
|
PGPPublicKey key = PGPMain.getPublicKey(keyId);
|
||||||
|
// if it is no public key get it from your own keys...
|
||||||
|
if (key == null) {
|
||||||
|
PGPSecretKey secretKey = PGPMain.getSecretKey(keyId);
|
||||||
|
if (secretKey == null) {
|
||||||
|
Log.e(Constants.TAG, "Key could not be found!");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
key = secretKey.getPublicKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
|
ArmoredOutputStream aos = new ArmoredOutputStream(bos);
|
||||||
|
String armouredKey = null;
|
||||||
|
try {
|
||||||
|
aos.write(key.getEncoded());
|
||||||
|
aos.close();
|
||||||
|
|
||||||
|
armouredKey = bos.toString("UTF-8");
|
||||||
|
} catch (IOException e) {
|
||||||
|
Log.e(Constants.TAG, "Problems while encoding key as armored string", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.d(Constants.TAG, "key:" + armouredKey);
|
||||||
|
|
||||||
|
return armouredKey;
|
||||||
|
}
|
||||||
|
|
||||||
public static String getFingerPrint(long keyId) {
|
public static String getFingerPrint(long keyId) {
|
||||||
PGPPublicKey key = PGPMain.getPublicKey(keyId);
|
PGPPublicKey key = PGPMain.getPublicKey(keyId);
|
||||||
if (key == null) {
|
if (key == null) {
|
||||||
PGPSecretKey secretKey = PGPMain.getSecretKey(keyId);
|
PGPSecretKey secretKey = PGPMain.getSecretKey(keyId);
|
||||||
if (secretKey == null) {
|
if (secretKey == null) {
|
||||||
return "";
|
Log.e(Constants.TAG, "Key could not be found!");
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
key = secretKey.getPublicKey();
|
key = secretKey.getPublicKey();
|
||||||
}
|
}
|
||||||
|
@ -662,7 +662,7 @@ public class PGPMain {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Bundle importKeyRings(Activity context, int type, InputData data,
|
public static Bundle importKeyRings(Context context, int type, InputData data,
|
||||||
ProgressDialogUpdater progress) throws GeneralException, FileNotFoundException,
|
ProgressDialogUpdater progress) throws GeneralException, FileNotFoundException,
|
||||||
PGPException, IOException {
|
PGPException, IOException {
|
||||||
Bundle returnData = new Bundle();
|
Bundle returnData = new Bundle();
|
||||||
@ -733,7 +733,7 @@ public class PGPMain {
|
|||||||
return returnData;
|
return returnData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Bundle exportKeyRings(Activity context, Vector<Integer> keyRingIds,
|
public static Bundle exportKeyRings(Context context, Vector<Integer> keyRingIds,
|
||||||
OutputStream outStream, ProgressDialogUpdater progress) throws GeneralException,
|
OutputStream outStream, ProgressDialogUpdater progress) throws GeneralException,
|
||||||
FileNotFoundException, PGPException, IOException {
|
FileNotFoundException, PGPException, IOException {
|
||||||
Bundle returnData = new Bundle();
|
Bundle returnData = new Bundle();
|
||||||
|
@ -26,6 +26,7 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Vector;
|
||||||
|
|
||||||
import org.spongycastle.openpgp.PGPSecretKey;
|
import org.spongycastle.openpgp.PGPSecretKey;
|
||||||
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
||||||
@ -66,7 +67,7 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
|
|||||||
|
|
||||||
/* keys for data bundle */
|
/* keys for data bundle */
|
||||||
|
|
||||||
// encrypt and decrypt
|
// encrypt, decrypt, import export
|
||||||
public static final String TARGET = "target";
|
public static final String TARGET = "target";
|
||||||
// possible targets:
|
// possible targets:
|
||||||
public static final int TARGET_BYTES = 1;
|
public static final int TARGET_BYTES = 1;
|
||||||
@ -91,7 +92,7 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
|
|||||||
public static final String RETURN_BYTES = "returnBinary";
|
public static final String RETURN_BYTES = "returnBinary";
|
||||||
public static final String CIPHERTEXT_BYTES = "ciphertextBytes";
|
public static final String CIPHERTEXT_BYTES = "ciphertextBytes";
|
||||||
public static final String ASSUME_SYMMETRIC = "assumeSymmetric";
|
public static final String ASSUME_SYMMETRIC = "assumeSymmetric";
|
||||||
public static final String LOOKUP_UNKNOWN_KEY = "lookup_unknown_key";
|
public static final String LOOKUP_UNKNOWN_KEY = "lookupUnknownKey";
|
||||||
|
|
||||||
// edit keys
|
// edit keys
|
||||||
public static final String NEW_PASSPHRASE = "newPassphrase";
|
public static final String NEW_PASSPHRASE = "newPassphrase";
|
||||||
@ -103,13 +104,26 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
|
|||||||
|
|
||||||
// generate key
|
// generate key
|
||||||
public static final String ALGORITHM = "algorithm";
|
public static final String ALGORITHM = "algorithm";
|
||||||
public static final String KEY_SIZE = "key_size";
|
public static final String KEY_SIZE = "keySize";
|
||||||
public static final String SYMMETRIC_PASSPHRASE = "passphrase";
|
public static final String SYMMETRIC_PASSPHRASE = "passphrase";
|
||||||
public static final String MASTER_KEY = "masterKey";
|
public static final String MASTER_KEY = "masterKey";
|
||||||
|
|
||||||
// delete file securely
|
// delete file securely
|
||||||
public static final String DELETE_FILE = "deleteFile";
|
public static final String DELETE_FILE = "deleteFile";
|
||||||
|
|
||||||
|
// import key
|
||||||
|
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";
|
||||||
|
|
||||||
|
// export key
|
||||||
|
public static final String EXPORT_OUTPUT_STREAM = "exportOutputStream";
|
||||||
|
public static final String EXPORT_FILENAME = "exportFilename";
|
||||||
|
public static final String EXPORT_KEY_TYPE = "exportKeyType";
|
||||||
|
public static final String EXPORT_ALL = "exportAll";
|
||||||
|
public static final String EXPORT_KEY_RING_ID = "exportKeyRingId";
|
||||||
|
|
||||||
/* possible EXTRA_ACTIONs */
|
/* possible EXTRA_ACTIONs */
|
||||||
public static final int ACTION_ENCRYPT_SIGN = 10;
|
public static final int ACTION_ENCRYPT_SIGN = 10;
|
||||||
|
|
||||||
@ -121,6 +135,9 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
|
|||||||
|
|
||||||
public static final int ACTION_DELETE_FILE_SECURELY = 40;
|
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;
|
||||||
|
|
||||||
/* possible data keys as result send over messenger */
|
/* possible data keys as result send over messenger */
|
||||||
// keys
|
// keys
|
||||||
public static final String RESULT_NEW_KEY = "newKey";
|
public static final String RESULT_NEW_KEY = "newKey";
|
||||||
@ -580,6 +597,104 @@ public class ApgService extends IntentService implements ProgressDialogUpdater {
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ACTION_IMPORT_KEY:
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Operation */
|
||||||
|
InputStream inStream = null;
|
||||||
|
long inLength = -1;
|
||||||
|
InputData inputData = null;
|
||||||
|
switch (target) {
|
||||||
|
case TARGET_BYTES: /* import key from bytes directly */
|
||||||
|
byte[] bytes = data.getByteArray(IMPORT_BYTES);
|
||||||
|
|
||||||
|
inStream = new ByteArrayInputStream(bytes);
|
||||||
|
inLength = bytes.length;
|
||||||
|
|
||||||
|
inputData = new InputData(inStream, inLength);
|
||||||
|
|
||||||
|
break;
|
||||||
|
case TARGET_FILE: /* import key from file */
|
||||||
|
String inputFile = data.getString(IMPORT_FILENAME);
|
||||||
|
|
||||||
|
inStream = new FileInputStream(inputFile);
|
||||||
|
File file = new File(inputFile);
|
||||||
|
inLength = file.length();
|
||||||
|
inputData = new InputData(inStream, inLength);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TARGET_STREAM:
|
||||||
|
// TODO: not implemented
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bundle resultData = new Bundle();
|
||||||
|
resultData = PGPMain.importKeyRings(this, keyType, inputData, this);
|
||||||
|
|
||||||
|
sendMessageToHandler(ApgHandler.MESSAGE_OKAY, resultData);
|
||||||
|
} catch (Exception e) {
|
||||||
|
sendErrorToHandler(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ACTION_EXPORT_KEY:
|
||||||
|
try {
|
||||||
|
|
||||||
|
/* Input */
|
||||||
|
int keyType = Id.type.public_key;
|
||||||
|
if (data.containsKey(EXPORT_KEY_TYPE)) {
|
||||||
|
keyType = data.getInt(EXPORT_KEY_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
String outputFile = data.getString(EXPORT_FILENAME);
|
||||||
|
|
||||||
|
boolean exportAll = data.getBoolean(EXPORT_ALL);
|
||||||
|
int keyRingId = -1;
|
||||||
|
if (!exportAll) {
|
||||||
|
keyRingId = data.getInt(EXPORT_KEY_RING_ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Operation */
|
||||||
|
|
||||||
|
// check if storage is ready
|
||||||
|
if (!FileHelper.isStorageMounted(outputFile)) {
|
||||||
|
sendErrorToHandler(new GeneralException(
|
||||||
|
getString(R.string.error_externalStorageNotReady)));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// OutputStream
|
||||||
|
FileOutputStream outStream = new FileOutputStream(outputFile);
|
||||||
|
|
||||||
|
Vector<Integer> keyRingIds = new Vector<Integer>();
|
||||||
|
if (exportAll) {
|
||||||
|
keyRingIds = PGPMain
|
||||||
|
.getKeyRingIds(keyType == Id.type.public_key ? Id.database.type_public
|
||||||
|
: Id.database.type_secret);
|
||||||
|
} else {
|
||||||
|
keyRingIds.add(keyRingId);
|
||||||
|
}
|
||||||
|
|
||||||
|
Bundle resultData = new Bundle();
|
||||||
|
resultData = PGPMain.exportKeyRings(this, keyRingIds, outStream, this);
|
||||||
|
|
||||||
|
sendMessageToHandler(ApgHandler.MESSAGE_OKAY, resultData);
|
||||||
|
} catch (Exception e) {
|
||||||
|
sendErrorToHandler(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -693,7 +693,7 @@ public class DecryptActivity extends SherlockFragmentActivity {
|
|||||||
private void decryptStart() {
|
private void decryptStart() {
|
||||||
Log.d(Constants.TAG, "decryptStart");
|
Log.d(Constants.TAG, "decryptStart");
|
||||||
|
|
||||||
// Send all information needed to service to edit key in other thread
|
// Send all information needed to service to decrypt in other thread
|
||||||
Intent intent = new Intent(this, ApgService.class);
|
Intent intent = new Intent(this, ApgService.class);
|
||||||
|
|
||||||
// fill values for this action
|
// fill values for this action
|
||||||
|
@ -33,6 +33,8 @@ import android.content.Intent;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import org.thialfihar.android.apg.util.Log;
|
import org.thialfihar.android.apg.util.Log;
|
||||||
|
|
||||||
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.google.zxing.integration.android.IntentIntegrator;
|
import com.google.zxing.integration.android.IntentIntegrator;
|
||||||
@ -61,87 +63,99 @@ public class ImportFromQRCodeActivity extends BaseActivity {
|
|||||||
new IntentIntegrator(this).initiateScan();
|
new IntentIntegrator(this).initiateScan();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// private void importAndSignOld(final long keyId, final String expectedFingerprint) {
|
||||||
|
// if (expectedFingerprint != null && expectedFingerprint.length() > 0) {
|
||||||
|
//
|
||||||
|
// Thread t = new Thread() {
|
||||||
|
// @Override
|
||||||
|
// public void run() {
|
||||||
|
// try {
|
||||||
|
// // TODO: display some sort of spinner here while the user waits
|
||||||
|
//
|
||||||
|
// // TODO: there should be only 1
|
||||||
|
// HkpKeyServer server = new HkpKeyServer(mPreferences.getKeyServers()[0]);
|
||||||
|
// String encodedKey = server.get(keyId);
|
||||||
|
//
|
||||||
|
// PGPKeyRing keyring = PGPHelper.decodeKeyRing(new ByteArrayInputStream(
|
||||||
|
// encodedKey.getBytes()));
|
||||||
|
// if (keyring != null && keyring instanceof PGPPublicKeyRing) {
|
||||||
|
// PGPPublicKeyRing publicKeyRing = (PGPPublicKeyRing) keyring;
|
||||||
|
//
|
||||||
|
// // make sure the fingerprints match before we cache this thing
|
||||||
|
// String actualFingerprint = PGPHelper.convertToHex(publicKeyRing
|
||||||
|
// .getPublicKey().getFingerprint());
|
||||||
|
// if (expectedFingerprint.equals(actualFingerprint)) {
|
||||||
|
// // store the signed key in our local cache
|
||||||
|
// int retval = PGPMain.storeKeyRingInCache(publicKeyRing);
|
||||||
|
// if (retval != Id.return_value.ok
|
||||||
|
// && retval != Id.return_value.updated) {
|
||||||
|
// status.putString(EXTRA_ERROR,
|
||||||
|
// "Failed to store signed key in local cache");
|
||||||
|
// } else {
|
||||||
|
// Intent intent = new Intent(ImportFromQRCodeActivity.this,
|
||||||
|
// SignKeyActivity.class);
|
||||||
|
// intent.putExtra(EXTRA_KEY_ID, keyId);
|
||||||
|
// startActivityForResult(intent, Id.request.sign_key);
|
||||||
|
// }
|
||||||
|
// } else {
|
||||||
|
// status.putString(
|
||||||
|
// EXTRA_ERROR,
|
||||||
|
// "Scanned fingerprint does NOT match the fingerprint of the received key. You shouldnt trust this key.");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// } catch (QueryException e) {
|
||||||
|
// Log.e(TAG, "Failed to query KeyServer", e);
|
||||||
|
// status.putString(EXTRA_ERROR, "Failed to query KeyServer");
|
||||||
|
// status.putInt(Constants.extras.STATUS, Id.message.done);
|
||||||
|
// } catch (IOException e) {
|
||||||
|
// Log.e(TAG, "Failed to query KeyServer", e);
|
||||||
|
// status.putString(EXTRA_ERROR, "Failed to query KeyServer");
|
||||||
|
// status.putInt(Constants.extras.STATUS, Id.message.done);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// t.setName("KeyExchange Download Thread");
|
||||||
|
// t.setDaemon(true);
|
||||||
|
// t.start();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
private void importAndSign(final long keyId, final String expectedFingerprint) {
|
private void importAndSign(final long keyId, final String expectedFingerprint) {
|
||||||
if (expectedFingerprint != null && expectedFingerprint.length() > 0) {
|
|
||||||
|
|
||||||
Thread t = new Thread() {
|
// setContentView(R.layout.import_from_qr_code);
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
// TODO: display some sort of spinner here while the user waits
|
|
||||||
|
|
||||||
// TODO: there should be only 1
|
|
||||||
HkpKeyServer server = new HkpKeyServer(mPreferences.getKeyServers()[0]);
|
|
||||||
String encodedKey = server.get(keyId);
|
|
||||||
|
|
||||||
PGPKeyRing keyring = PGPHelper.decodeKeyRing(new ByteArrayInputStream(
|
|
||||||
encodedKey.getBytes()));
|
|
||||||
if (keyring != null && keyring instanceof PGPPublicKeyRing) {
|
|
||||||
PGPPublicKeyRing publicKeyRing = (PGPPublicKeyRing) keyring;
|
|
||||||
|
|
||||||
// make sure the fingerprints match before we cache this thing
|
|
||||||
String actualFingerprint = PGPHelper.convertToHex(publicKeyRing
|
|
||||||
.getPublicKey().getFingerprint());
|
|
||||||
if (expectedFingerprint.equals(actualFingerprint)) {
|
|
||||||
// store the signed key in our local cache
|
|
||||||
int retval = PGPMain.storeKeyRingInCache(publicKeyRing);
|
|
||||||
if (retval != Id.return_value.ok
|
|
||||||
&& retval != Id.return_value.updated) {
|
|
||||||
status.putString(EXTRA_ERROR,
|
|
||||||
"Failed to store signed key in local cache");
|
|
||||||
} else {
|
|
||||||
Intent intent = new Intent(ImportFromQRCodeActivity.this,
|
|
||||||
SignKeyActivity.class);
|
|
||||||
intent.putExtra(EXTRA_KEY_ID, keyId);
|
|
||||||
startActivityForResult(intent, Id.request.sign_key);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
status.putString(
|
|
||||||
EXTRA_ERROR,
|
|
||||||
"Scanned fingerprint does NOT match the fingerprint of the received key. You shouldnt trust this key.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (QueryException e) {
|
|
||||||
Log.e(TAG, "Failed to query KeyServer", e);
|
|
||||||
status.putString(EXTRA_ERROR, "Failed to query KeyServer");
|
|
||||||
status.putInt(Constants.extras.STATUS, Id.message.done);
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.e(TAG, "Failed to query KeyServer", e);
|
|
||||||
status.putString(EXTRA_ERROR, "Failed to query KeyServer");
|
|
||||||
status.putInt(Constants.extras.STATUS, Id.message.done);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
t.setName("KeyExchange Download Thread");
|
|
||||||
t.setDaemon(true);
|
|
||||||
t.start();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
switch (requestCode) {
|
switch (requestCode) {
|
||||||
case IntentIntegrator.REQUEST_CODE: {
|
case IntentIntegrator.REQUEST_CODE: {
|
||||||
boolean debug = true; // TODO: remove this!!!
|
|
||||||
IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode,
|
IntentResult scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode,
|
||||||
data);
|
data);
|
||||||
if (debug || (scanResult != null && scanResult.getFormatName() != null)) {
|
if (scanResult != null && scanResult.getFormatName() != null) {
|
||||||
String[] bits = debug ? new String[] { "5993515643896327656",
|
|
||||||
"0816 F68A 6816 68FB 01BF 2CA5 532D 3EB9 1E2F EDE8" } : scanResult
|
// show layout
|
||||||
.getContents().split(",");
|
setContentView(R.layout.import_from_qr_code);
|
||||||
if (bits.length != 2) {
|
TextView contentView = (TextView) findViewById(R.id.import_from_qr_code_content);
|
||||||
return; // dont know how to handle this. Not a valid code
|
|
||||||
|
String content = scanResult.getContents();
|
||||||
|
|
||||||
|
contentView.setText(content);
|
||||||
|
// String[] bits = scanResult.getContents().split(",");
|
||||||
|
// if (bits.length != 2) {
|
||||||
|
// return; // dont know how to handle this. Not a valid code
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// long keyId = Long.parseLong(bits[0]);
|
||||||
|
// String expectedFingerprint = bits[1];
|
||||||
|
|
||||||
|
// importAndSign(keyId, expectedFingerprint);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
long keyId = Long.parseLong(bits[0]);
|
|
||||||
String expectedFingerprint = bits[1];
|
|
||||||
|
|
||||||
importAndSign(keyId, expectedFingerprint);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
case Id.request.sign_key: {
|
case Id.request.sign_key: {
|
||||||
// signals the end of processing. Signature was either applied, or it wasnt
|
// signals the end of processing. Signature was either applied, or it wasnt
|
||||||
|
@ -16,9 +16,6 @@
|
|||||||
|
|
||||||
package org.thialfihar.android.apg.ui;
|
package org.thialfihar.android.apg.ui;
|
||||||
|
|
||||||
import org.spongycastle.openpgp.PGPException;
|
|
||||||
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
|
||||||
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
|
||||||
import org.thialfihar.android.apg.Constants;
|
import org.thialfihar.android.apg.Constants;
|
||||||
import org.thialfihar.android.apg.Id;
|
import org.thialfihar.android.apg.Id;
|
||||||
import org.thialfihar.android.apg.helper.PGPHelper;
|
import org.thialfihar.android.apg.helper.PGPHelper;
|
||||||
@ -26,14 +23,19 @@ import org.thialfihar.android.apg.helper.PGPMain;
|
|||||||
import org.thialfihar.android.apg.provider.KeyRings;
|
import org.thialfihar.android.apg.provider.KeyRings;
|
||||||
import org.thialfihar.android.apg.provider.Keys;
|
import org.thialfihar.android.apg.provider.Keys;
|
||||||
import org.thialfihar.android.apg.provider.UserIds;
|
import org.thialfihar.android.apg.provider.UserIds;
|
||||||
|
import org.thialfihar.android.apg.service.ApgHandler;
|
||||||
|
import org.thialfihar.android.apg.service.ApgService;
|
||||||
|
import org.thialfihar.android.apg.ui.dialog.DeleteFileDialogFragment;
|
||||||
|
import org.thialfihar.android.apg.ui.dialog.DeleteKeyDialogFragment;
|
||||||
import org.thialfihar.android.apg.ui.dialog.FileDialogFragment;
|
import org.thialfihar.android.apg.ui.dialog.FileDialogFragment;
|
||||||
import org.thialfihar.android.apg.util.InputData;
|
import org.thialfihar.android.apg.ui.dialog.ProgressDialogFragment;
|
||||||
import org.thialfihar.android.apg.R;
|
import org.thialfihar.android.apg.R;
|
||||||
|
|
||||||
|
import com.actionbarsherlock.app.SherlockFragmentActivity;
|
||||||
import com.actionbarsherlock.view.MenuItem;
|
import com.actionbarsherlock.view.MenuItem;
|
||||||
|
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.app.Dialog;
|
import android.app.ProgressDialog;
|
||||||
import android.app.SearchManager;
|
import android.app.SearchManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
@ -59,25 +61,14 @@ import android.widget.ImageView;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
public class KeyListActivity extends BaseActivity {
|
public class KeyListActivity extends SherlockFragmentActivity {
|
||||||
|
|
||||||
public static final String ACTION_IMPORT = Constants.INTENT_PREFIX + "IMPORT";
|
public static final String ACTION_IMPORT = Constants.INTENT_PREFIX + "IMPORT";
|
||||||
|
|
||||||
public static final String EXTRA_TEXT = "text";
|
public static final String EXTRA_TEXT = "text";
|
||||||
|
|
||||||
// TODO: remove when using new intentservice:
|
|
||||||
public static final String EXTRA_ERROR = "error";
|
|
||||||
|
|
||||||
protected ExpandableListView mList;
|
protected ExpandableListView mList;
|
||||||
protected KeyListAdapter mListAdapter;
|
protected KeyListAdapter mListAdapter;
|
||||||
protected View mFilterLayout;
|
protected View mFilterLayout;
|
||||||
@ -251,7 +242,7 @@ public class KeyListActivity extends BaseActivity {
|
|||||||
|
|
||||||
case Id.menu.delete: {
|
case Id.menu.delete: {
|
||||||
mSelectedItem = groupPosition;
|
mSelectedItem = groupPosition;
|
||||||
showDialog(Id.dialog.delete_key);
|
showDeleteKeyDialog();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,177 +252,87 @@ public class KeyListActivity extends BaseActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void showDeleteKeyDialog() {
|
||||||
protected Dialog onCreateDialog(int id) {
|
|
||||||
|
|
||||||
switch (id) {
|
|
||||||
case Id.dialog.delete_key: {
|
|
||||||
final int keyRingId = mListAdapter.getKeyRingId(mSelectedItem);
|
final int keyRingId = mListAdapter.getKeyRingId(mSelectedItem);
|
||||||
mSelectedItem = -1;
|
mSelectedItem = -1;
|
||||||
// TODO: better way to do this?
|
|
||||||
String userId = "<unknown>";
|
|
||||||
Object keyRing = PGPMain.getKeyRing(keyRingId);
|
|
||||||
if (keyRing != null) {
|
|
||||||
if (keyRing instanceof PGPPublicKeyRing) {
|
|
||||||
userId = PGPHelper.getMainUserIdSafe(this,
|
|
||||||
PGPHelper.getMasterKey((PGPPublicKeyRing) keyRing));
|
|
||||||
} else {
|
|
||||||
userId = PGPHelper.getMainUserIdSafe(this,
|
|
||||||
PGPHelper.getMasterKey((PGPSecretKeyRing) keyRing));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
// Message is received after key is deleted
|
||||||
builder.setTitle(R.string.warning);
|
Handler returnHandler = new Handler() {
|
||||||
builder.setMessage(getString(
|
@Override
|
||||||
mKeyType == Id.type.public_key ? R.string.keyDeletionConfirmation
|
public void handleMessage(Message message) {
|
||||||
: R.string.secretKeyDeletionConfirmation, userId));
|
if (message.what == DeleteKeyDialogFragment.MESSAGE_OKAY) {
|
||||||
builder.setIcon(android.R.drawable.ic_dialog_alert);
|
refreshList();
|
||||||
builder.setPositiveButton(R.string.btn_delete, new DialogInterface.OnClickListener() {
|
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
|
||||||
deleteKey(keyRingId);
|
|
||||||
removeDialog(Id.dialog.delete_key);
|
|
||||||
}
|
}
|
||||||
});
|
|
||||||
builder.setNegativeButton(android.R.string.cancel,
|
|
||||||
new DialogInterface.OnClickListener() {
|
|
||||||
public void onClick(DialogInterface dialog, int id) {
|
|
||||||
removeDialog(Id.dialog.delete_key);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return builder.create();
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
default: {
|
// Create a new Messenger for the communication back
|
||||||
return super.onCreateDialog(id);
|
Messenger messenger = new Messenger(returnHandler);
|
||||||
}
|
|
||||||
}
|
DeleteKeyDialogFragment deleteKeyDialog = DeleteKeyDialogFragment.newInstance(messenger,
|
||||||
|
keyRingId, mKeyType);
|
||||||
|
|
||||||
|
deleteKeyDialog.show(getSupportFragmentManager(), "deleteKeyDialog");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void importKeys() {
|
public void importKeys() {
|
||||||
showDialog(Id.dialog.importing);
|
Log.d(Constants.TAG, "importKeys started");
|
||||||
mTask = Id.task.import_keys;
|
|
||||||
startThread();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void exportKeys() {
|
// Send all information needed to service to import key in other thread
|
||||||
showDialog(Id.dialog.exporting);
|
Intent intent = new Intent(this, ApgService.class);
|
||||||
mTask = Id.task.export_keys;
|
|
||||||
startThread();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
intent.putExtra(ApgService.EXTRA_ACTION, ApgService.ACTION_IMPORT_KEY);
|
||||||
public void run() {
|
|
||||||
String error = null;
|
// fill values for this action
|
||||||
Bundle data = new Bundle();
|
Bundle data = new Bundle();
|
||||||
Message msg = new Message();
|
|
||||||
|
|
||||||
try {
|
data.putInt(ApgService.IMPORT_KEY_TYPE, mKeyType);
|
||||||
InputStream importInputStream = null;
|
|
||||||
OutputStream exportOutputStream = null;
|
|
||||||
long size = 0;
|
|
||||||
if (mTask == Id.task.import_keys) {
|
|
||||||
if (mImportData != null) {
|
if (mImportData != null) {
|
||||||
byte[] bytes = mImportData.getBytes();
|
data.putInt(ApgService.TARGET, ApgService.TARGET_BYTES);
|
||||||
size = bytes.length;
|
data.putByteArray(ApgService.IMPORT_BYTES, mImportData.getBytes());
|
||||||
importInputStream = new ByteArrayInputStream(bytes);
|
|
||||||
} else {
|
} else {
|
||||||
File file = new File(mImportFilename);
|
data.putInt(ApgService.TARGET, ApgService.TARGET_FILE);
|
||||||
size = file.length();
|
data.putString(ApgService.IMPORT_FILENAME, mImportFilename);
|
||||||
importInputStream = new FileInputStream(file);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
exportOutputStream = new FileOutputStream(mExportFilename);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mTask == Id.task.import_keys) {
|
intent.putExtra(ApgService.EXTRA_DATA, data);
|
||||||
data = PGPMain.importKeyRings(this, mKeyType, new InputData(importInputStream,
|
|
||||||
size), this);
|
|
||||||
} else {
|
|
||||||
Vector<Integer> keyRingIds = new Vector<Integer>();
|
|
||||||
if (mSelectedItem == -1) {
|
|
||||||
keyRingIds = PGPMain
|
|
||||||
.getKeyRingIds(mKeyType == Id.type.public_key ? Id.database.type_public
|
|
||||||
: Id.database.type_secret);
|
|
||||||
} else {
|
|
||||||
int keyRingId = mListAdapter.getKeyRingId(mSelectedItem);
|
|
||||||
keyRingIds.add(keyRingId);
|
|
||||||
mSelectedItem = -1;
|
|
||||||
}
|
|
||||||
data = PGPMain.exportKeyRings(this, keyRingIds, exportOutputStream, this);
|
|
||||||
}
|
|
||||||
} catch (FileNotFoundException e) {
|
|
||||||
error = getString(R.string.error_fileNotFound);
|
|
||||||
} catch (IOException e) {
|
|
||||||
error = "" + e;
|
|
||||||
} catch (PGPException e) {
|
|
||||||
error = "" + e;
|
|
||||||
} catch (PGPMain.GeneralException e) {
|
|
||||||
error = "" + e;
|
|
||||||
}
|
|
||||||
|
|
||||||
mImportData = null;
|
// create progress dialog
|
||||||
|
ProgressDialogFragment importingDialog = ProgressDialogFragment.newInstance(
|
||||||
|
R.string.progress_importing, ProgressDialog.STYLE_HORIZONTAL);
|
||||||
|
|
||||||
if (mTask == Id.task.import_keys) {
|
// Message is received after importing is done in ApgService
|
||||||
data.putInt(Constants.extras.STATUS, Id.message.import_done);
|
ApgHandler saveHandler = new ApgHandler(this, importingDialog) {
|
||||||
} else {
|
public void handleMessage(Message message) {
|
||||||
data.putInt(Constants.extras.STATUS, Id.message.export_done);
|
// handle messages by standard ApgHandler first
|
||||||
}
|
super.handleMessage(message);
|
||||||
|
|
||||||
if (error != null) {
|
if (message.arg1 == ApgHandler.MESSAGE_OKAY) {
|
||||||
data.putString(EXTRA_ERROR, error);
|
// get returned data bundle
|
||||||
}
|
Bundle returnData = message.getData();
|
||||||
|
|
||||||
msg.setData(data);
|
int added = returnData.getInt("added");
|
||||||
sendMessage(msg);
|
int updated = returnData.getInt("updated");
|
||||||
}
|
int bad = returnData.getInt("bad");
|
||||||
|
String toastMessage;
|
||||||
protected void deleteKey(int keyRingId) {
|
|
||||||
PGPMain.deleteKey(keyRingId);
|
|
||||||
refreshList();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void refreshList() {
|
|
||||||
mListAdapter.rebuild(true);
|
|
||||||
mListAdapter.notifyDataSetChanged();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void doneCallback(Message msg) {
|
|
||||||
super.doneCallback(msg);
|
|
||||||
|
|
||||||
Bundle data = msg.getData();
|
|
||||||
if (data != null) {
|
|
||||||
int type = data.getInt(Constants.extras.STATUS);
|
|
||||||
switch (type) {
|
|
||||||
case Id.message.import_done: {
|
|
||||||
removeDialog(Id.dialog.importing);
|
|
||||||
|
|
||||||
String error = data.getString(EXTRA_ERROR);
|
|
||||||
if (error != null) {
|
|
||||||
Toast.makeText(KeyListActivity.this, getString(R.string.errorMessage, error),
|
|
||||||
Toast.LENGTH_SHORT).show();
|
|
||||||
} else {
|
|
||||||
int added = data.getInt("added");
|
|
||||||
int updated = data.getInt("updated");
|
|
||||||
int bad = data.getInt("bad");
|
|
||||||
String message;
|
|
||||||
if (added > 0 && updated > 0) {
|
if (added > 0 && updated > 0) {
|
||||||
message = getString(R.string.keysAddedAndUpdated, added, updated);
|
toastMessage = getString(R.string.keysAddedAndUpdated, added, updated);
|
||||||
} else if (added > 0) {
|
} else if (added > 0) {
|
||||||
message = getString(R.string.keysAdded, added);
|
toastMessage = getString(R.string.keysAdded, added);
|
||||||
} else if (updated > 0) {
|
} else if (updated > 0) {
|
||||||
message = getString(R.string.keysUpdated, updated);
|
toastMessage = getString(R.string.keysUpdated, updated);
|
||||||
} else {
|
} else {
|
||||||
message = getString(R.string.noKeysAddedOrUpdated);
|
toastMessage = getString(R.string.noKeysAddedOrUpdated);
|
||||||
}
|
}
|
||||||
Toast.makeText(KeyListActivity.this, message, Toast.LENGTH_SHORT).show();
|
Toast.makeText(KeyListActivity.this, toastMessage, Toast.LENGTH_SHORT).show();
|
||||||
if (bad > 0) {
|
if (bad > 0) {
|
||||||
AlertDialog.Builder alert = new AlertDialog.Builder(this);
|
AlertDialog.Builder alert = new AlertDialog.Builder(KeyListActivity.this);
|
||||||
|
|
||||||
alert.setIcon(android.R.drawable.ic_dialog_alert);
|
alert.setIcon(android.R.drawable.ic_dialog_alert);
|
||||||
alert.setTitle(R.string.warning);
|
alert.setTitle(R.string.warning);
|
||||||
alert.setMessage(this.getString(R.string.badKeysEncountered, bad));
|
alert.setMessage(KeyListActivity.this.getString(
|
||||||
|
R.string.badKeysEncountered, bad));
|
||||||
|
|
||||||
alert.setPositiveButton(android.R.string.ok,
|
alert.setPositiveButton(android.R.string.ok,
|
||||||
new DialogInterface.OnClickListener() {
|
new DialogInterface.OnClickListener() {
|
||||||
@ -443,41 +344,94 @@ public class KeyListActivity extends BaseActivity {
|
|||||||
alert.create().show();
|
alert.create().show();
|
||||||
} else if (mDeleteAfterImport) {
|
} else if (mDeleteAfterImport) {
|
||||||
// everything went well, so now delete, if that was turned on
|
// everything went well, so now delete, if that was turned on
|
||||||
setDeleteFile(mImportFilename);
|
DeleteFileDialogFragment deleteFileDialog = DeleteFileDialogFragment
|
||||||
showDialog(Id.dialog.delete_file);
|
.newInstance(mImportFilename);
|
||||||
}
|
deleteFileDialog.show(getSupportFragmentManager(), "deleteDialog");
|
||||||
}
|
}
|
||||||
refreshList();
|
refreshList();
|
||||||
break;
|
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create a new Messenger for the communication back
|
||||||
|
Messenger messenger = new Messenger(saveHandler);
|
||||||
|
intent.putExtra(ApgService.EXTRA_MESSENGER, messenger);
|
||||||
|
|
||||||
|
// show progress dialog
|
||||||
|
importingDialog.show(getSupportFragmentManager(), "importingDialog");
|
||||||
|
|
||||||
|
// start service with intent
|
||||||
|
startService(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
case Id.message.export_done: {
|
public void exportKeys() {
|
||||||
removeDialog(Id.dialog.exporting);
|
Log.d(Constants.TAG, "exportKeys started");
|
||||||
|
|
||||||
String error = data.getString(EXTRA_ERROR);
|
// Send all information needed to service to export key in other thread
|
||||||
if (error != null) {
|
Intent intent = new Intent(this, ApgService.class);
|
||||||
Toast.makeText(KeyListActivity.this, getString(R.string.errorMessage, error),
|
|
||||||
Toast.LENGTH_SHORT).show();
|
intent.putExtra(ApgService.EXTRA_ACTION, ApgService.ACTION_EXPORT_KEY);
|
||||||
|
|
||||||
|
// fill values for this action
|
||||||
|
Bundle data = new Bundle();
|
||||||
|
|
||||||
|
data.putString(ApgService.EXPORT_FILENAME, mExportFilename);
|
||||||
|
data.putInt(ApgService.EXPORT_KEY_TYPE, mKeyType);
|
||||||
|
|
||||||
|
if (mSelectedItem == -1) {
|
||||||
|
data.putBoolean(ApgService.EXPORT_ALL, true);
|
||||||
} else {
|
} else {
|
||||||
int exported = data.getInt("exported");
|
int keyRingId = mListAdapter.getKeyRingId(mSelectedItem);
|
||||||
String message;
|
data.putInt(ApgService.EXPORT_KEY_RING_ID, keyRingId);
|
||||||
|
mSelectedItem = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
intent.putExtra(ApgService.EXTRA_DATA, data);
|
||||||
|
|
||||||
|
// create progress dialog
|
||||||
|
ProgressDialogFragment exportingDialog = ProgressDialogFragment.newInstance(
|
||||||
|
R.string.progress_exporting, ProgressDialog.STYLE_HORIZONTAL);
|
||||||
|
|
||||||
|
// Message is received after exporting is done in ApgService
|
||||||
|
ApgHandler exportHandler = new ApgHandler(this, exportingDialog) {
|
||||||
|
public void handleMessage(Message message) {
|
||||||
|
// handle messages by standard ApgHandler first
|
||||||
|
super.handleMessage(message);
|
||||||
|
|
||||||
|
if (message.arg1 == ApgHandler.MESSAGE_OKAY) {
|
||||||
|
// get returned data bundle
|
||||||
|
Bundle returnData = message.getData();
|
||||||
|
|
||||||
|
int exported = returnData.getInt("exported");
|
||||||
|
String toastMessage;
|
||||||
if (exported == 1) {
|
if (exported == 1) {
|
||||||
message = getString(R.string.keyExported);
|
toastMessage = getString(R.string.keyExported);
|
||||||
} else if (exported > 0) {
|
} else if (exported > 0) {
|
||||||
message = getString(R.string.keysExported, exported);
|
toastMessage = getString(R.string.keysExported, exported);
|
||||||
} else {
|
} else {
|
||||||
message = getString(R.string.noKeysExported);
|
toastMessage = getString(R.string.noKeysExported);
|
||||||
}
|
}
|
||||||
Toast.makeText(KeyListActivity.this, message, Toast.LENGTH_SHORT).show();
|
Toast.makeText(KeyListActivity.this, toastMessage, Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
}
|
}
|
||||||
break;
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create a new Messenger for the communication back
|
||||||
|
Messenger messenger = new Messenger(exportHandler);
|
||||||
|
intent.putExtra(ApgService.EXTRA_MESSENGER, messenger);
|
||||||
|
|
||||||
|
// show progress dialog
|
||||||
|
exportingDialog.show(getSupportFragmentManager(), "exportingDialog");
|
||||||
|
|
||||||
|
// start service with intent
|
||||||
|
startService(intent);
|
||||||
}
|
}
|
||||||
|
|
||||||
default: {
|
protected void refreshList() {
|
||||||
break;
|
mListAdapter.rebuild(true);
|
||||||
}
|
mListAdapter.notifyDataSetChanged();
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected class KeyListAdapter extends BaseExpandableListAdapter {
|
protected class KeyListAdapter extends BaseExpandableListAdapter {
|
||||||
|
@ -1,212 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.Vector;
|
|
||||||
import java.util.regex.Matcher;
|
|
||||||
|
|
||||||
import org.thialfihar.android.apg.R;
|
|
||||||
import org.thialfihar.android.apg.helper.PGPMain;
|
|
||||||
import org.thialfihar.android.apg.helper.Preferences;
|
|
||||||
|
|
||||||
import android.app.ListActivity;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.database.Cursor;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.text.Html;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.AdapterView;
|
|
||||||
import android.widget.AdapterView.OnItemClickListener;
|
|
||||||
import android.widget.BaseAdapter;
|
|
||||||
import android.widget.ImageView;
|
|
||||||
import android.widget.ListAdapter;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
public class MailListActivity extends ListActivity {
|
|
||||||
LayoutInflater mInflater = null;
|
|
||||||
|
|
||||||
public static final String EXTRA_ACCOUNT = "account";
|
|
||||||
|
|
||||||
private static class Conversation {
|
|
||||||
public long id;
|
|
||||||
public String subject;
|
|
||||||
public Vector<Message> messages;
|
|
||||||
|
|
||||||
public Conversation(long id, String subject) {
|
|
||||||
this.id = id;
|
|
||||||
this.subject = subject;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class Message {
|
|
||||||
public Conversation parent;
|
|
||||||
public long id;
|
|
||||||
public String subject;
|
|
||||||
public String fromAddress;
|
|
||||||
public String data;
|
|
||||||
public String replyTo;
|
|
||||||
public boolean signedOnly;
|
|
||||||
|
|
||||||
public Message(Conversation parent, long id, String subject, String fromAddress,
|
|
||||||
String replyTo, String data, boolean signedOnly) {
|
|
||||||
this.parent = parent;
|
|
||||||
this.id = id;
|
|
||||||
this.subject = subject;
|
|
||||||
this.fromAddress = fromAddress;
|
|
||||||
this.replyTo = replyTo;
|
|
||||||
this.data = data;
|
|
||||||
if (this.replyTo == null || this.replyTo.equals("")) {
|
|
||||||
this.replyTo = this.fromAddress;
|
|
||||||
}
|
|
||||||
this.signedOnly = signedOnly;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Vector<Conversation> mConversations;
|
|
||||||
private Vector<Message> mMessages;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
|
||||||
Preferences prefs = Preferences.getPreferences(this);
|
|
||||||
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
|
|
||||||
mInflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
|
||||||
|
|
||||||
mConversations = new Vector<Conversation>();
|
|
||||||
mMessages = new Vector<Message>();
|
|
||||||
|
|
||||||
String account = getIntent().getExtras().getString(EXTRA_ACCOUNT);
|
|
||||||
// TODO: what if account is null?
|
|
||||||
Uri uri = Uri.parse("content://gmail-ls/conversations/" + account);
|
|
||||||
Cursor cursor = managedQuery(uri, new String[] { "conversation_id", "subject" }, null,
|
|
||||||
null, null);
|
|
||||||
for (int i = 0; i < cursor.getCount(); ++i) {
|
|
||||||
cursor.moveToPosition(i);
|
|
||||||
|
|
||||||
int idIndex = cursor.getColumnIndex("conversation_id");
|
|
||||||
int subjectIndex = cursor.getColumnIndex("subject");
|
|
||||||
long conversationId = cursor.getLong(idIndex);
|
|
||||||
Conversation conversation = new Conversation(conversationId,
|
|
||||||
cursor.getString(subjectIndex));
|
|
||||||
Uri messageUri = Uri.withAppendedPath(uri, "" + conversationId + "/messages");
|
|
||||||
Cursor messageCursor = managedQuery(messageUri, new String[] { "messageId", "subject",
|
|
||||||
"fromAddress", "replyToAddresses", "body" }, null, null, null);
|
|
||||||
Vector<Message> messages = new Vector<Message>();
|
|
||||||
for (int j = 0; j < messageCursor.getCount(); ++j) {
|
|
||||||
messageCursor.moveToPosition(j);
|
|
||||||
idIndex = messageCursor.getColumnIndex("messageId");
|
|
||||||
subjectIndex = messageCursor.getColumnIndex("subject");
|
|
||||||
int fromAddressIndex = messageCursor.getColumnIndex("fromAddress");
|
|
||||||
int replyToIndex = messageCursor.getColumnIndex("replyToAddresses");
|
|
||||||
int bodyIndex = messageCursor.getColumnIndex("body");
|
|
||||||
String data = messageCursor.getString(bodyIndex);
|
|
||||||
data = Html.fromHtml(data).toString();
|
|
||||||
boolean signedOnly = false;
|
|
||||||
Matcher matcher = PGPMain.PGP_MESSAGE.matcher(data);
|
|
||||||
if (matcher.matches()) {
|
|
||||||
data = matcher.group(1);
|
|
||||||
} else {
|
|
||||||
matcher = PGPMain.PGP_SIGNED_MESSAGE.matcher(data);
|
|
||||||
if (matcher.matches()) {
|
|
||||||
data = matcher.group(1);
|
|
||||||
signedOnly = true;
|
|
||||||
} else {
|
|
||||||
data = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Message message = new Message(conversation, messageCursor.getLong(idIndex),
|
|
||||||
messageCursor.getString(subjectIndex),
|
|
||||||
messageCursor.getString(fromAddressIndex),
|
|
||||||
messageCursor.getString(replyToIndex), data, signedOnly);
|
|
||||||
|
|
||||||
messages.add(message);
|
|
||||||
mMessages.add(message);
|
|
||||||
}
|
|
||||||
conversation.messages = messages;
|
|
||||||
mConversations.add(conversation);
|
|
||||||
}
|
|
||||||
|
|
||||||
setListAdapter(new MailboxAdapter());
|
|
||||||
getListView().setOnItemClickListener(new OnItemClickListener() {
|
|
||||||
public void onItemClick(AdapterView<?> arg0, View v, int position, long id) {
|
|
||||||
Intent intent = new Intent(MailListActivity.this, DecryptActivity.class);
|
|
||||||
intent.setAction(DecryptActivity.ACTION_DECRYPT);
|
|
||||||
Message message = (Message) ((MailboxAdapter) getListAdapter()).getItem(position);
|
|
||||||
intent.putExtra(DecryptActivity.EXTRA_TEXT, message.data);
|
|
||||||
intent.putExtra(DecryptActivity.EXTRA_SUBJECT, message.subject);
|
|
||||||
intent.putExtra(DecryptActivity.EXTRA_REPLY_TO, message.replyTo);
|
|
||||||
startActivity(intent);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private class MailboxAdapter extends BaseAdapter implements ListAdapter {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnabled(int position) {
|
|
||||||
Message message = (Message) getItem(position);
|
|
||||||
return message.data != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasStableIds() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getCount() {
|
|
||||||
return mMessages.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Object getItem(int position) {
|
|
||||||
return mMessages.get(position);
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getItemId(int position) {
|
|
||||||
return mMessages.get(position).id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public View getView(int position, View convertView, ViewGroup parent) {
|
|
||||||
View view = mInflater.inflate(R.layout.mailbox_message_item, null);
|
|
||||||
|
|
||||||
Message message = (Message) getItem(position);
|
|
||||||
|
|
||||||
TextView subject = (TextView) view.findViewById(R.id.subject);
|
|
||||||
TextView email = (TextView) view.findViewById(R.id.emailAddress);
|
|
||||||
ImageView status = (ImageView) view.findViewById(R.id.ic_status);
|
|
||||||
|
|
||||||
subject.setText(message.subject);
|
|
||||||
email.setText(message.fromAddress);
|
|
||||||
if (message.data != null) {
|
|
||||||
if (message.signedOnly) {
|
|
||||||
status.setImageResource(R.drawable.signed);
|
|
||||||
} else {
|
|
||||||
status.setImageResource(R.drawable.encrypted);
|
|
||||||
}
|
|
||||||
status.setVisibility(View.VISIBLE);
|
|
||||||
} else {
|
|
||||||
status.setVisibility(View.INVISIBLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
return view;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -17,9 +17,6 @@
|
|||||||
|
|
||||||
package org.thialfihar.android.apg.ui;
|
package org.thialfihar.android.apg.ui;
|
||||||
|
|
||||||
import java.security.Security;
|
|
||||||
|
|
||||||
import org.spongycastle.jce.provider.BouncyCastleProvider;
|
|
||||||
import org.thialfihar.android.apg.Id;
|
import org.thialfihar.android.apg.Id;
|
||||||
import org.thialfihar.android.apg.R;
|
import org.thialfihar.android.apg.R;
|
||||||
|
|
||||||
@ -33,9 +30,6 @@ import android.os.Bundle;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
public class MainActivity extends SherlockActivity {
|
public class MainActivity extends SherlockActivity {
|
||||||
static {
|
|
||||||
Security.addProvider(new BouncyCastleProvider());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void manageKeysOnClick(View view) {
|
public void manageKeysOnClick(View view) {
|
||||||
startActivity(new Intent(this, PublicKeyListActivity.class));
|
startActivity(new Intent(this, PublicKeyListActivity.class));
|
||||||
|
@ -19,16 +19,19 @@ package org.thialfihar.android.apg.ui;
|
|||||||
import org.thialfihar.android.apg.R;
|
import org.thialfihar.android.apg.R;
|
||||||
import org.thialfihar.android.apg.Constants;
|
import org.thialfihar.android.apg.Constants;
|
||||||
import org.thialfihar.android.apg.Id;
|
import org.thialfihar.android.apg.Id;
|
||||||
import org.thialfihar.android.apg.deprecated.AskForPassphrase;
|
|
||||||
import org.thialfihar.android.apg.helper.PGPHelper;
|
import org.thialfihar.android.apg.helper.PGPHelper;
|
||||||
import org.thialfihar.android.apg.helper.PGPMain;
|
import org.thialfihar.android.apg.helper.PGPMain;
|
||||||
|
import org.thialfihar.android.apg.ui.dialog.PassphraseDialogFragment;
|
||||||
|
import org.thialfihar.android.apg.util.Log;
|
||||||
|
|
||||||
import com.actionbarsherlock.view.Menu;
|
import com.actionbarsherlock.view.Menu;
|
||||||
import com.actionbarsherlock.view.MenuItem;
|
import com.actionbarsherlock.view.MenuItem;
|
||||||
|
|
||||||
import android.app.Dialog;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Handler;
|
||||||
|
import android.os.Message;
|
||||||
|
import android.os.Messenger;
|
||||||
import android.view.ContextMenu;
|
import android.view.ContextMenu;
|
||||||
import android.view.ContextMenu.ContextMenuInfo;
|
import android.view.ContextMenu.ContextMenuInfo;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@ -39,6 +42,7 @@ import android.widget.ExpandableListView.OnChildClickListener;
|
|||||||
import com.google.zxing.integration.android.IntentIntegrator;
|
import com.google.zxing.integration.android.IntentIntegrator;
|
||||||
|
|
||||||
public class SecretKeyListActivity extends KeyListActivity implements OnChildClickListener {
|
public class SecretKeyListActivity extends KeyListActivity implements OnChildClickListener {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
mExportFilename = Constants.path.APP_DIR + "/secexport.asc";
|
mExportFilename = Constants.path.APP_DIR + "/secexport.asc";
|
||||||
@ -86,7 +90,7 @@ public class SecretKeyListActivity extends KeyListActivity implements OnChildCli
|
|||||||
menu.add(0, Id.menu.edit, 0, R.string.menu_editKey);
|
menu.add(0, Id.menu.edit, 0, R.string.menu_editKey);
|
||||||
menu.add(0, Id.menu.export, 1, R.string.menu_exportKey);
|
menu.add(0, Id.menu.export, 1, R.string.menu_exportKey);
|
||||||
menu.add(0, Id.menu.delete, 2, R.string.menu_deleteKey);
|
menu.add(0, Id.menu.delete, 2, R.string.menu_deleteKey);
|
||||||
menu.add(0, Id.menu.share, 2, R.string.menu_share);
|
menu.add(0, Id.menu.share_qr_code, 2, R.string.menu_share);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,12 +111,13 @@ public class SecretKeyListActivity extends KeyListActivity implements OnChildCli
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Id.menu.share: {
|
case Id.menu.share_qr_code: {
|
||||||
mSelectedItem = groupPosition;
|
mSelectedItem = groupPosition;
|
||||||
|
|
||||||
long keyId = ((KeyListAdapter) mList.getExpandableListAdapter())
|
long keyId = ((KeyListAdapter) mList.getExpandableListAdapter())
|
||||||
.getGroupId(mSelectedItem);
|
.getGroupId(mSelectedItem);
|
||||||
String msg = keyId + "," + PGPHelper.getFingerPrint(keyId);
|
// String msg = keyId + "," + PGPHelper.getFingerPrint(keyId);
|
||||||
|
String msg = PGPHelper.getPubkeyAsArmoredString(keyId);
|
||||||
|
|
||||||
new IntentIntegrator(this).shareText(msg);
|
new IntentIntegrator(this).shareText(msg);
|
||||||
}
|
}
|
||||||
@ -130,38 +135,44 @@ public class SecretKeyListActivity extends KeyListActivity implements OnChildCli
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected Dialog onCreateDialog(int id) {
|
|
||||||
switch (id) {
|
|
||||||
case Id.dialog.pass_phrase: {
|
|
||||||
long keyId = ((KeyListAdapter) mList.getExpandableListAdapter())
|
|
||||||
.getGroupId(mSelectedItem);
|
|
||||||
return AskForPassphrase.createDialog(this, keyId, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
default: {
|
|
||||||
return super.onCreateDialog(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void checkPassPhraseAndEdit() {
|
public void checkPassPhraseAndEdit() {
|
||||||
long keyId = ((KeyListAdapter) mList.getExpandableListAdapter()).getGroupId(mSelectedItem);
|
long keyId = ((KeyListAdapter) mList.getExpandableListAdapter()).getGroupId(mSelectedItem);
|
||||||
String passPhrase = PGPMain.getCachedPassPhrase(keyId);
|
String passPhrase = PGPMain.getCachedPassPhrase(keyId);
|
||||||
if (passPhrase == null) {
|
if (passPhrase == null) {
|
||||||
showDialog(Id.dialog.pass_phrase);
|
showPassphraseDialog(keyId);
|
||||||
} else {
|
} else {
|
||||||
PGPMain.setEditPassPhrase(passPhrase);
|
PGPMain.setEditPassPhrase(passPhrase);
|
||||||
editKey();
|
editKey();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void showPassphraseDialog(final long secretKeyId) {
|
||||||
|
// Message is received after passphrase is cached
|
||||||
|
Handler returnHandler = new Handler() {
|
||||||
@Override
|
@Override
|
||||||
public void passPhraseCallback(long keyId, String passPhrase) {
|
public void handleMessage(Message message) {
|
||||||
super.passPhraseCallback(keyId, passPhrase);
|
if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) {
|
||||||
|
String passPhrase = PGPMain.getCachedPassPhrase(secretKeyId);
|
||||||
PGPMain.setEditPassPhrase(passPhrase);
|
PGPMain.setEditPassPhrase(passPhrase);
|
||||||
editKey();
|
editKey();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create a new Messenger for the communication back
|
||||||
|
Messenger messenger = new Messenger(returnHandler);
|
||||||
|
|
||||||
|
try {
|
||||||
|
PassphraseDialogFragment passphraseDialog = PassphraseDialogFragment.newInstance(
|
||||||
|
messenger, secretKeyId);
|
||||||
|
|
||||||
|
passphraseDialog.show(getSupportFragmentManager(), "passphraseDialog");
|
||||||
|
} catch (PGPMain.GeneralException e) {
|
||||||
|
Log.d(Constants.TAG, "No passphrase for this secret key, encrypt directly!");
|
||||||
|
// send message to handler to start encryption directly
|
||||||
|
returnHandler.sendEmptyMessage(PassphraseDialogFragment.MESSAGE_OKAY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void createKey() {
|
private void createKey() {
|
||||||
PGPMain.setEditPassPhrase("");
|
PGPMain.setEditPassPhrase("");
|
||||||
|
@ -0,0 +1,130 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2012 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.dialog;
|
||||||
|
|
||||||
|
import org.spongycastle.openpgp.PGPPublicKeyRing;
|
||||||
|
import org.spongycastle.openpgp.PGPSecretKeyRing;
|
||||||
|
import org.thialfihar.android.apg.Constants;
|
||||||
|
import org.thialfihar.android.apg.Id;
|
||||||
|
import org.thialfihar.android.apg.R;
|
||||||
|
import org.thialfihar.android.apg.helper.PGPHelper;
|
||||||
|
import org.thialfihar.android.apg.helper.PGPMain;
|
||||||
|
import org.thialfihar.android.apg.util.Log;
|
||||||
|
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Message;
|
||||||
|
import android.os.Messenger;
|
||||||
|
import android.os.RemoteException;
|
||||||
|
import android.support.v4.app.DialogFragment;
|
||||||
|
import android.support.v4.app.FragmentActivity;
|
||||||
|
|
||||||
|
public class DeleteKeyDialogFragment extends DialogFragment {
|
||||||
|
|
||||||
|
private Messenger mMessenger;
|
||||||
|
|
||||||
|
private static final String ARG_MESSENGER = "messenger";
|
||||||
|
private static final String ARG_DELETE_KEY_RING_ID = "delete_file";
|
||||||
|
private static final String ARG_KEY_TYPE = "key_type";
|
||||||
|
|
||||||
|
public static final int MESSAGE_OKAY = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates new instance of this delete file dialog fragment
|
||||||
|
*/
|
||||||
|
public static DeleteKeyDialogFragment newInstance(Messenger messenger, int deleteKeyRingId,
|
||||||
|
int keyType) {
|
||||||
|
DeleteKeyDialogFragment frag = new DeleteKeyDialogFragment();
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
|
||||||
|
args.putParcelable(ARG_MESSENGER, messenger);
|
||||||
|
args.putInt(ARG_DELETE_KEY_RING_ID, deleteKeyRingId);
|
||||||
|
args.putInt(ARG_KEY_TYPE, keyType);
|
||||||
|
|
||||||
|
frag.setArguments(args);
|
||||||
|
|
||||||
|
return frag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates dialog
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
|
final FragmentActivity activity = getActivity();
|
||||||
|
|
||||||
|
final int deleteKeyRingId = getArguments().getInt(ARG_DELETE_KEY_RING_ID);
|
||||||
|
final int keyType = getArguments().getInt(ARG_KEY_TYPE);
|
||||||
|
|
||||||
|
// TODO: better way to do this?
|
||||||
|
String userId = "<unknown>";
|
||||||
|
Object keyRing = PGPMain.getKeyRing(deleteKeyRingId);
|
||||||
|
if (keyRing != null) {
|
||||||
|
if (keyRing instanceof PGPPublicKeyRing) {
|
||||||
|
userId = PGPHelper.getMainUserIdSafe(activity,
|
||||||
|
PGPHelper.getMasterKey((PGPPublicKeyRing) keyRing));
|
||||||
|
} else {
|
||||||
|
userId = PGPHelper.getMainUserIdSafe(activity,
|
||||||
|
PGPHelper.getMasterKey((PGPSecretKeyRing) keyRing));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(activity);
|
||||||
|
builder.setTitle(R.string.warning);
|
||||||
|
builder.setMessage(getString(
|
||||||
|
keyType == Id.type.public_key ? R.string.keyDeletionConfirmation
|
||||||
|
: R.string.secretKeyDeletionConfirmation, userId));
|
||||||
|
builder.setIcon(android.R.drawable.ic_dialog_alert);
|
||||||
|
builder.setPositiveButton(R.string.btn_delete, new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
|
// deleteKey(deleteKeyRingId);
|
||||||
|
PGPMain.deleteKey(deleteKeyRingId);
|
||||||
|
|
||||||
|
dismiss();
|
||||||
|
|
||||||
|
sendMessageToHandler(MESSAGE_OKAY);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
|
dismiss();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return builder.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send message back to handler which is initialized in a activity
|
||||||
|
*
|
||||||
|
* @param what
|
||||||
|
* Message integer you want to send
|
||||||
|
*/
|
||||||
|
private void sendMessageToHandler(Integer what) {
|
||||||
|
Message msg = Message.obtain();
|
||||||
|
msg.what = what;
|
||||||
|
|
||||||
|
try {
|
||||||
|
mMessenger.send(msg);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Log.w(Constants.TAG, "Exception sending message, Is handler present?", e);
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
Log.w(Constants.TAG, "Messenger is null!", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,133 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2012 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.dialog;
|
||||||
|
|
||||||
|
import org.thialfihar.android.apg.helper.PGPHelper;
|
||||||
|
import org.thialfihar.android.apg.Constants;
|
||||||
|
import org.thialfihar.android.apg.Id;
|
||||||
|
import org.thialfihar.android.apg.R;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.app.Dialog;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.DialogInterface.OnCancelListener;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.os.Message;
|
||||||
|
import android.os.Messenger;
|
||||||
|
import android.os.RemoteException;
|
||||||
|
import android.support.v4.app.DialogFragment;
|
||||||
|
|
||||||
|
import org.thialfihar.android.apg.ui.KeyServerQueryActivity;
|
||||||
|
import org.thialfihar.android.apg.util.Log;
|
||||||
|
|
||||||
|
public class LookupUnknownKeyDialogFragment extends DialogFragment {
|
||||||
|
|
||||||
|
private Messenger mMessenger;
|
||||||
|
|
||||||
|
private static final String ARG_MESSENGER = "messenger";
|
||||||
|
private static final String ARG_UNKNOWN_KEY_ID = "unknown_key_id";
|
||||||
|
|
||||||
|
public static final int MESSAGE_OKAY = 1;
|
||||||
|
public static final int MESSAGE_CANCEL = 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates new instance of this dialog fragment
|
||||||
|
*
|
||||||
|
* @param messenger
|
||||||
|
* @param unknownKeyId
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static LookupUnknownKeyDialogFragment newInstance(Messenger messenger, long unknownKeyId) {
|
||||||
|
LookupUnknownKeyDialogFragment frag = new LookupUnknownKeyDialogFragment();
|
||||||
|
Bundle args = new Bundle();
|
||||||
|
args.putLong(ARG_UNKNOWN_KEY_ID, unknownKeyId);
|
||||||
|
args.putParcelable(ARG_MESSENGER, messenger);
|
||||||
|
|
||||||
|
frag.setArguments(args);
|
||||||
|
|
||||||
|
return frag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates dialog
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||||
|
final Activity activity = getActivity();
|
||||||
|
|
||||||
|
final long unknownKeyId = getArguments().getLong(ARG_UNKNOWN_KEY_ID);
|
||||||
|
mMessenger = getArguments().getParcelable(ARG_MESSENGER);
|
||||||
|
|
||||||
|
AlertDialog.Builder alert = new AlertDialog.Builder(activity);
|
||||||
|
|
||||||
|
alert.setIcon(android.R.drawable.ic_dialog_alert);
|
||||||
|
alert.setTitle(R.string.title_unknownSignatureKey);
|
||||||
|
alert.setMessage(getString(R.string.lookupUnknownKey,
|
||||||
|
PGPHelper.getSmallFingerPrint(unknownKeyId)));
|
||||||
|
|
||||||
|
alert.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
|
dismiss();
|
||||||
|
|
||||||
|
sendMessageToHandler(MESSAGE_OKAY);
|
||||||
|
|
||||||
|
Intent intent = new Intent(activity, KeyServerQueryActivity.class);
|
||||||
|
intent.setAction(KeyServerQueryActivity.ACTION_LOOK_UP_KEY_ID);
|
||||||
|
intent.putExtra(KeyServerQueryActivity.EXTRA_KEY_ID, unknownKeyId);
|
||||||
|
startActivityForResult(intent, Id.request.look_up_key_id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
alert.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
|
dismiss();
|
||||||
|
|
||||||
|
sendMessageToHandler(MESSAGE_CANCEL);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
alert.setCancelable(true);
|
||||||
|
alert.setOnCancelListener(new OnCancelListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCancel(DialogInterface dialog) {
|
||||||
|
sendMessageToHandler(MESSAGE_CANCEL);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return alert.create();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send message back to handler which is initialized in a activity
|
||||||
|
*
|
||||||
|
* @param what
|
||||||
|
* Message integer you want to send
|
||||||
|
*/
|
||||||
|
private void sendMessageToHandler(Integer what) {
|
||||||
|
Message msg = Message.obtain();
|
||||||
|
msg.what = what;
|
||||||
|
|
||||||
|
try {
|
||||||
|
mMessenger.send(msg);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
Log.w(Constants.TAG, "Exception sending message, Is handler present?", e);
|
||||||
|
} catch (NullPointerException e) {
|
||||||
|
Log.w(Constants.TAG, "Messenger is null!", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user