1 /* 2 * Copyright (C) 2011 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 17 package com.android.cellbroadcastreceiver; 18 19 import android.app.AlertDialog; 20 import android.app.KeyguardManager; 21 import android.content.Context; 22 import android.content.DialogInterface; 23 import android.content.Intent; 24 import android.graphics.drawable.Drawable; 25 import android.os.Bundle; 26 import android.os.Handler; 27 import android.os.Message; 28 import android.view.WindowManager; 29 import android.widget.ImageView; 30 31 /** 32 * Custom alert dialog with optional flashing warning icon. 33 * Alert audio and text-to-speech handled by {@link CellBroadcastAlertAudio}. 34 */ 35 public class CellBroadcastAlertDialog extends AlertDialog { 36 37 /** Whether to show the flashing warning icon. */ 38 private final boolean mShowWarningIcon; 39 40 /** The broadcast delivery time, for marking as read (or 0). */ 41 private final long mDeliveryTime; 42 43 /** Length of time for the warning icon to be visible. */ 44 private static final int WARNING_ICON_ON_DURATION_MSEC = 800; 45 46 /** Length of time for the warning icon to be off. */ 47 private static final int WARNING_ICON_OFF_DURATION_MSEC = 800; 48 49 /** Warning icon state. false = visible, true = off */ 50 private boolean mIconAnimationState; 51 52 /** Stop animating icon after {@link #onStop()} is called. */ 53 private boolean mStopAnimation; 54 55 /** The warning icon Drawable. */ 56 private Drawable mWarningIcon; 57 58 /** The View containing the warning icon. */ 59 private ImageView mWarningIconView; 60 61 /** Keyguard lock to show emergency alerts while in the lock screen. */ 62 private KeyguardManager.KeyguardLock mKeyguardLock; 63 64 /** Icon animation handler for flashing warning alerts. */ 65 private final Handler mAnimationHandler = new Handler() { 66 @Override 67 public void handleMessage(Message msg) { 68 if (mIconAnimationState) { 69 mWarningIconView.setAlpha(255); 70 if (!mStopAnimation) { 71 mAnimationHandler.sendEmptyMessageDelayed(0, WARNING_ICON_ON_DURATION_MSEC); 72 } 73 } else { 74 mWarningIconView.setAlpha(0); 75 if (!mStopAnimation) { 76 mAnimationHandler.sendEmptyMessageDelayed(0, WARNING_ICON_OFF_DURATION_MSEC); 77 } 78 } 79 mIconAnimationState = !mIconAnimationState; 80 mWarningIconView.invalidateDrawable(mWarningIcon); 81 } 82 }; 83 84 /** 85 * Create a new alert dialog for the broadcast notification. 86 * @param context the local Context 87 * @param titleId the resource ID of the dialog title 88 * @param body the message body contents 89 * @param showWarningIcon true if the flashing warning icon should be shown 90 * @param deliveryTime the delivery time of the broadcast, for marking as read 91 */ CellBroadcastAlertDialog(Context context, int titleId, CharSequence body, boolean showWarningIcon, long deliveryTime)92 public CellBroadcastAlertDialog(Context context, int titleId, CharSequence body, 93 boolean showWarningIcon, long deliveryTime) { 94 super(context); 95 mShowWarningIcon = showWarningIcon; 96 mDeliveryTime = deliveryTime; 97 98 setTitle(titleId); 99 setMessage(body); 100 setCancelable(true); 101 setOnCancelListener(new AlertDialog.OnCancelListener() { 102 public void onCancel(DialogInterface dialog) { 103 dialog.dismiss(); 104 } 105 }); 106 setButton(DialogInterface.BUTTON_NEUTRAL, context.getText(R.string.button_dismiss), 107 new DialogInterface.OnClickListener() { 108 public void onClick(DialogInterface dialog, int whichButton) { 109 dialog.dismiss(); 110 } 111 }); 112 113 // Set warning icon for emergency alert 114 if (mShowWarningIcon) { 115 mWarningIcon = getContext().getResources().getDrawable(R.drawable.ic_warning_large); 116 setIcon(mWarningIcon); 117 } 118 } 119 120 @Override onCreate(Bundle savedInstanceState)121 protected void onCreate(Bundle savedInstanceState) { 122 if (mShowWarningIcon) { 123 // Turn screen on and show above the keyguard for emergency alert 124 getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED 125 | WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD 126 | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON 127 | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON 128 | WindowManager.LayoutParams.FLAG_ALLOW_LOCK_WHILE_SCREEN_ON); 129 } 130 super.onCreate(savedInstanceState); 131 if (mShowWarningIcon) { 132 KeyguardManager km = (KeyguardManager) 133 getContext().getSystemService(Context.KEYGUARD_SERVICE); 134 mKeyguardLock = km.newKeyguardLock("CellBroadcastReceiver"); 135 mWarningIconView = (ImageView) findViewById(com.android.internal.R.id.icon); 136 } 137 } 138 139 /** 140 * Start animating warning icon. 141 */ 142 @Override onStart()143 protected void onStart() { 144 if (mShowWarningIcon) { 145 // Disable keyguard 146 mKeyguardLock.disableKeyguard(); 147 // start icon animation 148 mAnimationHandler.sendEmptyMessageDelayed(0, WARNING_ICON_ON_DURATION_MSEC); 149 } 150 } 151 152 /** 153 * Stop animating warning icon and stop the {@link CellBroadcastAlertAudio} 154 * service if necessary. 155 */ 156 @Override onStop()157 protected void onStop() { 158 // Stop playing alert sound/vibration/speech (if started) 159 Context context = getContext(); 160 context.stopService(new Intent(context, CellBroadcastAlertAudio.class)); 161 // Start database service to mark broadcast as read 162 Intent intent = new Intent(context, CellBroadcastDatabaseService.class); 163 intent.setAction(CellBroadcastDatabaseService.ACTION_MARK_BROADCAST_READ); 164 intent.putExtra(CellBroadcastDatabaseService.DATABASE_DELIVERY_TIME_EXTRA, mDeliveryTime); 165 context.startService(intent); 166 if (mShowWarningIcon) { 167 // Reenable keyguard 168 mKeyguardLock.reenableKeyguard(); 169 // stop animating icon 170 mStopAnimation = true; 171 } 172 } 173 174 /** 175 * Ignore the back button for emergency alerts (user must dismiss with button). 176 */ 177 @Override onBackPressed()178 public void onBackPressed() { 179 if (!mShowWarningIcon) { 180 super.onBackPressed(); 181 } 182 } 183 } 184