如何在收到PendingIntent后停止执行警报 - Android

时间:2017-07-28 19:31:19

标签: android alarmmanager android-pendingintent

在关闭此问题或根据标题标记为重复之前,它与使用AlarmManager和PendingIntent"的常规"取消警报不同。的问题。

我有能力创建和取消待定意图,只要它们在未来设置一段时间并且还没有结束。我使用以下终端命令对此进行测试,以便在创建警报之前以及之后查看PendingIntent

adb shell dumpsys alarm

以下是我在自定义Alarm类中安排警报的代码:

/**
 * Schedules a PendingIntent for the alarm.
 * @param context Activity context
 */
public void scheduleAlarm(Context context) {
    AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    Intent intent = new Intent(context, MyBroadcastReceiver.class);

    Gson g = new Gson();
    String s = g.toJson(this);
    intent.putExtra("alarm", s);
    String id = this.getId().replaceAll("[^0-9]+", "");
    PendingIntent alarmIntent = PendingIntent.getBroadcast(context, Integer.parseInt(id), intent, PendingIntent.FLAG_UPDATE_CURRENT);

    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(System.currentTimeMillis());
    calendar.set(Calendar.HOUR_OF_DAY, this.getHour());
    calendar.set(Calendar.MINUTE, this.getMinute());

    long calendarTime = calendar.getTimeInMillis();
    am.setExact(AlarmManager.RTC_WAKEUP, calendarTime, alarmIntent);
}

毫不奇怪,在创建警报之前,终端输出中没有关于我的应用程序警报的未决意图。创建警报后,终端输出中有1个与我的应用程序相关的待处理意图,如下所示:

  

+ Batch {b28a2db num = 1 start = 619295497 end = 619385497}:+ RTC#0:Alarm {24e4178 tag

     

闹钟:com.google.android.location.internal.action.ULR_BAROMETER_READ_ALARM输入1501206840000 com.google.android.gms}时的类型1 +

     

tag = 闹钟:com.google.android.location.internal.action.ULR_BAROMETER_READ_ALARM + type = 1 whenElapsed = + 1m59s428ms when = 2017-07-27 21:54:00 + window = + 1m30s0ms repeatInterval = 120000 count = 0 flags = 0x0 +

     

operation = PendingIntent {cb99ddd:PendingIntentRecord {f0fbd52

     

com.google.android.gms startService}}

注意我现在无法访问我的家用电脑,所以我无法准确发布我的应用程序的内容,所以我只是抓住了PendingIntent用于其他应用程序,但它是相同的结构。

我在使用下面的代码关闭之前取消了警报,从之前重新启用了adb命令,并且待处理的意图不再在终端输出中,所以一切都运行良好。

以下是取消闹钟的代码:

/**
 * Cancels the PendingIntent for the alarm.
 * @param context
 */
public void cancelAlarm(Context context) {
    AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    Intent intent = new Intent(context, MyBroadcastReceiver.class);
    intent.putExtra("alarm", this);
    String id = this.getId().replaceAll("[^0-9]+", "");
    PendingIntent alarmIntent = PendingIntent.getBroadcast(context, Integer.parseInt(id), intent, 0);
    alarmIntent.cancel();
    am.cancel(alarmIntent);
}

现在,如果达到PendingIntent(BroadcastReceiver运行其onReceive()代码并打开自定义活动),当我重新运行adb命令时,我在终端输出中得到以下条目:

  
      
  • u0a149:com.my.app + 172ms正在运行,0次唤醒:      
        
    • + 172ms 0唤醒3个警报,持续-5d8h25m0s423ms:
    •   
    • 报警:com.google.firebase.INSTANCE_ID_EVENT
    •   
  •   

但我无法再像预期的那样看到PendingIntent。无论我是否运行cancelAlarm()代码,此条目将始终保留在此处

这样做的结果是,每当我打开应用程序后PendingIntent已经关闭了#34;我的BroadcastReceiver类运行它的代码,应用程序就好像警报一直在关闭,所以它反复这样做,但就像我说的那样adb输出中没有PendingIntent条目。我想知道如何关闭此警报或“解雇”#34;如果你愿意的话。

这是我的BroadcastReceiver类:

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

        String alarm = intent.getStringExtra("alarm");

        Intent myIntent = new Intent();
        Toast.makeText(context, "Alarm is 1: " + alarm, Toast.LENGTH_SHORT).show();
        myIntent.setClassName("com.my.package.name", "com.my.package.name.AlarmReceivedActivity");
        myIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        myIntent.putExtra("alarm", alarm);

        context.startActivity(myIntent);
    }
}

这是我的AlarmReceivedActivity:

public class AlarmReceivedActivity extends AppCompatActivity {

    private Alarm alarmReceived;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_alarm_received);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        TextView tvTime = (TextView) findViewById(R.id.tv_time);
        String lTime = "11:05";
        tvTime.setText(lTime);

        Intent intent = getIntent();
        String s = intent.getStringExtra("alarm");
        Toast.makeText(getApplicationContext(), "Alarm is: " + s, Toast.LENGTH_SHORT).show();
        Gson g = new Gson();
        alarmReceived = g.fromJson(s, Alarm.class);

        Uri ringtoneUri = Uri.parse(alarmReceived.getRingtone());
        Toast.makeText(getApplicationContext(), "Ringtone is: " + alarmReceived.getRingtone(), Toast.LENGTH_SHORT).show();
        try {
            MediaPlayer mMediaPlayer = new MediaPlayer();
            mMediaPlayer.setDataSource(this, ringtoneUri);
            final AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
            if (audioManager.getStreamVolume(AudioManager.STREAM_ALARM) != 0) {
                mMediaPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);
                mMediaPlayer.setLooping(false);
                mMediaPlayer.prepare();
                mMediaPlayer.start();
            }
        } catch (Exception e) {
            Toast.makeText(getApplicationContext(), "Failed to play ringtone", Toast.LENGTH_SHORT).show();
        }
    }

    public void dismissButtonClick(View view) {
        Context context = getApplicationContext();
        alarmReceived.cancelAlarm(context);
        alarmReceived.setIsSet(false);
        writeAlarmToSharedPrefs(alarmReceived, context);
        alarmReceived.cancelAlarm(context);
        System.exit(0);
    }

    private void writeAlarmToSharedPrefs(Alarm alarmReceived, Context context) {
        String alarm = getAlarmObjectAsJson(alarmReceived);
        SharedPreferences sPrefs = getApplicationContext().getSharedPreferences("Sleepin", MODE_PRIVATE);
        SharedPreferences.Editor pe = sPrefs.edit();
        pe.putString(alarmReceived.getId(), alarm);
        pe.apply();
    }

    private String getAlarmObjectAsJson(Alarm a) {
        Gson g = new Gson();
        return g.toJson(a);
    }

    public void snoozeButtonClick(View view) {

    }
}

所以我有几个问题:

1)由于已达到PendingIntent,adb命令输出中的这个条目是什么? A" ReachedPendingIntent" (显然不是这个,但我希望你能得到我的目标)。

2)如何阻止我的应用运行BroadcastReceiver代码?我现在的解决方法是清除应用程序的数据和缓存。执行此操作后,adb命令中的第二个条目不会出现,并且BroadcastReceiver会停止运行它的代码。

0 个答案:

没有答案