NewConversationActivity.java

  1package de.gultsch.chat.ui;
  2
  3import java.util.ArrayList;
  4import java.util.Collections;
  5import java.util.Comparator;
  6import java.util.List;
  7
  8import de.gultsch.chat.R;
  9import de.gultsch.chat.entities.Account;
 10import de.gultsch.chat.entities.Contact;
 11import de.gultsch.chat.entities.Conversation;
 12import de.gultsch.chat.utils.UIHelper;
 13import de.gultsch.chat.utils.Validator;
 14import android.net.Uri;
 15import android.os.Bundle;
 16import android.provider.ContactsContract;
 17import android.text.Editable;
 18import android.text.TextWatcher;
 19import android.util.Log;
 20import android.view.LayoutInflater;
 21import android.view.Menu;
 22import android.view.MenuItem;
 23import android.view.View;
 24import android.view.ViewGroup;
 25import android.widget.AdapterView;
 26import android.widget.AdapterView.OnItemClickListener;
 27import android.widget.ArrayAdapter;
 28import android.widget.EditText;
 29import android.widget.ListView;
 30import android.widget.TextView;
 31import android.widget.ImageView;
 32import android.annotation.SuppressLint;
 33import android.app.Activity;
 34import android.app.AlertDialog;
 35import android.content.Context;
 36import android.content.CursorLoader;
 37import android.content.DialogInterface;
 38import android.content.DialogInterface.OnClickListener;
 39import android.content.Intent;
 40import android.content.Loader;
 41import android.content.Loader.OnLoadCompleteListener;
 42import android.database.Cursor;
 43
 44public class NewConversationActivity extends XmppActivity {
 45
 46	protected List<Contact> phoneContacts = new ArrayList<Contact>();
 47	protected List<Contact> rosterContacts = new ArrayList<Contact>();
 48	protected List<Contact> aggregatedContacts = new ArrayList<Contact>();
 49	protected ListView contactsView;
 50	protected ArrayAdapter<Contact> contactsAdapter;
 51
 52	protected EditText search;
 53	protected String searchString = "";
 54	private TextView contactsHeader;
 55	private List<Account> accounts;
 56
 57	protected void updateAggregatedContacts() {
 58
 59		aggregatedContacts.clear();
 60		for (Contact contact : phoneContacts) {
 61			if (contact.match(searchString))
 62				aggregatedContacts.add(contact);
 63		}
 64		for (Contact contact : rosterContacts) {
 65			if (contact.match(searchString))
 66				aggregatedContacts.add(contact);
 67		}
 68
 69		Collections.sort(aggregatedContacts, new Comparator<Contact>() {
 70
 71			@SuppressLint("DefaultLocale")
 72			@Override
 73			public int compare(Contact lhs, Contact rhs) {
 74				return lhs.getDisplayName().toLowerCase().compareTo(rhs.getDisplayName().toLowerCase());
 75			}
 76		});
 77
 78		if (aggregatedContacts.size() == 0) {
 79
 80			if (Validator.isValidJid(searchString)) {
 81				String name = searchString.split("@")[0];
 82				Contact newContact = new Contact(null,name, searchString,null);
 83				aggregatedContacts.add(newContact);
 84				contactsHeader.setText("Create new contact");
 85			} else {
 86				contactsHeader.setText("Contacts");
 87			}
 88		} else {
 89			contactsHeader.setText("Contacts");
 90		}
 91
 92		contactsAdapter.notifyDataSetChanged();
 93		contactsView.setScrollX(0);
 94	}
 95
 96	static final String[] PROJECTION = new String[] {
 97			ContactsContract.Data.CONTACT_ID,
 98			ContactsContract.Data.DISPLAY_NAME,
 99			ContactsContract.Data.PHOTO_THUMBNAIL_URI,
100			ContactsContract.CommonDataKinds.Im.DATA };
101
102	// This is the select criteria
103	static final String SELECTION = "(" + ContactsContract.Data.MIMETYPE
104			+ "=\"" + ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE
105			+ "\") AND (" + ContactsContract.CommonDataKinds.Im.PROTOCOL
106			+ "=\"" + ContactsContract.CommonDataKinds.Im.PROTOCOL_JABBER
107			+ "\")";
108
109	@Override
110	protected void onCreate(Bundle savedInstanceState) {
111
112		super.onCreate(savedInstanceState);
113
114		setContentView(R.layout.activity_new_conversation);
115
116		contactsHeader = (TextView) findViewById(R.id.contacts_header);
117
118		search = (EditText) findViewById(R.id.new_conversation_search);
119		search.addTextChangedListener(new TextWatcher() {
120
121			@Override
122			public void onTextChanged(CharSequence s, int start, int before,
123					int count) {
124				searchString = search.getText().toString();
125				updateAggregatedContacts();
126			}
127
128			@Override
129			public void afterTextChanged(Editable s) {
130				// TODO Auto-generated method stub
131
132			}
133
134			@Override
135			public void beforeTextChanged(CharSequence s, int start, int count,
136					int after) {
137				// TODO Auto-generated method stub
138
139			}
140		});
141
142		contactsView = (ListView) findViewById(R.id.contactList);
143		contactsAdapter = new ArrayAdapter<Contact>(getApplicationContext(),
144				R.layout.contact, aggregatedContacts) {
145			@Override
146			public View getView(int position, View view, ViewGroup parent) {
147				LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
148				if (view == null) {
149					view = (View) inflater.inflate(R.layout.contact, null);
150				}
151
152				((TextView) view.findViewById(R.id.contact_display_name))
153						.setText(getItem(position).getDisplayName());
154				((TextView) view.findViewById(R.id.contact_jid))
155						.setText(getItem(position).getJid());
156				String profilePhoto = getItem(position).getProfilePhoto();
157				ImageView imageView = (ImageView) view.findViewById(R.id.contact_photo);
158				if (profilePhoto!=null) {
159					imageView.setImageURI(Uri.parse(profilePhoto));
160				} else {
161					imageView.setImageBitmap(UIHelper.getUnknownContactPicture(getItem(position).getDisplayName(),90));
162				}
163				return view;
164			}
165		};
166		contactsView.setAdapter(contactsAdapter);
167		final Activity activity = this;
168		contactsView.setOnItemClickListener(new OnItemClickListener() {
169
170			@Override
171			public void onItemClick(AdapterView<?> arg0, final View view, int pos,
172					long arg3) {
173				final Contact clickedContact = aggregatedContacts.get(pos);
174				Log.d("gultsch",
175						"clicked on " + clickedContact.getDisplayName());
176				
177				final List<Account> accounts = xmppConnectionService.getAccounts();
178				if (accounts.size() == 1) {
179					startConversation(clickedContact, accounts.get(0));
180				} else {
181					String[] accountList = new String[accounts.size()];
182					for(int i = 0; i < accounts.size(); ++i) {
183						accountList[i] = accounts.get(i).getJid();
184					}
185	
186					AlertDialog.Builder builder = new AlertDialog.Builder(activity);
187					builder.setTitle("Choose account");
188					builder.setSingleChoiceItems(accountList,0,new OnClickListener() {
189						
190						@Override
191						public void onClick(DialogInterface dialog, int which) {
192							Account account = accounts.get(which);
193							startConversation(clickedContact, account);
194						}
195					});
196					builder.create().show();
197				}
198			}
199		});
200	}
201	
202	public void startConversation(Contact contact, Account account) {
203		Conversation conversation = xmppConnectionService
204				.findOrCreateConversation(account, contact);
205
206		Intent viewConversationIntent = new Intent(this,ConversationActivity.class);
207		viewConversationIntent.setAction(Intent.ACTION_VIEW);
208		viewConversationIntent.putExtra(
209				ConversationActivity.CONVERSATION,
210				conversation.getUuid());
211		viewConversationIntent
212				.setType(ConversationActivity.VIEW_CONVERSATION);
213		viewConversationIntent.setFlags(viewConversationIntent
214				.getFlags() | Intent.FLAG_ACTIVITY_CLEAR_TOP);
215		startActivity(viewConversationIntent);
216	}
217
218	@Override
219	public void onStart() {
220		super.onStart();
221
222		CursorLoader mCursorLoader = new CursorLoader(this,
223				ContactsContract.Data.CONTENT_URI, PROJECTION, SELECTION, null,
224				null);
225		mCursorLoader.registerListener(0, new OnLoadCompleteListener<Cursor>() {
226
227			@Override
228			public void onLoadComplete(Loader<Cursor> arg0, Cursor cursor) {
229				phoneContacts.clear();
230				while (cursor.moveToNext()) {
231					String profilePhoto = cursor.getString(cursor
232							.getColumnIndex(ContactsContract.Data.PHOTO_THUMBNAIL_URI));
233					/*if (profilePhoto == null) {
234						profilePhoto = DEFAULT_PROFILE_PHOTO;
235					}*/
236					Contact contact = new Contact(null,
237							cursor.getString(cursor
238									.getColumnIndex(ContactsContract.Data.DISPLAY_NAME)),
239							cursor.getString(cursor
240									.getColumnIndex(ContactsContract.CommonDataKinds.Im.DATA)),
241							profilePhoto);
242					phoneContacts.add(contact);
243				}
244				updateAggregatedContacts();
245			}
246		});
247		mCursorLoader.startLoading();
248
249	}
250
251	@Override
252	void onBackendConnected() {
253		if (xmppConnectionService.getConversationCount() == 0) {
254			getActionBar().setDisplayHomeAsUpEnabled(false);
255			getActionBar().setHomeButtonEnabled(false);
256		}
257		this.accounts = xmppConnectionService.getAccounts();
258		this.rosterContacts.clear();
259		for(Account account : this.accounts) {
260			xmppConnectionService.getRoster(account, new OnRosterFetchedListener() {
261				
262				@Override
263				public void onRosterFetched(List<Contact> roster) {
264					rosterContacts.addAll(roster);
265					runOnUiThread(new Runnable() {
266						
267						@Override
268						public void run() {
269							updateAggregatedContacts();
270						}
271					});
272	
273				}
274			});
275		}
276	}
277
278	@Override
279	public boolean onCreateOptionsMenu(Menu menu) {
280		// Inflate the menu; this adds items to the action bar if it is present.
281		getMenuInflater().inflate(R.menu.newconversation, menu);
282		return true;
283	}
284
285	@Override
286	public boolean onOptionsItemSelected(MenuItem item) {
287		switch (item.getItemId()) {
288		case R.id.action_settings:
289			startActivity(new Intent(this, SettingsActivity.class));
290			break;
291		case R.id.action_accounts:
292			startActivity(new Intent(this, ManageAccountActivity.class));
293			break;
294		default:
295			break;
296		}
297		return super.onOptionsItemSelected(item);
298	}
299
300}