Khi ứng dụng của tôi bắt đầu, tôi muốn nó kiểm tra xem một báo thức cụ thể (đã đăng ký qua AlarmManager) đã được thiết lập và đang chạy chưa. Kết quả từ google dường như chỉ ra rằng không có cách nào để làm điều này. Điều này vẫn đúng không? Tôi cần thực hiện việc kiểm tra này để tư vấn cho người dùng trước khi thực hiện bất kỳ hành động nào để tạo báo thức mới.Cách kiểm tra xem AlarmManager đã có bộ báo thức chưa?
Trả lời
Bạn đang nói về đồng hồ báo thức - mà nguồn bạn có thể tải về từ đây - https://android.googlesource.com/platform/packages/apps/AlarmClock
Hoặc bạn đang nói về thiết lập thời gian khi nhiệm vụ nhất định phải được thực hiện - http://developer.android.com/reference/android/app/AlarmManager.html
họ đổi tên thành DeskClock: http://android.git.kernel.org/?p=platform/packages/apps/DeskClock.git;a=summary – CommonsWare
Tôi đang đề cập đến một báo thức được đặt trong mã của tôi bằng cách sử dụng AlarmManager. Tôi không thể tìm thấy bất kỳ phương pháp nào để kiểm tra xem báo thức đã được đặt cho một mục đích cụ thể hay chưa. Vì chương trình cho phép người dùng đặt báo thức và sau đó đóng ứng dụng tôi muốn biết khi nào ứng dụng được mở cho dù báo thức được đặt và đang chạy 'ngoài tầm nhìn'. – ron
Có vẻ như lớp AlarmManager không cung cấp chức năng như vậy. Tại đây, bạn có thể xem nguồn của AlarmManager - http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.1_r2/android/app/AlarmManager.java Nếu bạn đang thực sự tuyệt vọng, bạn có thể mở rộng nó (hoặc thực hiện lại IAlarmManager) và tạo trình quản lý báo thức của riêng bạn. Quá mức cần thiết. – fiction
Im theo ấn tượng rằng theres không có cách nào để làm điều này, nó sẽ là tốt đẹp mặc dù.
Bạn có thể đạt được kết quả tương tự bằng cách có Alarm_last_set_time được ghi ở đâu đó và có điều Onabo_starter BroadcastReciever: BOOT_COMPLETED.
Theo dõi nhận xét được đăng, đây là giải pháp chi tiết. Hãy nói rằng bạn đã đăng ký một báo động lặp đi lặp lại với một ý định cấp phát như thế này:
Intent intent = new Intent("com.my.package.MY_UNIQUE_ACTION");
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.MINUTE, 1);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * 60, pendingIntent);
Cách bạn sẽ kiểm tra để xem nếu nó đang hoạt động là:
boolean alarmUp = (PendingIntent.getBroadcast(context, 0,
new Intent("com.my.package.MY_UNIQUE_ACTION"),
PendingIntent.FLAG_NO_CREATE) != null);
if (alarmUp)
{
Log.d("myTag", "Alarm is already active");
}
Mấu chốt ở đây là FLAG_NO_CREATE
mà như được mô tả trong javadoc: if the described PendingIntent **does not** already exists, then simply return null
(thay vì tạo hình mới)
Liệu nó có phải sử dụng Intent chỉ với một Chuỗi hành động không? Tôi đã cố gắng xác định một lớp, Intent mới (context, MyClass.class) nhưng nó dường như không hoạt động. Nó luôn trả về null ngay cả khi báo thức đang chạy. – toc777
toc777, không cần phải là Chuỗi phù hợp với hành động được khai báo trong bộ lọc ý định trong tệp kê khai của bạn.xml –
Chris, Đó là một vấn đề khác gây ra sự cố của tôi. Ý định tôi đã đề cập ở trên thực sự không hoạt động :) – toc777
Tôi có 2 báo thức. Tôi đang sử dụng ý định với các tính năng bổ sung thay vì hành động để xác định các sự kiện:
Intent i = new Intent(context, AppReciever.class);
i.putExtra("timer", "timer1");
có điều là với mục đích bổ sung (và báo thức) sẽ không độc đáo. Vì vậy, để có thể xác định được báo động đang hoạt động hay không, tôi phải xác định diff requestCode
-s:
boolean alarmUp = (PendingIntent.getBroadcast(context, MyApp.TIMER_1, i,
PendingIntent.FLAG_NO_CREATE) != null);
và đây là làm thế nào báo động đã được tạo ra:
public static final int TIMER_1 = 1;
public static final int TIMER_2 = 2;
PendingIntent pending = PendingIntent.getBroadcast(context, TIMER_1, i,
PendingIntent.FLAG_CANCEL_CURRENT);
setInexactRepeating(AlarmManager.RTC_WAKEUP,
cal.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pending);
pending = PendingIntent.getBroadcast(context, TIMER_2, i,
PendingIntent.FLAG_CANCEL_CURRENT);
setInexactRepeating(AlarmManager.RTC_WAKEUP,
cal.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pending);
Sử dụng mục đích bổ sung và giải pháp này làm việc cho tôi. Chỉ có một thay đổi là tôi đang sử dụng dịch vụ vì vậy tôi đã thay đổi nó thành 'PendingIntent.getService' – Pankaj
Đối với người khác có thể cần điều này, đây là một câu trả lời.
Sử dụng adb shell dumpsys alarm
Bạn có thể biết báo động đã được thiết lập và khi nào họ sẽ báo động và khoảng thời gian. Cũng bao nhiêu lần báo động này đã được gọi.
đây phải là câu trả lời đúng – user1406716
Đây là chính xác –
Không thực sự là một câu trả lời có lập trình cho OP, nhưng là một mẹo hay. Rất tốt để biết. – JustSomeGuy
Ví dụ làm việc với người nhận (câu trả lời hàng đầu chỉ là với hành động).
//starting
AlarmManager alarmManager = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(getActivity(), MyReceiver.class);
intent.setAction(MyReceiver.ACTION_ALARM_RECEIVER);//my custom string action name
PendingIntent pendingIntent = PendingIntent.getBroadcast(getActivity(), 1001, intent, PendingIntent.FLAG_CANCEL_CURRENT);//used unique ID as 1001
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), aroundInterval, pendingIntent);//first start will start asap
//and stopping
Intent intent = new Intent(getActivity(), MyReceiver.class);//the same as up
intent.setAction(MyReceiver.ACTION_ALARM_RECEIVER);//the same as up
PendingIntent pendingIntent = PendingIntent.getBroadcast(getActivity(), 1001, intent, PendingIntent.FLAG_CANCEL_CURRENT);//the same as up
alarmManager.cancel(pendingIntent);//important
pendingIntent.cancel();//important
//checking if alram is working with pendingIntent
Intent intent = new Intent(getActivity(), MyReceiver.class);//the same as up
intent.setAction(MyReceiver.ACTION_ALARM_RECEIVER);//the same as up
boolean isWorking = (PendingIntent.getBroadcast(getActivity(), 1001, intent, PendingIntent.FLAG_NO_CREATE) != null);//just changed the flag
Log.d(TAG, "alarm is " + (isWorking ? "" : "not") + " working...");
tôi đã mô tả cũng trên tôi blog
Tôi không chắc rằng điều này là đủ. Trong trường hợp PendingIntent được đăng ký với AlarmManager và sau đó bị dừng bởi cả hai phương thức hủy, 'isWorking' ở trên sẽ vẫn đúng. PendingIntent dường như chưa được gỡ bỏ khỏi AlarmManager, và sẽ tiếp tục trả về một cá thể. Làm thế nào để chúng ta có thể biết khi nào báo động đã được bật/tắt? – johnDisplayClass
Điều này thực sự làm việc hoàn hảo. Những điều cần lưu ý: setAction() và requestCode() cần phải giống hệt nhau trong tất cả getBroadcast() và giá trị của nó gỡ cài đặt ứng dụng khỏi thiết bị của bạn. Điều đó khiến tôi hiểu. Cảm ơn – johnDisplayClass
Hoạt động tuyệt vời. Cảm ơn! – Ambran
Note trích dẫn này từ các tài liệu cho người quản lý báo động:
Nếu có đã là một báo động cho Ý định này dự kiến (với sự bình đẳng của hai ý định được xác định bởi Intent.filterEquals), sau đó nó sẽ bị xóa và thay thế bằng cái này.
Đừng bận tâm hỏi liệu báo thức có tồn tại không nếu bạn đang cố gắng quyết định có tạo báo thức hay không. Chỉ cần tạo nó mỗi lần khởi động ứng dụng của bạn. Bạn sẽ thay thế bất kỳ báo thức nào trong quá khứ mà bạn đã định cấu hình.
Bạn cần một cách tiếp cận khác nếu bạn đang cố gắng tính toán thời gian còn lại trên báo thức đã tạo trước đó, hoặc nếu bạn thực sự cần biết liệu báo thức đó có tồn tại hay không. Để trả lời các câu hỏi đó, hãy cân nhắc lưu dữ liệu đã được chia sẻ vào lúc bạn tạo báo thức. Bạn có thể lưu dấu thời gian đồng hồ tại thời điểm báo thức được đặt, thời gian bạn mong đợi báo thức sẽ tắt và thời gian lặp lại (nếu bạn cài đặt báo thức lặp lại).
Theo tôi, đây là câu trả lời được chấp nhận. Trừ khi OP có tình huống đặc biệt để biện minh cho việc không đặt lại báo động –
Trong trường hợp của tôi, tôi muốn biết liệu báo thức đã được cài đặt chưa và nếu tôi không muốn tạo báo thức mới hoặc đặt lại báo thức hiện có. –
Tôi đã tạo một tập lệnh bash đơn giản (ngu ngốc hoặc không), trích xuất các thời gian từ vỏ adb, chuyển đổi chúng thành dấu thời gian và hiển thị màu đỏ.
echo "Please set a search filter"
read search
adb shell dumpsys alarm | grep $search | (while read i; do echo $i; _DT=$(echo $i | grep -Eo 'when\s+([0-9]{10})' | tr -d '[[:alpha:][:space:]]'); if [ $_DT ]; then echo -e "\e[31m$(date -d @$_DT)\e[0m"; fi; done;)
thử nó;)
Intent intent = new Intent("com.my.package.MY_UNIQUE_ACTION");
PendingIntent pendingIntent = PendingIntent.getBroadcast(
sqlitewraper.context, 0, intent,
PendingIntent.FLAG_NO_CREATE);
FLAG_NO_CREATE không được tạo cấp phát ý định để nó mang lại giá trị boolean false.
boolean alarmUp = (PendingIntent.getBroadcast(sqlitewraper.context, 0,
new Intent("com.my.package.MY_UNIQUE_ACTION"),
PendingIntent.FLAG_NO_CREATE) != null);
if (alarmUp) {
System.out.print("k");
}
AlarmManager alarmManager = (AlarmManager) sqlitewraper.context
.getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
System.currentTimeMillis(), 1000 * 60, pendingIntent);
Sau khi bộ kiểm tra cảnh báo kiểm tra giá trị của mục đích đang chờ nó thực hiện đúng vì Cập nhật báo động.
boolean alarmUp1 = (PendingIntent.getBroadcast(sqlitewraper.context, 0,
new Intent("com.my.package.MY_UNIQUE_ACTION"),
PendingIntent.FLAG_UPDATE_CURRENT) != null);
if (alarmUp1) {
System.out.print("k");
}
Chỉ cần tìm thấy một giải pháp khác, có vẻ như để làm việc cho tôi
Intent myIntent = new Intent(MainActivity.this, MyReceiver.class);
boolean isWorking = (PendingIntent.getBroadcast(MainActivity.this, 0, myIntent, PendingIntent.FLAG_NO_CREATE) != null);
if (isWorking) {Log.d("alarm", "is working");} else {Log.d("alarm", "is not working");}
if(!isWorking) {
pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
int timeNotif = 5 * 60 * 1000;//time in ms, 7*24*60*60*1000 for 1 week
Log.d("Notif", "Notification every (ms): " + timeNotif);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), timeNotif, pendingIntent);
}
Đôi khi, trên Marshmallow, sau khi bạn buộc dừng một ứng dụng, getBroadcast() sẽ trả về không null, nhưng báo thức không được thiết lập. – hopia
Vui lòng xác nhận câu trả lời rằng giải quyết vấn đề của bạn hoặc gửi giải pháp của riêng bạn. – AnixPasBesoin