大家!我在有闹钟的地方有时钟应用程序。我使用了AlarmManager
。一切正常,但有时当我打开应用程序并单击按钮Start
(没有选择新时间,因此我使用了上次使用的时间)时,我的闹钟立即响起,我不知道为什么。你能帮我解决我的问题吗?
AlarmFragment.java内部:
public class AlarmFragment extends Fragment {
private Button mButtonStart, mButtonStop;
private TextView mTextAlarm;
private AlarmManager mAlarmManager;
private TimePickerDialog mTimePickerDialog;
private Calendar mCalendar;
private SharedPreferences mSharedPreferences;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_alarm, container, false);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mButtonStart = getActivity().findViewById(R.id.button_start_alarm);
mButtonStop = getActivity().findViewById(R.id.button_stop_alarm);
mTextAlarm = getActivity().findViewById(R.id.text_alarm);
mAlarmManager = (AlarmManager) getContext().getSystemService(Context.ALARM_SERVICE);
mSharedPreferences = getContext().getSharedPreferences("pref", Context.MODE_PRIVATE);
mCalendar = Calendar.getInstance();
mCalendar.setTimeInMillis(mSharedPreferences.getLong("alarm_time", mCalendar.getTimeInMillis()));
updateTextAlarmTime();
playBehaviourOfButtons();
setTime();
}
@Override
public void onResume() {
super.onResume();
// change style of buttons
if (mSharedPreferences.getBoolean("alarm_running", false)) {
mButtonStart.setVisibility(View.GONE);
mButtonStop.setVisibility(View.VISIBLE);
} else {
mButtonStart.setVisibility(View.VISIBLE);
mButtonStop.setVisibility(View.GONE);
}
}
private void playBehaviourOfButtons() {
mButtonStart.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mButtonStart.setVisibility(View.GONE);
mButtonStop.setVisibility(View.VISIBLE);
startAlarm();
}
});
mButtonStop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mButtonStart.setVisibility(View.VISIBLE);
mButtonStop.setVisibility(View.GONE);
stopAlarm();
}
});
}
private void setTime() {
mTextAlarm.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// set new time for alarm
if (!mSharedPreferences.getBoolean("alarm_running", false)) {
mTimePickerDialog = new TimePickerDialog(
getContext(),
new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
mCalendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
mCalendar.set(Calendar.MINUTE, minute);
updateTextAlarmTime();
}
},
mCalendar.get(Calendar.HOUR_OF_DAY),
mCalendar.get(Calendar.MINUTE),
true);
mTimePickerDialog.show();
}
}
});
}
private void startAlarm() {
// if the selected time is less than the current time we have to set alarm on the next day
if (mCalendar.getTimeInMillis() < Calendar.getInstance().getTimeInMillis()) {
mCalendar.setTimeInMillis(mCalendar.getTimeInMillis() + 86_400_000L);
}
// start an alarm
Intent intent = new Intent(getContext(), AlarmManagerBroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
getContext(),
1,
intent,
PendingIntent.FLAG_UPDATE_CURRENT);
if (Build.VERSION.SDK_INT >= 23) {
AlarmManager.AlarmClockInfo alarmClockInfo =
new AlarmManager.AlarmClockInfo(mCalendar.getTimeInMillis(), pendingIntent);
mAlarmManager.setAlarmClock(alarmClockInfo, pendingIntent);
} else if (Build.VERSION.SDK_INT >= 19) {
mAlarmManager.setExact(AlarmManager.RTC_WAKEUP, mCalendar.getTimeInMillis(), pendingIntent);
} else {
mAlarmManager.set(AlarmManager.RTC_WAKEUP, mCalendar.getTimeInMillis(), pendingIntent);
}
// create a notification about a running alarm
Intent intentNotification = new Intent(getContext(), AlarmNotificationService.class);
intentNotification.putExtra("alarm_time" , String.format(
Locale.getDefault(),
"%02d:%02d",
mCalendar.get(Calendar.HOUR_OF_DAY),
mCalendar.get(Calendar.MINUTE)));
getActivity().startService(intentNotification);
mSharedPreferences.edit().putBoolean("alarm_running", true).apply();
mSharedPreferences.edit().putLong("alarm_time", mCalendar.getTimeInMillis()).apply();
}
private void stopAlarm() {
// cancel the current alarm
Intent intent = new Intent(getContext(), AlarmManagerBroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
getContext(),
1,
intent,
PendingIntent.FLAG_UPDATE_CURRENT);
mAlarmManager.cancel(pendingIntent);
// hide a notification about a running alarm
getActivity().stopService(new Intent(getContext(), AlarmNotificationService.class));
mSharedPreferences.edit().putBoolean("alarm_running", false).apply();
}
private void updateTextAlarmTime() {
mTextAlarm.setText(String.format(
Locale.getDefault(),
"%02d:%02d",
mCalendar.get(Calendar.HOUR_OF_DAY),
mCalendar.get(Calendar.MINUTE)));
}
}
在我的BroadcastReceiver内部:
public class AlarmManagerBroadcastReceiver extends BroadcastReceiver {
private static final int ALARM_EXPIRED_NOTIFICATION_ID = 1;
@Override
public void onReceive(Context context, Intent intent) {
// hide a notification about a running alarm
context.stopService(new Intent(context, AlarmNotificationService.class));
// turn the screen on to show the notification
ScreenWakeup.screenWakeUp(context);
// show a notification about an expired alarm
NotificationManager notificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Intent notificationIntent = new Intent(context, MainActivity.class);
notificationIntent.putExtra("alarm_cancel_notification", true);
PendingIntent notificationPendingIntent = PendingIntent.getActivity(
context,
1,
notificationIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
RemoteViews remoteViews = new RemoteViews(
context.getPackageName(),
R.layout.partial_notification);
remoteViews.setTextViewText(
R.id.cancel_button_notification,
context.getString(R.string.alarm_notification));
remoteViews.setOnClickPendingIntent(
R.id.cancel_button_notification,
notificationPendingIntent);
NotificationCompat.Builder builder = new NotificationCompat.Builder(
context,
ChannelIdApp.CHANNEL_ID);
builder.setAutoCancel(true)
.setTicker("Alarm")
.setCustomContentView(remoteViews)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM))
.setSmallIcon(R.drawable.ic_stat_notify_clock);
Notification notification = builder.build();
notification.flags = notification.flags | Notification.FLAG_INSISTENT;
if (notificationManager != null) {
notificationManager.notify(ALARM_EXPIRED_NOTIFICATION_ID, notification);
}
SharedPreferences sharedPreferences = context.getSharedPreferences(
"pref",
Context.MODE_PRIVATE);
sharedPreferences.edit().putBoolean("alarm_running", false).apply();
}
}
内部清单:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<application
android:name=".ChannelIdApp"
android:allowBackup="true"
android:icon="@drawable/ic_launcher_app"
android:label="@string/app_name"
android:roundIcon="@drawable/ic_launcher_app"
android:supportsRtl="true"
android:theme="@style/MyToolbarTheme"
tools:ignore="GoogleAppIndexingWarning">
<activity
android:name=".activities.LauncherActivity"
android:screenOrientation="portrait"
android:theme="@style/PreloaderTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:launchMode="singleTop"
android:name=".activities.MainActivity"
android:screenOrientation="portrait" />
<receiver
android:exported="false"
android:name=".AlarmManagerBroadcastReceiver" />
<service
android:exported="false"
android:name=".AlarmNotificationService" />
</application>