/*
* Copyright (C) 2008 Esmertec AG.
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.mms.ui;
import com.android.mms.R;
import android.database.sqlite.SqliteWrapper;
import com.android.mms.transaction.MessagingNotification;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.AsyncQueryHandler;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.DialogInterface.OnClickListener;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.sqlite.SQLiteException;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.provider.Telephony.Sms;
import android.telephony.SmsManager;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import com.android.internal.telephony.IccCard;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneFactory;
import com.android.internal.telephony.TelephonyIntents;
/**
* Displays a list of the SMS messages stored on the ICC.
*/
public class ManageSimMessages extends Activity
implements View.OnCreateContextMenuListener {
private Uri mIccUri;
private static final String TAG = "ManageSimMessages";
private static final int MENU_COPY_TO_PHONE_MEMORY = 0;
private static final int MENU_DELETE_FROM_SIM = 1;
private static final int MENU_VIEW = 2;
private static final int OPTION_MENU_DELETE_ALL = 0;
private static final int OPTION_MENU_SIM_CAPACITY = 1;
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 ProgressDialog progressDialog;
private ContentResolver mContentResolver;
private Cursor mCursor = null;
private ListView mSimList;
private TextView mMessage;
private MessageListAdapter mListAdapter = null;
private AsyncQueryHandler mQueryHandler = null;
private Context mContext;
public static final int SIM_FULL_NOTIFICATION_ID = 234;
private int mPhoneId;
private SimContactsReceiver mReceiver ;
private ArrayList<String> selectState;
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
mContext=this;
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
mContentResolver = getContentResolver();
mQueryHandler = new QueryHandler(mContentResolver, this);
setContentView(R.layout.sim_list);
mSimList = (ListView) findViewById(R.id.messages);
mMessage = (TextView) findViewById(R.id.empty_message);
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);
Log.d(TAG, "[dlg]creat");
init();
}
@Override
protected void onNewIntent(Intent intent) {
setIntent(intent);
init();
}
private void init() {
MessagingNotification.cancelNotification(getApplicationContext(),
SIM_FULL_NOTIFICATION_ID);
Intent intent=getIntent();
mPhoneId=intent.getIntExtra(Phone.PHONE_ID,-1);
if (mPhoneId==-1) {
finish();
return;
}
if (mPhoneId==0) {
mIccUri=Uri.parse("content://sms/icc");
} else {
mIccUri=Uri.parse("content://sms/icc"+mPhoneId);
}
updateState(SHOW_BUSY);
Log.d(TAG, "init startQuery()");
startQuery();
}
private void showProgressDialog() {
if (null != progressDialog && progressDialog.isShowing()) {
Log.d(TAG, "[dlg]showProgressDialog hide");
progressDialog.hide();
}
if (!isFinishing()) {
progressDialog.show();
Log.d(TAG, "[dlg]showProgressDialog show");
}
}
private Handler hander = new Handler() {
public void handleMessage(Message msg) {
if (msg.what == 1) {
if (null != progressDialog) {
Log.d(TAG, "[dlg]handleMessage hide");
progressDialog.hide();
}
}
}
};
private class QueryHandler extends AsyncQueryHandler {
private final ManageSimMessages mParent;
public QueryHandler(
ContentResolver contentResolver, ManageSimMessages 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 MessageListAdapter(
mParent, cursor, mSimList, false, null);
mSimList.setAdapter(mListAdapter);
mSimList.setOnCreateContextMenuListener(mParent);
updateState(SHOW_LIST);
} else {
mListAdapter.changeCursor(cursor);
updateState(SHOW_LIST);
}
//startManagingCursor(mCursor);
} else {
// Let user know the SIM is empty
updateState(SHOW_EMPTY);
}
if ( mCursor != null && !mCursor.isClosed() ) {
mCursor.close();
}
mCursor = cursor;
Log.d(TAG, "onQueryComplete() mCursor = " + mCursor);
}
/*fixed by luning for CR<NEWMS00139156> at 2011.11.11*/
protected void onDeleteComplete(int token, Object cookie, int result) {
super.onDeleteComplete(token, cookie, result);
if (selectState != null && selectState.size() > 0) {
Log.d(TAG, "onChange DelAllPending");
String cursorIndxe = selectState.get(0);
deleteFromSim(cursorIndxe);
selectState.remove(cursorIndxe);
} else {
Log.d(TAG, "onChange refreshMessageList");
refreshMessageList();
}
}
}
private void startQuery() {
try {
mQueryHandler.startQuery(0, null, mIccUri, null, null, null, null);
} catch (SQLiteException e) {
SqliteWrapper.checkSQLiteException(this, e);
}
}
private void refreshMessageList() {
updateState(SHOW_BUSY);
if (mCursor != null) {
//stopManagingCursor(mCursor);
mCursor.close();
}
Log.d(TAG, "refreshMessageList startQuery()");
startQuery();
}
@Override
public void onCreateContextMenu(
ContextMenu menu, View v,
ContextMenu.ContextMenuInfo menuInfo) {
menu.add(0, MENU_COPY_TO_PHONE_MEMORY, 0,
R.string.sim_copy_to_phone_memory);
menu.add(0, MENU_DELETE_FROM_SIM, 0, R.string.sim_delete);
// TODO: Enable this once viewMessage is written.
// menu.add(0, MENU_VIEW, 0, R.string.sim_view);
}
@Override
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo info;
try {
info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
} catch (ClassCastException exception) {
Log.e(TAG, "Bad menuInfo.", exception);
return false;
}
final Cursor cursor = (Cursor) mListAdapter.getItem(info.position);
switch (item.getItemId()) {
case MENU_COPY_TO_PHONE_MEMORY:
copyToPhoneMemory(cursor);
return true;
case MENU_DELETE_FROM_SIM:
confirmDeleteDialog(new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
if(cursor.isClosed()){
Toast.makeText(mContext,mContext.getResources().getString(R.string.sms_init),/*fixed CR<NEWMS00133563> by luning*/
Toast.LENGTH_SHORT).show();
} else {
Log.d(TAG, "delete one message");
updateState(SHOW_BUSY);
deleteFromSim(getMessageIndexString(cursor));
}
}
}, R.string.confirm_delete_SIM_message);
sendHander();
return true;
case MENU_VIEW:
viewMessage(cursor);
return true;
}
return super.onContextItemSelected(item);
}
@Override
public void onResume() {
super.onResume();
//for bugzilla 13356
final TelephonyManager telManager = (TelephonyManager) getSystemService(
PhoneFactory.getServiceName(Context.TELEPHONY_SERVICE, mPhoneId));
if(TelephonyManager.SIM_STATE_READY != telManager.getSimState()){
finish();
}
mReceiver = new SimContactsReceiver();
IntentFilter filter = new IntentFilter(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
this.registerReceiver(mReceiver, filter);
}
private class SimContactsReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
if (intent == null) {
return;
}
String state = intent.getStringExtra(IccCard.INTENT_KEY_ICC_STATE);
int phoneId = intent.getIntExtra(IccCard.INTENT_KEY_PHONE_ID, -1);
final TelephonyManager telManager = (TelephonyManager) getSystemService(
PhoneFactory.getServiceName(Context.TELEPHONY_SERVICE, mPhoneId));
Log.i(TAG, "phoneId=" + phoneId + ", state="+state);
if(phoneId==mPhoneId && TelephonyManager.SIM_STATE_READY != telManager.getSimState()){
ManageSimMessages.this.finish();
}
}
}
@Override
public void onPause() {
super.onPause();
this.unregisterReceiver(mReceiver);
}
private void copyToPhoneMemory(Cursor cursor) {
String address = cursor.getString(
cursor.getColumnIndexOrThrow("address"));
String body = cursor.getString(cursor.getColumnIndexOrThrow("body"));
Long date = cursor.getLong(cursor.getColumnIndexOrThrow("date"));
try {
if (isIncomingMessage(cursor)) {
Sms.Inbox.addMessage(mContentResolver, address, body, null, date, true /* read */);
} else {
Sms.Sent.addMessage(mContentResolver, address, body, null, date);
}
Toast.makeText(this, R.string.move_message_to_phone_memory, Toast.LENGTH_SHORT).show();
} catch (SQLiteException e) {
Toast.makeText(this, R.string.can_not_copy_the_message, Toast.LENGTH_SHORT).show();
SqliteWrapper.checkSQLiteException(this, e);
}
}
private boolean isIncomingMessage(Cursor cursor) {
int messageStatus = cursor.getInt(
cursor.getColumnIndexOrThrow("status"));
return (messageStatus == SmsManager.STATUS_ON_ICC_READ) ||
(messageStatus == SmsManager.STATUS_ON_ICC_UNREAD);
}
private void deleteFromSim(String messageIndexString) {
Uri simUri = mIccUri.buildUpon().appendPath(messageIndexString).build();
mQueryHandler.startDelete(0, null, simUri, null, null);/*add by luning for CR<NEWMS00139156> at 2011.11.11*/
}
private void deleteAllFromSim() {
Cursor delCursor = (Cursor) mListAdapter.getCursor();
selectState = new ArrayList<String>();
if (delCursor != null) {
if (delCursor.moveToFirst()) {
String messageIndexString = getMessageIndexString(delCursor);
selectState.add(messageIndexString);
while (delCursor.moveToNext()) {
messageIndexString = getMessageIndexString(delCursor);
selectState.add(messageIndexString);
}
deleteFromSim(messageIndexString);
selectState.remove(messageIndexString);
}
}
}
private String getMessageIndexString (Cursor delCursor) {
String messageIndexString = delCursor.getString(delCursor
.getColumnIndexOrThrow("index_on_icc"));
return messageIndexString;
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
menu.clear();
if ((null != mCursor) && (mCursor.getCount() > 0) && mState == SHOW_LIST) {
menu.add(0, OPTION_MENU_DELETE_ALL, 0, R.string.menu_delete_messages).setIcon(
android.R.drawable.ic_menu_delete);
}
menu.add(0, OPTION_MENU_SIM_CAPACITY, 0, R.string.menu_sim_capacity).setIcon(
android.R.drawable.ic_menu_save);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case OPTION_MENU_DELETE_ALL:
confirmDeleteDialog(new OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Log.d(TAG, "delete all messages");
updateState(SHOW_BUSY);
deleteAllFromSim();
dialog.dismiss();
}
}, R.string.confirm_delete_all_SIM_messages);
sendHander();
break;
case OPTION_MENU_SIM_CAPACITY:
String capacityDetails = getCapacityDetails(this,this.mPhoneId);
//getCapacityDetails
viewCapacityDialog(capacityDetails);
break;
}
return true;
}
private void confirmDeleteDialog(OnClickListener listener, int messageId) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.confirm_dialog_title);
builder.setIcon(android.R.drawable.ic_dialog_alert);
builder.setCancelable(true);
builder.setPositiveButton(R.string.yes, listener);
builder.setNegativeButton(R.string.no, null);
builder.setMessage(messageId);
builder.show();
}
private void viewCapacityDialog(String detailstring) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle(R.string.menu_sim_capacity);
builder.setCancelable(true);
builder.setPositiveButton(R.string.yes, null);
builder.setMessage(detailstring);
builder.show();
}
private static String getCapacityDetails(Context context,int phoneId) {
StringBuilder details = new StringBuilder();
Resources res = context.getResources();
//SmsManager smsManager = SmsManager.getDefault(phoneId);
SmsManager smsManager = SmsManager.getDefault(phoneId);
String capaStr = smsManager.getSimCapacity();
Log.d(TAG, "[sms]getSimCapacity =" + capaStr);
String[] splitStr = capaStr.split(":");
details.append(res.getString(R.string.menu_sim_capacity_used));
Log.d(TAG, "[sms]getSimCapacity simUsed:" + splitStr[0]);
Log.d(TAG, "[sms]getSimCapacity simTotal:" + splitStr[1]);
details.append(splitStr[0]);
details.append('\n');
details.append(res.getString(R.string.menu_sim_capacity_total));
details.append(splitStr[1]);
return details.toString();
}
private void updateState(int state) {
showProgressDialog();
if (mState == state) {
return;
}
mState = state;
switch (state) {
case SHOW_LIST:
mSimList.setVisibility(View.VISIBLE);
mMessage.setVisibility(View.GONE);
if(MessageUtils.isMSMS){
if(mPhoneId == 0){
setTitle(getString(R.string.sim_manage_messages_title1));
}else if(mPhoneId == 1){
setTitle(getString(R.string.sim_manage_messages_title2));
}else{
//do nothing
}
}else{
setTitle(getString(R.string.sim_manage_messages_title));
}
setProgressBarIndeterminateVisibility(false);
break;
case SHOW_EMPTY:
mSimList.setVisibility(View.GONE);
mMessage.setVisibility(View.VISIBLE);
if(MessageUtils.isMSMS){
if(mPhoneId == 0){
setTitle(getString(R.string.sim_manage_messages_title1));
}else if(mPhoneId == 1){
setTitle(getString(R.string.sim_manage_messages_title2));
}else{
//do nothing
}
}else{
setTitle(getString(R.string.sim_manage_messages_title));
}
setProgressBarIndeterminateVisibility(false);
break;
case SHOW_BUSY:
mSimList.setVisibility(View.GONE);
mMessage.setVisibility(View.GONE);
setTitle(getString(R.string.refreshing));
setProgressBarIndeterminateVisibility(true);
break;
default:
Log.e(TAG, "Invalid State");
}
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mCursor != null) {
mCursor.close();
}
Log.d(TAG, "[dlg]onDestroy");
if (null != progressDialog && progressDialog.isShowing()) {
Log.d(TAG, "[dlg]dismiss");
progressDialog.dismiss();
}
if (mListAdapter != null) {
mListAdapter.changeCursor(null);
}
}
private void viewMessage(Cursor cursor) {
// TODO: Add this.
}
private void sendHander(){
Message message = new Message();
message.what = 1;
hander.sendMessage(message);
}
}