2012-06-02 13 views
6

Tôi đã tìm kiếm 3 ngày ngay bây giờ nhưng không tìm thấy giải pháp hoặc vấn đề/câu hỏi tương tự ở bất kỳ nơi nào khác. Đây là thỏa thuận:Trình kích hoạt cảnh báo đang chờ xử lý quá sớm

kích hoạt trong 1 giờ -> làm việc đúng

kích hoạt trong 2 giờ -> Goes của trong 1:23

kích hoạt trong 1 ngày -> Goes của trong ~ 11: 00

Vậy tại sao Trình báo thức lại không thể đoán trước và luôn luôn quá sớm? Hay tôi đang làm gì sai? Và có cách nào khác để nó có thể hoạt động chính xác không?

Đây là cách tôi đăng ký PendingIntent tôi trong AlarmManager (rút gọn):

AlarmManager alarmManager = (AlarmManager)parent.getSystemService(ALARM_SERVICE); 
Intent myIntent = new Intent(parent, UpdateKlasRoostersService.class); 
PendingIntent pendingIntent = PendingIntent.getService(parent, 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT); 

//Set startdate of PendingIntent so it triggers in 10 minutes 
Calendar start = Calendar.getInstance(); 
start.setTimeInMillis(SystemClock.elapsedRealtime()); 
start.add(Calendar.MINUTE, 10); 

//Set interval of PendingIntent so it triggers every day 
Integer interval = 1*24*60*60*1000; 

//Cancel any similar instances of this PendingIntent if already scheduled 
alarmManager.cancel(pendingIntent); 

//Schedule PendingIntent 
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, start.getTimeInMillis(), interval, pendingIntent); 
//Old way I used to schedule a PendingIntent, didn't seem to work either 
//alarmManager.set(AlarmManager.RTC_WAKEUP, start.getTimeInMillis(), pendingIntent); 

Nó sẽ là tuyệt vời nếu có ai có cách giải quyết. Cảm ơn vì bất kì sự giúp đỡ!

Cập nhật: 2 giờ trước nó đã hoạt động để kích hoạt nó với khoảng thời gian là 2 giờ, nhưng sau đó nó được kích hoạt sau 1:20 giờ. Nó trở nên thực sự kỳ lạ. Tôi sẽ theo dõi các kích hoạt xuống với một logfile và đăng nó ở đây vào ngày mai.

Cập nhật: PendingIntent được lên lịch chạy 3 giờ một lần. Từ dòng thứ hai của log nó có vẻ như một PendingIntent theo lịch trình cũ vẫn chạy:

[2012-5-3 2:15:42 519] Updating Klasroosters 
[2012-5-3 4:15:15 562] Updating Klasroosters 
[2012-5-3 5:15:42 749] Updating Klasroosters 
[2012-5-3 8:15:42 754] Updating Klasroosters 
[2012-5-3 11:15:42 522] Updating Klasroosters 

Nhưng, tôi chắc chắn rằng tôi đã hủy bỏ kế hoạch PendingIntent trước khi tôi sắp xếp một hình mới. Và mọi PendingIntent không được tái tạo theo cùng một cách, vì vậy nó phải giống hệt nhau. Nếu không, câu hỏi chủ đề này không liên quan nữa.

+1

Tôi không thể tái tạo vấn đề của bạn. Chính xác làm thế nào để bạn thay đổi 'bắt đầu' để tạm ứng nó 2 giờ, cũng 1 ngày? – Sam

+1

Tôi đã thêm logfile và phát hiện ra rằng có lẽ một PendingIntent cũ vẫn đang chạy. – Wezelkrozum

+0

Tôi cũng gặp vấn đề tương tự, bạn có giải pháp làm việc không? – david

Trả lời

1

Khi sử dụng lịch, bạn sẽ tính đến thời gian lịch sử dụng thời gian xuống đến vài nghìn giây. Có lẽ bạn nên đặt trường Milli thứ hai và trường giây thành 0 để nó xuất hiện trên chấm.

Cũng trong một ngày nó sẽ được dễ dàng hơn để sử dụng này

Calendar cal = Calendar.getInstance(); 
cal.setTimeInMillis(0); 
cal.add(Calendar.DAY_OF_MONTH, 1); 

Ngoài ra khi bạn sử dụng getInstance không rằng đặt thời gian lịch để thời gian nó đã được tạo ra vì vậy không nên có bất kỳ nhu cầu đặt lại thời gian đúng không?

+1

