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); 
相关问题