CellBroadcastAlertFullScreen.java revision 00b87064abfb9d254fbbf72110643d2e626365e6
1/* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.cellbroadcastreceiver; 18 19import android.app.Activity; 20import android.app.NotificationManager; 21import android.content.Context; 22import android.content.Intent; 23import android.graphics.drawable.Drawable; 24import android.os.Bundle; 25import android.os.Handler; 26import android.os.Message; 27import android.view.LayoutInflater; 28import android.view.View; 29import android.view.Window; 30import android.view.WindowManager; 31import android.widget.Button; 32import android.widget.ImageView; 33import android.widget.TextView; 34 35/** 36 * Full-screen emergency alert with flashing warning icon. 37 * Alert audio and text-to-speech handled by {@link CellBroadcastAlertAudio}. 38 * Keyguard handling based on {@code AlarmAlertFullScreen} class from DeskClock app. 39 */ 40public class CellBroadcastAlertFullScreen extends Activity { 41 42 /** 43 * Intent extra for full screen alert launched from dialog subclass as a result of the 44 * screen turning off. 45 */ 46 static final String SCREEN_OFF = "screen_off"; 47 48 /** Whether to show the flashing warning icon. */ 49 private boolean mIsEmergencyAlert; 50 51 /** The cell broadcast message to display. */ 52 CellBroadcastMessage mMessage; 53 54 /** Length of time for the warning icon to be visible. */ 55 private static final int WARNING_ICON_ON_DURATION_MSEC = 800; 56 57 /** Length of time for the warning icon to be off. */ 58 private static final int WARNING_ICON_OFF_DURATION_MSEC = 800; 59 60 /** Warning icon state. false = visible, true = off */ 61 private boolean mIconAnimationState; 62 63 /** Stop animating icon after {@link #onStop()} is called. */ 64 private boolean mStopAnimation; 65 66 /** The warning icon Drawable. */ 67 private Drawable mWarningIcon; 68 69 /** The View containing the warning icon. */ 70 private ImageView mWarningIconView; 71 72 /** Icon animation handler for flashing warning alerts. */ 73 private final Handler mAnimationHandler = new Handler() { 74 @Override 75 public void handleMessage(Message msg) { 76 if (mIconAnimationState) { 77 mWarningIconView.setAlpha(255); 78 if (!mStopAnimation) { 79 mAnimationHandler.sendEmptyMessageDelayed(0, WARNING_ICON_ON_DURATION_MSEC); 80 } 81 } else { 82 mWarningIconView.setAlpha(0); 83 if (!mStopAnimation) { 84 mAnimationHandler.sendEmptyMessageDelayed(0, WARNING_ICON_OFF_DURATION_MSEC); 85 } 86 } 87 mIconAnimationState = !mIconAnimationState; 88 mWarningIconView.invalidateDrawable(mWarningIcon); 89 } 90 }; 91 92 @Override 93 protected void onCreate(Bundle savedInstanceState) { 94 super.onCreate(savedInstanceState); 95 96 final Window win = getWindow(); 97 98 // We use a custom title, so remove the standard dialog title bar 99 win.requestFeature(Window.FEATURE_NO_TITLE); 100 101 // Full screen alerts display above the keyguard and when device is locked. 102 win.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN 103 | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED 104 | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD); 105 106 // Turn on the screen unless we're being launched from the dialog subclass as a result of 107 // the screen turning off. 108 if (!getIntent().getBooleanExtra(SCREEN_OFF, false)) { 109 win.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON 110 | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 111 } 112 113 // Save message for passing from dialog to fullscreen activity, and for marking read. 114 mMessage = getIntent().getParcelableExtra( 115 CellBroadcastMessage.SMS_CB_MESSAGE_EXTRA); 116 117 updateLayout(mMessage); 118 } 119 120 protected int getLayoutResId() { 121 return R.layout.cell_broadcast_alert_fullscreen; 122 } 123 124 private void updateLayout(CellBroadcastMessage message) { 125 LayoutInflater inflater = LayoutInflater.from(this); 126 127 setContentView(inflater.inflate(getLayoutResId(), null)); 128 129 /* Initialize dialog text from alert message. */ 130 int titleId = message.getDialogTitleResource(); 131 setTitle(titleId); 132 ((TextView) findViewById(R.id.alertTitle)).setText(titleId); 133 ((TextView) findViewById(R.id.message)).setText(message.getFormattedMessageBody(this)); 134 135 /* dismiss button: close notification */ 136 findViewById(R.id.dismissButton).setOnClickListener( 137 new Button.OnClickListener() { 138 public void onClick(View v) { 139 dismiss(); 140 } 141 }); 142 143 mIsEmergencyAlert = message.isPublicAlertMessage() || CellBroadcastConfigService 144 .isOperatorDefinedEmergencyId(message.getServiceCategory()); 145 146 if (mIsEmergencyAlert) { 147 mWarningIcon = getResources().getDrawable(R.drawable.ic_warning_large); 148 mWarningIconView = (ImageView) findViewById(R.id.icon); 149 if (mWarningIconView != null) { 150 mWarningIconView.setImageDrawable(mWarningIcon); 151 } 152 153 // Dismiss the notification that brought us here 154 ((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)) 155 .cancel((int) message.getDeliveryTime()); 156 } 157 } 158 159 /** 160 * Start animating warning icon. 161 */ 162 @Override 163 protected void onStart() { 164 super.onStart(); 165 if (mIsEmergencyAlert) { 166 // start icon animation 167 mAnimationHandler.sendEmptyMessageDelayed(0, WARNING_ICON_ON_DURATION_MSEC); 168 } 169 } 170 171 /** 172 * Stop animating warning icon and stop the {@link CellBroadcastAlertAudio} 173 * service if necessary. 174 */ 175 void dismiss() { 176 // Stop playing alert sound/vibration/speech (if started) 177 stopService(new Intent(this, CellBroadcastAlertAudio.class)); 178 179 // Start database service to mark broadcast as read 180 Intent intent = new Intent(this, CellBroadcastDatabaseService.class); 181 intent.setAction(CellBroadcastDatabaseService.ACTION_MARK_BROADCAST_READ); 182 // Select by delivery time because we don't know the database row ID. 183 intent.putExtra(CellBroadcastDatabaseService.DATABASE_DELIVERY_TIME_EXTRA, 184 mMessage.getDeliveryTime()); 185 startService(intent); 186 187 if (mIsEmergencyAlert) { 188 // stop animating emergency alert icon 189 mStopAnimation = true; 190 } else { 191 // decrement unread non-emergency alert count 192 CellBroadcastReceiverApp.decrementUnreadAlertCount(); 193 } 194 finish(); 195 } 196 197 /** 198 * Ignore the back button for emergency alerts (overridden by alert dialog so that the dialog 199 * is dismissed). 200 */ 201 @Override 202 public void onBackPressed() { 203 // ignored 204 } 205} 206