2010-12-29 27 views
182

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?

+0

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

Trả lời

-3

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

+0

họ đổi tên thành DeskClock: http://android.git.kernel.org/?p=platform/packages/apps/DeskClock.git;a=summary – CommonsWare

+0

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

+0

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

1

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.

277

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)

+8

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

+5

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 –

+4

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

7

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); 
+0

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

92

Đố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.

+4

đây phải là câu trả lời đúng – user1406716

+1

Đây là chính xác –

+24

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

36

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

+1

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

+0

Đ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

+0

Hoạt động tuyệt vời. Cảm ơn! – Ambran

29

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).

+0

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 –

+0

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ó. –

3

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

2
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"); 

      } 
5

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

Đô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

Các vấn đề liên quan