Trying to delete the sent sms from app, when I have tried below code in Lenovo A6000(5.0.2) device
public static void deleteMessage(Context context, String phoneNo, String message) {
try {
Log.d(TAG, "deleteMessage: Deleting SMS from inbox");
Uri uriSms = Uri.parse("content://sms/");
Cursor c = context.getContentResolver().query(uriSms,
new String[]{"_id", "thread_id", "address",
"person", "date", "body"}, null, null, null);
Uri uri = null;
if (c != null && c.moveToFirst()) {
do {
long id = c.getLong(0);
long threadId = c.getLong(1);
String address = c.getString(2);
String body = c.getString(5);
int rowsDeleted = 0;
Log.d(TAG, "Deleting threads: " + threadId);
Log.d(TAG, "deleteMessage: id- "+ id + "" +
" threadId- " + threadId + "" +
" body- " + body + "" +
" rowsDeleted- " + rowsDeleted + "" +
" address- " + address);
if (address.equalsIgnoreCase(phoneNo)
&& body.equalsIgnoreCase(message)) {
ConversationQueryHandler handler = new ConversationQueryHandler(context.getContentResolver(), context);
synchronized (sDeletingThreadsLock) {
Log.v(TAG, "Conversation startDelete sDeletingThreads: " + sDeletingThreads);
if (sDeletingThreads) {
Log.e(TAG, "startDeleteAll already in the middle of a delete", new Exception());
}
sDeletingThreads = true;
uri = ContentUris.withAppendedId(Telephony.Threads.CONTENT_URI, threadId);
String selection = true ? null : "locked=0";
handler.setDeleteToken(0);
handler.startDelete(0, new Long(threadId), uri, selection, null);
}
}
} while (c.moveToNext());
}
} catch (Exception e) {
Log.d(TAG, "deleteMessage: Could not delete SMS from inbox: " + e.getMessage());
}
}
The ConversationQueryHandler sends 1 as a result in case of successful deletion of sms on to onDeletionComplete but this doesn't work in all the devices.
private static Object sDeletingThreadsLock = new Object();
private static boolean sDeletingThreads;
public static class ConversationQueryHandler extends AsyncQueryHandler {
private int mDeleteToken;
private Context mContext;
public ConversationQueryHandler(ContentResolver cr, Context context) {
super(cr);
mContext = context;
}
public void setDeleteToken(int token) {
mDeleteToken = token;
}
/**
* Always call this super method from your overridden onDeleteComplete function.
*/
#Override
protected void onDeleteComplete(int token, Object cookie, int result) {
Log.v(TAG, "Conversation onDeleteComplete token: " + token + " cookie- " + cookie + " result- " + result);
if (token == mDeleteToken) {
// release lock
synchronized (sDeletingThreadsLock) {
sDeletingThreads = false;
sDeletingThreadsLock.notifyAll();
}
}
}
}
I have tested this and found it is failed to delete the sms in all the below devices
Sony Xperia Z1(5.1.1)
Lenovo A200 device (5.1)
Samsung J210F (6.0.1)
As I mentioned earlier I am able to delete sms with the same code in
Lenovo A6000(5.0.2)
Is there a chance I am missing something here, or is this a right way of deleting the sent sms. Thank you for the help in advance.
Related
I am building an app , there is a requirement of notifying app when a new contact added or existing contact gets edited or removed. Although a lot of questions are already available those have answers as well. But my question is little bit different. I am using approach of Content Observer as mentioned below in the code
ContactChangeObserver contactChangeObserver = new ContactChangeObserver(this, new Handler());
getContentResolver().registerContentObserver(ContactsContract.Contacts.CONTENT_URI, true, contactChangeObserver);
and in ContactChangeObserver class I am overriding onChange() method as it was already recommended in many of the post. Code is mentioned below
public class ContactChangeObserver extends ContentObserver {
private Context mContext;
public ContactChangeObserver(Context context, Handler handler) {
super(handler);
mContext = context;
}
#Override
public void onChange(boolean selfChange, Uri uri) {
super.onChange(selfChange, uri);
List<ContactsModel> listOfDBContact = new ChildTrackingDB().getAllContacts(ChildTrackingDB.getInstance(mContext));
List<ContactsModel> listOfCellPhoneContact = ContactUtility.readContactDirectoryOfPhone(mContext);
if (listOfCellPhoneContact.size() == listOfDBContact.size()) {
//this is edit case
} else if (listOfCellPhoneContact.size() > listOfDBContact.size()) {
//this is add case
}else {
//this is remove case
}
}
}
I am getting call back of onChange() as expected(in all cases of adding, removing and editing case). As mentioned in above example, I am overriding onChange() that has URI param. And when I get call back i also receive uri as well. my question is that can that uri be useful to only get that contact which got changed or added? The uri I am getting is
content://com.android.contacts
In my example code, if contact is edited and the device has let's suppose more than thousands contacts then it is a very time consuming to iterate over each contact.Or is there any better approach available for the problem.
I've faced a similar kind of problem. First of all the Uri which you are getting in onChange() method is vague. From my previous encounter I can tell, You won't be able to detect which contact got inserted, updated or deleted. So yes it becomes very time-consuming to detect which contact to get and perform Crud.
To answer your second question, I would suggest you to use Set instead of List. Here is a sample class which you might helpful. It's a linear operation and i've tested it with 2-3k+ data. And it performs well.
public class AddressBookObserver extends ContentObserver {
private static final String TAG = "AddressBookObserver";
private static final String FLAG_INSERT = "INSERT";
private static final String FLAG_DELETE = "DELETE";
private long lastTimeOfCall = 0L;
private long lastTimeOfUpdate = 0L;
private long threshold_time = 5000;
private WeakReference<Context> mContextWeakReference;
public AddressBookObserver(Handler handler, Context context) {
super(handler);
this.mContextWeakReference = new WeakReference<Context>(context);
}
#Override
public void onChange(boolean selfChange) {
onChange(selfChange, null);
}
#Override
public void onChange(boolean selfChange, Uri uri) {
Log.d(TAG, "onChange() Address Book Changed!");
lastTimeOfCall = System.currentTimeMillis();
Set<String> phoneBookSet = new HashSet<>();
Set<String> providerSet = new HashSet<>();
if (checkContactPermission() && (lastTimeOfCall - lastTimeOfUpdate > threshold_time) && General.getIsContactListImported(mContextWeakReference.get())) {
lastTimeOfUpdate = System.currentTimeMillis();
phoneBookSet.addAll(getOnlyPhoneNumbers());
providerSet.addAll(getProviderNumbers());
int bookCount = phoneBookSet.size();
int providerCount = providerSet.size();
Log.e(TAG, "onChange: bookCount: " + bookCount + " providerCount: " + providerCount);
if (bookCount > providerCount) {
Log.i(TAG, "onChange() Insert!");
phoneBookSet.removeAll(providerSet);
String val = phoneBookSet.toString().replaceAll("[\\(\\)\\[\\]\\{\\}]", "");
Log.w(TAG, "value to insert: " + val);
//DO Insert Operations
} else if (bookCount < providerCount) {
Log.i(TAG, "onChange() DELETE!");
providerSet.removeAll(phoneBookSet);
String val = providerSet.toString().replaceAll("[\\(\\)\\[\\]\\{\\}]", "");
Log.w(TAG, "value to delete: " + val);
//Do Delete Operations
} else {
Log.i(TAG, "onChange() UPDATE!");
Set<String> tempPhoneBookSet = new HashSet<>();
tempPhoneBookSet.addAll(phoneBookSet);
phoneBookSet.removeAll(providerSet);
String newData = phoneBookSet.toString().replaceAll("[\\(\\)\\[\\]\\{\\}]", "");
Log.e(TAG, "newData: " + newData);
providerSet.removeAll(tempPhoneBookSet);
String deleteData = providerSet.toString().replaceAll("[\\(\\)\\[\\]\\{\\}]", "");
Log.e(TAG, "deleteData: " + deleteData);
if (!newData.equals(deleteData)) {
//DO Update Operations
} else {
Log.i(TAG, "onChange() Nothing to update!");
}
}
} else if (!checkContactPermission()) {
Log.e(TAG, "onChange() Contact Permission not granted!");
} else {
Log.e(TAG, "onChange() Time threshold not reached Or Contacts not imported yet!");
}
}
private boolean checkContactPermission() {
return ContextCompat.checkSelfPermission(mContextWeakReference.get(), Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED;
}
/**
* Get only phone numbers from device's addressBook
*
* #return - Set of distinct phone numbers
*/
private Set<String> getOnlyPhoneNumbers() {
Log.d(TAG, "getOnlyPhoneNumbers()");
Cursor phones = mContextWeakReference.get().getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " ASC");
Set<String> uniquePhoneContacts = new HashSet<>();
while (phones.moveToNext()) {
String name = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)).replaceAll("\\D", "");
String id = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID));
String photoUri = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.PHOTO_URI));
if (uniquePhoneContacts.add(id + "," + name + "," + photoUri + "," + phoneNumber)) {
Log.w(TAG, "Book#" + id + "," + name + "," + photoUri + "," + phoneNumber);
}
}
phones.close();
return uniquePhoneContacts;
}
/**
* Get all the Contacts from provider which are not deletable
*
* #return - All distinct phone numbers from app's provider
*/
private Set<String> getProviderNumbers() {
Log.d(TAG, "getProviderNumbers()");
Cursor phones = mContextWeakReference.get().getContentResolver().query(MyContactProvider.CONTENT_URI, null, PhoneContactController.COL_IS_DELETABLE + "=?",
new String[]{"0"}, MyContactProvider.COL_CONTACT_ID + " ASC");
Set<String> uniquePhoneContacts = new HashSet<>();
while (phones.moveToNext()) {
String id = phones.getString(phones.getColumnIndex(MyContactProvider.COL_CONTACT_ID));
String name = phones.getString(phones.getColumnIndex(MyContactProvider.COL_NAME));
String phoneNumber = phones.getString(phones.getColumnIndex(MyContactProvider.COL_CONTACT_NO));
String photoUri = phones.getString(phones.getColumnIndex(MyContactProvider.COL_PHOTO_URI));
if (uniquePhoneContacts.add(id + "," + name + "," + photoUri + "," + phoneNumber)) {
Log.w(TAG, "QueryProvider#" + id + "," + name + "," + photoUri + "," + phoneNumber);
}
}
phones.close();
return uniquePhoneContacts;
}
}
I hope this helps.
on sms received , i have saved that sms in my database
now i want to move that sms into inbox
i used this code but it move it as sent by me
please help me to move it as a received sms
ListViewLogItem lm = listArray.get(position);
long datein = Long.parseLong(lm.getInboxTime());
Uri uri = Uri.parse("content://sms/");
ContentValues cv2 = new ContentValues();
cv2.put("address","+"+lm.getNumber());
cv2.put("date", datein);
cv2.put("read", 1);
cv2.put("type", 2);
cv2.put("body", lm.getSms());
getContentResolver().insert(Uri.parse("content://sms/inbox"), cv2);
Change:
cv2.put("type", 2);
To:
cv2.put("type", 1);
Because:
public static final int MESSAGE_TYPE_INBOX = 1;
public static final int MESSAGE_TYPE_SENT = 2;
You can use following method for deleting SMS from Inbox,
private void deleteMessage()
{
Cursor c = getContentResolver().query(SMS_INBOX, null, null, null, null);
//c.moveToFirst();
while (c.moveToNext())
{
System.out.println("Inside if loop");
try
{
String address = c.getString(2);
String MobileNumber = mainmenu.getParameterData().getMobileNumber().trim();
//Log.i( LOGTAG, MobileNumber + "," + address );
Log.i( LOGTAG, c.getString(2) );
if ( address.trim().equals( MobileNumber ) )
{
String pid = c.getString(1);
String uri = "content://sms/conversations/" + pid;
getContentResolver().delete(Uri.parse(uri), null, null);
stopSelf();
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
Use thisvalues.put("status", SmsManager.STATUS_ON_ICC_UNREAD); . Status can be anything like read/unread/seen. I have keep it as unread.
Look at Message status
values.put("read", true); // As Read
and
values.put("read", false); // As Un Read
public class Message {
final Uri SMS_INBOX = Uri.parse("content://sms/inbox");
#SuppressWarnings("unused")
private ContentResolver resolver;
public Message(ContentResolver ConResolver){
resolver = ConResolver;
}
public String getMessage(int batas) {
Cursor cur = resolver.query(SMS_INBOX, null, null, null,null);
String sms = "Message >> \n";
int hitung = 0;
while (cur.moveToNext()) {
sms += "From :" + cur.getString(2) + " : " + cur.getString(11)+"\n";
if(hitung == batas)
break;
hitung++;
}
return sms;
}
public int getMessageCountUnread(){
Cursor c = resolver.query(SMS_INBOX, null, "read = 0", null, null);
int unreadMessagesCount = c.getCount();
c.deactivate();
return unreadMessagesCount;
}
public String getMessageAll(){
Cursor cur = resolver.query(SMS_INBOX, null, null, null,null);
String sms = "Message >> \n";
while (cur.moveToNext()) {
sms += "From :" + cur.getString(2) + " : " + cur.getString(11)+"\n";
}
return sms;
}
public String getMessageUnread() {
Cursor cur = resolver.query(SMS_INBOX, null, null, null,null);
String sms = "Message >> \n";
int hitung = 0;
while (cur.moveToNext()) {
sms += "From :" + cur.getString(2) + " : " + cur.getString(11)+"\n";
if(hitung == getMessageCountUnread())
break;
hitung++;
}
return sms;
}
public void setMessageStatusRead() {
ContentValues values = new ContentValues();
values.put("read",true);
resolver.update(SMS_INBOX,values, "_id="+SmsMessageId, null);
}
}
I am exporting logs using csv file in android.I am getting only call logs but not getting sms logs.Here is the code
while (curLog.moveToNext()) {
String callName = curLog
.getString(curLog
.getColumnIndex(android.provider.CallLog.Calls.CACHED_NAME));
if (callName == null)
callName="Unknown";
String callNumber = curLog.getString(curLog
.getColumnIndex(android.provider.CallLog.Calls.NUMBER));
String callDate = curLog.getString(curLog
.getColumnIndex(android.provider.CallLog.Calls.DATE));
String callType = curLog.getString(curLog
.getColumnIndex(android.provider.CallLog.Calls.TYPE));
String duration = curLog.getString(curLog
.getColumnIndex(android.provider.CallLog.Calls.DURATION));
data.add(new String[] {callName,callNumber,callDate,callType,duration});
}
Please suggest how to fix it.....
This is my way of getting the SMS. It can get body, content, date of the current message as well as check if it is incoming or outgoing. In addition, it can get the contact name that matches the phone number by another method.
First of all, add permission to AndroidManifest.xml file.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.app.myapp" >
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
...
</manifest>
Secondly, implement SMS Observer class to get the information you need
public class SMSObserver extends ContentObserver {
private Context context;
private static final String TAG = "SMSObserver";
private static final Uri SMS_URI = Telephony.Sms.CONTENT_URI; //get uri depending on different devices
public SMSObserver(Handler handler, Context context) {
super(handler);
this.context = context;
}
#Override
public boolean deliverSelfNotifications() {
return true;
}
//this onChange method will be fired up when you send or receive message
#Override
public void onChange(boolean selfChange) {
Cursor cursor = context.getContentResolver().query(SMS_URI, null, null, null, Telephony.Sms.DATE + " DESC");
String phNumber = null;
//make sure there is a message being operating
if (cursor != null && cursor.moveToFirst()) {
try {
//the meanings of those variables are quite straight forward
String type = cursor.getString(cursor.getColumnIndex(Telephony.Sms.TYPE));
String content = cursor.getString(cursor.getColumnIndex(Telephony.Sms.BODY));
String date = cursor.getString(cursor.getColumnIndex(Telephony.Sms.DATE));
Date SMSDate = new Date(Long.valueOf(date));
phNumber = cursor.getString(cursor.getColumnIndex(Telephony.Sms.ADDRESS)); //this is phone number rather than address
String contact = getContactDisplayNameByNumber(phNumber); //call the metod that convert phone number to contact name in your contacts
int typeCode = Integer.parseInt(type);
String direction = "";
//get the right direction
switch (typeCode) {
case Telephony.Sms.MESSAGE_TYPE_INBOX:
direction = "INCOMING";
break;
case Telephony.Sms.MESSAGE_TYPE_OUTBOX:
direction = "OUTGOING";
break;
case Telephony.Sms.MESSAGE_TYPE_SENT:
direction = "SENT";
break;
default:
direction = "UNKNOWN";
Log.e(TAG, typeCode + " is unknown");
break;
}
} catch (CursorIndexOutOfBoundsException e) {
Log.e(TAG, "SMSHelper: outgoingSMS", e);
} finally {
cursor.close();
}
}
Toast.makeText(context, "\nName: " + contact + "\nPhone Number:--- " + phNumber + " \nContent:--- "
+ content + " \nCall Date:--- " + SMSDate
+ " Direction: " + direction, Toast.LENGTH_LONG).show();
Log.i(TAG, "\nName: " + contact + "\nPhone Number:--- " + phNumber + " \nContent:--- "
+ content + " \nCall Date:--- " + SMSDate
+ " Direction: " + direction + "\n----------------------------------");
super.onChange(selfChange);
}
/**
* http://stackoverflow.com/questions/3712112/search-contact-by-phone-number
* Look up phone number
*
* #param number phone number
* #return the name matched with the phone number
*/
private String getContactDisplayNameByNumber(String number) {
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(number));
String name = "<Not in contact list>";
ContentResolver contentResolver = context.getContentResolver();
Cursor contactLookup = contentResolver.query(uri, new String[]{BaseColumns._ID, ContactsContract.PhoneLookup.DISPLAY_NAME}, null, null, null);
try {
if (contactLookup != null && contactLookup.getCount() > 0) {
contactLookup.moveToFirst();
name = contactLookup.getString(contactLookup.getColumnIndex(ContactsContract.Data.DISPLAY_NAME));
//String contactId = contactLookup.getString(contactLookup.getColumnIndex(BaseColumns._ID));
Log.i(TAG, "Found number in contacts: " + number + " = " + name);
} else {
Log.e(TAG, "Cursor is null or empty " + number + " not found in contacts");
}
} finally {
if (contactLookup != null) {
contactLookup.close();
}
}
return name;
}
}
If the device is on running Android 6.0 (API level 23) and the
app's target SdkVersion is 23 or higher, the SMS permission will be
considered as dangerous permission. Therefore you must get the right
permission beforehand .
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED
&&ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_SMS) != PackageManager.PERMISSION_GRANTED) {
//grant permission
ActivityCompat.requestPermissions( this,
new String[]{Manifest.permission.READ_CONTACTS,Manifest.permission.READ_SMS},
10);
return;
}
Lastly, instantiate the SMSObserver class in the HomeActivity class or any
other Activity classes.
//sms log
smsObserver = new SMSObserver(new Handler(), getApplicationContext());
getContentResolver().registerContentObserver(Telephony.Sms.CONTENT_URI, true, smsObserver);
this is quite odd to me: in my project (which by the way is derived from Yaxim, so it's a chat app for android), I'm trying to implement writing notification through the messageeventlistener. I do receive the notification event. To make it appear in the listview (which is in another class) I'm adding a row in the database, as if it were a message (only the text is "..."). I've added a counter and the row is properly inserted in the db (subsequently the row is deleted from the db when the actual message comes). The notifychanges is also called properly. The strange thing is that despite all of this the row doesn't appear in the listview. If I move the procedure a few lines below, on the packetlistener for the regular messages, it gets inserted. However I cannot leave it like that because the packetlistener doesn't receive properly all composing notifications, so it doesn't work all the time for that purpose. Also, while the writing notification is properly inserted into the db, if I keep the procedure in the messageEventNotificationListener() the writing notification message does not get deleted when the actual message arrives (and the iCount keeps increasing); if I put the procedure in the packetListener it does (hence iCount equals 0 after the message is pushed into the db)
This is the messageeventlistener:
private void messageEventNotificationListener(){
// Create a MessageEventManager
if (mMessageEventManager == null)
mMessageEventManager = new MessageEventManager(mXMPPConnection);
// Add the listener that will react to the event notifications
mMessageEventManager.addMessageEventNotificationListener(new MessageEventNotificationListener() {
public void deliveredNotification(String from, String packetID) {
Log.d(TAG, "The message has been delivered (" + from + ", " + packetID + ")");
}
public void displayedNotification(String from, String packetID) {
Log.d(TAG, "The message has been displayed (" + from + ", " + packetID + ")");
}
public void composingNotification(String from, String packetID) {
Log.d(TAG, "The message's receiver is composing a reply (" + from + ", " + packetID + ")");
//controlla se l'utente non sta giĆ scrivendo
String selection = ChatConstants.JID + " = '" + from + "' AND " +
ChatConstants.DELIVERY_STATUS + " = " + ChatConstants.DS_WRITING;
Cursor cursor = mContentResolver.query(ChatProvider.CONTENT_URI,
new String[] { "count(" + ChatConstants._ID + ")" },
selection, null, null);
cursor.moveToFirst();
int iCount = cursor.getInt(0);
//if (iCount == 0)
//{
addChatMessageToDB(ChatConstants.INCOMING, from, "...", ChatConstants.DS_WRITING, System.currentTimeMillis(), packetID);
//}
}
public void offlineNotification(String from, String packetID) {
Log.d(TAG, "The message's receiver is offline (" + from + ", " + packetID + ")");
}
public void cancelledNotification(String from, String packetID) {
Log.d(TAG, "The message's receiver cancelled composing a reply (" + from + ", " + packetID + ")");
}
});
}
and here is the packetlistener:
private void registerMessageListener() {
// do not register multiple packet listeners
if (mPacketListener != null)
mXMPPConnection.removePacketListener(mPacketListener);
PacketTypeFilter filter = new PacketTypeFilter(Message.class);
mPacketListener = new PacketListener() {
public void processPacket(Packet packet) {
try {
if (packet instanceof Message) {
Message msg = (Message) packet;
String chatMessage = msg.getBody();
DeliveryReceipt dr = (DeliveryReceipt)msg.getExtension("received", DeliveryReceipt.NAMESPACE);
if (dr != null) {
Log.d(TAG, "got delivery receipt for " + dr.getId());
changeMessageDeliveryStatus(dr.getId(), ChatConstants.DS_DELIVERED);
}
if (chatMessage == null)
return;
if (msg.getType() == Message.Type.error) {
chatMessage = "<Error> " + chatMessage;
}
long ts;
DelayInfo timestamp = (DelayInfo)msg.getExtension("delay", "urn:xmpp:delay");
if (timestamp == null)
timestamp = (DelayInfo)msg.getExtension("x", "jabber:x:delay");
if (timestamp != null)
ts = timestamp.getStamp().getTime();
else
ts = System.currentTimeMillis();
String fromJID = getJabberID(msg.getFrom());
//elimina il messaggio "writing" se esiste
deleteWritingChatMessageFromDB(fromJID);
if (msg.getExtension("request", DeliveryReceipt.NAMESPACE) != null) {
// got XEP-0184 request, send receipt
sendReceipt(msg.getFrom(), msg.getPacketID());
}
addChatMessageToDB(ChatConstants.INCOMING, fromJID, chatMessage, ChatConstants.DS_NEW, ts, msg.getPacketID());
mServiceCallBack.newMessage(fromJID, chatMessage);
}
}
} catch (Exception e) {
// SMACK silently discards exceptions dropped from processPacket :(
Log.e(TAG, "failed to process packet:");
e.printStackTrace();
}
};
mXMPPConnection.addPacketListener(mPacketListener, filter);
}
and finally the insert and delete method
private void addChatMessageToDB(int direction, String JID,
String message, int delivery_status, long ts, String packetID) {
ContentValues values = new ContentValues();
values.put(ChatConstants.DIRECTION, direction);
values.put(ChatConstants.JID, JID);
values.put(ChatConstants.MESSAGE, message);
values.put(ChatConstants.DELIVERY_STATUS, delivery_status);
values.put(ChatConstants.DATE, ts);
values.put(ChatConstants.PACKET_ID, packetID);
Uri noteUri = mContentResolver.insert(ChatProvider.CONTENT_URI, values);
//mContentResolver.notifyChange(noteUri, null);
}
private void deleteWritingChatMessageFromDB(String JID) {
int count = mContentResolver.delete(ChatProvider.CONTENT_URI,
ChatConstants.JID + " = ? AND " + ChatConstants.MESSAGE + " = ? AND " + ChatConstants.DELIVERY_STATUS + " = ?", new String[] { JID, "...", "3" });
debugLog("deleteWritingChatMessageEntryFromDB: Deleted " + count + " entries");
}
both these methods get called into the ChatProvider class and end with
getContext().getContentResolver().notifyChange(url, null);
Turns out the problem was different: I posting this just in case someone else runs in the same issue. The message was infact inserted into the db, but while the packetlistener returns only the jid, the messageeventlistener returns the jid with the resource at the end as well, which needed to be taken away before the insert. Done that, the message appeared in the list. Also: the code I posted is not completely correct to handle the messageEvent. The listeners need to be called from inside the packetListener directly.
Im using Android 2.1 Api
I need to add a String MIME type into existing contacts for storing a userdefined data apart from Phone numbers,email etc.Please help me how to add that Custom Field from my application.
I request with an example because I am a week old on Android.
Here is an example that saves a boolean as my custom mime type to the contacts. It uses the latest SDK 2.1
public static final String MIMETYPE_FORMALITY = "vnd.android.cursor.item/useformality";
public clsMyClass saveFormality() {
try {
ContentValues values = new ContentValues();
values.put(Data.DATA1, this.getFormality() ? "1" : "0");
int mod = ctx.getContentResolver().update(
Data.CONTENT_URI,
values,
Data.CONTACT_ID + "=" + this.getId() + " AND "
+ Data.MIMETYPE + "= '"
+ clsContacts.FORMALITY_MIMETYPE + "'", null);
if (mod == 0) {
values.put(Data.CONTACT_ID, this.getId());
values.put(Data.MIMETYPE, clsContacts.FORMALITY_MIMETYPE);
ctx.getContentResolver().insert(Data.CONTENT_URI, values);
}
} catch (Exception e) {
Log.v(TAG(), "saveFormality failed");
}
return this;
}
public boolean getFormality() {
if (data.containsKey(FORMALITY)) {
return data.getAsBoolean(FORMALITY);
} else {
// read formality
Cursor c = readDataWithMimeType(clsContacts.MIMETYPE_FORMALITY, this.getId());
if (c != null) {
try {
if (c.moveToFirst()) {
this.setFormality(c.getInt(0) == 1);
return (c.getInt(0) == 1);
}
} finally {
c.close();
}
}
return false;
}
}
public clsMyClass setFormality(Boolean value) {
data.remove(FORMALITY);
data.put(FORMALITY, value);
return this;
}
/**
* Utility method to read data with mime type
*
* #param mimetype String representation of the mimetype used for this type
* of data
* #param contactid String representation of the contact id
* #return
*/
private Cursor readDataWithMimeType(String mimetype, String contactid) {
return ctx.getContentResolver().query(
Data.CONTENT_URI,
new String[] {
Data.DATA1
},
Data.RAW_CONTACT_ID + "=" + contactid + " AND " + Data.MIMETYPE + "= '" + mimetype
+ "'", null, null);
}
Usage is
objContact.setFormality(true).saveFormality();