0

有沒有辦法確保服務在啓動後將在後臺繼續運行,即使用戶從最近屏幕清除了應用程序?一個完美的例子就是潘多拉的應用程序,一旦它開始播放,即使你從最新音樂中清除它,音樂仍在播放,通知依然存在。即使應用程序被清除,如何保持服務正常運行?

在我的示例應用程序中,我有一個簡單的處理程序,它只記錄當前時間500ms,因此我可以看到該服務是否正在運行,並且使用4個切換之一啓動它,每個切換設置爲使其從一個4種服務啓動類型(START_STICKY,START_NOT_STICKY,START_REDELIVER_INTENT,START_STICKY_COMPTIBILITY)。我啓動服務,退出應用程序,然後從最近清除它。在每一種情況下,服務都會死亡,循環記錄停止。

MainActivity.java

public class MainActivity extends Activity { 

    private Boolean recording = false; 
    private Intent recordingService; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     recordingService = new Intent(this, RecordingService.class); 

     Button START_STICKY = (Button) findViewById(R.id.START_STICKY); 
     START_STICKY.setOnClickListener(new OnClickListener(){ 
      @Override 
      public void onClick(View arg0) { 
       startStopRecordingService(Service.START_STICKY); 
      } 
     }); 

     Button START_NOT_STICKY = (Button) findViewById(R.id.START_NOT_STICKY); 
     START_NOT_STICKY.setOnClickListener(new OnClickListener(){ 
      @Override 
      public void onClick(View arg0) { 
       startStopRecordingService(Service.START_NOT_STICKY); 
      } 
     }); 

     Button START_REDELIVER_INTENT = (Button) findViewById(R.id.START_REDELIVER_INTENT); 
     START_REDELIVER_INTENT.setOnClickListener(new OnClickListener(){ 
      @Override 
      public void onClick(View arg0) { 
       startStopRecordingService(Service.START_REDELIVER_INTENT); 
      } 
     }); 

     Button START_STICKY_COMPATIBILITY = (Button) findViewById(R.id.START_STICKY_COMPATIBILITY); 
     START_STICKY_COMPATIBILITY.setOnClickListener(new OnClickListener(){ 
      @Override 
      public void onClick(View arg0) { 
       startStopRecordingService(Service.START_STICKY_COMPATIBILITY); 
      } 
     }); 
    } 

    private void startStopRecordingService(int START_TYPE) { 
     if (recording) { 
      recordingService.removeExtra(RecordingService.START_TYPE); 
      stopService(recordingService); 
     } else { 
      recordingService.putExtra(RecordingService.START_TYPE, START_TYPE); 
      startService(recordingService); 
     } 

     recording = !recording; 
    } 
} 

RecordingService.java

public class RecordingService extends Service 
{ 
    public final static String START_TYPE = "START_TYPE"; 

    @Override 
    public IBinder onBind(Intent arg0) { 
     return null; 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startID) { 
     Log.i(getClass().getName(), "onStartCommand"); 

     int start_type = intent.getExtras().getInt(START_TYPE); 
     Log.i(getClass().getName(), "START_STICKY: " + String.valueOf(start_type == Service.START_STICKY)); 
     Log.i(getClass().getName(), "START_NOT_STICKY: " + String.valueOf(start_type == Service.START_NOT_STICKY)); 
     Log.i(getClass().getName(), "START_REDELIVER_INTENT: " + String.valueOf(start_type == Service.START_REDELIVER_INTENT)); 
     Log.i(getClass().getName(), "START_STICKY_COMPATIBILITY: " + String.valueOf(start_type == Service.START_STICKY_COMPATIBILITY)); 

     logTime(); 

     return start_type; 
    } 

    @Override 
    public void onDestroy() { 
     Log.i(getClass().getName(), "onDestroy"); 
     updateDisplayTimer.removeCallbacks(updateDisplayHandler); 
    } 

    public void logTime() { 
     Log.i(getClass().getName(), String.valueOf(System.currentTimeMillis())); 
     updateDisplayTimer.postDelayed(updateDisplayHandler, LOOP_TIME); 
    } 

    private static final int LOOP_TIME = 500; 
    private Handler updateDisplayTimer = new Handler(); 
    private Runnable updateDisplayHandler = new Runnable() { 
     @Override 
     public void run() { 
      logTime(); 
     } 
    }; 
} 

回答

2

嘗試實施前景的服務。 foreground service

前臺服務顯示通知並且從不停止。

在服務中實現此代碼段

Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text), 
     System.currentTimeMillis()); 
Intent notificationIntent = new Intent(this, ExampleActivity.class); 
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); 
notification.setLatestEventInfo(this, getText(R.string.notification_title), 
     getText(R.string.notification_message), pendingIntent); 
startForeground(ONGOING_NOTIFICATION_ID, notification); 
相關問題