5

Tôi có IntentService tải lên tệp. Mọi thứ hoạt động tốt, nhưng tôi hơi bối rối về cách xử lý các thông báo. Khi tôi bắt đầu thông báo, tôi sử dụng startForeground() vì các tệp có thể khá lớn và tôi không muốn tải lên bị xóa trừ khi thực sự cần thiết. Khi tôi sử dụng startForeground() nó sẽ hiển thị hai thông báo trong vùng thông báo (một dưới đang thực hiện và một trong Thông báo):Cách xử lý chính xác startForegrounds hai thông báo

Example:

Tôi đã đọc qua một số bài viết Stack Overflow khác nhau và các bài viết trên web, nhưng không ai trong số họ trả lời câu hỏi tôi có ... hy vọng tôi đã không bỏ lỡ một câu nói về ths.

Đó là sự hiểu biết của tôi rằng thông báo đang diễn ra trong hình ảnh ở trên (không có thanh tiến trình) được đặt ở đó vì điều này đang chạy ở nền trước (Services documentation). Đó là tất cả tốt và tốt nếu bạn hỏi tôi, và tôi hiểu tại sao. Tuy nhiên, tôi không cần hai thông báo được hiển thị và tôi chắc chắn rằng hầu hết mọi người sẽ không muốn hai thông báo làm lộn xộn khu vực thông báo. Tôi muốn biết cách xử lý thông báo đúng cách để chỉ có một màn hình hiển thị và không làm lộn xộn vùng thông báo.

Cách duy nhất tôi có thể thực hiện việc này là nếu tôi đặt ID số nguyên cho startForeground (int id, Notification notification) (ONGOING_NOTIFICATION_ID trong mã của tôi bên dưới) về 0. Tuy nhiên, các tài liệu tôi trích dẫn ở trên nói:

Caution: The integer ID you give to startForeground() must not be 0

Đặt nó đến 0 vô hiệu hóa các thông báo liên tục và sau đó chỉ cần thấy thông báo thường xuyên với thanh tiến trình. Tôi hình dung rằng tôi có thể "sửa" điều này bằng cách thiết lập .setOngoing(true) cho đến khi nó được thực hiện tải lên tệp và sau đó thiết lập .setOngoing(false) khi nó đã hoàn tất, vì vậy nó có thể được loại bỏ. Tôi không chắc chắn chính xác như thế nào "thận trọng" một trong những đã được thiết lập các số nguyên ID đến 0. Với tôi nó có vẻ như là một cách lười biếng để có thể để có được xung quanh vấn đề tôi đang gặp, nhưng tôi không biết nếu có những hậu quả khác để đặt nó thành 0. Ngoài ra, điều này chỉ hoạt động nếu tôi chỉ có một thông báo mà tôi đang xử lý. Nếu tôi có nhiều thông báo khác nhau, thì tôi sẽ cần các ID khác nhau cho mỗi thông báo và điều này sẽ không hoạt động. Cập nhật: Có vẻ như setting the ID to 0 won't work in Android 4.3, vì vậy bây giờ tôi quay lại hình vuông.

Cách hợp lệ để hiển thị cả hai thông báo là gì?

Cập nhật/Giải pháp: Duh, hãy dành một chút thời gian và sau đó quay lại và kiểm tra lại những gì tôi đã thực hiện dựa trên đề xuất của @dsandler đã giúp tôi tìm ra những gì tôi đã làm sai. Tôi đã không đặt ID chính xác khi tôi đang thực hiện cập nhật tiến độ, vì vậy đó là lý do tại sao nó tạo hai thông báo và một thông báo không được cập nhật. Sử dụng cùng một ID (ONGOING_NOTIFICATION_ID) cho tất cả các thông báo đã giải quyết được vấn đề cho tôi. Xem đoạn mã dưới đây để biết thêm các phần tôi chưa bao gồm trước đây và nơi tôi đã phạm sai lầm.

đang

liên quan từ UploadFile.java:

public class UploadFile extends IntentService { 

    private static final int ONGOING_NOTIFICATION_ID = 1; 

