当前位置: 首页 > 知识库问答 >
问题:

前台计时器停止时发送通知

柴兴修
2023-03-14

我在创建计时器点击00:00时发送通知的方法时遇到一些问题。

我的意思是,我希望当计时器结束时,如果应用程序关闭,它会发送一个通知事件。

我已经找到了一种方法来显示通知,并使计时器即使在应用程序关闭时也能工作。

但当我把功能发送通知在计时器的末尾它只工作时,应用程序打开。

这是我的主要活动。JAVA

   @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        notificationManager = NotificationManagerCompat.from(this);


        mTextViewCountDown = findViewById(R.id.timerTv);
        mButtonStartPause = findViewById(R.id.btn_start_pause);
        mButtonReset =  findViewById(R.id.btn_reset);



        mButtonStartPause.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if (mTimerRunning) {
                    pauseTimer();
                } else {
                    startTimer();
                }


            }
        });
        mButtonReset.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                resetTimer();
            }
        });


    }







    private void startTimer() {
        mEndTime = System.currentTimeMillis() + mTimeLeftInMillis;
        mCountDownTimer = new CountDownTimer(mTimeLeftInMillis, 1000) {
            @Override
            public void onTick(long millisUntilFinished) {
                mTimeLeftInMillis = millisUntilFinished;
                updateCountDownText();
            }
            @Override
            public void onFinish() {
                mTimeLeftInMillis=0;
                updateCountDownText();
                mTimerRunning = false;
                updateButtons();


                Notification notification = new NotificationCompat.Builder(getApplicationContext(), CHANNEL_1_ID)
                        .setSmallIcon(R.drawable.ic_money)
                        .setContentTitle("Test 1")
                        .setContentText("Important Message")
                        .setPriority(NotificationCompat.PRIORITY_HIGH)
                        .setCategory(NotificationCompat.CATEGORY_MESSAGE)
                        .build();
                notificationManager.notify(1, notification);

            }
        }.start();
        mTimerRunning = true;
        updateButtons();
    }
    private void pauseTimer() {
        mCountDownTimer.cancel();
        mTimerRunning = false;
        updateButtons();
    }
    private void resetTimer() {
        mTimeLeftInMillis = START_TIME_IN_MILLIS;
        updateCountDownText();
        updateButtons();
    }
    private void updateCountDownText() {
        int minutes = (int) (mTimeLeftInMillis / 1000) / 60;
        int seconds = (int) (mTimeLeftInMillis / 1000) % 60;
        String timeLeftFormatted = String.format(Locale.getDefault(), "%02d:%02d", minutes, seconds);
        mTextViewCountDown.setText(timeLeftFormatted);
    }
    private void updateButtons() {
        if (mTimerRunning) {
            mButtonReset.setVisibility(View.INVISIBLE);
            mButtonStartPause.setText("Pause");
        } else {
            mButtonStartPause.setText("Start");
            if (mTimeLeftInMillis < 1000) {
                mButtonStartPause.setVisibility(View.INVISIBLE);
            } else {
                mButtonStartPause.setVisibility(View.VISIBLE);
            }
            if (mTimeLeftInMillis < START_TIME_IN_MILLIS) {
                mButtonReset.setVisibility(View.VISIBLE);
            } else {
                mButtonReset.setVisibility(View.INVISIBLE);
            }
        }
    }
    @Override
    public void onStop() {
        super.onStop();
        SharedPreferences prefs = getSharedPreferences("pref", MODE_PRIVATE);
        SharedPreferences.Editor editor = prefs.edit();
        editor.putLong("millisLeft", mTimeLeftInMillis);
        editor.putBoolean("timerRunning", mTimerRunning);
        editor.putLong("endTime", mEndTime);
        editor.apply();
        if (mCountDownTimer != null) {
            mCountDownTimer.cancel();
        }

    }
    @Override
    public void onStart() {
        super.onStart();
        SharedPreferences prefs = getSharedPreferences("pref", MODE_PRIVATE);
        mTimeLeftInMillis = prefs.getLong("millisLeft", START_TIME_IN_MILLIS);
        mTimerRunning = prefs.getBoolean("timerRunning", false);
        updateCountDownText();
        updateButtons();
        if (mTimerRunning) {
            mEndTime = prefs.getLong("endTime", 0);
            mTimeLeftInMillis = mEndTime - System.currentTimeMillis();
            if (mTimeLeftInMillis < 0) {
                mTimeLeftInMillis = 0;
                mTimerRunning = false;
                updateCountDownText();
                updateButtons();
            } else {
                startTimer();
            }
        }
    }


}

