无法弄清楚如何为警报创建取消按钮 [英] Cannot figure out how to create the cancel button for ringing alarm

查看:107
本文介绍了无法弄清楚如何为警报创建取消按钮的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

即使按了stopAlarm按钮,也无法阻止警报响起。我无法弄清楚如何访问相同的Ringtone实例并调用stop()。

I am having trouble to stop the alarm from ringing even after I have pressed the stopAlarm button. I cannot figure out how to get access to the same Ringtone instance and call stop().

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

This is my start alarm switch in MainActivity java class.

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按钮。

Here is my StopAlarm button in MainActivity 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类。

This is the 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 添加到您的项目中(不要忘了在清单中声明它)

add RingtonePlayingService to your project (don't forget to declare it in manifest)

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 并输入以下内容:

remove code you have inside onReceive and put this:

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

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

now RingtonePlayingService is handling ringtone playing and keeps reference to it. Your stopAlarm method is just cancelling potentially pending alarm, so if it didn't fired yet until stop button click it won't never fire. But when it started ringing already then you should stop ringtone instance held by started service. Add on the end of your method:

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

现在 stopAlarm 做两者:取消待处理的警报(如果有的话)并停止服务(如果有生命的话),该服务可能正在播放铃声

Now stopAlarm do both: cancels pending alarm (if any) and stops service (if is alive), which is potentially playing ringtone

还删除 MainActivity.instance( )模式,这真是太糟糕了……当您设置将来的警报(例如now + 1h)并且系统(或用户)在应用被触发之前将其从内存中删除时,您将得到 NullPointerException ,因为 .instance() null ,您会立即尝试访问 inst.setAlarmText 方法。您可以使用本地广播服务绑定以更新您的用户界面-将广播/消息发送到您的活动正在运行 RingtonePlayingService 并具有开始/停止/当前状态

also remove MainActivity.instance() pattern, it is bad as hell... When you set future alarm (e.g. now+1h) and system (or user) remove app from memory before it gets fired then you will get NullPointerException, as .instance() is null, and you are immediatelly trying to access inst.setAlarmText method. Intead of you may use Local Broadcasting or service binding to update your UI - send broadcasts/messages to your Activity from working RingtonePlayingService with start/stop/current status

这篇关于无法弄清楚如何为警报创建取消按钮的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