Android add contact email - android

I'm trying to insert a new contact into the Androids contact list. Adding a name and phone numbers works fine, but adding an email address doesn't work. My code:
//name is a string
//phone and email are string arrays
ContentValues values = new ContentValues();
values.put(People.NAME, name);
Uri newPerson = People.createPersonInMyContactsGroup(cr, values);
if (newPerson != null) {
for (i=0; i<phone.length; i++) {
Log.i("Phone",""+phone[i]);
values.clear();
Uri mobilesUri = Uri.withAppendedPath(newPerson,People.Phones.CONTENT_DIRECTORY);
values.put(People.Phones.NUMBER,phone[i]);
values.put(People.Phones.TYPE,People.Phones.TYPE_MOBILE);
Uri phonesUpdate = cr.insert(mobilesUri, values);
}
for (i=0; i<email.length; i++) {
Log.i("Email",""+email[i]);
values.clear();
Uri emailUri = Uri.withAppendedPath(newPerson,People.ContactMethods.CONTENT_DIRECTORY);
values.put(People.ContactMethods.KIND,People.ContactMethods.KIND_EMAIL);
values.put(People.ContactMethods.TYPE,People.ContactMethods.TYPE_HOME);
values.put(People.ContactMethods.DATA,email[i]);
Uri emailUpdate = cr.insert(emailUri, values);
}
}
I get an error in this line:
values.put(People.ContactMethods.KIND,People.ContactMethods.KIND_EMAIL);
of
error: cannot find symbol
Edit: I forgot to mention I use Xcode/Ant and revision 8 (2.2 (Froyo)).

This works for me:
values.put(People.ContactMethods.KIND, Contacts.KIND_EMAIL);
which I got from the well-hidden (at least for Contact programming info):
developer.android.com: Content Providers: Modifying data in a provider

You may get some help from this example: Android Developers - ContactOperations.

Related

How to read filenames from the download directory on android 10 and higher?

