有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java无法理解如何创建用于响铃报警的取消按钮

即使在按下停止报警按钮后,我仍无法停止报警。我不知道如何访问同一个Ringtone实例和call stop()

这是MainActivity java类中的启动报警开关

public void switchClicked(View view) {
    if (((Switch) view).isChecked()) {
        Log.d("MainActivity", "Alarm On");
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, alarmTimePicker.getHour());
        calendar.set(Calendar.MINUTE, alarmTimePicker.getMinute());
        Intent myIntent = new Intent(MainActivity.this, AlarmReceiver.class);
        pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, myIntent, 0);
        alarmManager.set(AlarmManager.RTC, calendar.getTimeInMillis(), pendingIntent);
        setAlarmText("ON");


    } else {
        alarmManager.cancel(pendingIntent);
        setAlarmText("OFF");
        Log.d("MainActivity", "Alarm Off");
    }
}

public void setAlarmText(String alarmText) {
    alarmTextView.setText(alarmText);
}

这是我在MainActivity java类中的StopAlarm按钮

public void stopAlarm(View view) {
        setAlarmText("Alarm stopped");
        Intent myIntent = new Intent(MainActivity.this, AlarmReceiver.class);
        pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        alarmManager.cancel(pendingIntent);
    }

这是AlarmReceiver java类

public class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(final Context context, Intent intent) {

    MainActivity inst = MainActivity.instance();
    inst.setAlarmText("Alarm! Wake up! Wake up!");
    Uri alarmUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
    if (alarmUri == null) {
        alarmUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    }
    Ringtone ringtone = RingtoneManager.getRingtone(context, alarmUri);
    ringtone.play();
}
}

共 (1) 个答案

  1. # 1 楼答案

    步骤:

    RingtonePlayingService添加到项目中(别忘了在清单中声明它)

    public class RingtonePlayingService extends Service{
    
        private Ringtone ringtone = null;
    
        @Override
        public int onStartCommand(Intent intent, int flags, int startId){
            Uri alarmUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
            if (alarmUri == null) 
                alarmUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
    
            this.ringtone = RingtoneManager.getRingtone(this, alarmUri);
            ringtone.play();
    
            return START_STICKY;
        }
    
        @Override
        public IBinder onBind(Intent intent){
            return null;
        }
    
        @Override
        public void onDestroy(){
            super.onDestroy();
            shutUpRingtone();
        }
    
        private void shutUpRingtone(){
            if(ringtone != null)
                ringtone.stop();
            ringtone = null;
        }
    }
    

    删除onReceive中的代码,并将其放入:

    @Override
    public void onReceive(final Context context, Intent intent) {
        Intent startIntent = new Intent(context, RingtonePlayingService.class);
        context.startService(startIntent);
    }
    

    现在RingtonePlayingService正在处理铃声播放,并不断引用它。您的stopAlarm方法只是取消潜在的挂起报警,因此,如果它在单击停止按钮之前尚未触发,它将永远不会触发。但当它已经开始响铃时,您应该停止启动服务持有的ringtone实例。在方法末尾添加:

    public void stopAlarm(View view) {
        ...
        Intent stopIntent = new Intent(context, RingtonePlayingService.class);
        stopService(stopIntent);
    }
    

    现在stopAlarm两个都做:取消挂起的报警(如果有)并停止服务(如果是活动的),这可能会播放铃声

    同时删除MainActivity.instance()模式,这是非常糟糕的。。。当你设置未来报警(例如,现在+1h)并且系统(或用户)在启动应用程序之前从内存中删除应用程序时,你将得到NullPointerException,因为.instance()null,你正在立即尝试访问inst.setAlarmText方法。您可以使用Local Broadcastingservice binding更新您的用户界面-从工作状态RingtonePlayingService向您的Activity发送广播/消息,并保持开始/停止/当前状态