package net.everythingandroid.smspopup.service;
import net.everythingandroid.smspopup.BuildConfig;
import net.everythingandroid.smspopup.provider.SmsMmsMessage;
import net.everythingandroid.smspopup.provider.SmsPopupContract.ContactNotifications;
import net.everythingandroid.smspopup.util.Log;
import net.everythingandroid.smspopup.util.ManageNotification;
import net.everythingandroid.smspopup.util.SmsPopupUtils;
import net.everythingandroid.smspopup.util.SmsPopupUtils.ContactIdentification;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import com.commonsware.cwac.wakeful.WakefulIntentService;
public class SmsPopupUtilsService extends WakefulIntentService {
private static final String TAG = SmsPopupUtilsService.class.getName();
public static final String ACTION_MARK_THREAD_READ =
"net.everythingandroid.smspopup.ACTION_MARK_THREAD_READ";
public static final String ACTION_MARK_MESSAGE_READ =
"net.everythingandroid.smspopup.ACTION_MARK_MESSAGE_READ";
public static final String ACTION_DELETE_MESSAGE =
"net.everythingandroid.smspopup.ACTION_DELETE_MESSAGE";
public static final String ACTION_UPDATE_NOTIFICATION =
"net.everythingandroid.smspopup.ACTION_UPDATE_NOTIFICATION";
public static final String ACTION_QUICKREPLY =
"net.everythingandroid.smspopup.ACTION_QUICKREPLY";
public static final String ACTION_SYNC_CONTACT_NAMES =
"net.everythingandroid.smspopup.ACTION_SYNC_CONTACT_NAMES";
public SmsPopupUtilsService() {
super(TAG);
}
/*
* (non-Javadoc)
*
* @see
* com.commonsware.cwac.wakeful.WakefulIntentService#doWakefulWork(android
* .content.Intent)
*/
@Override
protected void doWakefulWork(Intent intent) {
if (BuildConfig.DEBUG) Log.v("SMSPopupUtilsService: doWakefulWork()");
final String action = intent.getAction();
if (ACTION_MARK_THREAD_READ.equals(action)) {
if (BuildConfig.DEBUG) Log.v("SMSPopupUtilsService: Marking thread read");
SmsMmsMessage message = new SmsMmsMessage(this, intent.getExtras());
message.setThreadRead();
} else if (ACTION_MARK_MESSAGE_READ.equals(action)) {
if (BuildConfig.DEBUG) Log.v("SMSPopupUtilsService: Marking message read");
SmsMmsMessage message = new SmsMmsMessage(this, intent.getExtras());
message.setMessageRead();
} else if (ACTION_DELETE_MESSAGE.equals(action)) {
if (BuildConfig.DEBUG) Log.v("SMSPopupUtilsService: Deleting message");
SmsMmsMessage message = new SmsMmsMessage(this, intent.getExtras());
message.delete();
} else if (ACTION_QUICKREPLY.equals(action)) {
if (BuildConfig.DEBUG) Log.v("SMSPopupUtilsService: Quick Reply to message");
SmsMmsMessage message = new SmsMmsMessage(this, intent.getExtras());
message.replyToMessage(intent.getStringExtra(SmsMmsMessage.EXTRAS_QUICKREPLY));
} else if (ACTION_UPDATE_NOTIFICATION.equals(action)) {
if (BuildConfig.DEBUG) Log.v("SMSPopupUtilsService: Updating notification");
updateNotification(intent);
} else if (ACTION_SYNC_CONTACT_NAMES.equals(action)) {
if (BuildConfig.DEBUG) Log.v("SMSPopupUtilsService: Sync'ing contact names");
syncContactNames(this);
}
}
/**
* Any custom contact notifications are stored in a local database, including the contact names
* so we can quickly display them on the configuration screens. This function will loop through
* the locally stored contacts and check to see if the system contact name has changed at all
* (from either a manual edit or some sort of sync event). If so, it will update the local
* database with the new name.
* @param context Context.
* @return The number of rows updated with a new name.
*/
private int syncContactNames(Context context) {
final ContentResolver contentResolver = context.getContentResolver();
final Cursor cursor = contentResolver.query(
ContactNotifications.CONTENT_URI, null, null, null, null);
if (cursor == null) {
return 0;
}
if (cursor.getCount() == 0) {
return 0;
}
int count = 0;
int updatedCount = 0;
String id;
String contactName;
String contactLookup;
String contactId;
// loop through the local sms popup contact notifications table
while (cursor.moveToNext()) {
count++;
id = cursor.getString(
cursor.getColumnIndexOrThrow(ContactNotifications._ID));
contactName = cursor.getString(
cursor.getColumnIndexOrThrow(ContactNotifications.CONTACT_NAME));
contactId = cursor.getString(
cursor.getColumnIndexOrThrow(ContactNotifications.CONTACT_ID));
contactLookup = cursor.getString(
cursor.getColumnIndexOrThrow(ContactNotifications.CONTACT_LOOKUPKEY));
ContactIdentification contactInfo =
SmsPopupUtils.getPersonNameByLookup(context, contactLookup, contactId);
if (contactInfo != null) {
boolean runUpdate = false;
ContentValues vals = new ContentValues();
if (contactName == null || !contactName.equals(contactInfo.contactName)) {
vals.put(ContactNotifications.CONTACT_NAME, contactInfo.contactName);
runUpdate = true;
}
if (contactId == null || !contactId.equals(contactInfo.contactId)) {
vals.put(ContactNotifications.CONTACT_ID, contactInfo.contactId);
runUpdate = true;
}
if (contactLookup == null || !contactLookup.equals(contactInfo.contactLookup)) {
vals.put(ContactNotifications.CONTACT_LOOKUPKEY, contactInfo.contactLookup);
runUpdate = true;
}
if (runUpdate && 1 == contentResolver.update(
ContactNotifications.buildContactUri(id), vals, null, null)) {
updatedCount++;
}
}
}
if (cursor != null) {
cursor.close();
}
if (BuildConfig.DEBUG)
Log.v("Sync Contacts: " + updatedCount + " / " + count);
return updatedCount;
}
public static void startSyncContactNames(Context context) {
Intent i = new Intent(context, SmsPopupUtilsService.class);
i.setAction(SmsPopupUtilsService.ACTION_SYNC_CONTACT_NAMES);
WakefulIntentService.sendWakefulWork(context, i);
}
private void updateNotification(Intent intent) {
// In the case the user is "replying" to the message (ie. starting an
// external intent) we need to ignore all messages in the thread when
// calculating the unread messages to show in the status notification
boolean ignoreThread = intent.getBooleanExtra(SmsMmsMessage.EXTRAS_REPLYING, false);
SmsMmsMessage message;
if (ignoreThread) {
// If ignoring messages from the thread, pass the full message over
message = new SmsMmsMessage(this, intent.getExtras());
} else {
// Otherwise we can just calculate unread messages by checking the
// database as normal
message = null;
}
// Get the most recent message + total message counts
SmsMmsMessage recentMessage = SmsPopupUtils.getRecentMessage(this, message);
// Update the notification in the status bar
ManageNotification.update(this, recentMessage,
recentMessage == null ? 0 : recentMessage.getUnreadCount());
}
}