AppJava类

public class App extends Application {
    public static final String CHANNEL_1_ID = "channel1";
    @Override
    public void onCreate() {
        super.onCreate();
        createNotificationChannels();
    }
    private void createNotificationChannels() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel1 = new NotificationChannel(
                    CHANNEL_1_ID,
                    "Channel 1",
                    NotificationManager.IMPORTANCE_HIGH
            );

            NotificationManager manager = getSystemService(NotificationManager.class);
            manager.createNotificationChannel(channel1);
        }
    }
}

AndroidManifest。xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.krisix.notificationtest">

    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />


    <application
        android:name=".App"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        
        <service android:name=".ExampleService"/>
    </application>

</manifest>

谢谢你的帮助!

祝你有愉快的一天

克里斯

共有1个答案

晁国发
2023-03-14

谢谢你的帮助对不起,我是初学者,所以我不确定我是否理解你告诉我的所有事情。你是指这样的事情吗?

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        notificationManager = NotificationManagerCompat.from(this);


        mTextViewCountDown = findViewById(R.id.timerTv);
        mButtonStartPause = findViewById(R.id.btn_start_pause);
        mButtonReset =  findViewById(R.id.btn_reset);



        mButtonStartPause.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if (mTimerRunning) {
                    pauseTimer();
                } else {
                    startTimer();
                }


            }
        });
        mButtonReset.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                resetTimer();
            }
        });


    }


    private void startTimer() {
        mEndTime = System.currentTimeMillis() + mTimeLeftInMillis;
        mCountDownTimer = new CountDownTimer(mTimeLeftInMillis, 1000) {
            @Override
            public void onTick(long millisUntilFinished) {
                mTimeLeftInMillis = millisUntilFinished;
                updateCountDownText();
            }
            @Override
            public void onFinish() {
                mTimeLeftInMillis=0;
                updateCountDownText();
                mTimerRunning = false;
                updateButtons();

                if(mTimeLeftInMillis==0){
                    callNotification();
                }

            }
        }.start();
        mTimerRunning = true;
        updateButtons();
    }
    private void pauseTimer() {
        mCountDownTimer.cancel();
        mTimerRunning = false;
        updateButtons();
    }
    private void resetTimer() {
        mTimeLeftInMillis = START_TIME_IN_MILLIS;
        updateCountDownText();
        updateButtons();
    }
    private void updateCountDownText() {
        int minutes = (int) (mTimeLeftInMillis / 1000) / 60;
        int seconds = (int) (mTimeLeftInMillis / 1000) % 60;
        String timeLeftFormatted = String.format(Locale.getDefault(), "%02d:%02d", minutes, seconds);
        mTextViewCountDown.setText(timeLeftFormatted);
    }
    private void updateButtons() {
        if (mTimerRunning) {
            mButtonReset.setVisibility(View.INVISIBLE);
            mButtonStartPause.setText("Pause");
        } else {
            mButtonStartPause.setText("Start");
            if (mTimeLeftInMillis < 1000) {
                mButtonStartPause.setVisibility(View.INVISIBLE);
            } else {
                mButtonStartPause.setVisibility(View.VISIBLE);
            }
            if (mTimeLeftInMillis < START_TIME_IN_MILLIS) {
                mButtonReset.setVisibility(View.VISIBLE);
            } else {
                mButtonReset.setVisibility(View.INVISIBLE);
            }
        }
    }
    @Override
    public void onStop() {
        super.onStop();
        SharedPreferences prefs = getSharedPreferences("pref", MODE_PRIVATE);
        SharedPreferences.Editor editor = prefs.edit();
        editor.putLong("millisLeft", mTimeLeftInMillis);
        editor.putBoolean("timerRunning", mTimerRunning);
        editor.putLong("endTime", mEndTime);
        editor.apply();
        if (mCountDownTimer != null) {
            mCountDownTimer.cancel();
        }



    }


    @Override
    public void onStart() {
        super.onStart();
        SharedPreferences prefs = getSharedPreferences("pref", MODE_PRIVATE);
        mTimeLeftInMillis = prefs.getLong("millisLeft", START_TIME_IN_MILLIS);
        mTimerRunning = prefs.getBoolean("timerRunning", false);
        updateCountDownText();
        updateButtons();
        if (mTimerRunning) {
            mEndTime = prefs.getLong("endTime", 0);
            mTimeLeftInMillis = mEndTime - System.currentTimeMillis();
            if (mTimeLeftInMillis < 0) {
                mTimeLeftInMillis = 0;
                mTimerRunning = false;
                updateCountDownText();
                updateButtons();
            } else {
                startTimer();
            }
        }
    }

    public void callNotification(){
        Notification notification = new NotificationCompat.Builder(getApplicationContext(), CHANNEL_1_ID)
                .setSmallIcon(R.drawable.ic_money)
                .setContentTitle("Test 1")
                .setContentText("Important Message")
                .setPriority(NotificationCompat.PRIORITY_HIGH)
                .setCategory(NotificationCompat.CATEGORY_MESSAGE)
                .build();
        notificationManager.notify(1, notification);
    }

}
 类似资料:
  • 问题内容: 我已将一个WAR文件部署到Tomcat服务器,该类之一将在启动时调用,然后init()方法将安排一个计时器,每5小时触发一次以执行一些任务。 我的init()代码如下所示: 我的应用程序运行没有问题,但是当我使用 /etc/init.d/tomcat7 stop 关闭Tomcat时,我检查了日志(catalina.out),它具有以下条目: 严重:Web应用程序[/ MyApplica

  • 问题内容: 我需要一些有关在PHP中启动和停止计时器的信息。我需要测量从我的.exe程序开始(我在PHP脚本中使用函数)到完成执行并显示所花费的时间(以秒为单位)之后经过的时间。 我怎样才能做到这一点? 问题答案: 您可以使用并计算差异: 这是PHP的文档:http : //php.net/manual/zh/function.microtime.php

  • 我正在用摇摆计时器打卡NetBeans: 我只是用System.out.print来测试程序,它不是真正程序的一部分。我调用停止()方法,但计时器继续计数。此外,我通过但它的计数速度是原来的两倍。有人能帮忙吗? 编辑: 这是我的计时器(有点像SSCCE): 它不能正常工作,因为秒没有出现,但它确实显示了20次,这就是我想要的。这只是在它自己的应用程序中,在我的实际程序中更容易看到问题。 我注意到游

  • 我有一个Swing计时器(javax.swing.Timer),用于在自定义Swing组件中执行一些动画。 然而,这会导致问题——特别是,即使在所有窗口都关闭后,它似乎也会阻止应用程序终止,因为实时计时器线程。此外,当看不到动画时,最好避免计时器在隐藏对象上运行的开销。 理想情况下,我希望做到以下几点: < li >当组件隐藏时停止计时器 < li >每当组件变得可见时,重新启动计时器 这是可能的

  • 所以我在firebase消息传递中经历了一个奇怪的行为。我在我的firebase messaging FCM调用中同时发送[通知]和[数据]对象,当应用程序在后台时,我可以接收到我调用FCM请求的多个推送通知。但现在的问题是,当我在打开应用程序时收到推送通知时,如果我点击了该通知,我将不再收到任何进一步的推送通知。 注意:如果我强行停止然后重新打开,我会再次开始收到通知。 我在几个安卓版本的安卓设

  • 我正在制作一个简单的页面,您可以扫描或键入一个UPC,它会自动添加到一个表中以供显示。我放弃了一些代码来启动一个计时器,它在键入完成后等待3秒,然后在我的表中创建一个新行来显示键入的UPC和项目信息。 但是,这段代码有一些问题。(我的问题) a.)当您手动输入UPC时,新行操作会发生多次(为同一UPC插入多行),但当您使用条形码扫描器扫描UPC时,它只完成一次操作。(这是正确的) b)当您从字段中