2012-03-29 23 views
7

Tôi có một IntentService và tôi muốn làm cho nó dính với một thông báo đang diễn ra. Vấn đề là thông báo xuất hiện và sau đó biến mất ngay lập tức. Dịch vụ tiếp tục chạy. Tôi nên sử dụng startForeground trong IntentService như thế nào?StartForeground for IntentService

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    super.onStartCommand(intent, flags, startId); 
    Notification notification = new Notification(R.drawable.marker, "Notification service is running", 
      System.currentTimeMillis()); 
    Intent notificationIntent = new Intent(this, DashboardActivity.class); 
    notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP| 
     Intent.FLAG_ACTIVITY_SINGLE_TOP); 
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); 
    notification.setLatestEventInfo(this, "App", 
      "Notification service is running", pendingIntent); 
    notification.flags|=Notification.FLAG_NO_CLEAR; 
    startForeground(1337, notification); 
    return START_STICKY; 
} 

@Override 
protected void onHandleIntent(Intent intent) { 

    String id = intent.getStringExtra(ID); 
    WebSocketConnectConfig config = new WebSocketConnectConfig(); 
    try { 
     config.setUrl(new URI("ws://" + App.NET_ADDRESS 
       + "/App/socket?id="+id)); 
    } catch (URISyntaxException e) { 
     e.printStackTrace(); 
    } 
    ws = SimpleSocketFactory.create(config, this); 
    ws.open(); 
} 

Cảm ơn

+2

bao gồm mã của bạn quá – waqaslam

Trả lời

9

Đây không phải là một IntentService. Như được viết, IntentService của bạn sẽ hoạt động trong một phần nghìn giây. Khi trả tiền onHandleIntent(), dịch vụ sẽ bị hủy. Đây phải là số Service thông thường, nơi bạn chia nhánh của riêng mình và quản lý thời gian tồn tại của chuỗi và dịch vụ.

Lý do Notification của bạn sẽ biến mất ngay lập tức là vì dịch vụ sẽ biến mất ngay lập tức.

+1

Cảm ơn, tôi chuyển nó trong một Service và bây giờ nó đang làm việc. – Matroska

+2

Bị bỏ phiếu vì: Có thể đó là câu trả lời sai. Trích từ tài liệu IntentService: "Tất cả yêu cầu được xử lý trên một chuỗi công nhân đơn lẻ - * chúng có thể mất bao lâu * (và sẽ không chặn vòng lặp chính của ứng dụng), nhưng chỉ một yêu cầu sẽ được xử lý tại một thời điểm." Không có gì nói về mili giây hoặc lâu hơn. https://developer.android.com/reference/android/app/IntentService.html – GregoryK

+1

Khi được viết, 'IntentService' này sẽ tồn tại trong một phần nghìn giây, vì lý do đơn giản là mã trong' onHandleIntent() 'sẽ chỉ mất một phần nghìn giây để chạy. – CommonsWare

1

Như documentation cho IntentService trạng thái:

... dịch vụ này được bắt đầu khi cần thiết, xử lý mỗi Ý định lần lượt sử dụng một sợi công nhân, và dừng lại chính nó khi nó chạy ra khỏi công việc.

Vì vậy, tôi cho rằng vấn đề là dịch vụ của bạn không hoạt động sau khi onHandleIntent() kết thúc. Do đó, dịch vụ dừng lại chính nó và thông báo được dissmissed. Vì vậy, khái niệm IntentService có lẽ không phải là trường hợp tốt nhất cho nhiệm vụ của bạn.


Như tiêu đề câu hỏi là "StartForeground cho IntentService", tôi muốn làm rõ một số điều:

Nó thực sự đơn giản để làm cho IntentService của bạn để chạy trong foreground (xem mã dưới đây), nhưng chắc chắn bạn cần phải xem xét một số điều:

  • Không chạy dịch vụ ở mặt trước nếu chỉ mất vài giây - điều đó có thể gây lỗi cho người dùng của bạn. Hãy tưởng tượng bạn chạy các tác vụ ngắn định kỳ - điều này sẽ khiến thông báo xuất hiện và biến mất - uhhhh *

  • Bạn có thể giữ cho thiết bị của mình luôn tỉnh táo (nhưng đó là một câu chuyện khác, được đề cập khá tốt trên stackoverflow) *

  • Nếu bạn xếp hàng nhiều mục đích vào IntentService, mã bên dưới sẽ kết thúc hiển thị/ẩn thông báo. (Vì vậy, có thể có giải pháp tốt hơn cho trường hợp của bạn - vì @CommonsWare đề xuất mở rộng Dịch vụ và tự làm mọi thứ, tuy nhiên muốn đề cập - không có gì trong javadoc cho IntentService nói rằng nó chỉ hoạt động trong vài giây - nó hoạt động miễn là nó phải làm điều gì đó.)


public class ForegroundService extends IntentService { 

    private static final String TAG = "FrgrndSrv"; 

    public ForegroundService() { 
     super(TAG); 
    } 

    @Override 
    protected void onHandleIntent(Intent intent) { 

     Notification.Builder builder = new Notification.Builder(getBaseContext()) 
       .setSmallIcon(R.drawable.ic_foreground_service) 
       .setTicker("Your Ticker") // use something from something from R.string 
       .setContentTitle("Your content title") // use something from something from 
       .setContentText("Your content text") // use something from something from 
       .setProgress(0, 0, true); // display indeterminate progress 

     startForeground(1, builder.build()); 
     try { 
      doIntesiveWork(); 
     } finally { 
      stopForeground(true); 
     } 
    } 

    protected void doIntesiveWork() { 
     // Below should be your logic that takes lots of time 
     try { 
      Thread.sleep(10000); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 
+0

Một quy tắc chung cho lập trình máy tính là: không bao giờ đưa ra giả định về tài nguyên mà một thứ khác có được thay cho bạn. Bạn đã không tạo chuỗi nền được sử dụng bởi 'IntentService'; do đó, bạn không nên đưa ra bất kỳ giả định nào về việc bạn có thể sử dụng nó một cách an toàn trong bao lâu. Chúng tôi đã gặp phải vấn đề này với 'AsyncTask', trong đó Google thay đổi các quy tắc cho 'execute()', giới hạn bạn thành một chuỗi duy nhất trên tất cả các tác vụ. Nếu bạn muốn giữ một chuỗi dài hơn một khoảng thời gian ngắn, hãy tạo chuỗi của riêng bạn. Downvoting cho đề xuất thực hành lập trình lúng túng. – CommonsWare

+1

@CommonsWare Tôi thấy quan điểm của bạn và hiểu điều đó. Điều đó có ý nghĩa. Trên thực tế, tôi đã có một chút không đồng ý về tuyên bố "Như được viết, IntentService của bạn sẽ sống trong một phần nghìn giây hoặc lâu hơn." Tôi không cố gắng đưa ra giả định, API java nói: "IntentService là lớp cơ sở cho các Dịch vụ xử lý các yêu cầu không đồng bộ (được biểu diễn dưới dạng Intents) theo yêu cầu. Khách hàng gửi yêu cầu thông qua các cuộc gọi startService (Intent); dịch vụ được bắt đầu khi cần thiết, xử lý từng Intent lần lượt bằng cách sử dụng một chuỗi công nhân, và tự dừng lại khi nó hết công việc. " – GregoryK

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