    @Override 
    protected void onHandleIntent(Intent intent) { 
     mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 
     mBuilder = new NotificationCompat.Builder(this); 
     mBuilder.setContentTitle(getText(R.string.upload)) 
      .setContentText("0% " + getText(R.string.upload_in_progress)) 
      .setSmallIcon(android.R.drawable.stat_sys_upload); 

     startForeground(ONGOING_NOTIFICATION_ID, mBuilder.build()); 


.... 

    if (progress > 0){ 
     percent = (Long.valueOf(progress) * 100)/totalSize; 
     mBuilder.setProgress(100, percent.intValue(), false); 
     mBuilder.setContentText(percent.intValue() + "% " + getText(R.string.upload_in_progress)); 
     mNotifyManager.notify(ONGOING_NOTIFICATION_ID, mBuilder.build()); // <-- My problem was that I had set the ID here to 0 and did not make it the same as the ID I set above 
    }      

.... 

} 

Trả lời

1

Trước hết, xét xử của mô tả của bạn, bạn có thể có thể nhận được ngay với một dịch vụ thường xuyên, thừa nhận rằng các out-of-bộ nhớ kẻ giết người đoạt' t gọi điện thoại trừ khi mọi thứ đang trở nên khốc liệt trên thiết bị và dịch vụ của bạn đã thực sự hoạt động rất lâu.

Điều đó nói rằng, nếu bạn phải thực hiện dịch vụ tiền cảnh, chiến lược điển hình ở đây là hiển thị tiến độ của bạn bằng cách sử dụng Thông báo bạn đã sử dụng khi bạn đặt dịch vụ của mình vào trạng thái tiền cảnh. Sử dụng NotificationManager.notify, bạn có thể đăng bao nhiêu cập nhật cho thông báo đó tùy thích, bao gồm cả điều chỉnh cho thanh tiến trình qua Notification.Builder.setProgress chẳng hạn.

Bằng cách này, bạn chỉ hiển thị một thông báo cho người dùng và đó là thông báo được yêu cầu bởi startForeground.

+0

cảm ơn cho câu trả lời. Tôi đã quay trở lại và kiểm tra lại những gì tôi đang làm (đã làm những gì bạn khuyên) và nhận ra rằng tôi đã không sử dụng đúng ID thông báo khi đăng tiến trình. Nó hoạt động như một sự quyến rũ ngay bây giờ! – Jason

+0

Tôi có một câu hỏi liên quan đến thông báo: biểu tượng nào sẽ được sử dụng cho "setLargeIcon", nếu bạn muốn sử dụng một trong Android (như bạn đã làm cho "setSmallIcon")? –

+0

Tại sao cần ** NotificationManager.notify **? 'startForegroundService()' đã hiển thị thông báo. –

-1

Khi bạn muốn cập nhật bộ Thông báo bằng startForeground(), chỉ cần tạo một chú thích mới và sau đó sử dụng NotificationManager để thông báo cho nó.

Điểm KEY là sử dụng cùng một id thông báo.

Tôi đã không kiểm tra kịch bản liên tục gọi startForeground() để cập nhật Thông báo, nhưng tôi nghĩ rằng việc sử dụng NotificationManager.notify sẽ tốt hơn.

Việc cập nhật Thông báo sẽ KHÔNG xóa Dịch vụ khỏi trạng thái tiền cảnh (điều này có thể được thực hiện chỉ bằng cách gọi stopForground);

Ví dụ:

private static final int notif_id=1; 

@Override 
public void onCreate(){ 
    this.startForeground(); 
} 

private void startForeground() { 
     startForeground(notif_id, getMyActivityNotification("")); 
} 

private Notification getMyActivityNotification(String text){ 
     // The PendingIntent to launch our activity if the user selects 
     // this notification 
     CharSequence title = getText(R.string.title_activity); 
     PendingIntent contentIntent = PendingIntent.getActivity(this, 
       0, new Intent(this, MyActivity.class), 0); 

     return new Notification.Builder(this) 
       .setContentTitle(title) 
       .setContentText(text) 
       .setSmallIcon(R.drawable.ic_launcher_b3) 
       .setContentIntent(contentIntent).getNotification();  
} 
/** 
this is the method that can be called to update the Notification 
*/ 
private void updateNotification() { 

       String text = "Some text that will update the notification"; 

       Notification notification = getMyActivityNotification(text); 

       NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 
       mNotificationManager.notify(notif_id, notification); 
} 
Các vấn đề liên quan