1/* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.dialer.app.list; 18 19import static android.Manifest.permission.READ_CONTACTS; 20 21import android.app.Activity; 22import android.content.BroadcastReceiver; 23import android.content.Context; 24import android.content.Intent; 25import android.content.Loader; 26import android.content.pm.PackageManager; 27import android.database.Cursor; 28import android.net.Uri; 29import android.provider.ContactsContract.CommonDataKinds.Phone; 30import android.provider.ContactsContract.QuickContact; 31import android.support.v13.app.FragmentCompat; 32import android.view.LayoutInflater; 33import android.view.View; 34import android.view.ViewGroup; 35import android.widget.AdapterView; 36import com.android.contacts.common.list.ContactEntryListAdapter; 37import com.android.contacts.common.list.ContactEntryListFragment; 38import com.android.contacts.common.list.ContactListFilter; 39import com.android.contacts.common.list.DefaultContactListAdapter; 40import com.android.dialer.app.R; 41import com.android.dialer.common.LogUtil; 42import com.android.dialer.compat.CompatUtils; 43import com.android.dialer.logging.InteractionEvent; 44import com.android.dialer.logging.Logger; 45import com.android.dialer.util.DialerUtils; 46import com.android.dialer.util.IntentUtil; 47import com.android.dialer.util.PermissionsUtil; 48import com.android.dialer.widget.EmptyContentView; 49import com.android.dialer.widget.EmptyContentView.OnEmptyViewActionButtonClickedListener; 50import java.util.Arrays; 51 52/** Fragments to show all contacts with phone numbers. */ 53public class AllContactsFragment extends ContactEntryListFragment<ContactEntryListAdapter> 54 implements OnEmptyViewActionButtonClickedListener, 55 FragmentCompat.OnRequestPermissionsResultCallback { 56 57 private static final int READ_CONTACTS_PERMISSION_REQUEST_CODE = 1; 58 59 private EmptyContentView mEmptyListView; 60 61 /** 62 * Listen to broadcast events about permissions in order to be notified if the READ_CONTACTS 63 * permission is granted via the UI in another fragment. 64 */ 65 private BroadcastReceiver mReadContactsPermissionGrantedReceiver = 66 new BroadcastReceiver() { 67 @Override 68 public void onReceive(Context context, Intent intent) { 69 reloadData(); 70 } 71 }; 72 73 public AllContactsFragment() { 74 setQuickContactEnabled(false); 75 setAdjustSelectionBoundsEnabled(true); 76 setPhotoLoaderEnabled(true); 77 setSectionHeaderDisplayEnabled(true); 78 setDarkTheme(false); 79 setVisibleScrollbarEnabled(true); 80 } 81 82 @Override 83 public void onViewCreated(View view, android.os.Bundle savedInstanceState) { 84 super.onViewCreated(view, savedInstanceState); 85 86 mEmptyListView = (EmptyContentView) view.findViewById(R.id.empty_list_view); 87 mEmptyListView.setImage(R.drawable.empty_contacts); 88 mEmptyListView.setDescription(R.string.all_contacts_empty); 89 mEmptyListView.setActionClickedListener(this); 90 getListView().setEmptyView(mEmptyListView); 91 mEmptyListView.setVisibility(View.GONE); 92 } 93 94 @Override 95 public void onStart() { 96 super.onStart(); 97 PermissionsUtil.registerPermissionReceiver( 98 getActivity(), mReadContactsPermissionGrantedReceiver, READ_CONTACTS); 99 } 100 101 @Override 102 public void onStop() { 103 PermissionsUtil.unregisterPermissionReceiver( 104 getActivity(), mReadContactsPermissionGrantedReceiver); 105 super.onStop(); 106 } 107 108 @Override 109 protected void startLoading() { 110 if (PermissionsUtil.hasPermission(getActivity(), READ_CONTACTS)) { 111 super.startLoading(); 112 mEmptyListView.setDescription(R.string.all_contacts_empty); 113 mEmptyListView.setActionLabel(R.string.all_contacts_empty_add_contact_action); 114 } else { 115 mEmptyListView.setDescription(R.string.permission_no_contacts); 116 mEmptyListView.setActionLabel(R.string.permission_single_turn_on); 117 mEmptyListView.setVisibility(View.VISIBLE); 118 } 119 } 120 121 @Override 122 public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 123 super.onLoadFinished(loader, data); 124 125 if (data == null || data.getCount() == 0) { 126 mEmptyListView.setVisibility(View.VISIBLE); 127 } 128 } 129 130 @Override 131 protected ContactEntryListAdapter createListAdapter() { 132 final DefaultContactListAdapter adapter = 133 new DefaultContactListAdapter(getActivity()) { 134 @Override 135 protected void bindView(View itemView, int partition, Cursor cursor, int position) { 136 super.bindView(itemView, partition, cursor, position); 137 itemView.setTag(this.getContactUri(partition, cursor)); 138 } 139 }; 140 adapter.setDisplayPhotos(true); 141 adapter.setFilter( 142 ContactListFilter.createFilterWithType(ContactListFilter.FILTER_TYPE_DEFAULT)); 143 adapter.setSectionHeaderDisplayEnabled(isSectionHeaderDisplayEnabled()); 144 return adapter; 145 } 146 147 @Override 148 protected View inflateView(LayoutInflater inflater, ViewGroup container) { 149 return inflater.inflate(R.layout.all_contacts_fragment, null); 150 } 151 152 @Override 153 public void onItemClick(AdapterView<?> parent, View view, int position, long id) { 154 final Uri uri = (Uri) view.getTag(); 155 if (uri != null) { 156 Logger.get(getContext()) 157 .logInteraction(InteractionEvent.Type.OPEN_QUICK_CONTACT_FROM_ALL_CONTACTS_GENERAL); 158 if (CompatUtils.hasPrioritizedMimeType()) { 159 QuickContact.showQuickContact(getContext(), view, uri, null, Phone.CONTENT_ITEM_TYPE); 160 } else { 161 QuickContact.showQuickContact(getActivity(), view, uri, QuickContact.MODE_LARGE, null); 162 } 163 } 164 } 165 166 @Override 167 protected void onItemClick(int position, long id) { 168 // Do nothing. Implemented to satisfy ContactEntryListFragment. 169 } 170 171 @Override 172 public void onEmptyViewActionButtonClicked() { 173 final Activity activity = getActivity(); 174 if (activity == null) { 175 return; 176 } 177 178 String[] deniedPermissions = 179 PermissionsUtil.getPermissionsCurrentlyDenied( 180 getContext(), PermissionsUtil.allContactsGroupPermissionsUsedInDialer); 181 if (deniedPermissions.length > 0) { 182 LogUtil.i( 183 "AllContactsFragment.onEmptyViewActionButtonClicked", 184 "Requesting permissions: " + Arrays.toString(deniedPermissions)); 185 FragmentCompat.requestPermissions( 186 this, deniedPermissions, READ_CONTACTS_PERMISSION_REQUEST_CODE); 187 } else { 188 // Add new contact 189 DialerUtils.startActivityWithErrorToast( 190 activity, IntentUtil.getNewContactIntent(), R.string.add_contact_not_available); 191 } 192 } 193 194 @Override 195 public void onRequestPermissionsResult( 196 int requestCode, String[] permissions, int[] grantResults) { 197 if (requestCode == READ_CONTACTS_PERMISSION_REQUEST_CODE) { 198 if (grantResults.length >= 1 && PackageManager.PERMISSION_GRANTED == grantResults[0]) { 199 // Force a refresh of the data since we were missing the permission before this. 200 reloadData(); 201 } 202 } 203 } 204} 205