/* * Copyright (C) 2011 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.cellbroadcastreceiver; import android.app.AlertDialog; import android.app.ListActivity; import android.app.NotificationManager; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.os.Bundle; import android.view.ContextMenu; import android.view.ContextMenu.ContextMenuInfo; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.View.OnCreateContextMenuListener; import android.widget.ListView; import android.widget.TextView; /** * This activity provides a list view of received cell broadcasts. */ public class CellBroadcastListActivity extends ListActivity { private static final String TAG = "CellBroadcastListActivity"; // IDs of the main menu items. public static final int MENU_DELETE_ALL = 3; public static final int MENU_PREFERENCES = 4; // IDs of the context menu items for the list of broadcasts. public static final int MENU_DELETE = 0; public static final int MENU_VIEW = 1; private CellBroadcastListAdapter mListAdapter; private SQLiteDatabase mBroadcastDb; private Cursor mAdapterCursor; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.cell_broadcast_list_screen); ListView listView = getListView(); listView.setOnCreateContextMenuListener(mOnCreateContextMenuListener); if (mBroadcastDb == null) { CellBroadcastDatabase.DatabaseHelper helper = new CellBroadcastDatabase.DatabaseHelper(this); mBroadcastDb = helper.getReadableDatabase(); } if (mAdapterCursor == null) { mAdapterCursor = CellBroadcastDatabase.getCursor(mBroadcastDb); } mListAdapter = new CellBroadcastListAdapter(this, mAdapterCursor); setListAdapter(mListAdapter); CellBroadcastDatabaseService.setActiveListActivity(this); parseIntent(getIntent()); } @Override protected void onDestroy() { if (mAdapterCursor != null) { mAdapterCursor.close(); mAdapterCursor = null; } if (mBroadcastDb != null) { mBroadcastDb.close(); mBroadcastDb = null; } CellBroadcastDatabaseService.setActiveListActivity(null); super.onDestroy(); } /** Callback from CellBroadcastDatabaseService after content changes. */ void databaseContentChanged() { runOnUiThread(new Runnable() { public void run() { mAdapterCursor.requery(); } }); } @Override protected void onNewIntent(Intent intent) { // TODO: how do multiple messages stack together? // removeDialog(DIALOG_SHOW_MESSAGE); parseIntent(intent); } @Override public boolean onPrepareOptionsMenu(Menu menu) { menu.clear(); if (mListAdapter.getCount() > 0) { menu.add(0, MENU_DELETE_ALL, 0, R.string.menu_delete_all).setIcon( android.R.drawable.ic_menu_delete); } menu.add(0, MENU_PREFERENCES, 0, R.string.menu_preferences).setIcon( android.R.drawable.ic_menu_preferences); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch(item.getItemId()) { case MENU_DELETE_ALL: confirmDeleteThread(-1); break; case MENU_PREFERENCES: Intent intent = new Intent(this, CellBroadcastSettings.class); startActivityIfNeeded(intent, -1); break; default: return true; } return false; } @Override protected void onListItemClick(ListView l, View v, int position, long id) { Cursor cursor = mListAdapter.getCursor(); if (cursor != null && cursor.getPosition() >= 0) { showDialogAndMarkRead(cursor); } } private final OnCreateContextMenuListener mOnCreateContextMenuListener = new OnCreateContextMenuListener() { public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { menu.add(0, MENU_VIEW, 0, R.string.menu_view); menu.add(0, MENU_DELETE, 0, R.string.menu_delete); } }; @Override public boolean onContextItemSelected(MenuItem item) { Cursor cursor = mListAdapter.getCursor(); if (cursor != null && cursor.getPosition() >= 0) { switch (item.getItemId()) { case MENU_DELETE: confirmDeleteThread(cursor.getLong(CellBroadcastDatabase.COLUMN_ID)); break; case MENU_VIEW: showDialogAndMarkRead(cursor); break; default: break; } } return super.onContextItemSelected(item); } private void showDialogAndMarkRead(Cursor cursor) { CellBroadcastMessage cbm = CellBroadcastMessage.createFromCursor(cursor); boolean isAlertMessage = cbm.isPublicAlertMessage() || CellBroadcastConfigService .isOperatorDefinedEmergencyId(cbm.getMessageIdentifier()); // show emergency alerts with the warning icon, but don't play alert tone CellBroadcastAlertDialog dialog = new CellBroadcastAlertDialog(this, cbm.getDialogTitleResource(), cbm.getMessageBody(), isAlertMessage, cbm.getDeliveryTime()); dialog.show(); } /** * Start the process of putting up a dialog to confirm deleting a broadcast. * @param rowId the row ID of the broadcast to delete, or -1 to delete all broadcasts */ public void confirmDeleteThread(long rowId) { DeleteThreadListener listener = new DeleteThreadListener(rowId); confirmDeleteThreadDialog(listener, (rowId == -1), this); } /** * Build and show the proper delete broadcast dialog. The UI is slightly different * depending on whether there are locked messages in the thread(s) and whether we're * deleting a single broadcast or all broadcasts. * @param listener gets called when the delete button is pressed * @param deleteAll whether to show a single thread or all threads UI * @param context used to load the various UI elements */ public static void confirmDeleteThreadDialog(DeleteThreadListener listener, boolean deleteAll, Context context) { View contents = View.inflate(context, R.layout.delete_broadcast_dialog_view, null); TextView msg = (TextView)contents.findViewById(R.id.message); msg.setText(deleteAll ? R.string.confirm_delete_all_broadcasts : R.string.confirm_delete_broadcast); AlertDialog.Builder builder = new AlertDialog.Builder(context); builder.setTitle(R.string.confirm_dialog_title) .setIcon(android.R.drawable.ic_dialog_alert) .setCancelable(true) .setPositiveButton(R.string.button_delete, listener) .setNegativeButton(R.string.button_cancel, null) .setView(contents) .show(); } public class DeleteThreadListener implements OnClickListener { private final long mRowId; public DeleteThreadListener(long rowId) { mRowId = rowId; } public void onClick(DialogInterface dialog, int whichButton) { if (mRowId != -1) { // delete from database on a separate service thread Intent dbWriteIntent = new Intent(CellBroadcastListActivity.this, CellBroadcastDatabaseService.class); dbWriteIntent.setAction(CellBroadcastDatabaseService.ACTION_DELETE_BROADCAST); dbWriteIntent.putExtra(CellBroadcastDatabaseService.DATABASE_ROW_ID_EXTRA, mRowId); startService(dbWriteIntent); } else { // delete from database on a separate service thread Intent dbWriteIntent = new Intent(CellBroadcastListActivity.this, CellBroadcastDatabaseService.class); dbWriteIntent.setAction(CellBroadcastDatabaseService.ACTION_DELETE_ALL_BROADCASTS); startService(dbWriteIntent); } dialog.dismiss(); } } private void parseIntent(Intent intent) { if (intent == null) { return; } Bundle extras = intent.getExtras(); if (extras == null) { return; } CellBroadcastMessage cbm = extras.getParcelable(CellBroadcastMessage.SMS_CB_MESSAGE_EXTRA); int notificationId = extras.getInt(CellBroadcastAlertService.SMS_CB_NOTIFICATION_ID_EXTRA); // Dismiss the notification that brought us here. NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.cancel(notificationId); boolean isEmergencyAlert = cbm.isPublicAlertMessage() || CellBroadcastConfigService .isOperatorDefinedEmergencyId(cbm.getMessageIdentifier()); CellBroadcastAlertDialog dialog = new CellBroadcastAlertDialog(this, cbm.getDialogTitleResource(), cbm.getMessageBody(), isEmergencyAlert, cbm.getDeliveryTime()); dialog.show(); } }