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