Не могу понять, как создать кнопку отмены звонка будильника - PullRequest
0 голосов
/ 09 марта 2019

У меня проблемы с отключением сигнала будильника даже после нажатия кнопки «Стоп-сигнал».Я не могу понять, как получить доступ к одному и тому же экземпляру Ringtone и вызову 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);
}

Вот моя кнопка StopAlarmв Java-классе MainActivity.

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);
    }

Это Java-класс AlarmReciver.

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 Ответ

0 голосов
/ 11 марта 2019

шаги:

добавить 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(), это чертовски плохо ... Когда вы устанавливаете будильник (например, сейчас + 1 час) и система (или пользователь) удаляет приложение из памяти до того, как оно будет запущено, вы получите NullPointerException , поскольку .instance() равно null, и вы немедленно пытаетесь получить доступ к методу inst.setAlarmText. Некоторые из вас могут использовать Local Broadcasting или привязку службы для обновления вашего интерфейса пользователя - отправлять широковещательные сообщения / сообщения на ваш Activity с работы RingtonePlayingService с запуском / остановкой / текущим статусом

...