在关闭此问题或根据标题标记为重复之前,它与使用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会停止运行它的代码。