package com.android.mms.ui;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.AsyncQueryHandler;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteException;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.provider.Telephony.Mms;
import android.provider.Telephony.Sms;
import com.android.mms.R;
import com.android.mms.data.ContactList;
import com.android.mms.data.Conversation;
import com.android.mms.transaction.MessagingNotification;
public class MessageBoxDeleteActivity extends Activity implements View.OnClickListener,OnItemClickListener {
private static final String TAG = "MessageBoxDeleteActivity";
private static final Uri uri_inbox_mms = Uri.parse("content://mms/inbox");
private static final Uri uri_icc = Uri.parse("content://sms/icc");
private static final int MENU_DELETE_ALL = 0;
private static final int MENU_MSG_FOLDER = 1;
public static String boxType = "";
public CheckBox mSelectAllCheckbox;
private ProgressDialog progressDialog;
private ProgressDialog mDelMessProDialog;
private TextView mTitle;
private ListView mMsgList;
private Button cancelBtn;
private Button mDeleteBtn;
public MessageListAdapter mMsgListAdapter;
private ContentResolver mContentResolver;
private Context mContext;
private static Cursor currentCursor = null;
private MsgBoxAdapter mAdapter;
private CheckBox mLockCheckBox;
private ItemView itemView;
private static final String INBOX = "inbox";
private static final String OUTBOX = "outbox";
private static final String SENT = "sent";
private static final String DRAFTS = "drafts";
private static final String SIMCARD = "simcard";
private static final short PROJECTION_ID = 0;
private static final short PROJECTION_DATE = 1;
private static final short PROJECTION_SUB = 2;
private static final short PROJECTION_SUB_CS = 3;
private static final short PROJECTION_THREAD_ID = 4;
private static final short PROJECTION_MSG_ID = 5;
private static final short PROJECTION_READ = 6;
private static final short PROJECTION_RECIPIENT_IDS = 7;
private static final short PROJECTION_MSG_TYPE = 8;
private AsyncQueryHandler mQueryHandler = null;
private static final int SHOW_LIST = 0;
private static final int SHOW_EMPTY = 1;
private static final int SHOW_BUSY = 2;
private int mState;
private MessageSimListAdapter mListAdapter = null;
private TextView mEmptyMsg;
// private CheckBox checkbox;
//Add for Dualsim
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
mContentResolver = getContentResolver();
mContext = this;
setContentView(R.layout.msg_box_delete_list);
mQueryHandler = new QueryHandler(mContentResolver, this);
progressDialog = new ProgressDialog(this);
CharSequence title = getString(R.string.pref_title_manage_sim_messages);
progressDialog.setTitle(title);
progressDialog.setMessage(getText(R.string.wait_message));
progressDialog.setCancelable(false);
setTitle();
initResource();
startQuery();
}
@Override
protected void onDestroy() {
super.onDestroy();
if ( mMsgListAdapter != null ) {
mMsgListAdapter.changeCursor(null);
}
if ( mListAdapter != null ) {
mListAdapter.changeCursor(null);
}
if ( currentCursor != null ) {
currentCursor.close();
}
}
private void setTitle() {
mTitle = (TextView) findViewById(R.id.box_title);
Intent it = getIntent();
Bundle bundle = it.getExtras();
if (bundle != null) {
boxType = bundle.getString("boxType");
}
if (INBOX.equals(boxType)) {
mTitle.setText(getString(R.string.folder_inbox));
} else if (OUTBOX.equals(boxType)) {
mTitle.setText(getString(R.string.folder_outbox));
} else if (SENT.equals(boxType)) {
mTitle.setText(getString(R.string.folder_sent));
} else if (DRAFTS.equals(boxType)) {
mTitle.setText(getString(R.string.folder_drafts));
} else if (SIMCARD.equals(boxType)) {
mTitle.setText(getString(R.string.folder_simcard));
}
}
private void initResource() {
mMsgList = (ListView) findViewById(R.id.box_messages_delete);
mSelectAllCheckbox = (CheckBox) findViewById(R.id.checkbox_selected_all);
mSelectAllCheckbox.setOnClickListener(this);
mDeleteBtn = (Button) findViewById(R.id.DeleteButton);
mDeleteBtn.setOnClickListener(this);
mDeleteBtn.setEnabled(false);
cancelBtn = (Button) findViewById(R.id.CancelButton);
cancelBtn.setOnClickListener(this);
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
menu.clear();
menu.add(0, MENU_MSG_FOLDER, 0, R.string.menu_msg_folder).setIcon(
R.drawable.ic_menu_folder);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case MENU_DELETE_ALL:
// createNewMessage();
Intent intentDelete = new Intent(this,
MessageBoxDeleteActivity.class);
startActivity(intentDelete);
break;
case MENU_MSG_FOLDER:
Intent it = new Intent(this, MessageFolderActivity.class);
startActivity(it);
break;
default:
return true;
}
return false;
}
private void startQuery() {
try {
if (INBOX.equals(boxType)) {//1
String mStr = "_id,date,sub,sub_cs,thread_id,msg_id,read,recipient_ids,msg_type from (select canonical_addresses.address as _id,sms.date as date,sms.body as sub,'' as sub_cs,sms.thread_id as thread_id,sms._id as msg_id,sms.read as read,threads.recipient_ids as recipient_ids,'s' as msg_type from sms,canonical_addresses,threads where sms.type = 1 and sms.thread_id = threads._id and threads.recipient_ids = canonical_addresses._id union all select canonical_addresses.address as _id,pdu.date * 1000 as date,pdu.sub as sub,pdu.sub_cs as sub_cs,pdu.thread_id as thread_id,pdu._id as msg_id,pdu.read as read,threads.recipient_ids as recepient_ids,'m' as msg_type from canonical_addresses,addr,pdu,threads where addr.type = 137 and addr.msg_id = pdu._id and pdu.msg_box = 1 and pdu.thread_id = threads._id and threads.recipient_ids = canonical_addresses._id) order by date desc --";
setListView(mStr);
} else if (OUTBOX.equals(boxType)) {//4
String mStr = "_id,date,sub,sub_cs,thread_id,msg_id,read,recipient_ids,msg_type from (select a.address as _id,threads.recipient_ids as recipient_ids,a.date as date,body as sub, '' as sub_cs,thread_id as thread_id,a._id as msg_id,a.read as read,'s' as msg_type from (select * from sms where (type=4 or type=5 or type=6) group by date) a left join threads on threads._id = a.thread_id union select b.address as _id,threads.recipient_ids as recipient_ids,b.date * 1000 as date,b.sub as sub,b.sub_cs as sub_cs,b.thread_id as thread_id,b._id as msg_id,b.read as read,'m' as msg_type from (select * from pdu,addr where (msg_box=4 or msg_box=5 or msg_box=6) and addr.type=137 and pdu._id = addr.msg_id group by date) b left join threads on threads._id = b.thread_id) order by date desc --";
setListView(mStr);
} else if (SENT.equals(boxType)) {//2
String mStr = "_id,date,sub,sub_cs,thread_id,msg_id,read,recipient_ids,msg_type from (select a.address as _id,threads.recipient_ids as recipient_ids,a.date as date,body as sub, '' as sub_cs,thread_id as thread_id,a._id as msg_id,a.read as read,'s' as msg_type from (select * from sms where type=2 group by date) a left join threads on threads._id = a.thread_id union select b.address as _id,threads.recipient_ids as recipient_ids,b.date * 1000 as date,b.sub as sub,b.sub_cs as sub_cs,b.thread_id as thread_id,b._id as msg_id,b.read as read,'m' as msg_type from (select * from pdu,addr where msg_box=2 and pdu._id = addr.msg_id group by date) b left join threads on threads._id = b.thread_id) order by date desc --";
setListView(mStr);
} else if (DRAFTS.equals(boxType)) {//3
String mStr = "_id,date,sub,sub_cs,thread_id,msg_id,read,recipient_ids,msg_type from (select a.address as _id,threads.recipient_ids as recipient_ids,a.date as date,body as sub, '' as sub_cs,thread_id as thread_id,a._id as msg_id,a.read as read,'s' as msg_type from (select * from sms where type=3 group by date) a left join threads on threads._id = a.thread_id union select b.address as _id,threads.recipient_ids as recipient_ids,b.date * 1000 as date,b.sub as sub,b.sub_cs as sub_cs,b.thread_id as thread_id,b._id as msg_id,b.read as read,'m' as msg_type from (select * from pdu,addr where msg_box=3 and addr.type=137 and pdu._id = addr.msg_id group by date) b left join threads on threads._id = b.thread_id) order by date desc --";
setListView(mStr);
}else if (SIMCARD.equalsIgnoreCase(boxType)){
mQueryHandler.startQuery(0, null, uri_icc, null, null, null,null);
}
} catch (SQLiteException e) {
//SqliteWrapper.checkSQLiteException(this, e);
}
}
private void showProgressDialog() {
if (null != progressDialog && progressDialog.isShowing()) {
progressDialog.hide();
}
if (null != progressDialog && !isFinishing()) {
progressDialog.show();
}
}
private void setListView(String str) {
if (currentCursor != null) {
currentCursor.close();
}
currentCursor = getContentResolver().query(uri_inbox_mms,new String[] { str }, null, null, null);
mAdapter = new MsgBoxAdapter(this,currentCursor);
mMsgList.setAdapter(mAdapter);
mMsgList.setOnItemClickListener(this);
}
class MsgBoxAdapter extends BaseAdapter {
Map<Integer,Boolean> selectedMap;
Map<Integer,ItemMessage> selectedIm;
Cursor cur;
Context context;
// String boxType;
public MsgBoxAdapter(Context context, Cursor c) {
super();
cur = c;
selectedMap = new HashMap<Integer,Boolean>();
for(int i = 0 ;i<c.getCount();i++){
selectedMap.put(i, false);
}
selectedIm = new HashMap<Integer,ItemMessage>();
}
@Override
public int getCount() {
return cur.getCount();
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public Object getItem(int position) {
if (cur.moveToPosition(position)) {
return cur;
} else {
return null;
}
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView == null){
convertView = LayoutInflater.from(MessageBoxDeleteActivity.this).inflate(
R.layout.box_messages_delete,null);
itemView = new ItemView();
itemView.tv_address = (TextView)convertView.findViewById(R.id.box_msg_address);
itemView.tv_date = (TextView)convertView.findViewById(R.id.box_msg_date);
itemView.tv_subject=(TextView)convertView.findViewById(R.id.box_msg_subject);
itemView.checkbox = (CheckBox)convertView.findViewById(R.id.checkbox_select);
itemView.mImageView = (ImageView)convertView.findViewById(R.id.msg_type_image);
convertView.setTag(itemView);
}
cur.moveToPosition(position);
ItemView itemView =(ItemView)convertView.getTag();
String recipitent_ids = cur.getString(PROJECTION_RECIPIENT_IDS);
if (recipitent_ids != null) {
ContactList recipients = ContactList.getByIds(recipitent_ids, true);
itemView.tv_address.setText(recipients.formatNames(", "));
}
long datel = cur.getLong(PROJECTION_DATE);
String date = MessageUtils.formatTimeStampString(MessageBoxDeleteActivity.this, datel);
itemView.tv_date.setText(date);
String subject = cur.getString(PROJECTION_SUB);
String subject_cs = cur.getString(PROJECTION_SUB_CS);
String mSub = "";
if (!"".equals(subject_cs)) {
mSub = MessageUtils.extractEncStrFromCursor(cur, PROJECTION_SUB, PROJECTION_SUB_CS);
} else {
mSub = subject;
}
itemView.tv_subject.setText(mSub);
itemView.checkbox.setChecked(selectedMap.get(position));
ItemMessage im = new ItemMessage();
im.id = cur.getString(PROJECTION_ID);
im.msg_type = cur.getString(PROJECTION_MSG_TYPE);
im.msg_id = cur.getString(PROJECTION_MSG_ID);
im.thread_id= cur.getString(PROJECTION_THREAD_ID);
im.date = datel;
selectedIm.put(position, im);
Long read = cur.getLong(PROJECTION_READ);
String msg_type = cur.getString(PROJECTION_MSG_TYPE);
if (INBOX.equals(boxType)) {
if (read == 0) {
if ("s".equals(msg_type)) {
itemView.mImageView.setBackgroundResource(R.drawable.msg_unread);
} else {
itemView.mImageView.setBackgroundResource(R.drawable.mms_unread);
}
} else {
if ("s".equals(msg_type)) {
itemView.mImageView.setBackgroundResource(R.drawable.msg_readed);
} else {
itemView.mImageView.setBackgroundResource(R.drawable.mms_readed);
}
}
} else if (OUTBOX.equals(boxType)) {
if ("s".equals(msg_type)) {
itemView.mImageView.setBackgroundResource(R.drawable.ic_outbox);
} else {
itemView.mImageView.setBackgroundResource(R.drawable.ic_outbox_mms);
}
} else if (SENT.equals(boxType)) {
if ("s".equals(msg_type)) {
itemView.mImageView.setBackgroundResource(R.drawable.ic_sent);
} else {
itemView.mImageView.setBackgroundResource(R.drawable.ic_sent_mms);
}
} else if (DRAFTS.equals(boxType)) {
if ("s".equals(msg_type)) {
itemView.mImageView.setBackgroundResource(R.drawable.msg_drafts_sms);
} else {
itemView.mImageView.setBackgroundResource(R.drawable.msg_drafts_mms);
}
}
return convertView;
}
}
@Override
public void onClick(View v) {
if(v == mSelectAllCheckbox){
if(mSelectAllCheckbox.isChecked()){
for(int i = 0;i<mAdapter.getCount();i++){
mAdapter.selectedMap.put(i, true);
mAdapter.cur.moveToPosition(i);
ItemMessage im = new ItemMessage();
im.id = mAdapter.cur.getString(PROJECTION_ID);
im.msg_type = mAdapter.cur.getString(PROJECTION_MSG_TYPE);
im.msg_id = mAdapter.cur.getString(PROJECTION_MSG_ID);
im.thread_id= mAdapter.cur.getString(PROJECTION_THREAD_ID);
im.date = mAdapter.cur.getLong(PROJECTION_DATE);
mAdapter.selectedIm.put(i, im);
}
mDeleteBtn.setEnabled(true);
}else{
for(int i=0;i<mAdapter.getCount();i++){
mAdapter.selectedMap.put(i, false);
}
mDeleteBtn.setEnabled(false);
}
mAdapter.notifyDataSetChanged();
}
else if(v == mDeleteBtn){
if (DRAFTS.equals(boxType)) {
new AlertDialog.Builder(MessageBoxDeleteActivity.this).setTitle(R.string.clearConfirmation_title)
.setMessage(R.string.clearConfirmation)
.setNegativeButton(android.R.string.cancel, null)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog,int which){
mDelMessProDialog = new ProgressDialog(MessageBoxDeleteActivity.this);
mDelMessProDialog.setTitle(getString(R.string.delete_message));
mDelMessProDialog.setMessage(getText(R.string.wait_message));
mDelMessProDialog.setCancelable(false);
final DeleteMessageAsyncTask task = new DeleteMessageAsyncTask();
mDelMessProDialog.show();
task.execute(mAdapter.selectedMap);
}
}).setCancelable(true).create().show();
} else {
View contents = View.inflate(MessageBoxDeleteActivity.this, R.layout.delete_box_message_dialog_view, null);
mLockCheckBox = (CheckBox)contents.findViewById(R.id.delete_locked);
new AlertDialog.Builder(MessageBoxDeleteActivity.this).setTitle(R.string.clearConfirmation_title)
.setView(contents)
.setNegativeButton(android.R.string.cancel, null)
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener(){
public void onClick(DialogInterface dialog,int which){
mDelMessProDialog = new ProgressDialog(MessageBoxDeleteActivity.this);
mDelMessProDialog.setTitle(getString(R.string.delete_message));
mDelMessProDialog.setMessage(getText(R.string.wait_message));
mDelMessProDialog.setCancelable(false);
final DeleteMessageAsyncTask task = new DeleteMessageAsyncTask();
mDelMessProDialog.show();
task.execute(mAdapter.selectedMap,mLockCheckBox.isChecked());
}
}).setCancelable(true).create().show();
}
}else if(v == cancelBtn){
this.finish();
}
}
public void onItemClick(AdapterView<?> arg0, View view, int position, long arg3) {
ItemView views = (ItemView) view.getTag();
views.checkbox.toggle();
mAdapter.selectedMap.put(position, views.checkbox.isChecked());
if (mAdapter.selectedMap.containsValue(false)) {
mSelectAllCheckbox.setChecked(false);
} else {
mSelectAllCheckbox.setChecked(true);
}
if (mAdapter.selectedMap.containsValue(true)) {
mDeleteBtn.setEnabled(true);
} else {
mDeleteBtn.setEnabled(false);
}
mAdapter.notifyDataSetChanged();
}
private final class ItemView{
TextView tv_address;
TextView tv_date;
TextView tv_subject;
ImageView mImageView;
CheckBox checkbox;
}
class DeleteMessageAsyncTask extends AsyncTask<Object,Void,Void>{
protected Void doInBackground(Object... object) {
String mWhere = "";
if (DRAFTS.equals(boxType)) {
mWhere = " locked = 0 ";
} else {
if (mLockCheckBox.isChecked()) {
mWhere = " (locked = 0 or locked = 1) ";
} else {
mWhere = " locked = 0 ";
}
}
String smsWhere = "";
String mmsWhere = "";
if (INBOX.equals(boxType)) {
smsWhere = mWhere + " and type = 1 ";
mmsWhere = mWhere + " and msg_box = 1 ";
} else if (OUTBOX.equals(boxType)) {
smsWhere = mWhere + " and (type = 4 or type = 5 or type = 6) ";
mmsWhere = mWhere + " and (msg_box = 4 or msg_box = 5 or msg_box = 6) ";
} else if (SENT.equals(boxType)) {
smsWhere = mWhere + " and type = 2 ";
mmsWhere = mWhere + " and msg_box = 2 ";
} else if (DRAFTS.equals(boxType)) {
smsWhere = " type = 3 ";
mmsWhere = " msg_box = 3 ";
}
if (mSelectAllCheckbox.isChecked()) {
if (INBOX.equals(boxType)) {
Conversation.markAllConversationsAsSeen(getApplicationContext());
}
getContentResolver().delete(Sms.CONTENT_URI, smsWhere, null);
getContentResolver().delete(Mms.CONTENT_URI, mmsWhere, null);
} else {
for ( int i = 0; i < mAdapter.selectedMap.size(); i++ ) {
if ( mAdapter.selectedMap.get(i) ) {
ItemMessage im = (ItemMessage)mAdapter.selectedIm.get(i);
Uri mDeleteUri = null;
if("s".equals(im.msg_type)){
mDeleteUri = ContentUris.withAppendedId(Sms.CONTENT_URI, Long.parseLong(im.msg_id));
String selection = "";
if (DRAFTS.equals(boxType)) {
selection = " thread_id = " +im.thread_id + " and " + " date = " + im.date;
} else {
selection = " thread_id = " +im.thread_id + " and " + " date = " + im.date + " and " + mWhere;
}
Cursor delCursor = mContentResolver.query(Sms.CONTENT_URI, new String[] { "_id"},selection, null, null);
if ( delCursor != null ) {
try {
while (delCursor.moveToNext()){
getContentResolver().delete(ContentUris.withAppendedId(Sms.CONTENT_URI,delCursor.getLong(0)),null, null);
}
} finally {
delCursor.close();
}
}
} else if ("m".equals(im.msg_type)) {
mDeleteUri = ContentUris.withAppendedId(Mms.CONTENT_URI, Long.parseLong(im.msg_id));
mContentResolver.delete(mDeleteUri, mWhere, null);
}
}
}
// Always update notifications regardless of the read state.
MessagingNotification.blockingUpdateAllNotifications(mContext);
}
return null;
}
protected void onPostExecute(Void result) {
Intent it = new Intent(MessageBoxDeleteActivity.this, MessageBoxActivity.class);
startActivity(it);
MessageBoxDeleteActivity.this.finish();
mDelMessProDialog.dismiss();
}
}
class ItemMessage{
String id ;
String msg_type;
String msg_id;
String thread_id;
long date;
public boolean equals(Object o) {
boolean result = false;
ItemMessage im = (ItemMessage)o;
if(id.equals(im.id)&&msg_type.equals(im.msg_type)&&msg_id.equals(im.msg_id)&&thread_id.equals(im.thread_id)){
result = true;
}else{
result = false;
}
return result;
}
}
private void updateState(int state) {
if (mState == state) {
return;
}
mState = state;
switch (state) {
case SHOW_LIST:
mMsgList.setVisibility(View.VISIBLE);
mEmptyMsg.setVisibility(View.GONE);
setProgressBarIndeterminateVisibility(false);
break;
case SHOW_EMPTY:
mMsgList.setVisibility(View.GONE);
mEmptyMsg.setVisibility(View.VISIBLE);
setProgressBarIndeterminateVisibility(false);
break;
case SHOW_BUSY:
mMsgList.setVisibility(View.GONE);
mEmptyMsg.setVisibility(View.GONE);
setTitle(getString(R.string.refreshing));
setProgressBarIndeterminateVisibility(true);
break;
default:
Log.e(TAG, "Invalid State");
}
}
private class QueryHandler extends AsyncQueryHandler {
private final Context mParent;
public QueryHandler(
ContentResolver contentResolver, Context parent) {
super(contentResolver);
mParent = parent;
}
@Override
protected void onQueryComplete(
int token, Object cookie, Cursor cursor) {
sendHander();
if (cursor != null) {
if (!cursor.moveToFirst()) {
// Let user know the SIM is empty
updateState(SHOW_EMPTY);
} else if (mListAdapter == null) {
// Note that the MessageListAdapter doesn't support auto-requeries. If we
// want to respond to changes we'd need to add a line like:
// mListAdapter.setOnDataSetChangedListener(mDataSetChangedListener);
// See ComposeMessageActivity for an example.
mListAdapter = new MessageSimListAdapter(mParent, cursor);
mMsgList.setAdapter(mListAdapter);
updateState(SHOW_LIST);
} else {
//mListAdapter.changeCursor(currentCursor);
updateState(SHOW_LIST);
}
//startManagingCursor(cursor);
} else {
// Let user know the SIM is empty
updateState(SHOW_EMPTY);
}
if ( currentCursor != null ) {
currentCursor.close();
}
currentCursor = cursor;
Log.d(TAG, "onQueryComplete() mCursor = " + currentCursor);
}
}
private void sendHander() {
Message message = new Message();
message.what = 1;
hander.sendMessage(message);
}
private Handler hander = new Handler() {
public void handleMessage(Message msg) {
if (msg.what == 1) {
if (null != progressDialog) {
progressDialog.hide();
}
}
}
};
}