Tìm trong tài liệu, SystemClock.elapsedRealtime() là thời gian kể từ khi điện thoại khởi động, không phải thời gian thực tế. Hơn nữa, tôi không nghĩ rằng các cuộc gọi setTimeInMillis (0) là cần thiết, bởi vì bạn muốn báo động 1 ngày kể từ bây giờ, không phải 1 ngày từ thời đại (đó là lứa tuổi trước đây). –

+1

Nhưng tôi tin rằng anh ta sử dụng 1 ngày như một khoảng thời gian không phải là một thời gian thực tế? – FabianCook

+1

vâng, nhưng tôi giả định vấn đề này là với thời gian kích hoạt được thiết lập bằng cách sử dụng 'Lịch'. Khoảng thời gian 1 ngày được xác định bằng cách sử dụng 'Integer' và sẽ ổn. –

1

Viết lại: Cuối cùng tôi đã thấy lỗi của bạn, nhưng không thể đoán trước.

tôi đã thay đổi này:

PendingIntent.getService(parent, 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT); 

này:

PendingIntent.getService(parent, 0, myIntent, PendingIntent.FLAG_CANCEL_CURRENT); 

theo giả định giống như bạn rằng bằng cách nào đó một ý định cũ là phát sóng. Tôi chưa từng thấy fluke kể từ khi ...

Cũng là lần duy nhất tôi nhìn thấy nó trong suốt cuộc gọi ban đầu của mình. Một cách tiếp cận khác có thể là theo dõi current và đối tượng Lịch previous, nếu khoảng thời gian không phải là những gì bạn mong đợi thì bỏ qua chương trình phát sóng "sớm" này.(Trong khi phương pháp này có vẻ không cần thiết xem xét cách báo động nên làm việc, nó giúp ngăn chặn những cuộc gọi không liên quan xem xét cách báo động làm việc ...)

Hy vọng rằng sẽ giúp, tôi sẽ cho bạn biết nếu tôi tìm thấy còn gì nữa không.

+1

Cảm ơn sự nỗ lực của bạn nhưng tôi đã làm điều này rồi. Khi tôi phân tích dữ liệu này, nó sẽ kích hoạt PendingIntent ngay trên thời gian, nhưng nó không. Vì vậy, đó là vấn đề. – Wezelkrozum

+1

Xin lỗi khi biết rằng ... Gắn thẻ cho tôi khi bạn đăng dữ liệu mới, tôi sẽ trợ giúp nếu có thể. – Sam

+1

Tôi đã cập nhật câu hỏi bằng một logfile – Wezelkrozum

1

Tôi biết câu hỏi này hơi cũ, nhưng bản thân tôi cũng gặp vấn đề này. Tôi phát hiện ra rằng nếu tôi cố gắng khai báo biến Calendar bên ngoài phương thức, nó sẽ không chơi độc đáo và báo động sẽ cháy sớm. Bởi vì lớp học của bạn bị tước bỏ nó rất khó để nói chính xác nơi bạn đang gọi ví dụ lịch.

Nếu tôi đặt nó lên như vậy, sau đó nó sẽ kích hoạt ngay đúng thời hạn:

protected void nextAlarm(Context context, int seconds){ 
    Calendar nextAlarm = Calendar.getInstance(); 

    Intent intent = new Intent(context, MyClass.class); 
    PendingIntent pending = PendingIntent.getBroadcast(context, MainActivity.REPEATING_ALARM, intent, PendingIntent.FLAG_CANCEL_CURRENT); 

    AlarmManager amanager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE); 
    nextAlarm.add(Calendar.SECOND, seconds); 

    amanager.set(AlarmManager.RTC_WAKEUP, nextAlarm.getTimeInMillis(), pending); 

} 
+1

Thành thật mà nói, đó không phải là sửa chữa. Tôi tạo Lịch trong phương thức. Nhưng tôi thấy sự khác biệt trong cách chúng ta lấy lại PendingIntent. Bạn sử dụng phương thức getBroadcast, trong khi tôi đang sử dụng phương thức getService. – Wezelkrozum

1

Hãy chắc chắn rằng onStartCommand của dịch vụ của bạn trả về START_NOT_STICKY, nếu không nó sẽ tự động tái cố gắng:

public class UpdateKlasRoostersService extends Service { 
    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     buildUpdate(); 
     return START_NOT_STICKY; 
    } 
} 
+1

Điều này có nghĩa là dịch vụ của tôi tiếp tục cố gắng bắt đầu? – Wezelkrozum