I am getting all of my contacts details from contactconstract table, and Want to store all my contact data to String array then I would like to pass it to AsyncTask for doing some background task,Currently I am passing single contacts detail to AsyncTask,that would made my code crash because one by one asynctask is being called for each contact detail, I would like to store all my contact detail into array an then I pass this array to AsyncTASK so only one time AsyncTask would call so Please help me in this regard,
Given below is my part of the code:
ContentResolver cr = getContentResolver();
SavingContacts savingcontacts=new SavingContacts();
Cursor = getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
null, null,
ContactsContract.Contacts.DISPLAY_NAME + " ASC");
Log.d("database1" ,"17");
if (Cursor.getCount() > 0) {
while (Cursor.moveToNext()) {
phone = Cursor.getString(Cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
if (!TextUtils.isEmpty(phone)) {
Log.d("Your Location4", "ok4:");
name = Cursor.getString(Cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
id = Cursor.getString(Cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID));
// photouri=Cursor.getString(Cursor.getColumnIndex(ContactsContract.CommonDataKinds.Photo.PHOTO));
email=Cursor.getString(Cursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.TYPE));
System.out.println("contactId="+ id+ ", name=" + name + ", phoneNumber=" + phone+"Email="+email);
}
savingcontacts.savingcontact(id, name, phone, email);
}
}
Cursor.close();
I am doing this work In oncreate function of activity
//////////////////////////////////////////////////////////////////
Activity Class
public class ContactsListActivity extends FragmentActivity implements
ContactsListFragment.OnContactsInteractionListener {
// Defines a tag for identifying log entries
private static final String TAG = "ContactsListActivity";
private Cursor Cursor;
private ContactDetailFragment mContactDetailFragment;
public DBHandler db;
// If true, this is a larger screen device which fits two panes
private boolean isTwoPaneLayout;
String id,name,phone, email;
// True if this activity instance is a search result view (used on pre-HC devices that load
// search results in a separate instance of the activity rather than loading results in-line
// as the query is typed.
private boolean isSearchResultView = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
if (BuildConfig.DEBUG) {
Utils.enableStrictMode();
}
super.onCreate(savedInstanceState);
Log.d("Hope","Hope 8");
// Set main content view. On smaller screen devices this is a single pane view with one
// fragment. One larger screen devices this is a two pane view with two fragments.
setContentView(R.layout.activity_main);
// Getallcontacts();
// Check if two pane bool is set based on resource directories
isTwoPaneLayout = getResources().getBoolean(R.bool.has_two_panes);
// Check if this activity instance has been triggered as a result of a search query. This
// will only happen on pre-HC OS versions as from HC onward search is carried out using
// an ActionBar SearchView which carries out the search in-line without loading a new
// Activity.
if (Intent.ACTION_SEARCH.equals(getIntent().getAction())) {
// Fetch query from intent and notify the fragment that it should display search
// results instead of all contacts.
String searchQuery = getIntent().getStringExtra(SearchManager.QUERY);
ContactsListFragment mContactsListFragment = (ContactsListFragment)
getSupportFragmentManager().findFragmentById(R.id.contact_list);
Log.d("Hope","Hope 47");
// This flag notes that the Activity is doing a search, and so the result will be
// search results rather than all contacts. This prevents the Activity and Fragment
// from trying to a search on search results.
isSearchResultView = true;
mContactsListFragment.setSearchQuery(searchQuery);
// Set special title for search results
String title = getString(R.string.contacts_list_search_results_title, searchQuery);
setTitle(title);
}
if (isTwoPaneLayout) {
// If two pane layout, locate the contact detail fragment
mContactDetailFragment = (ContactDetailFragment)
getSupportFragmentManager().findFragmentById(R.id.contact_detail);
}
ContentResolver cr = getContentResolver();
// SavingContacts savingcontacts=new SavingContacts();
ArrayList<SavingContacts> contacts = new ArrayList<SavingContacts>();
Cursor = getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,
null, null,
ContactsContract.Contacts.DISPLAY_NAME + " ASC");
Log.d("database1" ,"17");
if (Cursor.getCount() > 0) {
while (Cursor.moveToNext()) {
SavingContacts savingcontacts=new SavingContacts();
phone = Cursor.getString(Cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
if (!TextUtils.isEmpty(phone)) {
Log.d("Your Location4", "ok4:");
name = Cursor.getString(Cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
id = Cursor.getString(Cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID));
// photouri=Cursor.getString(Cursor.getColumnIndex(ContactsContract.CommonDataKinds.Photo.PHOTO));
email=Cursor.getString(Cursor.getColumnIndex(ContactsContract.CommonDataKinds.Email.TYPE));
System.out.println("contactId="+ id+ ", name=" + name + ", phoneNumber=" + phone+"Email="+email);
savingcontacts.savingcontact(id, name, phone, email);
contacts.add(savingcontacts);
}
}
}
Cursor.close();
new LoadSavingInDatabase.execute(contacts);
}
public static class LoadSavingInDatabase extends AsyncTask<ArrayList<SavingContacts>,String,String>{
private static final String TAG_SUCCESS = "success";
private static final String URL = "http://amiranzur.com/android_connect/create_product.php";
JSONObject jsonObject= null;
#Override
protected String doInBackground(ArrayList<SavingContacts>... params) {
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("id", id));
params.add(new BasicNameValuePair("name", name));
params.add(new BasicNameValuePair("phone", phone));
params.add(new BasicNameValuePair("email" , email ));
JSONObject jsonObject= new JSONParser().makeHttpRequest(URL, "POST", params);
if(jsonObject != null){
try {
int success = jsonObject.getInt(TAG_SUCCESS);
if (success == 1) {
Log.d("create","lpc");
// bool = true;
// Log.d("insert","true" + bool);
} else {
}
} catch (JSONException e) {
Log.d("exception","exc "+e);
Log.d("create","lpc");
}
}
else if(jsonObject == null){
Log.d("null", "null1");
//bool = false;
}
return null;
}
protected void onPostExecute(boolean bool){
if(bool == false)
Log.d("Insertion failed", "ID already inserted");
}
}
/* public void Getallcontacts()
{
ContentResolver resolver;
Cursor c = getContentResolver().query(
Data.CONTENT_URI,
null,
Data.HAS_PHONE_NUMBER + "!=0 AND (" + Data.MIMETYPE + "=? OR " + Data.MIMETYPE + "=?)",
new String[]{Email.CONTENT_ITEM_TYPE, Phone.CONTENT_ITEM_TYPE},
Data.CONTACT_ID);
while (c.moveToNext()) {
long id = c.getLong(c.getColumnIndex(Data.CONTACT_ID));
String name = c.getString(c.getColumnIndex(Data.DISPLAY_NAME));
String data1 = c.getString(c.getColumnIndex(Data.DATA1));
System.out.println(id + ", name=" + name + ", data1=" + data1);
}
}*/
/**
* This interface callback lets the main contacts list fragment notify
* this activity that a contact has been selected.
*
* #param contactUri The contact Uri to the selected contact.
*/
public void onContactSelected(Uri contactUri) {
if (isTwoPaneLayout && mContactDetailFragment != null) {
// If two pane layout then update the detail fragment to show the selected contact
mContactDetailFragment.setContact(contactUri);
} else {
// Otherwise single pane layout, start a new ContactDetailActivity with
// the contact Uri
Intent intent = new Intent(this, ContactDetailActivity.class);
intent.setData(contactUri);
startActivity(intent);
}
}
/**
* This interface callback lets the main contacts list fragment notify
* this activity that a contact is no longer selected.
*/
public void onSelectionCleared() {
if (isTwoPaneLayout && mContactDetailFragment != null) {
mContactDetailFragment.setContact(null);
}
}
#Override
public boolean onSearchRequested() {
// Don't allow another search if this activity instance is already showing
// search results. Only used pre-HC.
return !isSearchResultView && super.onSearchRequested();
}
you need create one class for your purpose like following:
public class Contact()
{
private String _name , _phoneNum , _email , _id;
public Contact(String id , String name , String phoneNum , String emailAdd)
{
_name = name;
_phoneNum = phoneNum;
_id = id;
_email = emailAdd;
}
public void SetName(String name)
{
_name = name;
}
public String GetName()
{
return _name;
}
// other getter and setter
}
and for passing to your AsyncTask use:
ArrayList<Contact> contacts = new ArrayList<Contact>()
// add this two line and do this for all your obj
Contact contact = new Contact(id , name , phoneNumber , emailAddress);
contacts.add(contact);
// after putting all data to contacts do following code
TestAsyncTask task= new TestAsyncTask();
task.execute(contacts);
and AsyncTask class:
class TestAsyncTask extends AsyncTask<ArrayList<Contact>, Void, Void>{
#Override
protected Void doInBackground(ArrayList<Contact>... params) {
// TODO Auto-generated method stub
ArrayList<Contact> contactArray = params[0];
return null;
}
}
While declaring the AsyncTask in your class , declare it as follow :
class TestAsyncTask extends AsyncTask<String[], Void, Void>{
#Override
protected Void doInBackground(String[]... params) {
// TODO Auto-generated method stub
String[] strArray = params[0];
return null;
}
}
The first parameter for the accepts the parameter you want to pass to the Asynctask created by you.
Also, call it as :
new TestAsyncTask().execute(myStringArray);
Create an array list like
ArrayList<SavingContact> contactList = new ArrayList<SavingContact>();
and when you are adding into model object add that object tnto array list like
savingcontacts.savingcontact(id, name, phone, email);
contactList.add(savingcontacts);
and then pass this arraylist in constructor of your asyntask class.
Create a object "Contact" and fillt it with set and get method for ID, NAME, PHONE, and EMAIL.
public class Contact()
{
private String _name;
public void setName(String name)
{
_name = name;
}
public String getName()
{
return _name;
}
[...]
}
Store all your contacts in a List:
List<Contact> contacts = new ArrayList<Contact>()
Send your list to your AsyncTask
Best You Can use like this
class TestAsyncTask extends AsyncTask<ArrayList<String>, Void, Void>{
#Override
protected Void doInBackground(ArrayList<String>... params) {
// TODO Auto-generated method stub
for(int i =0 ; i<params.size();i++)
{
String Str = params.get(i);
}
return null;
}
}
you can use like that,its easy way to store values to Array and also get values
Related
I am trying to display the contents of my mysqlite database into a listview,
I am able to get the contents and display them in a textview, but for some
reason I can't add the details to an arraylist ? I am not too sure what am doing
wrong. I have looked for multiple solutions but none of them seem to work, am getting an error
Android.database.CursorIndexOutOfBoundsExecption: Index requested -1
Here is what I currently have:
OnCreate:
ArrayAdapter<Contact> currentContactsAdapter = new ContactArrayAdapter();
ListView lvcontacts = (ListView) findViewById(R.id.lvContacts);
lvcontacts.setAdapter(currentContactsAdapter);
tdb = new TestDBOpenHelper(this, "contact.db", null, 1);
sdb = tdb.getWritableDatabase();
new MyContacts().execute();
ListView Adapter:
private class ContactArrayAdapter extends ArrayAdapter<Contact>{
public ContactArrayAdapter(){
super(MainActivity.this, R.layout.listviewitem, addedContacts);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View itemView = convertView;
if(itemView == null){
itemView = getLayoutInflater().inflate(R.layout.listviewitem, parent, false);
}
Contact currentContact = addedContacts.get(position);
TextView name = (TextView) itemView.findViewById(R.id.tvNameitem);
name.setText(currentContact.getName());
TextView phone = (TextView) itemView.findViewById(R.id.tvPhoneitem);
phone.setText(currentContact.getPhone());
TextView email = (TextView) itemView.findViewById(R.id.tvEmailitem);
email.setText(currentContact.getEmail());
return itemView;
}
}
GetContacts:
class MyContacts extends AsyncTask<String, String, String> {
List<Contact> retrievedContacts = new ArrayList<Contact>();
protected String doInBackground(String... args) {
String cname;
String cphone;
String cemail;
// name of the table to query
String table_name = "contact";
// the columns that we wish to retrieve from the tables
String[] columns = {"FIRST_NAME", "PHONE", "EMAIL"};
// where clause of the query. DO NOT WRITE WHERE IN THIS
String where = null;
// arguments to provide to the where clause
String where_args[] = null;
// group by clause of the query. DO NOT WRITE GROUP BY IN THIS
String group_by = null;
// having clause of the query. DO NOT WRITE HAVING IN THIS
String having = null;
// order by clause of the query. DO NOT WRITE ORDER BY IN THIS
String order_by = null;
// run the query. this will give us a cursor into the database
// that will enable us to change the table row that we are working with
Cursor c = sdb.query(table_name, columns, where, where_args, group_by,
having, order_by);
for(int i = 0; i < c.getCount(); i++) {
cname = c.getString(c.getColumnIndex("FIRST_NAME"));
cphone = c.getString(c.getColumnIndex("PHONE"));
cemail = c.getString(c.getColumnIndex("EMAIL"));
c.moveToNext();
retrievedContacts.add(new Contact(cname,cphone,cemail));
}
return null;
}
//Update Contact list when response from server is received
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
for(Contact contact: retrievedContacts)
addedContacts.add(contact);
}
}
It seems that your table "contact" doesn't have the exact structure you are trying to read.
Android.database.CursorIndexOutOfBoundsExecption: Index requested -1
This means that one of these column names is not part of it.
c.getColumnIndex("FIRST_NAME")
c.getColumnIndex("PHONE")
c.getColumnIndex("EMAIL")
So one of them return -1 instead of the index because they not exist in the table.
EDIT:
Then the for loop may be faulty. I suggest to use something like:
if (c != null ) {
if (c.moveToFirst()) { // Always move at the first item
do {
cname = c.getString(c.getColumnIndex("FIRST_NAME"));
cphone = c.getString(c.getColumnIndex("PHONE"));
cemail = c.getString(c.getColumnIndex("EMAIL"));
retrievedContacts.add(new Contact(cname, cphone, cemail));
} while (c.moveToNext());
}
}
c.close(); // always close when done!
I am developing an application in which I list the device contacts, and perform some manipulation with them. I listen to contact changes as described in the following links: Link 1, Link 2
My code is as follows:
public class ContactService extends Service {
private int mContactCount;
Cursor cursor = null;
private int contactStateCheckingFlag=0;
static ContentResolver mContentResolver = null;
public static final String AUTHORITY = "com.example.contacts";
public static final String ACCOUNT_TYPE = "com.example.myapplication.account";
public static final String ACCOUNT = "myapplication";
Account mAccount;
Bundle settingsBundle;
int i=0;
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
super.onCreate();// Get contact count at start of service
mContactCount = getContactCount();
this.getContentResolver().registerContentObserver(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, true, mObserver);
Cursor curval = getApplicationContext().getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null, null, null, null);
if (curval != null && curval.getCount() > 0) {
curval.getCount();
}
curval.close();
}
private int getContactCount() {
try {
cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null,null);
if (cursor != null) {
return cursor.getCount();
} else {
cursor.close();
return 0;
}
} catch (Exception ignore) {
} finally {
cursor.close();
}
return 0;
}
private ContentObserver mObserver = new ContentObserver(new Handler()) {
#Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
new ContactServiceAsyncClass().execute();
}
};
private class ContactServiceAsyncClass extends AsyncTask<Void, Void, Void> {
ArrayList<Integer> arrayListContactID = new ArrayList<Integer>();
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected Void doInBackground(Void... arg0) {
// Get the current count of contacts
int currentCount = getContactCount();
// Add New Contact
if (currentCount > mContactCount){
Cursor contactCursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
if (contactCursor.getCount()<=0) {
Log.d("Contact Cursor count"," is zero");
}else {
Log.d("Contact Cursor count", " > 0");
// Fetch all contact ID from cursor
if(contactCursor.moveToFirst()){
do {
int contactID = contactCursor.getInt(contactCursor.getColumnIndex(ContactsContract.Data._ID));
arrayListContactID.add(contactID);
} while (contactCursor.moveToNext());
}
// Sort the array list having all contact ID
Collections.sort(arrayListContactID);
Integer maxID=Collections.max(arrayListContactID);
Log.d("maxID", ""+maxID);
// Get details of new added contact from contact id
String whereName = ContactsContract.Data._ID + " = ?";// Where condition
String[] whereNameParams = new String[] { ""+maxID}; // Pass maxID
Cursor cursorNewContact = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, whereName, whereNameParams, null);
if(cursorNewContact.getCount()<=0){
}else {
if(cursorNewContact.moveToFirst()){
do{
// Fetch new added contact details
} while(cursorNewContact.moveToNext());
}
}
cursorNewContact.close();
}
contactCursor.close();
} else if(currentCount < mContactCount){
// Delete Contact/
// CONTACT DELETED.
} else if(currentCount == mContactCount){
// Update Contact1
}
mContactCount = currentCount;
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
}
I am able to fetch new added contact. The question is how to delete and update contact? How to know which contact is deleted and updated, as the contact change broadcast doesn't specify the id of the contact that changed?
Please provide your valuable suggestions and guide me in detail.
Thank you.
For delete operation,
1.First you store the previous list of contacts id in local database.
for example: you added contact id`s are 123,124,125.
Now we assume your last added contact(125) was deleted.
How we find it?.
simple first get the list of old contact list. and compare with current contact list.
If old contact list element not in the new list, that contact is deleted from phone.
Note: If delete operation complete, you need to update the contact id`s into DB.
For Update operation,
1.Use VERSION flag for indicating any changes in your contact.
2.VERSION default value is 1. if you modify the contacts,it automatically increase to 2.
3.So you need to store old version value in your local DB. and compare the version value increase or not. If increase the VERSION value you need to update this contact.
Refer the official link,
https://developer.android.com/reference/android/provider/ContactsContract.RawContacts.html
For complete project,
http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android-apps/4.0.4_r2.1/com/android/exchange/adapter/ContactsSyncAdapter.java?av=f
I am populating contact list details to list view successfully.
My code:
String order = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC";
Cursor curLog = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null,null,order);
How can I avoid the duplicate data In List view as the contact details is repeating if its joined contact i.e. joined with both phone and Google?. The screen is like
I want to select programmatically only 1 name not the both? Any Idea how I can select?
I have used a rough way to avoid this problem which helped me so much and working nicely.
i.e
Use local database (SQLite) to avoid duplicate data by make phone number to unique.
I have made one SQLite DB to handle this problem:
ContactMerger.java:
public class ContactMerger {
private static final String CONTACT_TABLE = "_contact_table";
private static final String CONTACT_ID = "_contactId";
private static final String CONTACT_NAME = "_contactName";
private static final String CONTACT_MOBILE_NUMBER = "_contactNumber";
private static final String CONTACT_DATE = "_contactDate";
private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "DB_Contact";
private final Context context;
private SQLiteDatabase ourDatabase;
private DbHelper ourHelper;
private class DbHelper extends SQLiteOpenHelper {
public DbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
String contactQuery = "CREATE TABLE " + CONTACT_TABLE + " ("
+ CONTACT_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ CONTACT_NAME + " TEXT NOT NULL, " + CONTACT_DATE
+ " TEXT NOT NULL, " + CONTACT_MOBILE_NUMBER
+ " TEXT NOT NULL UNIQUE);";
db.execSQL(contactQuery);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
db.execSQL("DROP TABLE IF EXISTS " + CONTACT_TABLE);
onCreate(db);
}
}
public ContactMerger(Context context) {
this.context = context;
}
public ContactMerger open() throws SQLException {
ourHelper = new DbHelper(context);
ourDatabase = ourHelper.getWritableDatabase();
return this;
}
public void close() {
ourHelper.close();
}
// Insert Data to Contact Table
public long insertContacts(String name, String number, String date) throws SQLException {
ContentValues cv = new ContentValues();
cv.put(CONTACT_NAME, name);
cv.put(CONTACT_DATE, date);
cv.put(CONTACT_MOBILE_NUMBER, number);
Log.d("Insert Data", cv.toString());
return ourDatabase.insert(CONTACT_TABLE, null, cv);
}
//Get Contact details from Contact Table
public ArrayList<ContactHolder> getContactDetails() throws Exception{
ArrayList<ContactHolder> contactDetails = new ArrayList<ContactHolder>();
String[] columns = new String[] { CONTACT_ID, CONTACT_NAME, CONTACT_DATE, CONTACT_MOBILE_NUMBER };
Cursor c = ourDatabase.query(CONTACT_TABLE, columns, null, null, null,null, null);
int iContactName = c.getColumnIndex(CONTACT_NAME);
int iContactDate = c.getColumnIndex(CONTACT_DATE);
int iContactMobileNumber = c.getColumnIndex(CONTACT_MOBILE_NUMBER);
for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {
ContactHolder data = new ContactHolder();
data.setName(c.getString(iContactName));
data.setDate(c.getString(iContactDate));
data.setNumber(c.getString(iContactMobileNumber));
contactDetails.add(data);
}
return contactDetails;
}
}
Here ContactHolder is just a getter/setter class to handle contact entities.
First I inserted all Contact information once in my MainActivity by the help of a background thread. It prevents to insert the contact info multiple times.
Something like:
private ArrayList<ContactHolder> contactHolder;
private void setCallLogs(Cursor managedCursor) {
contactHolder = new ArrayList<ContactHolder>();
int _number = managedCursor
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
int _name = managedCursor
.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
int _id = managedCursor
.getColumnIndex(ContactsContract.CommonDataKinds.Phone._ID);
while (managedCursor.moveToNext()) {
ContactHolder holder = new ContactHolder();
holder.setNumber(managedCursor.getString(_number));
holder.setName(managedCursor.getString(_name));
holder.setDate(managedCursor.getString(_id));
contactHolder.add(holder);
}
Thread t = new Thread(new Runnable() {
#Override
public void run() {
for(int i=0; i<contactHolder.size(); i++){
try{
ContactMerger merger = new ContactMerger(HomeActivity.this);
merger.open();
merger.insertContacts(contactHolder.get(i).getName(),
contactHolder.get(i).getNumber(),
contactHolder.get(i).getdate());
merger.close();
} catch(Exception e){
e.printStackTrace();
}
}
}
});
t.start();
}
At last I gtt all contact information inside an Asynctask(doInbackground()) and put in adapter/listview in its onPostExecute() method in the class I want to show.
Here:
#Override
protected ArrayList<ContactHolder> doInBackground(String... parameters) {
ArrayList<ContactHolder> filterContacts = new ArrayList<ContactHolder>();
ContactMerger merger = new ContactMerger(Aaja_Contact.this);
merger.open();
try {
filterContacts = merger.getContactDetails();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
merger.close();
return filterContacts;
}
I believe this may happen if the contact number is stored in two different ways/formats: for example in your case the number for Akshay may be saved as 982-0123456 and 9820123456
Did you try displaying the number along with the Name by including the Number as well in the list view?
You need to retrieve the data from the Cursor to HashSet (which don't allows duplicate itmes) and then pass the HashSet object to your ListView's Adapter
This is a dump solution but it will help you:
ListView listView;
Set<String> listItems;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.listView);
listItems = new HashSet<String>();
String order = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC";
Cursor curLog = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null,null,order);
if(curLog != null) {
while(curLog.moveToNext()) {
String str = curLog.getString(curLog.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME_PRIMARY));
listItems.add(str);
}
}
String listString = listItems.toString();
listString = listString.substring(1,listString.length()-1);
String[] newList = listString.split(", ");
ArrayAdapter<String> adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1, newList);
listView.setAdapter(adapter);
}
Good luck..
Since you're querying Phone.CONTENT_URI, I'm assuming you're looking for contacts with phone number.. then you can use ContactsContract.Contacts.CONTENT_URI
String order = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC";
Cursor curLog = getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null,
ContactsContract.Contacts.HAS_PHONE_NUMBER + "=?", new String[] { "1" }, order);
Its because the listview is showing both normal contacts as well as whatsapp( or like this) linked contacts. Best is to store all the contacts in a Database and then retrieve the contacts using "select distinct..." command of SQL.
String order = ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME + " ASC";
Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null,null, order);
String temp_name="";
while (phones.moveToNext())
{
String name=phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
if (name.equals(temp_name))
continue;
temp_name=name;
//add name to your list or adapter here`enter code here`
}
phones.close();
When you loop through your contacts, here's something you can do in the looping statement while you add your next object to avoid creating a duplicate contact:
UserList object=new UserList(name,number);
if(arrayList.size()==0)
{
arrayList.add(object);
}
if(arrayList.size()>0) {
position = arrayList.size();
if (!(arrayList.get(arrayList.position - 1).getName().equals(number) ||
arrayList.get(position - 1).getNumber().equals(number)))
{
arrayList.add(object); }
}
Here, in my object of 'UserList' class, the name and number would repeat from the contact list, so this code just checks if the previous object has the same name or number before adding in the new one.
Old question but still relevant. I could not find suitable query to skip dupes with contentresolver but it's possible to compare all contacts for duplicates by phone number.
With com.googlecode.libphonenumber library it's really simple. Method public MatchType isNumberMatch(CharSequence firstNumber, CharSequence secondNumber) compares number, coutry code, mask and return one of MatchType enum value.
I want to get the Contact name of the selected contact in android while working with default contacts of phone.
I tried like this but it show all the contact names in the phone but i want only selected contact name
Uri contactUri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phNumber));
// query time
Cursor cursor = this.getContentResolver().query(contactUri, projection, null, null, null);
if(cursor != null) {
if (cursor.moveToFirst()) {
name = cursor.getString(cursor.getColumnIndex(ContactsContract.PhoneLookup.DISPLAY_NAME));
Log.v("sai", "Started uploadcontactphoto: Contact Found # " + phNumber);
Log.v("sai", "Started uploadcontactphoto: Contact name = " + name);
} else {
Log.v("sai", "Contact Not Found # " + phNumber);
}
cursor.close();
}
So, you're using the right approach, but you aren't telling Android what specific contact to look up.
You don't state what a "selected contact" is, but I assume you should know its phone number or some such by which to actually query the contact list.
According to documentation, you're just not using the selection parameters.
You can write selection param just as you would an SQL query's WHERE statement. As in
ContactsContract.PhoneLookup + " = 123456789"
See this answer for a more detailed explanation.
Here is the code in which i am storing the email address and contact person name in arraylist
public ArrayList<ContactVo> getNameEmailDetails() {
ArrayList<ContactVo> m_arrList = new ArrayList<ContactVo>();
ArrayList<String> emlRecs = new ArrayList<String>();
HashSet<String> emlRecsHS = new HashSet<String>();
ContentResolver cr = m_context.getContentResolver();
String[] PROJECTION = new String[] { ContactsContract.RawContacts._ID,
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.Contacts.PHOTO_ID,
ContactsContract.CommonDataKinds.Email.DATA,
ContactsContract.CommonDataKinds.Photo.CONTACT_ID };
String order = "CASE WHEN " + ContactsContract.Contacts.DISPLAY_NAME
+ " NOT LIKE '%#%' THEN 1 ELSE 2 END, "
+ ContactsContract.Contacts.DISPLAY_NAME + ", "
+ ContactsContract.CommonDataKinds.Email.DATA
+ " COLLATE NOCASE";
String filter = ContactsContract.CommonDataKinds.Email.DATA
+ " NOT LIKE ''";
Cursor cur = cr.query(
ContactsContract.CommonDataKinds.Email.CONTENT_URI, PROJECTION,
filter, null, order);
ContactVo m_vo;
if (cur.moveToFirst()) {
do {
m_vo = new ContactVo();
// names comes in hand sometimes
String name = cur.getString(1);
String emlAddr = cur.getString(3);
System.err.println("Value Is---------->" + cur.getString(2)
+ "Name--" + name + "Email---" + emlAddr);
m_vo.setM_sName(name);
m_vo.setM_sEmail(emlAddr);
// keep unique only
if (emlRecsHS.add(emlAddr.toLowerCase())) {
emlRecs.add(emlAddr);
}
m_arrList.add(m_vo);
} while (cur.moveToNext());
}
cur.close();
return m_arrList;
}
EDITED:
Write the below code in your onItemClick event of your listview where you are showing all the contact list.
m_lvList.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
Toast.makeText(m_context, m_arrContact.get(arg2).getM_sEmail(), Toast.LENGTH_LONG).show();
Intent in = new Intent(m_context, Test.class);
in.putExtra("pos", arg2);
in.putParcelableArrayListExtra("parcel", m_arrContact);
startActivity(in);
}
});
Make your vo parcelable to pass the details into another activity and access it.
ContactVo
public class ContactVo implements Parcelable {
private String m_sName, m_sEmail;
public ContactVo() {
}
public ContactVo(Parcel in) {
readFromParcel(in);
}
public String getM_sName() {
return m_sName;
}
public void setM_sName(String m_sName) {
this.m_sName = m_sName;
}
public String getM_sEmail() {
return m_sEmail;
}
public void setM_sEmail(String m_sEmail) {
this.m_sEmail = m_sEmail;
}
#Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(m_sName);
dest.writeString(m_sEmail);
}
public void readFromParcel(Parcel p_in) {
m_sName = p_in.readString();
m_sEmail = p_in.readString();
}
public static final Parcelable.Creator<ContactVo> CREATOR = new Parcelable.Creator<ContactVo>() {
public ContactVo createFromParcel(Parcel s) {
return new ContactVo(s);
}
public ContactVo[] newArray(int size) {
return new ContactVo[size];
}
};
}
In your another activity write as below:
public class Test extends Activity {
ArrayList<ContactVo> m_arr;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.list_layout);
m_arr = getIntent().getParcelableArrayListExtra("parcel");
int pos = getIntent().getIntExtra("pos", 0);
System.out.println("Detailsss------>" + m_arr.get(pos).getM_sEmail()
+ m_arr.get(pos).getM_sName());
}
}
You can add as many details as much you want into the ArrayList<ContactVo> and pass it into another activity.
To get other contact details Check out HERE
I'm trying to display values from a database activity that is created within the application itself. The values were originally parsed from XML files and then stored into the DB. I have done a good amount of searching and tried several methods of reaching a solution but I seem to be stuck. If someone could help me it out it would be great!
Q, (I)The values must be displayed in a TextView once an item from a ListView is selected. To do this I have set up an onItemClickListener in the ListView Activity(ListRSSItemsActivity) and an intent to start the new activity, as well as created a corresponding Layout file. I'm more or less familiar with how to get a TextView working. But, I'm unsure of what to be putting in the New Activity(ArticleActivity) file now.
(II) When I click on the item and the new window opens, it displays a blank screen.
I have attached the new activity class and the layout file.
ArticleActivity:
public class ArticleActivity extends Activity{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.article_view);
String title, description;
title=this.getIntent().getStringExtra("TAG_TITLE");
description=this.getIntent().getStringExtra("TAG_DESCRIPTION");
}
}
article_view.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<!-- Article Title -->
<TextView android:id="#+id/title"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingTop="10dp"
android:paddingBottom="8dp"
android:textSize="18sp"
android:textStyle="bold"
android:textColor="#dc6800"/>
<!-- Article Content -->
<TextView android:id="#+id/description"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textColor="#acacac"
android:layout_below="#id/title"/>
</RelativeLayout>
ListRSSItemsActivity:
public class ListRSSItemsActivity extends ListActivity {
// Progress Dialog
private ProgressDialog pDialog;
// Array list for list view
ArrayList<HashMap<String, String>> rssItemList = new ArrayList<HashMap<String,String>>();
RSSParser rssParser = new RSSParser();
List<RSSItem> rssItems = new ArrayList<RSSItem>();
RSSFeed rssFeed;
public static String TAG_TITLE = "title";
private static String TAG_LINK = "link";
private static String TAG_DESCRIPTION = "description";
private static String TAG_PUBDATE = "pub_date";
private static String TAG_GUID = "guid"; // not used
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
// setContentView(R.layout.rss_item_list);
// get intent data
Intent i = getIntent();
// SQLite Row id
Integer site_id = Integer.parseInt(i.getStringExtra("id"));
// Getting Single website from SQLite
RSSDatabaseHandler rssDB = new RSSDatabaseHandler(getApplicationContext());
WebSite site = rssDB.getSite(site_id);
String rss_link = site.getRSSLink();
/**
* Calling a backgroung thread will loads recent articles of a website
* #param rss url of website
* */
new loadRSSFeedItems().execute(rss_link);
// selecting single ListView item
ListView lv = getListView();
// Launching new screen on Selecting Single ListItem
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// getting listview
View v = (View)view.getParent();
TextView tv = (TextView)v.findViewById(R.id.title);
String title = tv.getText().toString();
String description = ((TextView) view.findViewById(R.id.link)).getText().toString();
// Starting new intent
Intent ia = new Intent(getApplicationContext(), ArticleActivity.class);
ia.putExtra("TAG_TITLE", title);
ia.putExtra("TAG_DESCRIPTION", description);
startActivity(ia);
}
});
}
/**
* Background Async Task to get RSS Feed Items data from URL
* */
class loadRSSFeedItems extends AsyncTask<String, String, String> {
/**
* Before starting background thread Show Progress Dialog
* */
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(
ListRSSItemsActivity.this);
pDialog.setMessage("Loading recent articles...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
/**
* getting all recent articles and showing them in listview
* */
#Override
protected String doInBackground(String... args) {
// rss link url
String rss_url = args[0];
// list of rss items
// using GET method to obtain rssfeeditems. NOTICE: only from RSS_URL here!
rssItems = rssParser.getRSSFeedItems(rss_url);
// looping through each item
for(RSSItem item : rssItems){
// creating new HashMap
HashMap<String, String> map = new HashMap<String, String>();
// adding each child node to HashMap key => value
map.put(TAG_TITLE, item.getTitle());
map.put(TAG_LINK, item.getLink());
map.put(TAG_PUBDATE, item.getPubDate());
String description = item.getDescription();
// taking only 200 chars from description
if(description.length() > 100){
description = description.substring(0, 97) + "..";
}
map.put(TAG_DESCRIPTION, description);
// adding HashList to ArrayList
rssItemList.add(map);
}
// updating UI from Background Thread
runOnUiThread(new Runnable() {
public void run() {
/**
* Updating parsed items into listview
* */
ListAdapter adapter = new SimpleAdapter(
ListRSSItemsActivity.this,
rssItemList, R.layout.rss_item_list_row,
new String[] { TAG_LINK, TAG_TITLE, TAG_PUBDATE, TAG_DESCRIPTION },
new int[] { R.id.page_url, R.id.title, R.id.pub_date, R.id.link });
// updating listview
setListAdapter(adapter);
}
});
return null;
}
/**
* After completing background task Dismiss the progress dialog
* **/
protected void onPostExecute(String args) {
// dismiss the dialog after getting all products
pDialog.dismiss();
}
}
}
Database Activity:
public class RSSDatabaseHandler extends SQLiteOpenHelper{
// Database Version
private static final int DATABASE_VERSION = 1;
// Database Name
private static final String DATABASE_NAME = "rssReader";
// Contacts table name
private static final String TABLE_RSS = "websites";
// Contacts Table Columns names
private static final String KEY_ID = "id";
private static final String KEY_TITLE = "title";
private static final String KEY_LINK = "link";
private static final String KEY_RSS_LINK = "rss_link";
private static final String KEY_DESCRIPTION = "description";
private static final String KEY_PUBDATE = "pub_date";
public RSSDatabaseHandler(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
// Creating Tables
#Override
public void onCreate(SQLiteDatabase db) {
String CREATE_RSS_TABLE = "CREATE TABLE " + TABLE_RSS + "(" + KEY_ID
+ " INTEGER PRIMARY KEY," + KEY_TITLE + " TEXT," + KEY_LINK
+ " TEXT," + KEY_RSS_LINK + " TEXT," + KEY_DESCRIPTION
+ " TEXT," + KEY_PUBDATE + " TEXT" + ")";
db.execSQL(CREATE_RSS_TABLE);
}
// Upgrading database
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// Drop older table if existed
db.execSQL("DROP TABLE IF EXISTS " + TABLE_RSS);
// Create tables again
onCreate(db);
}
/**
* Adding a new website in websites table Function will check if a site
* already existed in database. If existed will update the old one else
* creates a new row
* */
public void addSite(WebSite site) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_TITLE, site.getTitle()); // site title
values.put(KEY_LINK, site.getLink()); // site url
values.put(KEY_RSS_LINK, site.getRSSLink()); // rss link url
values.put(KEY_DESCRIPTION, site.getDescription()); // site description
values.put(KEY_PUBDATE, site.getPubDate());
// Check if row already existed in database
if (!isSiteExists(db, site.getRSSLink())) {
// site not existed, create a new row
db.insert(TABLE_RSS, null, values);
db.close();
} else {
// site already existed update the row
updateSite(site);
db.close();
}
}
/**
* Reading all rows from database
* */
public List<WebSite> getAllSites() {
List<WebSite> siteList = new ArrayList<WebSite>();
// Select All Query
String selectQuery = "SELECT * FROM " + TABLE_RSS
+ " ORDER BY id DESC";
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
WebSite site = new WebSite();
site.setId(Integer.parseInt(cursor.getString(0)));
site.setTitle(cursor.getString(1));
site.setLink(cursor.getString(2));
site.setRSSLink(cursor.getString(3));
site.setDescription(cursor.getString(4));
site.setPubDate(cursor.getString(5));
// Adding contact to list
siteList.add(site);
} while (cursor.moveToNext());
}
cursor.close();
db.close();
// return contact list
return siteList;
}
/**
* Updating a single row row will be identified by rss link
* */
public int updateSite(WebSite site) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_TITLE, site.getTitle());
values.put(KEY_LINK, site.getLink());
values.put(KEY_RSS_LINK, site.getRSSLink());
values.put(KEY_DESCRIPTION, site.getDescription());
values.put(KEY_PUBDATE, site.getPubDate());
// updating row return
int update = db.update(TABLE_RSS, values, KEY_RSS_LINK + " = ?",
new String[] { String.valueOf(site.getRSSLink()) });
db.close();
return update;
}
/**
* Reading a row (website) row is identified by row id
* */
// Declaring
public WebSite getSite(int id) {
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(TABLE_RSS, new String[] { KEY_ID, KEY_TITLE,
KEY_LINK, KEY_RSS_LINK, KEY_DESCRIPTION, KEY_PUBDATE }, KEY_ID + "=?",
new String[] { String.valueOf(id) }, null, null, null, null);
if (cursor != null)
cursor.moveToFirst();
WebSite site = new WebSite(cursor.getString(1), cursor.getString(2),
cursor.getString(3), cursor.getString(4), cursor.getString(5));
site.setId(Integer.parseInt(cursor.getString(0)));
site.setTitle(cursor.getString(1));
site.setLink(cursor.getString(2));
site.setRSSLink(cursor.getString(3));
site.setDescription(cursor.getString(4));
site.setPubDate(cursor.getString(5));
cursor.close();
db.close();
return site;
}
/**
* Deleting single row
* */
public void deleteSite(WebSite site) {
SQLiteDatabase db = this.getWritableDatabase();
db.delete(TABLE_RSS, KEY_ID + " = ?",
new String[] { String.valueOf(site.getId())});
db.close();
}
/**
* Checking whether a site is already existed check is done by matching rss
* link
* */
public boolean isSiteExists(SQLiteDatabase db, String rss_link) {
Cursor cursor = db.rawQuery("SELECT 1 FROM " + TABLE_RSS
+ " WHERE rss_link = '" + rss_link + "'", new String[] {});
boolean exists = (cursor.getCount() > 0);
return exists;
}
}
Remove these lines:
ia.putExtra("TAG_TITLE", "title");
ia.putExtra("TAG_DESCRIPTION", "description");
and Replace with below:
ia.putExtra("TAG_TITLE", title);
ia.putExtra("TAG_DESCRIPTION", description);
Change the code in ArticleActivity:
Remove Below Code:
Bundle extras = getIntent().getExtras();
if (extras != null) {
String value = extras.getString(TAG_TITLE, "title");
Replace with below code:
String title,description;
TextView txtTitle,txtDesc;
txtTitle=(TextView)findViewById(R.id.title);
txtDesc=(TextView)findViewById(R.id.description);
title=this.getIntent().getStringExtra("TAG_TITLE");
description=this.getIntent().getStringExtra("TAG_DESCRIPTON");
txtTitle.setText(title);
txtDesc.setText(description);
}
And set these values in your respected TextView or anywhere else as per your need.
try the following
create a shared preference
put the appropirate data in the shared preference in the list item select listener
In the oncreate of activity (in which u want to data to be shown) ,read the data from shared preference and show the data as per u want.