/*
* VoIP.ms SMS
* Copyright (C) 2015-2016 Michael Kourlas
*
* 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 net.kourlas.voipms_sms.adapters;
import android.annotation.TargetApi;
import android.content.Context;
import android.database.Cursor;
import android.graphics.Outline;
import android.net.Uri;
import android.os.Build;
import android.provider.ContactsContract;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewOutlineProvider;
import android.widget.*;
import net.kourlas.voipms_sms.R;
import net.kourlas.voipms_sms.activities.NewConversationActivity;
import net.kourlas.voipms_sms.utils.Utils;
import java.util.ArrayList;
import java.util.List;
public class NewConversationListViewAdapter extends BaseAdapter
implements Filterable, SectionIndexer
{
private static final int ITEM_COUNT = 2;
private static final int ITEM_PRIMARY = 0;
private static final int ITEM_SECONDARY = 1;
private final NewConversationActivity activity;
private final List<NewConversationListViewAdapter.ContactItem> items;
private String typedInPhoneNumber;
public NewConversationListViewAdapter(NewConversationActivity activity) {
this.activity = activity;
this.typedInPhoneNumber = null;
this.items = new ArrayList<>();
}
public void refresh(String newFilterConstraint) {
getFilter().filter(newFilterConstraint);
}
public Filter getFilter() {
return new NewConversationFilter();
}
public void showTypedInItem(String phoneNumber) {
typedInPhoneNumber = phoneNumber;
}
public void hideTypedInItem() {
typedInPhoneNumber = null;
}
@Override
public int getItemViewType(int position) {
ContactItem contactItem = (ContactItem) getItem(position);
if (contactItem.isPrimary()) {
return ITEM_PRIMARY;
} else {
return ITEM_SECONDARY;
}
}
@Override
public int getViewTypeCount() {
return ITEM_COUNT;
}
@Override
public int getCount() {
return items.size();
}
@SuppressWarnings("WeakerAccess")
public static class ContactItem {
private final long id;
private final String name;
private final String phoneNumber;
private final String phoneNumberType;
private final String photoUri;
private final boolean typedIn;
private boolean primary;
ContactItem(long id, String name, String phoneNumber,
String phoneNumberType, String photoUri,
boolean primary, boolean typedIn)
{
this.id = id;
this.name = name;
this.phoneNumber = phoneNumber;
this.phoneNumberType = phoneNumberType;
this.photoUri = photoUri;
this.primary = primary;
this.typedIn = typedIn;
}
public String getName() {
return name;
}
public String getPhoneNumber() {
return phoneNumber;
}
public String getPhoneNumberType() {
return phoneNumberType;
}
public String getPhotoUri() {
return photoUri;
}
public boolean isPrimary() {
return primary;
}
public void setPrimary(boolean primary) {
this.primary = primary;
}
public boolean isTypedIn() {
return typedIn;
}
public long getId() {
return id;
}
}
class NewConversationFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
List<ContactItem> contactItemResults = new ArrayList<>();
String searchText = constraint.toString();
List<ContactItem> phoneNumberEntries = new ArrayList<>();
phoneNumberEntries.addAll(getContacts());
if (typedInPhoneNumber != null) {
phoneNumberEntries.add(0, new ContactItem(-1,
typedInPhoneNumber,
typedInPhoneNumber,
"", null, true,
true));
}
for (ContactItem contactItem : phoneNumberEntries) {
if (contactItem.getName().toLowerCase()
.contains(searchText.toLowerCase()) ||
contactItem.getPhoneNumber().toLowerCase()
.contains(searchText.toLowerCase()) ||
(!searchText.replaceAll("[^0-9]", "").equals("") &&
contactItem.getPhoneNumber().replaceAll("[^0-9]", "")
.contains(
searchText.replaceAll("[^0-9]", ""))) ||
contactItem.isTypedIn())
{
contactItemResults.add(contactItem);
}
}
for (int i = 0; i < contactItemResults.size(); i++) {
boolean found = false;
for (int j = 0; j < i; j++) {
if (contactItemResults.get(i).getName().equals(
contactItemResults.get(j).getName()))
{
contactItemResults.get(i).setPrimary(false);
contactItemResults.get(j).setPrimary(true);
found = true;
break;
}
}
if (!found) {
contactItemResults.get(i).setPrimary(true);
}
}
results.count = contactItemResults.size();
results.values = contactItemResults;
return results;
}
private List<ContactItem> getContacts() {
List<ContactItem> phoneNumberEntries = new ArrayList<>();
try {
Cursor cursor = activity.getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null, null, null,
ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME
+ " ASC");
if (cursor != null && cursor.getCount() > 0) {
while (cursor.moveToNext()) {
if (cursor.getString(cursor.getColumnIndex(
ContactsContract.Contacts.HAS_PHONE_NUMBER))
.equals("1"))
{
long id = cursor.getLong(
cursor.getColumnIndex(
ContactsContract.CommonDataKinds.Phone
.CONTACT_ID));
String contact = cursor.getString(
cursor.getColumnIndex(
ContactsContract.Contacts.DISPLAY_NAME));
String phoneNumber = cursor.getString(
cursor.getColumnIndex(
ContactsContract.CommonDataKinds
.Phone.NUMBER));
String phoneNumberType =
Utils.getPhoneNumberType(
cursor.getInt(
cursor.getColumnIndex(
ContactsContract.CommonDataKinds
.Phone.TYPE)));
String photoUri = cursor.getString(
cursor.getColumnIndex(
ContactsContract.Contacts.PHOTO_URI));
boolean showPhoto = true;
for (ContactItem contactItem : phoneNumberEntries) {
if (id == contactItem.getId()) {
showPhoto = false;
}
}
ContactItem contactItem = new ContactItem(
id, contact, phoneNumber, phoneNumberType,
photoUri, showPhoto, false);
phoneNumberEntries.add(contactItem);
}
}
cursor.close();
} else if (cursor != null) {
cursor.close();
}
return phoneNumberEntries;
} catch (SecurityException ignored) {
return phoneNumberEntries;
}
}
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint,
FilterResults results)
{
items.clear();
if (results.values != null) {
items.addAll((List<ContactItem>) results.values);
}
notifyDataSetChanged();
}
}
@Override
public Object getItem(int position) {
return items.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LayoutInflater inflater = (LayoutInflater) activity.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
ContactItem contactItem = (ContactItem) getItem(position);
// Set item layout
if (contactItem.isPrimary()) {
convertView = inflater.inflate(
R.layout.new_conversation_item_primary, parent, false);
} else {
convertView = inflater.inflate(
R.layout.new_conversation_item_secondary, parent, false);
}
// Add indexes to entries where appropriate
TextView textView = (TextView) convertView.findViewById(R.id.letter);
if (contactItem.isPrimary() && !contactItem.isTypedIn()) {
if (position == 0 || contactItem.getName().charAt(0) !=
((ContactItem) getItem(position - 1)).getName()
.charAt(
0))
{
textView.setText(String.valueOf(
contactItem.getName().toUpperCase().charAt(0)));
}
}
if (contactItem.isPrimary()) {
QuickContactBadge photo =
(QuickContactBadge) convertView.findViewById(R.id.photo);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
photo.setOutlineProvider(new ViewOutlineProvider() {
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override
public void getOutline(View view, Outline outline) {
outline
.setOval(0, 0, view.getWidth(), view.getHeight());
}
});
photo.setClipToOutline(true);
}
photo.assignContactFromPhone(contactItem.getPhoneNumber(), true);
if (contactItem.isTypedIn()) {
photo.setScaleType(ImageView.ScaleType.CENTER);
photo.setBackgroundResource(R.color.primary);
photo.setImageResource(R.drawable.ic_dialpad_white_24dp);
} else if (contactItem.getPhotoUri() == null) {
photo.setImageToDefault();
} else {
photo.setImageURI(Uri.parse(contactItem.getPhotoUri()));
}
TextView contactTextView =
(TextView) convertView.findViewById(R.id.contact);
if (contactItem.isTypedIn()) {
contactTextView.setText(
activity.getString(R.string.new_conversation_manual_entry));
} else {
contactTextView.setText(contactItem.getName());
}
}
TextView phoneNumberTextView =
(TextView) convertView.findViewById(R.id.phone_number);
phoneNumberTextView.setText(contactItem.getPhoneNumber());
TextView phoneNumberTypeTextView =
(TextView) convertView.findViewById(R.id.phone_number_type);
phoneNumberTypeTextView.setText(contactItem.getPhoneNumberType());
return convertView;
}
@Override
public Object[] getSections() {
List<String> sections = new ArrayList<>();
if (getCount() > 0 && ((ContactItem) getItem(0)).isTypedIn()) {
sections.add("");
}
int itemCount = getCount();
for (int i =
getCount() > 0 && ((ContactItem) getItem(0)).isTypedIn() ? 1 : 0;
i < itemCount; i++) {
ContactItem contactItem = (ContactItem) getItem(i);
if (!sections
.contains(contactItem.getName().toUpperCase().charAt(0) + ""))
{
sections
.add(contactItem.getName().toUpperCase().charAt(0) + "");
}
}
String[] sectionsArray = new String[sections.size()];
return sections.toArray(sectionsArray);
}
@Override
public int getPositionForSection(int sectionIndex) {
if (getSections()[sectionIndex].toString().equals("")) {
return 0;
}
int itemCount = getCount();
for (int i =
getCount() > 0 && ((ContactItem) getItem(0)).isTypedIn() ? 1 : 0;
i < itemCount; i++) {
if (((ContactItem) getItem(i)).getName().toUpperCase().charAt(0) ==
getSections()[sectionIndex].toString().charAt(0))
{
return i;
}
}
return 0;
}
@Override
public int getSectionForPosition(int position) {
if (((ContactItem) getItem(position)).isTypedIn()) {
return 0;
}
String[] sections = (String[]) getSections();
for (int i = sections.length > 0 && sections[0].equals("") ? 1 : 0;
i < sections.length; i++) {
if (sections[i].charAt(0) == ((ContactItem) getItem(position))
.getName().toUpperCase().charAt(0))
{
return i;
}
}
return 0;
}
}