Android: Cách sử dụng AlarmManager


89

Tôi cần kích hoạt một khối mã sau 20 phút kể từ khi AlarmManagerđược đặt.

Ai đó có thể chỉ cho tôi mã mẫu về cách sử dụng một AlarmManagertrong ِ Android không?

Tôi đã thử với một số mã trong vài ngày và nó sẽ không hoạt động.

Câu trả lời:


109

"Một số mã mẫu" không phải là dễ dàng khi nói đến AlarmManager.

Đây là một đoạn mã hiển thị thiết lập của AlarmManager:

AlarmManager mgr=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent i=new Intent(context, OnAlarmReceiver.class);
PendingIntent pi=PendingIntent.getBroadcast(context, 0, i, 0);

mgr.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), PERIOD, pi);

Trong ví dụ này, tôi đang sử dụng setRepeating(). Nếu bạn muốn báo thức một lần, bạn chỉ cần sử dụng set(). Đảm bảo cung cấp thời gian để báo thức bắt đầu trong cùng thời gian mà bạn sử dụng trong tham số ban đầu set(). Trong ví dụ của tôi ở trên, tôi đang sử dụng AlarmManager.ELAPSED_REALTIME_WAKEUP, vì vậy cơ sở thời gian của tôi là SystemClock.elapsedRealtime().

Đây là một dự án mẫu lớn hơn cho thấy kỹ thuật này.


2
Xin chào lần nữa. Cảm ơn vi đa trả lơi. Nếu tôi mua sách của bạn, cuốn sách đó có giải thích chi tiết cách triển khai trình quản lý báo thức không?
Tom

7
Sách Android Nâng cao (Phiên bản 0.9) có ~ 9 trang bao gồm AlarmManager, WakeLocks và phần còn lại của ví dụ đó. Điều đó có thể sẽ mở rộng một chút trong Phiên bản 1.0 khi tôi thực hiện bản sửa lỗi mà tôi đã đề cập trong câu trả lời của mình ở trên. Và nếu bạn có câu hỏi liên quan đến cuốn sách hoặc mã mẫu của sách, hãy chuyển tới groups.google.com/group/cw-android và tôi sẽ sẵn lòng trả lời chúng.
CommonsWare

17
Bất kỳ nhà phát triển Android nào cũng nên đăng ký sách của Mark :) Ít nhất một lần
Bostone

1
@ MarioGalván: Bạn cần đặt thời điểm ứng dụng của bạn được chạy lần đầu tiên và khi khởi động lại.
CommonsWare

Tôi nghĩ bạn nên sử dụng AlarmManager.RTC_WAKEUP nếu bạn muốn nó kích hoạt ngay lập tức và sau đó mỗi PERIOD. Trong mã của bạn, nó sẽ kích hoạt sau SystemClock.elapsedRealtime () và sau đó mỗi PERIOD.
Damon Yuan

66

Có một số ví dụ điển hình trong mã mẫu android

. \ android-sdk \ samples \ android-10 \ ApiDemos \ src \ com \ example \ android \ apis \ app

Những thứ nên kiểm tra là:

  • AlarmController.java
  • OneShotAlarm.java

Trước tiên, bạn cần một bộ thu, một thứ có thể nghe báo thức của bạn khi nó được kích hoạt. Thêm phần sau vào tệp AndroidManifest.xml của bạn

<receiver android:name=".MyAlarmReceiver" />

Sau đó, tạo lớp sau

public class MyAlarmReceiver extends BroadcastReceiver { 
     @Override
     public void onReceive(Context context, Intent intent) {
         Toast.makeText(context, "Alarm went off", Toast.LENGTH_SHORT).show();
     }
}

Sau đó, để kích hoạt báo thức, hãy sử dụng thông tin sau (ví dụ: trong hoạt động chính của bạn):

AlarmManager alarmMgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, MyAlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
Calendar time = Calendar.getInstance();
time.setTimeInMillis(System.currentTimeMillis());
time.add(Calendar.SECOND, 30);
alarmMgr.set(AlarmManager.RTC_WAKEUP, time.getTimeInMillis(), pendingIntent);

.


Hoặc, tốt hơn, tạo một lớp xử lý tất cả và sử dụng nó như thế này

Bundle bundle = new Bundle();
// add extras here..
MyAlarm alarm = new MyAlarm(this, bundle, 30);

bằng cách này, bạn có tất cả ở một nơi (đừng quên chỉnh sửa AndroidManifest.xml)

public class MyAlarm extends BroadcastReceiver {
    private final String REMINDER_BUNDLE = "MyReminderBundle"; 

    // this constructor is called by the alarm manager.
    public MyAlarm(){ }

