我想在我的应用程序中使用AutoCompleteTextView显示联系人。我用谷歌搜索并使用堆栈溢出的一些代码,但有时它不能很好地工作,有时它也会崩溃。请任何人帮助我。
custcontview.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:padding="10dp"
card_view:cardBackgroundColor="#ffffff"
card_view:cardCornerRadius="1dp"
android:layout_marginLeft="15dp"
card_view:cardElevation="5dp"
card_view:contentPadding="2dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
android:layout_marginBottom="10dp"
android:weightSum="2">
<TextView
android:id="@+id/ccontName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Large Text"
android:layout_weight="1"
android:textSize="15sp"
android:textAppearance="?android:attr/textAppearanceLarge" />
<TextView
android:id="@+id/ccontNo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="@id/ccontName"
android:text="Medium Text"
android:layout_weight="1"
android:textSize="15sp"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
<TextView
android:id="@+id/ccontType"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/ccontNo"
android:layout_alignParentRight="true"
android:layout_marginRight="14dp"
android:text="Small Text"
android:textSize="15sp"
android:visibility="gone"
android:textColor="#A5000000"
android:textAppearance="?android:attr/textAppearanceSmall" />
</android.support.v7.widget.CardView>
mianfragment.java:
AutoCompleteTextView mobile_prepaid_mobilenum_edttxt;
private ArrayList<Map<String, String>> mPeopleList;
oncreate:
mPeopleList = new ArrayList<Map<String, String>>();
mobile_prepaid_mobilenum_edttxt = (AutoCompleteTextView) lay.findViewById(R.id.mobile_prepaid_mobilenum_edttxt);
new Task1().execute();
mAdapter = new SimpleAdapter(getActivity(), mPeopleList, R.layout.custcontview ,new String[] { "Name", "Phone" , "Type" }, new int[] { R.id.ccontName, R.id.ccontNo, R.id.ccontType });
mobile_prepaid_mobilenum_edttxt.setAdapter(mAdapter);
mobile_prepaid_mobilenum_edttxt.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> av, View arg1, int index, long arg3) {
Map<String, String> map = (Map<String, String>) av.getItemAtPosition(index);
String name = map.get("Name");
String number = map.get("Phone");
mobile_prepaid_mobilenum_edttxt.setText(number);
}
});
}
public void PopulatePeopleList()
{
mPeopleList.clear();
Cursor people = getActivity().getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
while (people.moveToNext())
{
String contactName = people.getString(people.getColumnIndex(
ContactsContract.Contacts.DISPLAY_NAME));
String contactId = people.getString(people.getColumnIndex(
ContactsContract.Contacts._ID));
String hasPhone = people.getString(people.getColumnIndex(
ContactsContract.Contacts.HAS_PHONE_NUMBER));
if ((Integer.parseInt(hasPhone) > 0))
{
// You know have the number so now query it like this
Cursor phones = getActivity().getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+ contactId,
null, null);
while (phones.moveToNext()) {
//store numbers and display a dialog letting the user select which.
String phoneNumber = phones.getString(
phones.getColumnIndex(
ContactsContract.CommonDataKinds.Phone.NUMBER));
String numberType = phones.getString(phones.getColumnIndex(
ContactsContract.CommonDataKinds.Phone.TYPE));
Map<String, String> NamePhoneType = new HashMap<String, String>();
NamePhoneType.put("Name", contactName);
NamePhoneType.put("Phone", phoneNumber.replace("-",""));
if(numberType.equals("0"))
NamePhoneType.put("Type", "Work");
else
if(numberType.equals("1"))
NamePhoneType.put("Type", "Home");
else if(numberType.equals("2"))
NamePhoneType.put("Type", "Mobile");
else
NamePhoneType.put("Type", "Other");
//Then add this map to the list.
mPeopleList.add(NamePhoneType);
}
phones.close();
}
}
people.close();
getActivity(). startManagingCursor(people);
}
class Task1 extends AsyncTask<Void, Void, String> {
@Override
protected void onPreExecute()
{
super.onPreExecute();
}
@Override
protected String doInBackground(Void... arg0)
{
//Record method
PopulatePeopleList();
return "name";
}
@Override
protected void onPostExecute(String result)
{
super.onPostExecute(result);
}
}
ERROR:
AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
Process: com.reload.reload, PID: 17564
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:304)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.ContentResolver android.support.v4.app.FragmentActivity.getContentResolver()' on a null object reference
at com.reload.reload.activity.MobileFragment.PopulatePeopleList(MobileFragment.java:1034)
at com.reload.reload.activity.MobileFragment$Task1.doInBackground(MobileFragment.java:1087)
at com.reloadapp.reload.activity.MobileFragment$Task1.doInBackground(MobileFragment.java:1076)
at android.os.AsyncTask$2.call(AsyncTask.java:292)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
答案 0 :(得分:0)
我可以看到您正在尝试getContentResolver()
来自getActivity()
。所以基本上你的片段是不附加到活动。这可能发生在两种情况下:
getActivity()
之前对getContentResolver()
进行空检查onAttach()
:所以在调用onAttach()
后调用该方法。根据评论中的讨论:
class Task1 extends AsyncTask<Void, Void, String> {
private Context context;
public Task1(Context context){
this.context = context;
}
@Override
protected void onPreExecute()
{
super.onPreExecute();
}
@Override
protected String doInBackground(Void... arg0)
{
//Record method
PopulatePeopleList(context);
return "name";
}
}
现在在PopulatePeopleList()
方法中使用此上下文。
public void PopulatePeopleList(Context context)
{
mPeopleList.clear();
Cursor people = context.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
}
希望这会帮助你。