无法弄清楚如何创建响铃警报的取消按钮
Cannot figure out how to create the cancel button for ringing alarm
即使我按下了停止警报按钮,我仍然无法阻止闹钟响起。我不知道如何访问同一个 Ringtone 实例并调用 stop()。
这是我在MainActivity中的启动闹钟开关javaclass.
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 中的 StopAlarm 按钮 java class。
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);
}
这是 AlarmReciver java class。
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();
}
}
步数:
将 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 Broadcasting or service binding 来更新您的 UI - 将 broadcasts/messages 从工作状态 RingtonePlayingService
发送到您的 Activity
,状态 start/stop/current
即使我按下了停止警报按钮,我仍然无法阻止闹钟响起。我不知道如何访问同一个 Ringtone 实例并调用 stop()。
这是我在MainActivity中的启动闹钟开关javaclass.
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 中的 StopAlarm 按钮 java class。
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);
}
这是 AlarmReciver java class。
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();
}
}
步数:
将 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 Broadcasting or service binding 来更新您的 UI - 将 broadcasts/messages 从工作状态 RingtonePlayingService
发送到您的 Activity
,状态 start/stop/current