I want to add custom field to contacts that will tell me if the contact was marked in my aplication or not.
First of all I want to make a function that will set my custom data to contact with given id, but the code that I try to use, don't work properly.
public static final String MIMETYPE_EMPLOYEE = "vnd.android.cursor.item/employee";
public void addEmployee(String id){
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
Uri newContactUri = null;
ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
.withSelection(ContactsContract.Data._ID + "=?", new String[]{id})
.withValue(ContactsContract.Data.MIMETYPE, MIMETYPE_EMPLOYEE)
.withValue(ContactsContract.Data.DATA1, "yes")
.build());
try{
ContentProviderResult[] res = act.getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
if (res!=null && res[0]!=null) {
newContactUri = res[0].uri;
Log.d(LOG_TAG, "URI added contact:"+ newContactUri); //here it says that it's null :(
}
else Log.e(LOG_TAG, "Contact not added.");
} catch (RemoteException e) {
// error
Log.e(LOG_TAG, "Error (1) adding contact.");
newContactUri = null;
} catch (OperationApplicationException e) {
// error
Log.e(LOG_TAG, "Error (2) adding contact.");
newContactUri = null;
}
Log.d(LOG_TAG, "Contact added to system contacts.");
if (newContactUri == null) {
Log.e(LOG_TAG, "Error creating contact");
}
}
I also tried to use Insert instead of update but with Insert my application crashed when I tried to retrieve "newContactUri = res[0].uri;"
I have searched for similar solutions but nothing worked for me :/
Topic linked from MAYUR BHOLA helped, thx.
I'm posting working version of my problem, maybe someone will need this.
public static final String MIMETYPE_EMPLOYEE = "vnd.android.cursor.item/employee";
private void updateEmployee(String id, String value){
try {
ContentValues values = new ContentValues();
values.put(Data.DATA1, value);
int mod = act.getContentResolver().update(
Data.CONTENT_URI,
values,
Data.RAW_CONTACT_ID + "=" + id + " AND "
+ Data.MIMETYPE + "= '"
+ MIMETYPE_EMPLOYEE + "'", null);
if (mod == 0) {
values.put(Data.RAW_CONTACT_ID, id);
values.put(Data.MIMETYPE, MIMETYPE_EMPLOYEE);
act.getContentResolver().insert(Data.CONTENT_URI, values);
Log.v(LOG_TAG, "data inserted");
} else {
Log.v(LOG_TAG, "data updated");
}
} catch (Exception e) {
Log.v(LOG_TAG, "failed");
}
}
Related
I am trying to delete mp3 file.
My code:
String path = songsList.get(position).getData();
File fdelete = new File(path);
if (fdelete.exists()) {
if (fdelete.delete()) {
DeleteRecursive(fdelete);
Log.d(TAG, "deleted");
} else {
Log.d(TAG, "failed");
}
} else {
Log.d(TAG, "file doesn't exist");
}
When I delete initially, it gives "deleted" message. But, the file appears and not able to play. if again tries to delete it it shows "file doesn't exist" message.
Can anyone please tell me how to delete properly.
Any help would be appreciated. Thank you.
Finally, I managed to delete the mp3 file completely from internal storage as well as SD card.
Here is the code: (may help to someone)
String[] projection = new String[]{BaseColumns._ID, MediaStore.MediaColumns.DATA};
String selection = BaseColumns._ID + " IN (" + id + ")";
try {
final Cursor cursor = context.getContentResolver().query(
MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, projection, selection,null, null);
if (cursor != null) {
// remove from the media database
context.getContentResolver().delete(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,selection, null);
// remove from storage / sdcard
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
final String name = cursor.getString(1);
try {
final File f = new File(name);
if (!f.delete()) {
Log.e(TAG, "deleteSong: " + title + " can't be deleted");
}
cursor.moveToNext();
} catch (#NonNull final SecurityException ex) {
cursor.moveToNext();
} catch (NullPointerException e) {
Log.e(TAG, "Failed to find file " + name);
}
}
cursor.close();
}
context.getContentResolver().notifyChange(Uri.parse("content://media"), null);
Toast.makeText(context, title + " deleted", Toast.LENGTH_SHORT).show();
} catch (SecurityException ignored) {
}
I'm trying to use this code to allow a user edit a contact's name and number. I get no errors and when I print nameofcontact and numberofcontact in my log it shows me the latest changes I've made to the name and number of the contact.
But it's not saving to my contacts database. Any ideas what's wrong?
public void editButton(View view) {
// the text in the 'nameofcontact' edittext box, can be modified by the user
contactname = nameofcontact.getText().toString();
// the text in the 'numberofcontact' edittext box, can be modified by the user
contactnumber = numberofcontact.getText().toString();
ContentResolver cr = getContentResolver();
String where = ContactsContract.Data.DISPLAY_NAME + " = ? AND " +
ContactsContract.Data.MIMETYPE + " = ? AND " +
String.valueOf(ContactsContract.CommonDataKinds.Phone.TYPE) + " = ? ";
String[] params = new String[] {contactname,
ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE,
String.valueOf(ContactsContract.CommonDataKinds.Phone.TYPE_HOME)};
Cursor phoneCur = getContentResolver().query(ContactsContract.Data.CONTENT_URI, null, where, params, null);
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
// if ( (null == phoneCur) ) {
// createContact(name, phone);
// } else
{
ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
.withSelection(where, params)
.withValue(ContactsContract.CommonDataKinds.Phone.DATA, contactnumber)
.build());
}
phoneCur.close();
try {
cr.applyBatch(ContactsContract.AUTHORITY, ops);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (OperationApplicationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println (contactname);
System.out.println (contactnumber);
Toast.makeText(this, "Updated", Toast.LENGTH_SHORT).show();
}
Please check you add below permission in your manifeast or not
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
and you can use this method it works for me.
public boolean updateContact(String name, String number, String ContactId) {
boolean success = true;
String phnumexp = "^[0-9]*$";
try {
name = name.trim();
number = number.trim();
if (name.equals("") && number.equals("")) {
success = false;
} else if ((!number.equals("")) && (!match(number, phnumexp))) {
success = false;
} else {
ContentResolver contentResolver = SwipableHomeActivity.this
.getContentResolver();
String where = Data.CONTACT_ID + " = ? AND "
+ Data.MIMETYPE + " = ?";
String[] nameParams = new String[]{
ContactId,
StructuredName.CONTENT_ITEM_TYPE};
String[] numberParams = new String[]{
ContactId,
Phone.CONTENT_ITEM_TYPE};
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
if (!name.equals("")) {
ops.add(ContentProviderOperation
.newUpdate(
Data.CONTENT_URI)
.withSelection(where, nameParams)
.withValue(StructuredName.DISPLAY_NAME, name)
.build());
}
if (!number.equals("")) {
ops.add(ContentProviderOperation
.newUpdate(
Data.CONTENT_URI)
.withSelection(where, numberParams)
.withValue(Phone.NUMBER, number).build());
}
contentResolver.applyBatch(ContactsContract.AUTHORITY, ops);
}
} catch (Exception e) {
e.printStackTrace();
success = false;
}
return success;
}
User Case :
Select item by id, if its already present in the basket.
Check the numbers of this item.
If item numbers == 1 then delete this item from basket table and return 0.
If its greater than 1 then decrement it by one and update the table and return number-- .
Its not updating my "numbers" column, and silently passes through the execution and I am helpless nor can I post any stack trace here, but I am posting my code fragment, responsible for this job.
public int removeFromBasketasAnonymous(Long _id){
Log.d("app : ", " _id = " + _id);
int numbers = 0;
try {
database = openDatabaseInReadMode();
Cursor cursor = database.rawQuery("select * from basket where basket._id=" + _id + ";", null);
if (cursor != null) {
cursor.moveToFirst();
Log.d(APP, "GetCount = " + cursor.getCount());
if (cursor.getCount() == 1) {
//this item already present in basket
numbers = cursor.getInt(1);
Log.d(APP, " numbers = " + numbers);
Log.d(APP, "db id = " + cursor.getString(0));
String[] columns = cursor.getColumnNames();
for(String str : columns){
Log.d("APP ", " columns = "+str);
}
Log.d(APP, " id = " + _id);
if (numbers == 1) {
//remove this row entry
cursor.close();
database.close();
database = openDatabaseInReadWriteMode();
database.beginTransaction();
String strSQL = "DELETE from basket where basket._id=" + _id;
try{
database.execSQL(strSQL);
}catch(Exception e){
e.printStackTrace();
}finally{
database.endTransaction();
database.close();
}
numbers--;
} else {
//decrement this number by one
Log.d(APP, " number " + numbers);
numbers--;
Log.d(APP, " dcremented numbers = " + numbers);
cursor.close();
database.close();
database = openDatabaseInReadWriteMode();
database.beginTransaction();
try{
ContentValues data = new ContentValues();
data.put("numbers", numbers);
database.update("basket", data, "_id = " + _id, null);
}catch (Exception e){
e.printStackTrace();
}finally {
database.endTransaction();
database.close();
}
}
}
}
}finally{
if(database != null){
database.close();
}
}
return numbers;
}
public SQLiteDatabase openDatabaseInReadMode() {
File dbFile = context.getDatabasePath(DB_NAME);
if (!isDataBaseExist()) {
try {
copyDatabase(dbFile);
} catch (IOException e) {
throw new RuntimeException("Error creating source database", e);
}
}
/*Log.d("DB available", "path = " + dbFile.exists() + " path" + dbFile.getPath());*/
/*Log.d("actual path ", "exists = " + isDataBaseExist());*/
return SQLiteDatabase.openDatabase(dbFile.getPath(), null, SQLiteDatabase.OPEN_READONLY);
}
public SQLiteDatabase openDatabaseInReadWriteMode() {
File dbFile = context.getDatabasePath(DB_NAME);
if (!isDataBaseExist()) {
try {
copyDatabase(dbFile);
} catch (IOException e) {
throw new RuntimeException("Error creating source database", e);
}
}
/*Log.d("DB available", "path = " + dbFile.exists() + " path" + dbFile.getPath());*/
/*Log.d("actual path ", "exists = " + isDataBaseExist());*/
return SQLiteDatabase.openDatabase(dbFile.getPath(), null, SQLiteDatabase.OPEN_READWRITE);
}
Regards,
Shashank
How you can use database transaction in Android
If you want to start the transaction there is a method beginTransaction()
If you want to commit the transaction there is a
method setTransactionSuccessful() which will commit the values in the
database
If you had start the transaction you need to close the transaction so there is a method endTransaction() which will end your database transaction
Now there are two main points
If you want to set transaction successful you need to write
setTransactionSuccessful() and then endTransaction() after
beginTransaction()
If you want to rollback your transaction then you need to endTransaction()
without committing the transaction by setTransactionSuccessful().
I'm trying to make my app update some contacts but it's updating the wrong people. I get the contact Name, Number and Raw Id. Then if it is true to my if I change his number and update it by his Raw ID. That's my code:
Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null,null, null);
while (phones.moveToNext())
{
String numero;
String fnum;
String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
int id = phones.getInt(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.RAW_CONTACT_ID));
String tipo = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.TYPE));
phoneNumber = phoneNumber.replace(" ", "");
phoneNumber = phoneNumber.replace("-", "");
phoneNumber = phoneNumber.replace("+", "");
phoneNumber = phoneNumber.replace("*", "");
phoneNumber = phoneNumber.replace("#", "");
int tamanho = phoneNumber.length();
numero = phoneNumber;
if (tamanho == 12) {
if (checar.indexOf(numero.substring(1, 3) + ",") != -1) {
if(numero.substring(3).startsWith("9")){
fnum = numero.substring(0, 3) + "" + numero.substring(4);
update(id, fnum, tipo);
}
}
}
Thread.sleep(2000);
}
phones.close();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
And that's the update method:
public void update(int id, String number, String tipo)
{
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
// Number
builder = ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI);
builder.withSelection(ContactsContract.Data.CONTACT_ID + "=?" + " AND " + ContactsContract.Data.MIMETYPE + "=?"+ " AND " + ContactsContract.CommonDataKinds.Organization.TYPE + "=?", new String[]{String.valueOf(id), ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE, tipo});
builder.withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, number);
ops.add(builder.build());
// Update
try
{
getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
}
catch (Exception e)
{
e.printStackTrace();
}
}
What am I doing wrong?
I think that what's wrong is that you're retrieving RAW_CONTACT_ID when you get the number, but in update() you're passing this value to the column CONTACT_ID. The first one points to raw contacts, but the second one points to the Contacts table. Don't mix them!
I also notice that you're trying to update the ORGANIZATION column with the value of Phone.TYPE, which may or may not work.
I been working on an app that helps sending sms to your contacts. Everything is great, except that I'm supposed to add a "custom field number" to a contact such as "Work" or "Private". I'd search the web for answers and the ones that are useful for evryone, aren't for me. This is my code:
private void AddCtxtAttribute(int contactID, String contactNumber) {
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
ContentProviderOperation.Builder builder = ContentProviderOperation
.newInsert(Data.CONTENT_URI);
builder.withValue(Data.RAW_CONTACT_ID, contactID);
builder.withValue(ContactsContract.Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
builder.withValue(ContactsContract.Data.DATA1, contactNumber);
builder.withValue(ContactsContract.Data.DATA2, Phone.TYPE_CUSTOM);
builder.withValue(ContactsContract.Data.DATA3, "My Custom Label");
ops.add(builder.build());
try {
getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
Log.e("RESULT", "Success! " + contactID + " - "
+ contactNumber);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.e("ERROR", "error : " + e.toString());
} catch (OperationApplicationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.e("ERROR", "error : " + e.toString());
}
}
And it's called:
AddCtxtAttribute(contacto_id, contacto_numero);
where contacto_id and contacto_numero are a int and a String respectively.
The problem is that when I pressed the button, I have the ID (contacto_id) of that contact but it updates other contact. (like the id's don't match) but i've debug it and the id doesn't change.
Can anyone help me with this?
I figured it out!
the problem was that i was using diferent column names and uris in reading the contacts and inserting a new contact number.
I did this:
to query all contacts:
private void llenar_contactos() {
ProgressDialog progress;
lista_contactos_cel_sobrantes = null;
sobrantes = false;
lista_contactos_cel = new ArrayList<HashMap<String, Object>>();
progress = ProgressDialog.show(contactsActivity.this, "",
"Cargando Contactos. Porfavor espere...");
String[] projection = new String[] { Data.RAW_CONTACT_ID,
Phone.DISPLAY_NAME, Phone.NUMBER, Phone.LABEL };
String selection = Data.MIMETYPE + "='" + Phone.CONTENT_ITEM_TYPE + "'";
// ContactsContract.CommonDataKinds.Phone.HAS_PHONE_NUMBER + "='1'";
String sort_order = "display_name ASC";
Uri mContacts = Data.CONTENT_URI;
// ContactsContract.CommonDataKinds.Phone.CONTENT_URI;
Cursor contacts = getContentResolver().query(mContacts, // Contact URI
projection, // Which columns to return
selection, // Which rows to return
null, // Where clause parameters
sort_order // Order by clause
);
total_contactos = contacts.getCount();
if (total_contactos > 0) {
int i = 0;
int multiplo = 0;
int indice_total = 0;
int temp_registros = 0;
String contact_id = "";
String name = "";
String phoneNo = "";
String label = "";
sobrantes = false;
int nameFieldColumnIndex = 0;
while (contacts.moveToNext()) {
nameFieldColumnIndex = contacts.getColumnIndex(Data.RAW_CONTACT_ID);
if (nameFieldColumnIndex > -1) {
contact_id = contacts.getString(nameFieldColumnIndex);
}
nameFieldColumnIndex = contacts.getColumnIndex(Phone.DISPLAY_NAME);
if (nameFieldColumnIndex > -1) {
name = contacts.getString(nameFieldColumnIndex);
}
nameFieldColumnIndex = contacts.getColumnIndex(Phone.NUMBER);
if (nameFieldColumnIndex > -1) {
phoneNo = contacts.getString(nameFieldColumnIndex);
}
nameFieldColumnIndex = contacts.getColumnIndex(Phone.LABEL);
if (nameFieldColumnIndex > -1) {
label = contacts.getString(nameFieldColumnIndex);
}
if(label != null){
Log.i("CONTACTO", "id: " + contact_id + " -> name: " + name
+ " ->number: " + phoneNo + " ->label: " + label);
} else {
Log.d("CONTACTO", "id: " + contact_id + " -> name: " + name
+ " ->number: " + phoneNo + " ->label: " + label);
}
}
contacts.close();
}
}
And to insert a new custom label:
private void AddCtxtAttribute(int contactID, String contactNumber) {
if (contactID != 0 && contactNumber != null) {
ArrayList<ContentProviderOperation> ops =
new ArrayList<ContentProviderOperation>();
ops.add(ContentProviderOperation.newInsert(Data.CONTENT_URI)
.withValue(Data.RAW_CONTACT_ID, contactID)
.withValue(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE)
.withValue(Phone.NUMBER, contactNumber)
.withValue(Phone.TYPE, Phone.TYPE_CUSTOM)
.withValue(Phone.LABEL, "My Custom Label")
.build());
try{
getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (OperationApplicationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}