【发布时间】:2014-05-23 05:56:15
【问题描述】:
我进行了研究,试图在我的应用程序之外获得警报 Dialog,但对我来说没有任何意义(我是 Android 的初学者)。我在我的应用程序中使用了一个基本计时器,我希望用户能够设置计时器,然后如果他们愿意,可以离开应用程序,当计时器完成时,无论他们在哪里,它都会在屏幕上弹出。
现在我可以让警报Dialog 显示在活动中。但是,如果您转到主屏幕并且计时器结束,则对话框不会出现在那里。任何想法如何让它在应用程序之外显示?我是否需要将此警报Dialog 代码放入其自己的类中(而不是在应用程序的另一个活动中,它现在所在的位置)?
这是警报Dialog 的代码。警报位于timerDone() 方法中,倒数第三个方法。
ZombieThemedActivity.java
package com.azurespot.disastertimer.app.themedactivities;
import android.app.Dialog;
import android.content.Intent;
import android.graphics.Color;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import com.azurespot.disastertimer.app.MainSelectorActivity.OnMediaPlayerUpdatedListener;
import com.azurespot.disastertimer.app.MainSelectorActivity;
import com.azurespot.disastertimer.app.R;
public class ZombieThemedActivity extends ActionBarActivity implements OnMediaPlayerUpdatedListener {
long start_time_seconds; //time user enters into timer in seconds (passed from main activity)
long remaining_time, remaining_time_paused; //keeps track of remaining time on timer
Boolean is_paused; //keeps track if timer is paused or not (to pause or restart timer)
TextView mTextField;
private CountDownTimer timer;
public MediaPlayer zombieDone;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_zombie_themed);
MainSelectorActivity.setOnMediaPlayerUpdatedListener(ZombieThemedActivity.this);
// The time in seconds from number picker that was send with the intent
Bundle bTimeSetSec = getIntent().getExtras(); // need to pass variable as a bundle !!!
start_time_seconds = bTimeSetSec.getInt("timeSetSecZ");
is_paused = false;
Log.i("DT", "Time is " + start_time_seconds + " in seconds Z");
SetUpTimer();
// Creates a visible pause button in themed activities, until toggle code
// in the PauseTimer() click method can take over
findViewById(R.id.btnPause).setBackgroundResource(R.drawable.ic_timer_pause);
}
// Interface
@Override
public void onMediaPlayerStopped() {
zombieDone.stop();
timer.cancel();
}
// This is a basic timer, but it counts down from time given
// Can maybe put a button click listener for pause, reset and save the millisUntilFinished
public void SetUpTimer() {
mTextField = (TextView) findViewById(R.id.txTimeCounting);
if (is_paused) {
// if pause button was hit then, stay on this screen, but use remaining time, not start time.
start_time_seconds = remaining_time_paused;
Log.i("DT","Is Paused state = " + is_paused);
}
timer = new CountDownTimer(start_time_seconds*1000, 1000) {
// since timer needs millisUntilFinished... the max of a long is 9223372036854775807seconds
public void onTick(long millisUntilFinished) {
// Convert seconds to hr/min/sec for message
// since millisUntilFinished is a long (>3billion) and modulus (%) is for ints, need to put a L at the end to tell it the number is literal and somehow allow ints.
remaining_time = millisUntilFinished/1000;
// Math.floor - will just get the opposite of the modulus (name?), requires double input.
// casting double -> int will result in getting rid of decimal (great, we don't have one!)
double remaining_time_double = (int)remaining_time;
int mHr = (int) Math.floor(remaining_time_double / 3600);
int mMin = (int) Math.floor((remaining_time_double-(3600*mHr)) / 60);
int mSec = (int) Math.floor(remaining_time_double-(3600*mHr)-(60*mMin));
// Convert int to string (and add a zero in front of int tht are <10 for looks
String smHr;
String smMin;
String smSec;
if (mHr < 10) {smHr = "0" + Integer.toString(mHr); } else { smHr = String.valueOf(mHr); }
if (mMin < 10) { smMin = "0" + String.valueOf(mMin); } else { smMin = String.valueOf(mMin); }
if (mSec < 10) { smSec = "0" + String.valueOf(mSec); } else { smSec = String.valueOf(mSec); }
Log.i("DT", "time is: " + smHr + ":" + smMin + ":" + smSec);
mTextField.setText(smHr + ":" + smMin + ":" + smSec);
// mTextField.setText(millisUntilFinished/1000 + " seconds");
if(millisUntilFinished <= 10000)
mTextField.setTextColor(Color.RED);
// if less than 10seconds make text red!
}
public void onFinish() {
mTextField.setText("BRAINS!!");
// call some media function here
MediaPlayer mp = MediaPlayer.create(ZombieThemedActivity.this, R.raw.zombie_sound);
mp.start();
zombieDone = mp;
// This disables the pause/play button when timer ends
Button disablePausePlay = (Button)findViewById(R.id.btnPause);
disablePausePlay.setEnabled(false);
timerDone();
}
};
timer.start();
}
public void PauseTimer (View v) {
// Dynamically creates the toggled buttons (without any xml)
switch(v.getId()){
case R.id.btnPause:
if(!is_paused){
// Removes set pause button from onCreate, and replaces with new one
v.setBackgroundResource(0);
v.setBackgroundResource(R.drawable.ic_timer_play);
}
else{
v.setBackgroundResource(R.drawable.ic_timer_pause);
}
}
// do something when the pause button is hit
// set IS_PAUSED to false (so when timer is called, it uses remaining time instead of start time.
// cancels current timer - set the time to display the paused time, re-labels the button to "Re-Start"
if (!is_paused) {
remaining_time_paused = remaining_time;
double paused_time = remaining_time_paused;
int mHr = (int) Math.floor(paused_time / 3600);
int mMin = (int) Math.floor((paused_time-(3600*mHr)) / 60);
int mSec = (int) Math.floor(paused_time-(3600*mHr)-(60*mMin));
// Convert int to string (and add a zero in front of int tht are <10 for looks
String smHr;
String smMin;
String smSec;
if (mHr < 10) {smHr = "0" + Integer.toString(mHr); } else { smHr = String.valueOf(mHr); }
if (mMin < 10) { smMin = "0" + String.valueOf(mMin); } else { smMin = String.valueOf(mMin); }
if (mSec < 10) { smSec = "0" + String.valueOf(mSec); } else { smSec = String.valueOf(mSec); }
// set the timer
Log.d("DT", "time is: " + smHr + ":" + smMin + ":" + smSec);
mTextField.setText(smHr + ":" + smMin + ":" + smSec);
is_paused = true;
timer.cancel();
Log.d("DT", "is paused hit yes, remaining time is " + remaining_time);
}
else {
SetUpTimer();
is_paused = false; // must reset the pause state AFTER calling the timer method
}
}
// This overrides the onPause() method so when back button is pressed,
// the music file stops and releases from memory, which means the object is gone
@Override
protected void onPause(){
super.onPause();
if (zombieDone != null) //add a null check here
{
if (zombieDone.isPlaying()) {
zombieDone.stop();
zombieDone.release();
// If this does nothing then the else is not needed
} else {
// Do nothing
}
}
}
public void ReturnToTimerScreen (View v) {
// RESET button is hit !!!!
// returns to first screen for selection of new time, must cancel timer
timer.cancel();
Intent iReset = new Intent(getBaseContext(), MainSelectorActivity.class);
startActivity(iReset);
Log.i("DT", "RESET button was hit");
}
public void timerDone() {
// Create custom dialog object
final Dialog dialog = new Dialog(ZombieThemedActivity.this);
// Include alert_popup.xml file
dialog.setContentView(R.layout.alert_popup);
// Set dialog title
dialog.setTitle("BRAINS!!!");
ImageView image = (ImageView) dialog.findViewById(R.id.imageView01);
image.setImageResource(R.drawable.ic_launcher_nuke);
dialog.show();
Button declineButton = (Button) dialog.findViewById(R.id.okbutton);
// if decline button is clicked, close the custom dialog
declineButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// Close dialog
dialog.dismiss();
timer.cancel();
zombieDone.stop();
zombieDone.release();
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.zombie_themed, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
【问题讨论】:
-
这样的事情是通过通知而不是通过警报对话框来实现的。当计时器用完时,您可以使用 NotificationManager 通知用户。然后,单击它,您可以启动一个活动左右。
-
哦,有趣。我也可以为此通知制作一个警报框吗?我们必须显示某种弹出图形,用户可以在其中按“确定”并关闭警报。
-
你也可以在通知栏中执行此操作,在这种情况下我认为诺丽更好
-
感谢 Mayank,这是否意味着链接页面希望我在其自己的 Activity 或类中拥有 Dialog(或者我应该使用 AlertDialog)?然后我只需将该代码添加到 Manifest 中就可以了?
标签: android timer android-alertdialog