Tworzę aplikację na Androida i muszę zadzwonić na listę kontaktów w telefonie. Muszę wywołać funkcję listy kontaktów, wybrać kontakt, a następnie wrócić do mojej aplikacji z nazwą kontaktu. Oto kod, który znalazłem w Internecie, ale nie działa.
import android.app.ListActivity;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.Contacts.People;
import android.view.View;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
public class Contacts extends ListActivity {
private ListAdapter mAdapter;
public TextView pbContact;
public static String PBCONTACT;
public static final int ACTIVITY_EDIT=1;
private static final int ACTIVITY_CREATE=0;
// Called when the activity is first created.
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
Cursor C = getContentResolver().query(People.CONTENT_URI, null, null, null, null);
startManagingCursor(C);
String[] columns = new String[] {People.NAME};
int[] names = new int[] {R.id.row_entry};
mAdapter = new SimpleCursorAdapter(this, R.layout.mycontacts, C, columns, names);
setListAdapter(mAdapter);
} // end onCreate()
// Called when contact is pressed
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
Cursor C = (Cursor) mAdapter.getItem(position);
PBCONTACT = C.getString(C.getColumnIndex(People.NAME));
// RHS 05/06
//pbContact = (TextView) findViewById(R.id.myContact);
//pbContact.setText(new StringBuilder().append("b"));
Intent i = new Intent(this, NoteEdit.class);
startActivityForResult(i, ACTIVITY_CREATE);
}
}
Odpowiedzi:
Nie jestem w 100% pewien, co powinien zrobić Twój przykładowy kod, ale poniższy fragment powinien pomóc Ci „wywołać funkcję listy kontaktów, wybrać kontakt, a następnie wrócić do [Twojej] aplikacji z nazwą kontaktu”.
Proces ten składa się z trzech kroków.
1. Uprawnienia
Dodaj uprawnienie do odczytu danych kontaktów do manifestu aplikacji.
<uses-permission android:name="android.permission.READ_CONTACTS"/>
2. Wywołanie selektora kontaktów
W ramach działania utwórz intencję, która prosi system o znalezienie działania, które może wykonać akcję PICK z elementów w identyfikatorze URI kontaktów.
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
Call
startActivityForResult
, przekazując tę intencję (i liczbę całkowitą kodu żądania,PICK_CONTACT
w tym przykładzie). Spowoduje to, że system Android uruchomi działanie, które jest zarejestrowane do obsługiACTION_PICK
wPeople.CONTENT_URI
, a następnie powróci do tego działania po dokonaniu wyboru (lub anulowaniu).startActivityForResult(intent, PICK_CONTACT);
3. Nasłuchiwanie wyniku
Również w swoim działaniu nadpisz
onActivityResult
metodę nasłuchiwania zwrotu z działania „wybierz kontakt”, które zostało uruchomione w kroku 2. Należy sprawdzić, czy zwrócony kod żądania odpowiada oczekiwanej wartości i czy kod wyniku toRESULT_OK
.Można uzyskać URI wybranego kontaktu dzwoniąc
getData()
na danych Intent parametru. Aby uzyskać nazwę wybranego kontaktu, musisz użyć tego identyfikatora URI do utworzenia nowego zapytania i wyodrębnienia nazwy z zwróconego kursora.@Override public void onActivityResult(int reqCode, int resultCode, Intent data) { super.onActivityResult(reqCode, resultCode, data); switch (reqCode) { case (PICK_CONTACT) : if (resultCode == Activity.RESULT_OK) { Uri contactData = data.getData(); Cursor c = getContentResolver().query(contactData, null, null, null, null); if (c.moveToFirst()) { String name = c.getString(c.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)); // TODO Whatever you want to do with the selected contact name. } } break; } }
Pełny kod źródłowy: tutorials-android.blogspot.com (jak wywołać listę kontaktów Androida) .
źródło
Robię to w ten sposób dla wersji Android 2.2 Froyo: w zasadzie użyj eclipse do stworzenia klasy takiej jak: klasa publiczna SomePickContactName rozszerza aktywność
następnie wstaw ten kod. Pamiętaj, aby dodać zmienne klasy prywatnej i STAŁE, do których odwołuje się moja wersja kodu:
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Intent intentContact = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI); startActivityForResult(intentContact, PICK_CONTACT); }//onCreate public void onActivityResult(int requestCode, int resultCode, Intent intent) { if (requestCode == PICK_CONTACT) { getContactInfo(intent); // Your class variables now have the data, so do something with it. } }//onActivityResult protected void getContactInfo(Intent intent) { Cursor cursor = managedQuery(intent.getData(), null, null, null, null); while (cursor.moveToNext()) { String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID)); name = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME)); String hasPhone = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER)); if ( hasPhone.equalsIgnoreCase("1")) hasPhone = "true"; else hasPhone = "false" ; if (Boolean.parseBoolean(hasPhone)) { Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,ContactsContract.CommonDataKinds.Phone.CONTACT_ID +" = "+ contactId,null, null); while (phones.moveToNext()) { phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); } phones.close(); } // Find Email Addresses Cursor emails = getContentResolver().query(ContactsContract.CommonDataKinds.Email.CONTENT_URI,null,ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = " + contactId,null, null); while (emails.moveToNext()) { emailAddress = emails.getString(emails.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA)); } emails.close(); Cursor address = getContentResolver().query( ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_URI, null, ContactsContract.CommonDataKinds.StructuredPostal.CONTACT_ID + " = " + contactId, null, null); while (address.moveToNext()) { // These are all private class variables, don't forget to create them. poBox = address.getString(address.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.POBOX)); street = address.getString(address.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.STREET)); city = address.getString(address.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.CITY)); state = address.getString(address.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.REGION)); postalCode = address.getString(address.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.POSTCODE)); country = address.getString(address.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.COUNTRY)); type = address.getString(address.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.TYPE)); } //address.moveToNext() } //while (cursor.moveToNext()) cursor.close(); }//getContactInfo
źródło
Rozglądając się za rozwiązaniem API na poziomie 5 za pomocą ContactsContract API, można nieznacznie zmodyfikować powyższy kod, wykonując następujące czynności:
Intent intent = new Intent(Intent.ACTION_PICK); intent.setType(ContactsContract.Contacts.CONTENT_TYPE); startActivityForResult(intent, PICK_CONTACT);
Następnie w onActivityResult użyj nazwy kolumny:
ContactsContract.Contacts.DISPLAY_NAME
źródło
Oto fragment kodu umożliwiający uzyskanie kontaktu:
package com.contact; import android.app.Activity; import android.content.ContentResolver; import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.provider.ContactsContract; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; public class GetContactDemoActivity extends Activity implements OnClickListener { private Button btn = null; private TextView txt = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); btn = (Button) findViewById(R.id.button1); txt = (TextView) findViewById(R.id.textView1); btn.setOnClickListener(this); } @Override public void onClick(View arg0) { if (arg0 == btn) { try { Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI); startActivityForResult(intent, 1); } catch (Exception e) { e.printStackTrace(); Log.e("Error in intent : ", e.toString()); } } } @Override public void onActivityResult(int reqCode, int resultCode, Intent data) { super.onActivityResult(reqCode, resultCode, data); try { if (resultCode == Activity.RESULT_OK) { Uri contactData = data.getData(); Cursor cur = managedQuery(contactData, null, null, null, null); ContentResolver contect_resolver = getContentResolver(); if (cur.moveToFirst()) { String id = cur.getString(cur.getColumnIndexOrThrow(ContactsContract.Contacts._ID)); String name = ""; String no = ""; Cursor phoneCur = contect_resolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[] { id }, null); if (phoneCur.moveToFirst()) { name = phoneCur.getString(phoneCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)); no = phoneCur.getString(phoneCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); } Log.e("Phone no & name :***: ", name + " : " + no); txt.append(name + " : " + no + "\n"); id = null; name = null; no = null; phoneCur = null; } contect_resolver = null; cur = null; // populateContacts(); } } catch (IllegalArgumentException e) { e.printStackTrace(); Log.e("IllegalArgumentException :: ", e.toString()); } catch (Exception e) { e.printStackTrace(); Log.e("Error :: ", e.toString()); } }
}
źródło
Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null,null, null); while (phones.moveToNext()) { String Name=phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME) String Number=phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); }
źródło
public void onActivityResult(int requestCode, int resultCode, Intent intent) { if (requestCode == PICK_CONTACT && intent != null) //here check whether intent is null R not { } }
ponieważ bez zaznaczenia żadnego kontaktu da wyjątek. więc lepiej sprawdzić ten stan.
źródło
Pełny kod podano poniżej
package com.testingContect; import android.app.Activity; import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.provider.ContactsContract; import android.provider.Contacts.People; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; public class testingContect extends Activity implements OnClickListener{ /** Called when the activity is first created. */ EditText ed; Button bt; int PICK_CONTACT; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); bt=(Button)findViewById(R.id.button1); ed =(EditText)findViewById(R.id.editText1); ed.setOnClickListener(this); bt.setOnClickListener(this); } @Override public void onClick(View v) { switch(v.getId()) { case R.id.button1: break; case R.id.editText1: Intent intent = new Intent(Intent.ACTION_PICK); intent.setType(ContactsContract.Contacts.CONTENT_TYPE); startActivityForResult(intent, PICK_CONTACT); break; } } public void onActivityResult(int requestCode, int resultCode, Intent intent) { if (requestCode == PICK_CONTACT) { Cursor cursor = managedQuery(intent.getData(), null, null, null, null); cursor.moveToNext(); String contactId = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID)); String name = cursor.getString(cursor.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME)); Toast.makeText(this, "Contect LIST = "+name, Toast.LENGTH_LONG).show(); } }//onActivityResult }//class ends
źródło
private static final int PICK_CONTACT = 1;
.Ku mojemu zdziwieniu nie potrzebujesz pozwolenia użytkownika CONTACT_READ, aby odczytać nazwiska i kilka podstawowych informacji (czy kontakt jest oznaczony gwiazdką, kiedy ostatnio dzwoniono). Potrzebujesz jednak pozwolenia, aby odczytać szczegóły kontaktu, takie jak numer telefonu.
źródło
Zachowaj ostrożność podczas pracy z listą kontaktów Androida.
Czytanie listy kontaktów w powyższych metodach działa na większości urządzeń z Androidem, z wyjątkiem HTC One i Sony Xperia. Zmarnowałem moje sześć tygodni, próbując dowiedzieć się, co jest nie tak!
Większość samouczków dostępnych w Internecie jest prawie podobnych - najpierw przeczytaj „WSZYSTKIE” kontakty, a następnie wyświetl je za
Listview
pomocąArrayAdapter
. To nie jest rozwiązanie wydajne pod względem pamięci. Zamiast najpierw szukać rozwiązań w innych witrynach, zajrzyj na developer.android.com. Jeśli jakieś rozwiązanie nie jest dostępne na developer.android.com, powinieneś poszukać gdzie indziej.Rozwiązaniem jest użycie
CursorAdapter
zamiastArrayAdapter
pobierania listy kontaktów. UżywanieArrayAdapter
działałoby na większości urządzeń, ale nie jest wydajne. WCursorAdapter
wyszukuje tylko część listy kontaktów w czasie wykonywania, gdyListView
jest przewijane.public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); ... // Gets the ListView from the View list of the parent activity mContactsList = (ListView) getActivity().findViewById(R.layout.contact_list_view); // Gets a CursorAdapter mCursorAdapter = new SimpleCursorAdapter( getActivity(), R.layout.contact_list_item, null, FROM_COLUMNS, TO_IDS, 0); // Sets the adapter for the ListView mContactsList.setAdapter(mCursorAdapter); }
Pobieranie listy kontaktów: pobieranie listy kontaktów
źródło
public static List<ContactItem> readPhoneContacts(Context context) { List<ContactItem> contactItems = new ArrayList<ContactItem>(); try { Cursor cursor = context.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, null, null, "upper("+ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + ") ASC"); /*context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID+ " = ?", new String[] { id }, ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME+" ASC");*/ Integer contactsCount = cursor.getCount(); // get how many contacts you have in your contacts list if (contactsCount > 0) { while (cursor.moveToNext()) { String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID)); String contactName = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)); if (Integer.parseInt(cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))) > 0) { ContactItem contactItem = new ContactItem(); contactItem.setContactName(contactName); //the below cursor will give you details for multiple contacts Cursor pCursor = context.getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[]{id}, null); // continue till this cursor reaches to all phone numbers which are associated with a contact in the contact list while (pCursor.moveToNext()) { int phoneType = pCursor.getInt(pCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE)); //String isStarred = pCur.getString(pCur.getColumnIndex(ContactsContract.CommonDataKinds.Phone.STARRED)); String phoneNo = pCursor.getString(pCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); //you will get all phone numbers according to it's type as below switch case. //Logs.e will print the phone number along with the name in DDMS. you can use these details where ever you want. switch (phoneType) { case Phone.TYPE_MOBILE: contactItem.setContactNumberMobile(phoneNo); Log.e(contactName + ": TYPE_MOBILE", " " + phoneNo); break; case ContactsContract.CommonDataKinds.Phone.TYPE_HOME: contactItem.setContactNumberMobile(phoneNo); Log.e(contactName + ": TYPE_HOME", " " + phoneNo); break; case ContactsContract.CommonDataKinds.Phone.TYPE_WORK: contactItem.setContactNumberMobile(phoneNo); Log.e(contactName + ": TYPE_WORK", " " + phoneNo); break; case ContactsContract.CommonDataKinds.Phone.TYPE_WORK_MOBILE: contactItem.setContactNumberMobile(phoneNo); Log.e(contactName + ": TYPE_WORK_MOBILE", " " + phoneNo); break; case Phone.TYPE_OTHER: contactItem.setContactNumberMobile(phoneNo); Log.e(contactName + ": TYPE_OTHER", " " + phoneNo); break; default: break; } } contactItem.setSelectedAddress(getContactPostalAddress(pCursor)); pCursor.close(); contactItems.add(contactItem); } } cursor.close(); } } catch (Exception ex) { ex.printStackTrace(); } return contactItems; }//loadContacts
źródło
Cześć, mam kod do zapisania kontaktu w Twojej bazie danych według wspólnych preferencji. Oto mój kod
public class Main22Activity extends AppCompatActivity { EditText nameInput,phoneInput; TextView LargeText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main22); nameInput = (EditText) findViewById(R.id.nameInput); phoneInput = (EditText) findViewById(R.id.phoneInput); LargeText = (TextView) findViewById(R.id.textView2); } public void saveInfo (View view){ SharedPreferences sharedPref = getSharedPreferences("nameInfo" , Context.MODE_PRIVATE); SharedPreferences.Editor editor= sharedPref.edit(); editor.putString("name", nameInput.getText().toString()); editor.putString("phone", phoneInput.getText().toString()); editor.apply(); Toast.makeText(this, "Saved", Toast.LENGTH_LONG).show(); } public void displayData(View view){ SharedPreferences sharedPref = getSharedPreferences("nameInfo" , Context.MODE_PRIVATE); String name = sharedPref.getString("name", ""); String ph = sharedPref.getString ("phone",""); LargeText.setText(name + " " + ph); } }
źródło
-> Add a permission to read contacts data to your application manifest. <uses-permission android:name="android.permission.READ_CONTACTS"/> -> Use Intent.Action_Pick in your Activity like below Intent contactPickerIntent = new Intent(Intent.ACTION_PICK, ContactsContract.CommonDataKinds.Phone.CONTENT_URI); startActivityForResult(contactPickerIntent, RESULT_PICK_CONTACT); -> Then Override the onActivityResult() @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { // check whether the result is ok if (resultCode == RESULT_OK) { // Check for the request code, we might be usign multiple startActivityForReslut switch (requestCode) { case RESULT_PICK_CONTACT: Cursor cursor = null; try { String phoneNo = null ; String name = null; Uri uri = data.getData(); cursor = getContentResolver().query(uri, null, null, null, null); cursor.moveToFirst(); int phoneIndex =cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER); phoneNo = cursor.getString(phoneIndex); textView2.setText(phoneNo); } catch (Exception e) { e.printStackTrace(); } break; } } else { Log.e("MainActivity", "Failed to pick contact"); } } This will work check it out
źródło
Używam kodu dostarczonego przez @Colin MacKenzie - III. Wielkie dzięki!
Dla kogoś, kto szuka zastąpienia „przestarzałego” managedQuery:
Po pierwsze, zakładając, że używana jest obsługa v4 lib:
import android.support.v4.app.LoaderManager; import android.support.v4.content.CursorLoader; import android.support.v4.content.Loader;
2:
your_(activity)_class implements LoaderManager.LoaderCallbacks<Cursor>
3rd,
// temporarily store the 'data.getData()' from onActivityResult private Uri tmp_url;
Po czwarte, zastąp wywołania zwrotne:
@Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { // create the loader here! CursorLoader cursorLoader = new CursorLoader(this, tmp_url, null, null, null, null); return cursorLoader; } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { getContactInfo(cursor); // here it is! } @Override public void onLoaderReset(Loader<Cursor> loader) { }
5:
public void initLoader(Uri data){ // will be used in onCreateLoader callback this.tmp_url = data; // 'this' is an Activity instance, implementing those callbacks this.getSupportLoaderManager().initLoader(0, null, this); }
Po szóste, powyższy kod , z tym że zmieniam parametr podpisu z Intent na Cursor:
protected void getContactInfo(Cursor cursor) { // Cursor cursor = managedQuery(intent.getData(), null, null, null, null); while (cursor.moveToNext()) { // same above ... }
7th, wywołaj initLoader:
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (PICK_CONTACT == requestCode) { this.initLoader(data.getData(), this); } }
Po ósme, nie zapomnij tego fragmentu kodu
Intent intentContact = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI); this.act.startActivityForResult(intentContact, PICK_CONTACT);
Bibliografia:
Podstawy Androida: prawidłowe ładowanie danych
Inicjowanie modułu ładującego w działaniu
źródło