【问题标题】:How do I get an alert Dialog to show outside of application?如何让警报对话框显示在应用程序之外?
【发布时间】: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 通知用户。然后,单击它,您可以启动一个活动左右。
  • 哦,有趣。我也可以为此通知制作一个警报框吗?我们必须显示某种弹出图形,用户可以在其中按“确定”并关闭警报。
  • 你也可以在通知栏中执行此操作,在这种情况下我认为诺丽更好
  • 答案在这个帖子里:stackoverflow.com/questions/2147144/…
  • 感谢 Mayank,这是否意味着链接页面希望我在其自己的 Activity 或类中拥有 Dialog(或者我应该使用 AlertDialog)?然后我只需将该代码添加到 Manifest 中就可以了?

标签: android timer android-alertdialog


【解决方案1】:

如果你想在应用程序之外发送消息,你必须使用 NotificationManager。

我建议你看看这个教程: http://www.vogella.com/tutorials/AndroidNotifications/article.html

【讨论】:

  • 感谢 CanDroid,我要试试这个,如果可以的话,我会检查你的回答是否正确。
  • 你好诺丽,谢谢。我也不知道您如何检查我的答案是否正确。 :)
  • 该死,本教程给出了运行时错误:java.lang.IllegalArgumentException: eglChooseConfig failed EGL_NOT_INITIALIZED,但我不明白为什么。在任何地方都找不到有关此错误的信息。
  • 实际上,这个错误是由于切换到新项目后没有重新启动我的模拟器造成的。我重新启动它,并让教程应用程序运行,但现在单击按钮并没有任何反应。我会继续努力的。
  • 我做了一个应用程序,也使用了通知管理器。我被试了很多次。 :) 我知道 Vogella 的教程很有效,你很快就能解决它。 :)
猜你喜欢
  • 2019-04-21
  • 1970-01-01
  • 1970-01-01
  • 2023-03-25
  • 2011-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多