    // you can use this constructor to create the alarm. 
    //  Just pass in the main activity as the context, 
    //  any extras you'd like to get later when triggered 
    //  and the timeout
     public MyAlarm(Context context, Bundle extras, int timeoutInSeconds){
         AlarmManager alarmMgr = 
             (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
         Intent intent = new Intent(context, MyAlarm.class);
         intent.putExtra(REMINDER_BUNDLE, extras);
         PendingIntent pendingIntent =
             PendingIntent.getBroadcast(context, 0, intent, 
             PendingIntent.FLAG_UPDATE_CURRENT);
         Calendar time = Calendar.getInstance();
         time.setTimeInMillis(System.currentTimeMillis());
         time.add(Calendar.SECOND, timeoutInSeconds);
         alarmMgr.set(AlarmManager.RTC_WAKEUP, time.getTimeInMillis(),
                      pendingIntent);
     }

      @Override
     public void onReceive(Context context, Intent intent) {
         // here you can get the extras you passed in when creating the alarm
         //intent.getBundleExtra(REMINDER_BUNDLE));

         Toast.makeText(context, "Alarm went off", Toast.LENGTH_SHORT).show();
     }
}

2
Xin chào! Tôi đã thử nghiệm mã này và nó tệ hơn (+1). nhưng tôi đã thử điều này cho nhiều báo thức (như một báo động trong 10 giây và một báo thức khác trong 15 giây và chỉ có báo thức cũ bị kích hoạt. Tôi có đang làm gì đó sai không hay đó là một số vấn đề? CHỈNH SỬA: Ok, tôi đã tìm thấy sự cố ở đây : stackoverflow.com/questions/2844274/…
Nuno Gonçalves

FWIW, tôi sẽ sử dụng một phương thức tĩnh thay vì một phương thức khởi tạo cho việc này.
Edward Falk

9

Điều bạn cần làm trước tiên là tạo ra ý định mà bạn cần để lên lịch. Sau đó, nhận được pendingIntent của ý định đó. Bạn có thể lên lịch các hoạt động, dịch vụ và chương trình phát sóng. Để lên lịch một hoạt động, ví dụ như MyActivity:

  Intent i = new Intent(getApplicationContext(), MyActivity.class);
  PendingIntent pi = PendingIntent.getActivity(getApplicationContext(),3333,i,
  PendingIntent.FLAG_CANCEL_CURRENT);

Cung cấp PendingIntent này cho alertManager:

  //getting current time and add 5 seconds in it
  Calendar cal = Calendar.getInstance();
  cal.add(Calendar.SECOND, 5);
  //registering our pending intent with alarmmanager
  AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
  am.set(AlarmManager.RTC_WAKEUP,cal.getTimeInMillis(), pi);

Bây giờ MyActivity sẽ được khởi chạy sau 5 giây kể từ khi khởi chạy ứng dụng, bất kể bạn dừng ứng dụng hoặc thiết bị của bạn ở trạng thái ngủ (do tùy chọn RTC_WAKEUP). Bạn có thể đọc mã mẫu hoàn chỉnh Lập lịch hoạt động, dịch vụ và chương trình phát sóng #Android


+1 câu trả lời tuyệt vời, chính xác những gì tôi cần, một ví dụ về 'bộ' đang hoạt động.
A.Alqadomi

4

Tôi muốn bình luận nhưng <50 đại diện, vì vậy hãy tiếp tục. Xin nhắc lại rằng nếu bạn đang chạy trên 5.1 trở lên và bạn sử dụng khoảng thời gian dưới một phút, điều này sẽ xảy ra:

Suspiciously short interval 5000 millis; expanding to 60 seconds

Xem tại đây .


3

Một số mã mẫu khi bạn muốn gọi một dịch vụ từ Alarmmanager:

PendingIntent pi;
AlarmManager mgr;
mgr = (AlarmManager)ctx.getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(DataCollectionActivity.this, HUJIDataCollectionService.class);    
pi = PendingIntent.getService(DataCollectionActivity.this, 0, i, 0);
mgr.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() , 1000, pi);

Bạn không cần phải yêu cầu quyền của người dùng.


Một từ viết tắt rất phổ biến.
Phantômaxx

0

AlarmManager được sử dụng để kích hoạt một số mã tại một thời điểm cụ thể.

Để khởi động Trình quản lý báo thức, trước tiên bạn cần lấy phiên bản từ Hệ thống. Sau đó, chuyển PendingIntent sẽ được thực thi vào một thời điểm trong tương lai mà bạn chỉ định

AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

Intent alarmIntent = new Intent(context, MyAlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, alarmIntent, 0);
int interval = 8000; //repeat interval
manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), interval, pendingIntent);

Bạn cần phải cẩn thận khi sử dụng Trình quản lý báo động. Thông thường, trình quản lý báo thức không thể lặp lại trước một phút. Ngoài ra ở chế độ năng lượng thấp, thời lượng có thể tăng lên đến 15 phút.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.