ConversationActivity.java

  1package eu.siacs.conversations.ui;
  2
  3import java.util.ArrayList;
  4import java.util.List;
  5
  6import eu.siacs.conversations.R;
  7import eu.siacs.conversations.entities.Contact;
  8import eu.siacs.conversations.entities.Conversation;
  9import eu.siacs.conversations.entities.Message;
 10import eu.siacs.conversations.services.XmppConnectionService.OnConversationUpdate;
 11import eu.siacs.conversations.ui.adapter.ConversationAdapter;
 12import eu.siacs.conversations.utils.ExceptionHelper;
 13import eu.siacs.conversations.utils.UIHelper;
 14import android.net.Uri;
 15import android.os.Bundle;
 16import android.preference.PreferenceManager;
 17import android.provider.MediaStore;
 18import android.app.ActionBar;
 19import android.app.AlertDialog;
 20import android.app.FragmentTransaction;
 21import android.app.PendingIntent;
 22import android.content.DialogInterface;
 23import android.content.DialogInterface.OnClickListener;
 24import android.content.IntentSender.SendIntentException;
 25import android.content.Intent;
 26import android.content.SharedPreferences;
 27import android.support.v4.widget.SlidingPaneLayout;
 28import android.support.v4.widget.SlidingPaneLayout.PanelSlideListener;
 29import android.view.KeyEvent;
 30import android.view.Menu;
 31import android.view.MenuItem;
 32import android.view.View;
 33import android.widget.AdapterView;
 34import android.widget.AdapterView.OnItemClickListener;
 35import android.widget.ArrayAdapter;
 36import android.widget.CheckBox;
 37import android.widget.ListView;
 38import android.widget.PopupMenu;
 39import android.widget.PopupMenu.OnMenuItemClickListener;
 40import android.widget.Toast;
 41
 42public class ConversationActivity extends XmppActivity {
 43
 44	public static final String VIEW_CONVERSATION = "viewConversation";
 45	public static final String CONVERSATION = "conversationUuid";
 46	public static final String TEXT = "text";
 47	public static final String PRESENCE = "eu.siacs.conversations.presence";
 48
 49	public static final int REQUEST_SEND_MESSAGE = 0x0201;
 50	public static final int REQUEST_DECRYPT_PGP = 0x0202;
 51	private static final int REQUEST_ATTACH_FILE_DIALOG = 0x0203;
 52	private static final int REQUEST_IMAGE_CAPTURE = 0x0204;
 53	private static final int REQUEST_RECORD_AUDIO = 0x0205;
 54	private static final int REQUEST_SEND_PGP_IMAGE = 0x0206;
 55	public static final int REQUEST_ENCRYPT_MESSAGE = 0x0207;
 56
 57	private static final int ATTACHMENT_CHOICE_CHOOSE_IMAGE = 0x0301;
 58	private static final int ATTACHMENT_CHOICE_TAKE_PHOTO = 0x0302;
 59	private static final int ATTACHMENT_CHOICE_RECORD_VOICE = 0x0303;
 60
 61	protected SlidingPaneLayout spl;
 62
 63	private List<Conversation> conversationList = new ArrayList<Conversation>();
 64	private Conversation selectedConversation = null;
 65	private ListView listView;
 66
 67	private boolean paneShouldBeOpen = true;
 68	private boolean useSubject = true;
 69	private boolean showLastseen = false;
 70	private ArrayAdapter<Conversation> listAdapter;
 71
 72	private OnConversationUpdate onConvChanged = new OnConversationUpdate() {
 73
 74		@Override
 75		public void onConversationUpdate() {
 76			runOnUiThread(new Runnable() {
 77
 78				@Override
 79				public void run() {
 80					updateConversationList();
 81					if (paneShouldBeOpen) {
 82						if (conversationList.size() >= 1) {
 83							swapConversationFragment();
 84						} else {
 85							startActivity(new Intent(getApplicationContext(),
 86									StartConversationActivity.class));
 87							finish();
 88						}
 89					}
 90					ConversationFragment selectedFragment = (ConversationFragment) getFragmentManager()
 91							.findFragmentByTag("conversation");
 92					if (selectedFragment != null) {
 93						selectedFragment.updateMessages();
 94					}
 95				}
 96			});
 97		}
 98	};
 99
100	protected ConversationActivity activity = this;
101	private Toast prepareImageToast;
102
103	private Uri pendingImageUri = null;
104
105	public List<Conversation> getConversationList() {
106		return this.conversationList;
107	}
108
109	public Conversation getSelectedConversation() {
110		return this.selectedConversation;
111	}
112
113	public void setSelectedConversation(Conversation conversation) {
114		this.selectedConversation = conversation;
115	}
116
117	public ListView getConversationListView() {
118		return this.listView;
119	}
120
121	public SlidingPaneLayout getSlidingPaneLayout() {
122		return this.spl;
123	}
124
125	public boolean shouldPaneBeOpen() {
126		return paneShouldBeOpen;
127	}
128
129	@Override
130	protected void onCreate(Bundle savedInstanceState) {
131		super.onCreate(savedInstanceState);
132
133		setContentView(R.layout.fragment_conversations_overview);
134
135		listView = (ListView) findViewById(R.id.list);
136
137		getActionBar().setDisplayHomeAsUpEnabled(false);
138		getActionBar().setHomeButtonEnabled(false);
139
140		this.listAdapter = new ConversationAdapter(this, conversationList);
141		listView.setAdapter(this.listAdapter);
142
143		listView.setOnItemClickListener(new OnItemClickListener() {
144
145			@Override
146			public void onItemClick(AdapterView<?> arg0, View clickedView,
147					int position, long arg3) {
148				paneShouldBeOpen = false;
149				if (getSelectedConversation() != conversationList.get(position)) {
150					setSelectedConversation(conversationList.get(position));
151					swapConversationFragment();
152				} else {
153					spl.closePane();
154				}
155			}
156		});
157		spl = (SlidingPaneLayout) findViewById(R.id.slidingpanelayout);
158		spl.setParallaxDistance(150);
159		spl.setShadowResource(R.drawable.es_slidingpane_shadow);
160		spl.setSliderFadeColor(0);
161		spl.setPanelSlideListener(new PanelSlideListener() {
162
163			@Override
164			public void onPanelOpened(View arg0) {
165				paneShouldBeOpen = true;
166				ActionBar ab = getActionBar();
167				if (ab != null) {
168					ab.setDisplayHomeAsUpEnabled(false);
169					ab.setHomeButtonEnabled(false);
170					ab.setTitle(R.string.app_name);
171				}
172				invalidateOptionsMenu();
173				hideKeyboard();
174			}
175
176			@Override
177			public void onPanelClosed(View arg0) {
178				paneShouldBeOpen = false;
179				if ((conversationList.size() > 0)
180						&& (getSelectedConversation() != null)) {
181					ActionBar ab = getActionBar();
182					if (ab != null) {
183						ab.setDisplayHomeAsUpEnabled(true);
184						ab.setHomeButtonEnabled(true);
185						ab.setTitle(getSelectedConversation().getName(
186								useSubject));
187					}
188					invalidateOptionsMenu();
189					if (!getSelectedConversation().isRead()) {
190						xmppConnectionService
191								.markRead(getSelectedConversation());
192						UIHelper.updateNotification(getApplicationContext(),
193								getConversationList(), null, false);
194						listView.invalidateViews();
195					}
196				}
197			}
198
199			@Override
200			public void onPanelSlide(View arg0, float arg1) {
201				// TODO Auto-generated method stub
202
203			}
204		});
205	}
206
207	@Override
208	public boolean onCreateOptionsMenu(Menu menu) {
209		getMenuInflater().inflate(R.menu.conversations, menu);
210		MenuItem menuSecure = (MenuItem) menu.findItem(R.id.action_security);
211		MenuItem menuArchive = (MenuItem) menu.findItem(R.id.action_archive);
212		MenuItem menuMucDetails = (MenuItem) menu
213				.findItem(R.id.action_muc_details);
214		MenuItem menuContactDetails = (MenuItem) menu
215				.findItem(R.id.action_contact_details);
216		MenuItem menuAttach = (MenuItem) menu.findItem(R.id.action_attach_file);
217		MenuItem menuClearHistory = (MenuItem) menu
218				.findItem(R.id.action_clear_history);
219		MenuItem menuAdd = (MenuItem) menu.findItem(R.id.action_add);
220		MenuItem menuInviteContact = (MenuItem) menu
221				.findItem(R.id.action_invite);
222
223		if ((spl.isOpen() && (spl.isSlideable()))) {
224			menuArchive.setVisible(false);
225			menuMucDetails.setVisible(false);
226			menuContactDetails.setVisible(false);
227			menuSecure.setVisible(false);
228			menuInviteContact.setVisible(false);
229			menuAttach.setVisible(false);
230			menuClearHistory.setVisible(false);
231		} else {
232			menuAdd.setVisible(!spl.isSlideable());
233			if (this.getSelectedConversation() != null) {
234				if (this.getSelectedConversation().getLatestMessage()
235						.getEncryption() != Message.ENCRYPTION_NONE) {
236					menuSecure.setIcon(R.drawable.ic_action_secure);
237				}
238				if (this.getSelectedConversation().getMode() == Conversation.MODE_MULTI) {
239					menuContactDetails.setVisible(false);
240					menuAttach.setVisible(false);
241				} else {
242					menuMucDetails.setVisible(false);
243					menuInviteContact.setVisible(false);
244				}
245			}
246		}
247		return true;
248	}
249
250	private void selectPresenceToAttachFile(final int attachmentChoice) {
251		selectPresence(getSelectedConversation(), new OnPresenceSelected() {
252
253			@Override
254			public void onPresenceSelected() {
255				if (attachmentChoice == ATTACHMENT_CHOICE_TAKE_PHOTO) {
256					pendingImageUri = xmppConnectionService.getFileBackend()
257							.getTakePhotoUri();
258					Intent takePictureIntent = new Intent(
259							MediaStore.ACTION_IMAGE_CAPTURE);
260					takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
261							pendingImageUri);
262					if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
263						startActivityForResult(takePictureIntent,
264								REQUEST_IMAGE_CAPTURE);
265					}
266				} else if (attachmentChoice == ATTACHMENT_CHOICE_CHOOSE_IMAGE) {
267					Intent attachFileIntent = new Intent();
268					attachFileIntent.setType("image/*");
269					attachFileIntent.setAction(Intent.ACTION_GET_CONTENT);
270					Intent chooser = Intent.createChooser(attachFileIntent,
271							getString(R.string.attach_file));
272					startActivityForResult(chooser, REQUEST_ATTACH_FILE_DIALOG);
273				} else if (attachmentChoice == ATTACHMENT_CHOICE_RECORD_VOICE) {
274					Intent intent = new Intent(
275							MediaStore.Audio.Media.RECORD_SOUND_ACTION);
276					startActivityForResult(intent, REQUEST_RECORD_AUDIO);
277				}
278			}
279		});
280	}
281
282	private void attachFile(final int attachmentChoice) {
283		final Conversation conversation = getSelectedConversation();
284		if (conversation.getNextEncryption() == Message.ENCRYPTION_PGP) {
285			if (hasPgp()) {
286				if (conversation.getContact().getPgpKeyId() != 0) {
287					xmppConnectionService.getPgpEngine().hasKey(
288							conversation.getContact(),
289							new UiCallback<Contact>() {
290
291								@Override
292								public void userInputRequried(PendingIntent pi,
293										Contact contact) {
294									ConversationActivity.this.runIntent(pi,
295											attachmentChoice);
296								}
297
298								@Override
299								public void success(Contact contact) {
300									selectPresenceToAttachFile(attachmentChoice);
301								}
302
303								@Override
304								public void error(int error, Contact contact) {
305									displayErrorDialog(error);
306								}
307							});
308				} else {
309					final ConversationFragment fragment = (ConversationFragment) getFragmentManager()
310							.findFragmentByTag("conversation");
311					if (fragment != null) {
312						fragment.showNoPGPKeyDialog(false,
313								new OnClickListener() {
314
315									@Override
316									public void onClick(DialogInterface dialog,
317											int which) {
318										conversation
319												.setNextEncryption(Message.ENCRYPTION_NONE);
320										selectPresenceToAttachFile(attachmentChoice);
321									}
322								});
323					}
324				}
325			} else {
326				showInstallPgpDialog();
327			}
328		} else if (getSelectedConversation().getNextEncryption() == Message.ENCRYPTION_NONE) {
329			selectPresenceToAttachFile(attachmentChoice);
330		} else {
331			selectPresenceToAttachFile(attachmentChoice);
332		}
333	}
334
335	@Override
336	public boolean onOptionsItemSelected(MenuItem item) {
337		switch (item.getItemId()) {
338		case android.R.id.home:
339			spl.openPane();
340			return true;
341		case R.id.action_attach_file:
342			View menuAttachFile = findViewById(R.id.action_attach_file);
343			if (menuAttachFile == null) {
344				break;
345			}
346			PopupMenu attachFilePopup = new PopupMenu(this, menuAttachFile);
347			attachFilePopup.inflate(R.menu.attachment_choices);
348			attachFilePopup
349					.setOnMenuItemClickListener(new OnMenuItemClickListener() {
350
351						@Override
352						public boolean onMenuItemClick(MenuItem item) {
353							switch (item.getItemId()) {
354							case R.id.attach_choose_picture:
355								attachFile(ATTACHMENT_CHOICE_CHOOSE_IMAGE);
356								break;
357							case R.id.attach_take_picture:
358								attachFile(ATTACHMENT_CHOICE_TAKE_PHOTO);
359								break;
360							case R.id.attach_record_voice:
361								attachFile(ATTACHMENT_CHOICE_RECORD_VOICE);
362								break;
363							}
364							return false;
365						}
366					});
367			attachFilePopup.show();
368			break;
369		case R.id.action_add:
370			startActivity(new Intent(this, StartConversationActivity.class));
371			break;
372		case R.id.action_archive:
373			this.endConversation(getSelectedConversation());
374			break;
375		case R.id.action_contact_details:
376			Contact contact = this.getSelectedConversation().getContact();
377			if (contact.showInRoster()) {
378				switchToContactDetails(contact);
379			} else {
380				showAddToRosterDialog(getSelectedConversation());
381			}
382			break;
383		case R.id.action_muc_details:
384			Intent intent = new Intent(this, ConferenceDetailsActivity.class);
385			intent.setAction(ConferenceDetailsActivity.ACTION_VIEW_MUC);
386			intent.putExtra("uuid", getSelectedConversation().getUuid());
387			startActivity(intent);
388			break;
389		case R.id.action_invite:
390			inviteToConversation(getSelectedConversation());
391			break;
392		case R.id.action_security:
393			final Conversation conversation = getSelectedConversation();
394			View menuItemView = findViewById(R.id.action_security);
395			if (menuItemView == null) {
396				break;
397			}
398			PopupMenu popup = new PopupMenu(this, menuItemView);
399			final ConversationFragment fragment = (ConversationFragment) getFragmentManager()
400					.findFragmentByTag("conversation");
401			if (fragment != null) {
402				popup.setOnMenuItemClickListener(new OnMenuItemClickListener() {
403
404					@Override
405					public boolean onMenuItemClick(MenuItem item) {
406						switch (item.getItemId()) {
407						case R.id.encryption_choice_none:
408							conversation
409									.setNextEncryption(Message.ENCRYPTION_NONE);
410							item.setChecked(true);
411							break;
412						case R.id.encryption_choice_otr:
413							conversation
414									.setNextEncryption(Message.ENCRYPTION_OTR);
415							item.setChecked(true);
416							break;
417						case R.id.encryption_choice_pgp:
418							if (hasPgp()) {
419								if (conversation.getAccount().getKeys()
420										.has("pgp_signature")) {
421									conversation
422											.setNextEncryption(Message.ENCRYPTION_PGP);
423									item.setChecked(true);
424								} else {
425									announcePgp(conversation.getAccount(),
426											conversation);
427								}
428							} else {
429								showInstallPgpDialog();
430							}
431							break;
432						default:
433							conversation
434									.setNextEncryption(Message.ENCRYPTION_NONE);
435							break;
436						}
437						fragment.updateChatMsgHint();
438						return true;
439					}
440				});
441				popup.inflate(R.menu.encryption_choices);
442				MenuItem otr = popup.getMenu().findItem(
443						R.id.encryption_choice_otr);
444				if (conversation.getMode() == Conversation.MODE_MULTI) {
445					otr.setEnabled(false);
446				}
447				switch (conversation.getNextEncryption()) {
448				case Message.ENCRYPTION_NONE:
449					popup.getMenu().findItem(R.id.encryption_choice_none)
450							.setChecked(true);
451					break;
452				case Message.ENCRYPTION_OTR:
453					otr.setChecked(true);
454					break;
455				case Message.ENCRYPTION_PGP:
456					popup.getMenu().findItem(R.id.encryption_choice_pgp)
457							.setChecked(true);
458					break;
459				default:
460					popup.getMenu().findItem(R.id.encryption_choice_none)
461							.setChecked(true);
462					break;
463				}
464				popup.show();
465			}
466
467			break;
468		case R.id.action_clear_history:
469			clearHistoryDialog(getSelectedConversation());
470			break;
471		default:
472			break;
473		}
474		return super.onOptionsItemSelected(item);
475	}
476
477	public void endConversation(Conversation conversation) {
478		conversation.setStatus(Conversation.STATUS_ARCHIVED);
479		paneShouldBeOpen = true;
480		spl.openPane();
481		xmppConnectionService.archiveConversation(conversation);
482		if (conversationList.size() > 0) {
483			setSelectedConversation(conversationList.get(0));
484		} else {
485			setSelectedConversation(null);
486		}
487	}
488
489	protected void clearHistoryDialog(final Conversation conversation) {
490		AlertDialog.Builder builder = new AlertDialog.Builder(this);
491		builder.setTitle(getString(R.string.clear_conversation_history));
492		View dialogView = getLayoutInflater().inflate(
493				R.layout.dialog_clear_history, null);
494		final CheckBox endConversationCheckBox = (CheckBox) dialogView
495				.findViewById(R.id.end_conversation_checkbox);
496		builder.setView(dialogView);
497		builder.setNegativeButton(getString(R.string.cancel), null);
498		builder.setPositiveButton(getString(R.string.delete_messages),
499				new OnClickListener() {
500
501					@Override
502					public void onClick(DialogInterface dialog, int which) {
503						activity.xmppConnectionService
504								.clearConversationHistory(conversation);
505						if (endConversationCheckBox.isChecked()) {
506							endConversation(conversation);
507						}
508					}
509				});
510		builder.create().show();
511	}
512
513	protected ConversationFragment swapConversationFragment() {
514		ConversationFragment selectedFragment = new ConversationFragment();
515		if (!isFinishing()) {
516
517			FragmentTransaction transaction = getFragmentManager()
518					.beginTransaction();
519			transaction.replace(R.id.selected_conversation, selectedFragment,
520					"conversation");
521
522			transaction.commitAllowingStateLoss();
523		}
524		return selectedFragment;
525	}
526
527	@Override
528	public boolean onKeyDown(int keyCode, KeyEvent event) {
529		if (keyCode == KeyEvent.KEYCODE_BACK) {
530			if (!spl.isOpen()) {
531				spl.openPane();
532				return false;
533			}
534		}
535		return super.onKeyDown(keyCode, event);
536	}
537
538	@Override
539	protected void onNewIntent(Intent intent) {
540		if (xmppConnectionServiceBound) {
541			if ((Intent.ACTION_VIEW.equals(intent.getAction()) && (VIEW_CONVERSATION
542					.equals(intent.getType())))) {
543				String convToView = (String) intent.getExtras().get(
544						CONVERSATION);
545				updateConversationList();
546				for (int i = 0; i < conversationList.size(); ++i) {
547					if (conversationList.get(i).getUuid().equals(convToView)) {
548						setSelectedConversation(conversationList.get(i));
549						break;
550					}
551				}
552				paneShouldBeOpen = false;
553				String text = intent.getExtras().getString(TEXT, null);
554				swapConversationFragment().setText(text);
555			}
556		} else {
557			handledViewIntent = false;
558			setIntent(intent);
559		}
560	}
561
562	@Override
563	public void onStart() {
564		super.onStart();
565		SharedPreferences preferences = PreferenceManager
566				.getDefaultSharedPreferences(this);
567		this.useSubject = preferences.getBoolean("use_subject_in_muc", true);
568		this.showLastseen = preferences.getBoolean("show_last_seen", false);
569		if (this.xmppConnectionServiceBound) {
570			this.onBackendConnected();
571		}
572		if (conversationList.size() >= 1) {
573			onConvChanged.onConversationUpdate();
574		}
575	}
576
577	@Override
578	protected void onStop() {
579		if (xmppConnectionServiceBound) {
580			xmppConnectionService.removeOnConversationListChangedListener();
581		}
582		super.onStop();
583	}
584
585	@Override
586	void onBackendConnected() {
587		this.registerListener();
588		if (conversationList.size() == 0) {
589			updateConversationList();
590		}
591
592		if (getSelectedConversation() != null && pendingImageUri != null) {
593			attachImageToConversation(getSelectedConversation(),
594					pendingImageUri);
595			pendingImageUri = null;
596		} else {
597			pendingImageUri = null;
598		}
599
600		if ((getIntent().getAction() != null)
601				&& (getIntent().getAction().equals(Intent.ACTION_VIEW) && (!handledViewIntent))) {
602			if (getIntent().getType().equals(
603					ConversationActivity.VIEW_CONVERSATION)) {
604				handledViewIntent = true;
605
606				String convToView = (String) getIntent().getExtras().get(
607						CONVERSATION);
608
609				for (int i = 0; i < conversationList.size(); ++i) {
610					if (conversationList.get(i).getUuid().equals(convToView)) {
611						setSelectedConversation(conversationList.get(i));
612					}
613				}
614				paneShouldBeOpen = false;
615				String text = getIntent().getExtras().getString(TEXT, null);
616				swapConversationFragment().setText(text);
617			}
618		} else {
619			if (xmppConnectionService.getAccounts().size() == 0) {
620				startActivity(new Intent(this, EditAccountActivity.class));
621			} else if (conversationList.size() <= 0) {
622				// add no history
623				startActivity(new Intent(this, StartConversationActivity.class));
624				finish();
625			} else {
626				spl.openPane();
627				// find currently loaded fragment
628				ConversationFragment selectedFragment = (ConversationFragment) getFragmentManager()
629						.findFragmentByTag("conversation");
630				if (selectedFragment != null) {
631					selectedFragment.onBackendConnected();
632				} else {
633					setSelectedConversation(conversationList.get(0));
634					swapConversationFragment();
635				}
636				ExceptionHelper.checkForCrash(this, this.xmppConnectionService);
637			}
638		}
639	}
640
641	public void registerListener() {
642		if (xmppConnectionServiceBound) {
643			xmppConnectionService
644					.setOnConversationListChangedListener(this.onConvChanged);
645		}
646	}
647
648	@Override
649	protected void onActivityResult(int requestCode, int resultCode,
650			final Intent data) {
651		super.onActivityResult(requestCode, resultCode, data);
652		if (resultCode == RESULT_OK) {
653			if (requestCode == REQUEST_DECRYPT_PGP) {
654				ConversationFragment selectedFragment = (ConversationFragment) getFragmentManager()
655						.findFragmentByTag("conversation");
656				if (selectedFragment != null) {
657					selectedFragment.hideSnackbar();
658				}
659			} else if (requestCode == REQUEST_ATTACH_FILE_DIALOG) {
660				pendingImageUri = data.getData();
661				if (xmppConnectionServiceBound) {
662					attachImageToConversation(getSelectedConversation(),
663							pendingImageUri);
664					pendingImageUri = null;
665				}
666			} else if (requestCode == REQUEST_SEND_PGP_IMAGE) {
667
668			} else if (requestCode == ATTACHMENT_CHOICE_CHOOSE_IMAGE) {
669				attachFile(ATTACHMENT_CHOICE_CHOOSE_IMAGE);
670			} else if (requestCode == ATTACHMENT_CHOICE_TAKE_PHOTO) {
671				attachFile(ATTACHMENT_CHOICE_TAKE_PHOTO);
672			} else if (requestCode == REQUEST_ANNOUNCE_PGP) {
673				announcePgp(getSelectedConversation().getAccount(),
674						getSelectedConversation());
675			} else if (requestCode == REQUEST_ENCRYPT_MESSAGE) {
676				// encryptTextMessage();
677			} else if (requestCode == REQUEST_IMAGE_CAPTURE) {
678				if (xmppConnectionServiceBound) {
679					attachImageToConversation(getSelectedConversation(),
680							pendingImageUri);
681					pendingImageUri = null;
682				}
683				Intent intent = new Intent(
684						Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
685				intent.setData(pendingImageUri);
686				sendBroadcast(intent);
687			} else if (requestCode == REQUEST_RECORD_AUDIO) {
688				attachAudioToConversation(getSelectedConversation(),
689						data.getData());
690			}
691		}
692	}
693
694	private void attachAudioToConversation(Conversation conversation, Uri uri) {
695
696	}
697
698	private void attachImageToConversation(Conversation conversation, Uri uri) {
699		prepareImageToast = Toast.makeText(getApplicationContext(),
700				getText(R.string.preparing_image), Toast.LENGTH_LONG);
701		prepareImageToast.show();
702		xmppConnectionService.attachImageToConversation(conversation, uri,
703				new UiCallback<Message>() {
704
705					@Override
706					public void userInputRequried(PendingIntent pi,
707							Message object) {
708						hidePrepareImageToast();
709						ConversationActivity.this.runIntent(pi,
710								ConversationActivity.REQUEST_SEND_PGP_IMAGE);
711					}
712
713					@Override
714					public void success(Message message) {
715						xmppConnectionService.sendMessage(message);
716					}
717
718					@Override
719					public void error(int error, Message message) {
720						hidePrepareImageToast();
721						displayErrorDialog(error);
722					}
723				});
724	}
725
726	private void hidePrepareImageToast() {
727		if (prepareImageToast != null) {
728			runOnUiThread(new Runnable() {
729
730				@Override
731				public void run() {
732					prepareImageToast.cancel();
733				}
734			});
735		}
736	}
737
738	public void updateConversationList() {
739		xmppConnectionService
740				.populateWithOrderedConversations(conversationList);
741		listView.invalidateViews();
742	}
743
744	public boolean showLastseen() {
745		if (getSelectedConversation() == null) {
746			return false;
747		} else {
748			return this.showLastseen
749					&& getSelectedConversation().getMode() == Conversation.MODE_SINGLE;
750		}
751	}
752
753	public void runIntent(PendingIntent pi, int requestCode) {
754		try {
755			this.startIntentSenderForResult(pi.getIntentSender(), requestCode,
756					null, 0, 0, 0);
757		} catch (SendIntentException e1) {
758		}
759	}
760
761	public void encryptTextMessage(Message message) {
762		xmppConnectionService.getPgpEngine().encrypt(message,
763				new UiCallback<Message>() {
764
765					@Override
766					public void userInputRequried(PendingIntent pi,
767							Message message) {
768						activity.runIntent(pi,
769								ConversationActivity.REQUEST_SEND_MESSAGE);
770					}
771
772					@Override
773					public void success(Message message) {
774						message.setEncryption(Message.ENCRYPTION_DECRYPTED);
775						xmppConnectionService.sendMessage(message);
776					}
777
778					@Override
779					public void error(int error, Message message) {
780
781					}
782				});
783	}
784}