/**
*
*/
package org.orange.familylink.sms;
import org.orange.familylink.BuildConfig;
import org.orange.familylink.MessagesActivity;
import org.orange.familylink.R;
import org.orange.familylink.data.MessageLogRecord.Status;
import org.orange.familylink.database.Contract;
import org.orange.familylink.database.Contract.Messages;
import android.app.Activity;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.NotificationCompat;
import android.telephony.SmsManager;
import android.util.Log;
import android.widget.Toast;
/**
* 短信发送状态接收器
* @author Team Orange
*/
public class SmsStatusReceiver extends BroadcastReceiver {
private static final String TAG = SmsStatusReceiver.class.getSimpleName();
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(SmsIntent.MESSAGE_SENT_ACTION.equals(action)) {
onMessageSent(context, intent);
} else if(SmsIntent.MESSAGE_DELIVERED_ACTION.equals(action)) {
onMessageDelivered(context, intent);
}
if(BuildConfig.DEBUG) Log.v(TAG, "receiver broadcase"+action+":"+intent.getDataString());
}
/**
* 当接收到{@link SmsIntent#MESSAGE_SENT_ACTION}时被调用
* @param context 上下文环境
* @param intent 接收到的{@link Intent}
*/
protected void onMessageSent(Context context, Intent intent) {
ContentResolver contentResolver = context.getContentResolver();
switch(getResultCode()) {
case Activity.RESULT_OK:
boolean shouldUpdate = false;
// 如果状态已经变为DELIVERED,则不再改变状态
Cursor c = contentResolver.query(intent.getData(),
new String[]{Messages.COLUMN_NAME_STATUS}, null, null, null);
if(c != null && c.moveToNext()) {
String status = c.getString(c.getColumnIndex(Messages.COLUMN_NAME_STATUS));
if(Status.valueOf(status) != Status.DELIVERED)
shouldUpdate = true;
} else {
if(BuildConfig.DEBUG)
throw new RuntimeException("Can't find message:"+intent.getDataString());
else
Log.e(TAG, "Can't find message:"+intent.getDataString());
}
if(shouldUpdate) {
ContentValues updateValues = new ContentValues();
updateValues.put(Messages.COLUMN_NAME_TIME, System.currentTimeMillis());
updateValues.put(Messages.COLUMN_NAME_STATUS, Status.SENT.name());
contentResolver.update(intent.getData(), updateValues, null, null);
}
// 提示发送了短信
String contactName = getReceiverOfMessage(context, intent.getData());
if(contactName == null)
contactName = context.getString(R.string.unknown);
Toast.makeText(context, context.getString(R.string.sms_sent_notification, contactName),
Toast.LENGTH_LONG).show();
return;
default:
onFailedToSend(context, intent);
return;
}
}
/**
* 当接收到{@link SmsIntent#MESSAGE_SENT_ACTION} 且
* {@link #getResultCode()} != {@link Activity#RESULT_OK} 时,被调用
* @param context 上下文环境
* @param intent 接收到的{@link Intent}
*/
//TODO 改进友好性
protected void onFailedToSend(Context context, Intent intent) {
Intent resultIntent = new Intent(context, MessagesActivity.class);
resultIntent.setAction(Intent.ACTION_VIEW);
resultIntent.setType(Messages.MESSAGES_TYPE);
long id = ContentUris.parseId(intent.getData());
if(id >= 1) {
resultIntent.putExtra(MessagesActivity.EXTRA_IDS, new long[]{id});
resultIntent.putExtra(MessagesActivity.EXTRA_STATUS, Status.FAILED_TO_SEND);
}
PendingIntent resultPendingIntent = PendingIntent.getActivity(
context, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setContentTitle(context.getString(R.string.failed_to_send))
.setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(resultPendingIntent)
.setAutoCancel(true);
switch(getResultCode()) {
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
Bundle extra = intent.getExtras();
boolean containErrorCode = false;
String errorCode = "null";
if(extra != null && extra.containsKey("errorCode"))
containErrorCode = true;
if(containErrorCode)
errorCode = extra.get("errorCode").toString();
if(BuildConfig.DEBUG) {
System.out.println("has errorCode:" + containErrorCode);
System.out.println("errorCode:" + errorCode);
// 无话费时,上边是true和21(Integer)
}
builder.setContentText(context.getString(
R.string.failed_to_send_because_of_generic_failure, errorCode));
break;
case SmsManager.RESULT_ERROR_NO_SERVICE:
//TODO 待处理
break;
case SmsManager.RESULT_ERROR_NULL_PDU:
//TODO 待处理
break;
case SmsManager.RESULT_ERROR_RADIO_OFF:
builder.setContentText(context.getString(
R.string.failed_to_send_because_of_radio_off));
break;
}
ContentValues updateValues = new ContentValues();
updateValues.put(Messages.COLUMN_NAME_TIME, System.currentTimeMillis());
updateValues.put(Messages.COLUMN_NAME_STATUS, Status.FAILED_TO_SEND.name());
context.getContentResolver().update(intent.getData(), updateValues, null, null);
((NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE))
.notify(0, builder.build());
if(BuildConfig.DEBUG) Log.v(TAG, "failed to send: "+getResultCode()+" "+getResultExtras(true));
}
/**
* 当接收到{@link SmsIntent#MESSAGE_DELIVERED_ACTION}时被调用
* @param context 上下文环境
* @param intent 接收到的{@link Intent}
*/
protected void onMessageDelivered(Context context, Intent intent) {
ContentValues updateValues = new ContentValues();
updateValues.put(Messages.COLUMN_NAME_STATUS, Status.DELIVERED.name());
context.getContentResolver().update(intent.getData(), updateValues, null, null);
// 提示短息已送达
String contactName = getReceiverOfMessage(context, intent.getData());
if(contactName == null)
contactName = context.getString(R.string.unknown);
Toast.makeText(context, context.getString(R.string.sms_delivered_notification, contactName),
Toast.LENGTH_LONG).show();
}
private String getReceiverOfMessage(final Context context, final Uri uriOfMessage) {
final ContentResolver contentResolver = context.getContentResolver();
Cursor cursor = contentResolver.query(uriOfMessage,
new String[]{Contract.Messages.COLUMN_NAME_CONTACT_ID}, null, null, null);
Long contactId = null;
if(cursor.moveToFirst()) {
int index = cursor.getColumnIndex(Contract.Messages.COLUMN_NAME_CONTACT_ID);
if(!cursor.isNull(index))
contactId = cursor.getLong(index);
}
cursor.close();
if(contactId == null)
return null;
final Uri uriOfContact = ContentUris.withAppendedId(
Contract.Contacts.CONTACTS_ID_URI, contactId);
cursor = contentResolver.query(uriOfContact,
new String[]{Contract.Contacts.COLUMN_NAME_NAME}, null, null, null);
String contactName = null;
if(cursor.moveToFirst()) {
int index = cursor.getColumnIndex(Contract.Contacts.COLUMN_NAME_NAME);
if(!cursor.isNull(index))
contactName = cursor.getString(index);
}
cursor.close();
return contactName;
}
}