У меня есть активность, которая должна отображать контакты телефона Android в формате ListView
, который является фрагментом внутри моей деятельности AddressBook.java
. Я смог получить список, чтобы отображать имена, но ничего больше. Я чувствую, что я рядом, но мне трудно найти работу. В моих XML-файлах (у меня 4) у меня есть активность XML (есть только фрагмент), ListView XML (contact_list_view.xml
), а затем типичная строка для ListView, которую я называю своим Item XML (contacts_list_item.xml
). Но как мне подключить все эти представления к виду моей активности? Я думаю, что у меня есть фрагмент внутри операции OK, так как список имен работает, но не уверен, как получить фотографию и электронную почту для отображения. Я знаю, что в моем основном коде тоже что-то отсутствует, ContactFragments.java
.Display ContactContracts Name, Email, Photo в ListView, используя Fragment - Android
Одна проблема, мне пришлось отфильтровать мои контакты по имени, иначе каждое электронное письмо в каждом приложении на моем телефоне опубликует, что не то, что я хочу. Я хочу, чтобы контакты в приложении Android Contacts отображались, поэтому я надеюсь, что это не мешает другим деталям контактов показывать.
Ниже мой код, я не показываю свою активность AddressBook.java
, потому что я использую только представление XML, чтобы отображать в нем свой фрагмент, используя теги фрагментов (что отлично работает, потому что я как минимум получаю имена контактов).
Я искал широкий и широкий ответы на это сообщение в Интернете, но есть так много частей, я не мог найти, как решить мою конкретную ситуацию. Я надеюсь использовать мой код, который у меня уже есть, и отредактировать его минимально (по сравнению с внедрением совершенно нового способа достижения этого с помощью других классов и т. Д.). Если у вас есть идеи, я буду очень благодарен.
ContactsFragment.java
package org.azurespot.practiceapp.addressbook;
import android.app.ListFragment;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.ContentUris;
import android.content.CursorLoader;
import android.content.Loader;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.ContactsContract.Contacts;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CursorAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import com.example.practiceapp.R;
/*
* Taken from http://stackoverflow.com/questions/18199359/how-to-display-contacts-in-a-listview-in-android-for-android-api-11
*/
public class ContactsFragment extends ListFragment implements
LoaderCallbacks<Cursor>{
private CursorAdapter mAdapter;
public ListView listView;
public Cursor cursor;
// Name should be displayed in the text1 TextView in item layout
public static final String[] FROM = { ContactsContract.Contacts
.DISPLAY_NAME_PRIMARY };
private static final int[] TO = { android.R.id.text1 };
private android.content.Context context;
public View view;
public static Uri uri;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// delete list if already there (old version)
if (!(listView == null)){
listView.setAdapter(null);
}
// create adapter once
context = getActivity();
int layout = android.R.layout.simple_list_item_1;
Cursor c = null; // there is no cursor yet
int flags = 0; // no auto-requery! Loader requeries.
// put List in adapter
mAdapter = new SimpleCursorAdapter(context, layout, c, FROM, TO, flags);
} // end onCreate
// columns requested from the database
private static final String[] PROJECTION = {
Contacts._ID,
ContactsContract.Contacts.PHOTO_THUMBNAIL_URI,
ContactsContract.Contacts.DISPLAY_NAME_PRIMARY,
ContactsContract.Contacts.HAS_PHONE_NUMBER,
ContactsContract.Contacts.IN_VISIBLE_GROUP
};
// this goes in the CursorLoader parameter list, it filters
// out only those contacts who have a phone number
private static final String SELECTION =
ContactsContract.Contacts.HAS_PHONE_NUMBER + "='1'";
// Empty public constructor, required by the system
public ContactsFragment() {}
// A UI Fragment must inflate its View (all fragments must override onCreateView)
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the fragment layout
View view = inflater.inflate(R.layout.contact_list_view,
container, false);
listView = (ListView) view.findViewById(R.id.list);
// set Contact photo to ImageView
ContactsFragment frag = new ContactsFragment();
ImageView thumb = (ImageView)view.findViewById(R.id.contact_thumbnail);
frag.getPhotoUriFromID(Contacts._ID);
thumb.setImageURI(uri);
return view;
}
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// and tell loader manager to start loading
getLoaderManager().initLoader(0, null, this);
listView.setAdapter(mAdapter);
listView.setFastScrollEnabled(true);
}
// a CursorLoader does a query in the background
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
// load from the "Contacts table"
Uri contentUri = Contacts.CONTENT_URI;
// no sub-selection, no sort order, simply every row
// projection says we want just the _id and the name column
return new CursorLoader(getActivity(),
contentUri,
PROJECTION,
SELECTION,
null,
ContactsContract.Contacts.DISPLAY_NAME
);
}
private Uri getPhotoUriFromID(String id) {
try {
Cursor cur = context.getContentResolver()
.query(ContactsContract.Data.CONTENT_URI,
null,
ContactsContract.Data.CONTACT_ID
+ "="
+ id
+ " AND "
+ ContactsContract.Data.MIMETYPE
+ "='"
+ ContactsContract.CommonDataKinds.Photo.CONTENT_ITEM_TYPE
+ "'", null, null);
if (cur != null) {
if (!cur.moveToFirst()) {
return null; // no photo
}
} else {
return null; // error in cursor process
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
Uri person = ContentUris.withAppendedId(
ContactsContract.Contacts.CONTENT_URI, Long.parseLong(id));
uri = Uri.withAppendedPath(person,
ContactsContract.Contacts.Photo.CONTENT_DIRECTORY);
return uri;
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
// Once cursor is loaded, give it to adapter
mAdapter.swapCursor(data);
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
// Delete the reference to the existing Cursor,
// so it can recycle it
mAdapter.swapCursor(null);
}
}
contact_list_view.xml
<?xml version="1.0" encoding="utf-8"?>
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</ListView>
contacts_list_item
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ImageView
android:id="@+id/contact_thumbnail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/thumbnail" />
<TextView
android:id='@+id/text_name'
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"/>
</LinearLayout>
Спасибо Арджун, однако я пытаюсь вытащить из своих «Контакты», что является целым другим зверьком, а не только «ListView». В некоторых учебниках говорится, что 'CursorLoader' имеет свой собственный вид, поэтому мне не нужно его предоставлять. Затем другие говорят, чтобы получить фото/электронную почту из запроса, используя мой «Курсор», обращаясь к таблице классов «ContactContracts.Data». Все еще исследую, но если я узнаю больше, я остановлюсь на этом здесь.Спасибо за эту идею. – Azurespot