How to read filenames from the download directory on android 10 and higher?
After filtering the names I want to let users select from this list to open
the file.
On Android versions 8 (API 28) the FILE api is quite simple to use.
Filenames are simple to read with the method DirListOld. With these names
I can read the content of the files.
I tried to make a method to do the same on Android 10 (API 30) and higher.
But documentation is not very clear. I did some experimenting with
MediaStore methods, but I could not get the filenames only got directory
names on external storage.
How to filter the results is not very well documented and examples of the
MediaStore.Downlaods are totally absent.
My experiment is shown in method DirListNew.
Also I had to ask for a permission for MANAGE_EXTERNAL_STORAGE. Without this
permission even DirListNew results in an empty string. As I read in several
comments Google-Play is not generous in giving this permission. Why not
special permission for only downloaded files. I don't have to read all external
files.
I don't understand why Google-Android developers made such a mess for retrieving
simple downloaded files.
public String DirListOld()
{
String sName;
File oDownloadDir;
String sDownloadDir;
StringBuilder dirContent = new StringBuilder();
oDownloadDir = this.getApplicationContext().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS);
try {
sDownloadDir = oDownloadDir.getName();
if (!sDownloadDir.equals("") )
{
for (File f : Objects.requireNonNull(oDownloadDir.listFiles()))
{
if (f.isFile())
{
sName = f.getName();
dirContent.append(sName);
dirContent.append("\n");
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return dirContent.toString();
} // DirListOld
#RequiresApi(api = Build.VERSION_CODES.Q)
public String DirListNew()
{
EditText editText = findViewById(R.id.editTextMultiLine2);
StringBuilder dirContent = new StringBuilder();
String[] projection = new String[] {
MediaStore.Downloads.DATA
};
String selection = null;
String[] selectionArgs = null;
String sortOrder = null;
Cursor cursor = getApplicationContext().getContentResolver().query(
MediaStore.Files.getContentUri("external"),
projection,
selection,
selectionArgs,
sortOrder
);
if (cursor != null) {
cursor.moveToFirst();
//iterate over rows
for (int i = 0; i < cursor.getCount(); i++) {
//iterate over the columns
for(int j = 0; j < cursor.getColumnNames().length; j++){
//append the column value to the string builder and delimit by \n
dirContent.append(cursor.getString(j));
dirContent.append("\n");
}
//add a new line carriage return
dirContent.append("\n");
//move to the next row
cursor.moveToNext();
}
//close the cursor
cursor.close();
}
return dirContent.toString();
} // DirListNew

Restoring backed up messages, conversations times are incorrect

I am developing an android app which backs up and restores the messages/conversations from device. It backup the messages, export file in the form of xml, and then later restore it. The only problem I am facing is the date/times of conversations. It is changed to current time at the time of restoration, but when I open any conversation, there time is correct. Have a look at photos.
Before backup:
After backup:
Code I am using for backup:
Uri uri = Uri.parse("content://sms/inbox");
//Uri uri = Uri.parse("content://mms-sms/conversations/");
ContentResolver contentResolver = getContentResolver();
final String[] projection = new String[]{"*"};
Cursor SMSL = contentResolver.query(Telephony.Sms.Inbox.CONTENT_URI, projection, null, null, null);
int msgscount = SMSL.getCount();
if (msgscount>0) {
msgs = new String[SMSL.getCount()][5];
int i = 0;
while (SMSL.moveToNext()) {
address = SMSL.getString(SMSL.getColumnIndex("address"));
body = SMSL.getString(SMSL.getColumnIndex("body"));
read = SMSL.getString(SMSL.getColumnIndex("read"));
date = SMSL.getString(SMSL.getColumnIndex("date"));
type = SMSL.getString(SMSL.getColumnIndex("type"));
msgs[i][0] = address;
msgs[i][1] = body;
msgs[i][2] = date;
msgs[i][3] = read;
msgs[i][4] = type;
Log.i("Date: ", String.valueOf(SMSL.getLong(SMSL.getColumnIndex("date"))));
i++;
}
SMSL.close();
}else{
msgs = new String[0][0];
Toast.makeText(getApplicationContext(),"No messages found!",Toast.LENGTH_LONG).show();
}
Code for restoring:
ContentResolver contentResolver = getContentResolver();
Uri uri = Uri.parse("content://sms/inbox");
//Uri uri = Uri.parse("content://mms-sms/conversations/");
ContentValues values = new ContentValues();
for (int i = 0; i < readMsgsFromFile.length; i++) {
values.put("address",readMsgsFromFile[i][0]);
values.put("body",readMsgsFromFile[i][1]);
values.put("date",readMsgsFromFile[i][2]);
values.put("read",readMsgsFromFile[i][3]);
values.put("type",readMsgsFromFile[i][4]);
contentResolver.insert(Telephony.Sms.Inbox.CONTENT_URI, values);
Log.i("Restoring: ",readMsgsFromFile[i][2]);
}
Thanks Mike M. I did find a solution and you are right, the conversation table is updated whenever a new message is received or sent by a user and the time of conversation is same as that message's (whether received or sent) time. But in case of writing messages through contentresolver query it does not work and the conversation time is current time at the time of writing. So what I did is add a temporary message in all of the conversations, right after messages are restored. And after that delete all the temporary messages, this will update the conversations time to last message time.
HashSet hs = new HashSet();
hs.addAll(list);
//list is the ArrayList<String> which contains the addressess of all the messages and
//through hashset we remove all the duplicates to get only the addressess once and hence we know the number of conversations and their addressess.
list.clear();
list.addAll(hs);
//Add some dummy message to each conversation
ContentValues values2 = new ContentValues();
for (int i = 0; i < list.size(); i++) {
values2.put("address",list.get(i));
values2.put("date_sent",readMsgsFromFile[0][1]);
values2.put("date",readMsgsFromFile[0][2]);
values2.put("type",readMsgsFromFile[0][3]);
values2.put("body","temp"); //this should be more unique
values2.put("read",readMsgsFromFile[0][5]);
values2.put("service_center","01010101");
contentResolver.insert(Telephony.Sms.CONTENT_URI, values2);
}
//Now deleting that message with body 'temp' from each conversation
Cursor c = contentResolver.query(Telephony.Sms.CONTENT_URI,null,null,null,null);
while (c.moveToNext()){
String body = c.getString(c.getColumnIndex("body"));
String mid = c.getString(0);
if (body.equals("temp")){
Log.i("Deleting ",mid);
getContentResolver().delete(Uri.parse(Telephony.Sms.CONTENT_URI+"/"+mid),null,null);
}
}
c.close();
This word 'temp' could be and should be more unique so that it is not mixed with actual message.

Is there a faster way to filter through and sort the Android Contacts list?

So I am working on a project where I need to get the user's contact list (Specifically the Name, email address, and location of the contact details), put that into a list, and then use that list in an autocomplete view so they can start typing a name and it will filter it out.
My code works just fine, it all compiles and all runs without error. The problem is that it is VERY slow. For someone who has 10 contacts, this will likely not take long, but my phone holds 1700 contacts in it so this entire process takes upwards of 2 minutes to complete... which is horrendous!
Here is the current working code below (I cut out the code for the location adding as it was wordy):
public static List<MyObject> getContactList(){
List<MyObject> contactList = new ArrayList<>();
Cursor people = MyApplication.getAppContext().getContentResolver().
query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
while (people.moveToNext()) {
String email = "";
String location = "";
String phone = "";
String contactName = people.getString(people.getColumnIndex(
ContactsContract.Contacts.DISPLAY_NAME));
String contactId = people.getString(people.getColumnIndex(
ContactsContract.Contacts._ID));
if(contactId != null){
Cursor contactsEmails = getSpecificEmailsCursor(contactId);
while (contactsEmails.moveToNext()){
//For now, just setting it to the last email
email = contactsEmails.getString(contactsEmails.getColumnIndex(
ContactsContract.CommonDataKinds.Email.DATA));
phone = contactsEmails.getString(contactsEmails.getColumnIndex(
ContactsContract.CommonDataKinds.Phone.NUMBER));
}
contactsEmails.close();
MyObject person = new MyObject();
try{
person.setEmail(email);
person.setName(contactName);
person.setPhone(phone);
} catch (NullPointerException e){
L.m("Null pointer hit on person");
}
if(contactName != null && email != null){
contactList.add(person);
}
}
}
people.close();
return contactList;
}
Does anyone have any recommendations on how to either speed this process up, or, a better way to go about what I am trying to accomplish? Thanks!
-Sil

When is the ANDROID Contact Group PHYSICALLY removed instead of being marked as deleted?

I am trying to permanently remove a Android Contact Group and have used the Sync parameter and it always appears the record is simply marked as deleted and not physically removed. Can anyone explain how/when, if ever, the Contract group row is deleted permanently or show a snippet of code demonstrating how to do this? The records I am trying to remove are ones that I added, so they are not Read-Only.
Linked back to https://stackoverflow.com/a/21376905/5398898
My Delete Code:
private void RemoveGroup()
{
TextView tv = (TextView) this.findViewById(R.id.helloworld);
int[] startId = {10};//{6, 7, 8, 9, 10, 11};
String groupName = "My New Contacts";
Uri mUri = ContactsContract.Groups.CONTENT_URI;
mUri.buildUpon().appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true").build();
for (int n = 0; n < startId.length; n++) {
groupCount = startId[n];
ContentValues values = new ContentValues();
values.put(ContactsContract.Groups._ID, groupCount);
try {
getContentResolver().delete(mUri, values.toString(),null);
} catch (Exception ex) {
tv.setText(ex.getMessage());
}
}
}
Result when reading the groups:
Image can be found here http://i.stack.imgur.com/5OOfc.png
You are building the correct Uri but not using it, try like this
Uri mUri = ContactsContract.Groups.CONTENT_URI;
mUri = mUri.buildUpon().appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true").build();

Make exception event from original recurring event?

I found that Events.CONTENT_EXCEPTION_URI (here) used for make recurring event.
It's hardly to find document or code example from internet. So I try many ways
1 Insert as SyncAdapter
ContentValues values = new ContentValues();
values.put(Events.ORIGINAL_INSTANCE_TIME, CaldavGlobalVar.getCurrentTime_());
values.put(Events.SELF_ATTENDEE_STATUS, status);
if(!username.equals("")){
values.put(Events.ORGANIZER, username);
}
if(event.getSummarry()!=null){
values.put(Events.TITLE, event.getSummarry());
}
if(event.getDescription()!=null){
values.put(Events.DESCRIPTION, event.getDescription());
}
if(event.getDateStart()!=null){
values.put(Events.DTSTART, CaldavGlobalVar.convertTIMEtomilisecond(event.getDateStart(), event.getAllDay()));
}
Uri exceptionUri = Uri. withAppendedPath(Events.CONTENT_EXCEPTION_URI, String.valueOf(event.getEventId()));
Uri syncUri = CalendarProvider.asSyncAdapter(exceptionUri, username,context.getResources().getString(R.string.ACCOUNT_TYPE));
Uri resultUri = context.getContentResolver().insert(syncUri, values);
resultUri return null, I didnot see any exception or any relation things, So I dig Android source code (from here) and find out the way they use Events.CONTENT_EXCEPTION_URI So I change
2 Insert by "ContentProviderOperation" like this, in line 1003
ContentValues values = new ContentValues();
values.put(Events.ORIGINAL_INSTANCE_TIME, CaldavGlobalVar.getCurrentTime_());
values.put(Events.SELF_ATTENDEE_STATUS, 1);
values.put(Events.STATUS, Events.STATUS_CONFIRMED);
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
Uri exceptionUri = Uri.withAppendedPath(Events.CONTENT_EXCEPTION_URI,
String.valueOf(eventId));
ops.add(ContentProviderOperation.newInsert(exceptionUri).withValues(values).build());
mHandler.startBatch(mHandler.getNextToken(), null, CalendarContract.AUTHORITY, ops, 1000);
But it show log that It installed unsuccessfully, I am so worry about that, may be Google not support it fully, I also list all Content Provider in Android, I dont has any exception uri (Events.CONTENT_EXCEPTION_URI) --content://com.android.calendar/exception
Exception throwed
java.lang.IllegalArgumentException: Unknown URL content://com.android.calendar/exception
Does anyone have experience ? Any help are appreciate :)
Kind regards
A small part of my code:
ContentValues args = new ContentValues();
args.put(CalendarContract.Events.ORIGINAL_INSTANCE_TIME, originalinstancetime);
args.put(CalendarContract.Events.STATUS, status);
Uri.Builder eventUriBuilder = CalendarContract.Events.CONTENT_EXCEPTION_URI.buildUpon();
ContentUris.appendId(eventUriBuilder, originalEventID);
try {
final Uri resultUri = context.getContentResolver().insert(eventUriBuilder.build(), args);
int eventID = Integer.parseInt(resultUri.getLastPathSegment());
} catch (Exception e) {
}

Categories

Resources