使用服务在应用程序生命周期之外继续计时器
Using service to continue timer outside of application lifecycle
编辑:感谢您的回复。我最终找到了一个很好的解决方案(我在下面发布),它为感兴趣的人使用前台服务和广播接收器。
原题:
我有一个简单的递增计时器,它使用更新文本视图的处理程序。我想要达到的目标是
- 即使应用程序关闭也继续计时
- 当计时器达到其持续时间
时发出通知并唤醒phone(如果睡眠)
我读过有关使用服务的信息,因为它与 activity 分开运行,但是我发现的所有示例似乎都比我尝试做的要复杂。
我的计时器供参考class
public class MyTimer implements Runnable {
MainActivity activity;
Handler handler;
TextView timerView;
long current_time,duration;
public MyTimer(MainActivity activity){
this.activity = activity;
this.handler = new Handler();
this.current_time = 0L;
timerView = (TextView) activity.findViewById(R.id.timerValue);
}
public MyTimer startTimer(int duration){
this.duration = duration;
handler.postDelayed(this,1000);
return this;
}
public MyTimer resetTimer(){
timerView.setText("0:00");
handler.removeCallbacks(this);
return this;
}
@Override
public void run() {
if(current_time == duration){
Toast.makeText(activity,"Timer is done",Toast.LENGTH_SHORT).show();
resetTimer();
return;
}
current_time += 1000;
int secs = (int) (current_time / 1000);
int minutes = secs / 60;
timerView.setText(Integer.toString(minutes) + ":" + String.format("%02d", secs%60));
handler.postDelayed(this, 1000);
}
}
timerView 和 start/stop
的两个按钮
我还想在 onStop/onDestroy 期间将计时器存储在数据库中,并使用系统时间及其保存时间之间的差异来更新计时器。但这并不能解决发出通知 and/or 唤醒 phone.
的问题
您找到的示例并不太复杂 - 为了实现您想要的,您需要:
- 绑定
Service
,它将跟踪经过的时间并将向 AlarmManager
注册警报
- Fragment/Activity可以绑定上面的
Service
,执行resetTimer()
、startTimer()
、getElapsedTime()
等方法。您需要使用 Handler
对 getElapsedTime()
执行查询,但是 1 秒的超时时间太长(我会使用 0.1 秒或类似时间)。
最后注意:您不能使用在 postDelayed()
上设置的超时来增加计时器。最好使用这样的东西:
public void startTimer(long duration) {
mStartTime = System.currentTimeMillis();
mDuration = duration;
// register alarm with AlarmManager here
}
public long getElapsedTime() {
return System.currentTimeMillis() - mStartTime;
}
对于那些可能需要回答这个问题的人,经过一些研究我决定最好的方法是使用前台服务和处理程序,因为警报管理器对于如此短且恒定的计时器来说效率低下。
总结
服役中Class
- 将计时器广播到 main activity,其中 MainActivity 将使用广播接收器接收它并更新 UI
- 服务 class 使用它自己的广播接收器检查 phone 屏幕是否 on/off 并在它 returns 从睡眠中更新计时器。
主要Activityclass
- 接收定时服务发送的广播并更新UI
- 其他后勤工作,例如何时 register/unregister 广播接收器以及向服务发送操作至 stop/start
服务Class:
//Timer service which uses a handler to monitor tick rate. Also uses a broadcast receiver
//to update the timer if the device was in sleep mode.
public class TimerService extends Service{
Intent intent;
public static final String TAG = TimerService.class.getSimpleName();
private final Handler handler = new Handler();
long currentTime, duration;
long timeSinceLastOn, elapsedTimeSinceOff;
@Override
public void onCreate() {
super.onCreate();
currentTime = duration = elapsedTimeSinceOff = 0L;
timeSinceLastOn = SystemClock.elapsedRealtime();
intent = new Intent(Constants.ACTION.BROADCAST_ACTION);
/**Starting Timer here**/
handler.removeCallbacks(timerThread);
handler.postDelayed(timerThread,0);
/**********************/
/**Broadcast receiver to check if the screen is on **/
IntentFilter screenStateFilter = new IntentFilter();
screenStateFilter.addAction(Intent.ACTION_SCREEN_ON);
screenStateFilter.addAction(Intent.ACTION_SCREEN_OFF);
registerReceiver(broadcastReceiver, screenStateFilter);
/***************************************************/
}
@Override
/**Depending on action issued by MainActivity either puts service in
*foreground with duration or destroys the service**/
public int onStartCommand(Intent intent, int flags, int startId) {
if(intent != null) {
if (intent.getAction().equals(Constants.ACTION.STARTFOREGROUND_ACTION)) {
if (intent.hasExtra(Constants.TIMER.DURATION))
duration = intent.getLongExtra(Constants.TIMER.DURATION, 0);
startForeground(Constants.NOTIFICATION_ID.FOREGROUND_SERVICE, createTimerNotification());
} else if (intent.getAction().equals(Constants.ACTION.STOPFOREGROUND_ACTION)) {
stopForeground(true);
stopSelf();
}
}
return START_STICKY;
}
/**Thread the handler uses to push to message queue. This creates a timer effect.**/
private Runnable timerThread = new Runnable() {
@Override
public void run() {
if(currentTime == duration){
stopSelf();
return;
}
currentTime += 1000;
sendTimerInfo();
handler.postDelayed(this,1000);
}
};
/**Broadcasts the timer in which the MainActivity will receive it and update the UI**/
private void sendTimerInfo(){
Log.d(TAG, "timer running: tick is " + currentTime);
intent.putExtra(Constants.TIMER.CURRENT_TIME, currentTime);
sendBroadcast(intent);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG,"timer service finished");
unregisterReceiver(broadcastReceiver);
handler.removeCallbacks(timerThread);
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
/******************** Broadcast Receiver To Check if Screen is on**************************************/
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
handler.removeCallbacks(timerThread);
/**If the screen is back on then update the timer and start it again**/
if(intent.getAction().equals(Intent.ACTION_SCREEN_ON)){
Log.d(TAG,"Screen is turned on");
elapsedTimeSinceOff = SystemClock.elapsedRealtime() - timeSinceLastOn;
Log.d(TAG," screen was off and updating current time by"+elapsedTimeSinceOff);
currentTime += elapsedTimeSinceOff;
handler.postDelayed(timerThread,0);
}
/**Turns off the timer when the screen is off**/
else if(intent.getAction().equals(Intent.ACTION_SCREEN_OFF)){
Log.d(TAG,"Screen is turned off");
timeSinceLastOn = SystemClock.elapsedRealtime();
}
}
};
/**Since this is foreground service it must have a notification**/
private Notification createTimerNotification() {
Intent notificationIntent = new Intent(this, MainActivity.class);
notificationIntent.setAction(Constants.ACTION.MAIN_ACTION);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
notificationIntent,0);
Bitmap icon = BitmapFactory.decodeResource(getResources(),
R.mipmap.ic_launcher);
Notification notification = new NotificationCompat.Builder(this)
.setContentTitle("Service Timer")
.setTicker("Count up timer")
.setContentText("timer")
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(Bitmap.createScaledBitmap(icon, 128, 128, false))
.setContentIntent(pendingIntent)
.setOngoing(true)
.build();
return notification;
}
}
主要Activity:
public class MainActivity extends Activity {
TextView timerView;
Intent timerService;
//Example duration of 3minutes
long currentTime, duration = 180000;
@Override
protected void onStart() {
super.onStart();
timerService = new Intent(this, TimerService.class);
//Register broadcast if service is already running
if(isMyServiceRunning(TimerService.class)){
registerReceiver(broadcastReceiver, new IntentFilter(Constants.ACTION.BROADCAST_ACTION));
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button startButton, stopButton;
timerView = (TextView) findViewById(R.id.timerValue);
startButton = (Button) findViewById(R.id.startButton);
stopButton = (Button) findViewById(R.id.stopButton);
//Button to Start the service when pushed
startButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
if(!isMyServiceRunning(TimerService.class)) {
timerService.setAction(Constants.ACTION.STARTFOREGROUND_ACTION);
timerService.putExtra(Constants.TIMER.DURATION,duration);
startService(timerService);
registerReceiver(broadcastReceiver, new IntentFilter(Constants.ACTION.BROADCAST_ACTION));
}
}
});
//Button to stop the service when pushed
stopButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
if(isMyServiceRunning(TimerService.class)) {
timerView.setText("0:00");
timerService.setAction(Constants.ACTION.STOPFOREGROUND_ACTION);
startService(timerService);
unregisterReceiver(broadcastReceiver);
}
}
});
}
@Override
protected void onResume() {
super.onResume();
if(!isMyServiceRunning(TimerService.class)) {
//Resets timer if no service is running
timerView.setText("0:00");
}
}
@Override
protected void onStop() {
super.onStop();
if(isMyServiceRunning(TimerService.class)) {
unregisterReceiver(broadcastReceiver);
Log.d(MainActivity.class.getSimpleName(), "unregistered broadcast");
}
}
/******************** Broadcast Receiver **************************************/
//Receives the broadcast sent out by the service and updates the UI accordingly.
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if(!updateUI(intent)){
if(!updateUI(timerService)){
timerService.setAction(Constants.ACTION.STOPFOREGROUND_ACTION);
startService(timerService);
showTimerCompleteNotification();
}
}
}
};
//Receives the timer from the service and updates the UI
public boolean updateUI(Intent intent){
if(!intent.hasExtra(Constants.TIMER.CURRENT_TIME)) return false;
this.currentTime = intent.getLongExtra(Constants.TIMER.CURRENT_TIME, 0L);
if(this.currentTime == duration){
timerView.setText("0:00");
Toast.makeText(this,"Timer done",Toast.LENGTH_SHORT).show();
return false;
}
int secs = (int) (currentTime / 1000);
int minutes = secs / 60;
timerView.setText(Integer.toString(minutes) + ":" + String.format("%02d", secs%60));
return true;
}
/******************************************************************************************/
/************* Helper Methods ****************************/
private void showTimerCompleteNotification() {
Intent resultIntent = new Intent(this, MainActivity.class);
PendingIntent resultPendingIntent =
PendingIntent.getActivity(
this,
0,
resultIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("Timer Done!")
.setContentText("Congrats")
.setContentIntent(resultPendingIntent)
.setColor(Color.BLACK)
.setLights(Color.BLUE, 500, 500)
.setDefaults(NotificationCompat.DEFAULT_VIBRATE)
.setDefaults(NotificationCompat.DEFAULT_SOUND)
.setStyle(new NotificationCompat.InboxStyle());
// Gets an instance of the NotificationManager service
final NotificationManager mNotifyMgr =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
// Builds the notification and issues it.
mNotifyMgr.notify(Constants.NOTIFICATION_ID.FOREGROUND_SERVICE, mBuilder.build());
//Cancel the notification after a little while
Handler h = new Handler();
long delayInMilliseconds = 5000;
h.postDelayed(new Runnable() {
public void run() {
mNotifyMgr.cancel(Constants.NOTIFICATION_ID.FOREGROUND_SERVICE);
}
}, delayInMilliseconds);
}
private boolean isMyServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
}
常数class:
package com.example.admin.servicetimer.service;
public class Constants {
public interface ACTION {
public static String MAIN_ACTION = "com.fahadhd.foregroundservice.action.main";
public static final String STARTFOREGROUND_ACTION = "com.fahadhd.foregroundservice.action.startforeground";
public static final String STOPFOREGROUND_ACTION = "com.fahadhd.foregroundservice.action.stopforeground";
public static final String BROADCAST_ACTION = "com.fahadhd.foregroundservice.action.broadcast";
}
public interface TIMER {
public static final String CURRENT_TIME = "com.fahadhd.foregroundservice.timer.current_time";
public static final String DURATION = "com.fahadhd.foregroundservice.timer.duration";
}
public interface NOTIFICATION_ID {
public static int FOREGROUND_SERVICE = 1;
}
}
编辑:感谢您的回复。我最终找到了一个很好的解决方案(我在下面发布),它为感兴趣的人使用前台服务和广播接收器。
原题:
我有一个简单的递增计时器,它使用更新文本视图的处理程序。我想要达到的目标是
- 即使应用程序关闭也继续计时
- 当计时器达到其持续时间 时发出通知并唤醒phone(如果睡眠)
我读过有关使用服务的信息,因为它与 activity 分开运行,但是我发现的所有示例似乎都比我尝试做的要复杂。
我的计时器供参考class
public class MyTimer implements Runnable {
MainActivity activity;
Handler handler;
TextView timerView;
long current_time,duration;
public MyTimer(MainActivity activity){
this.activity = activity;
this.handler = new Handler();
this.current_time = 0L;
timerView = (TextView) activity.findViewById(R.id.timerValue);
}
public MyTimer startTimer(int duration){
this.duration = duration;
handler.postDelayed(this,1000);
return this;
}
public MyTimer resetTimer(){
timerView.setText("0:00");
handler.removeCallbacks(this);
return this;
}
@Override
public void run() {
if(current_time == duration){
Toast.makeText(activity,"Timer is done",Toast.LENGTH_SHORT).show();
resetTimer();
return;
}
current_time += 1000;
int secs = (int) (current_time / 1000);
int minutes = secs / 60;
timerView.setText(Integer.toString(minutes) + ":" + String.format("%02d", secs%60));
handler.postDelayed(this, 1000);
}
}
timerView 和 start/stop
的两个按钮我还想在 onStop/onDestroy 期间将计时器存储在数据库中,并使用系统时间及其保存时间之间的差异来更新计时器。但这并不能解决发出通知 and/or 唤醒 phone.
的问题您找到的示例并不太复杂 - 为了实现您想要的,您需要:
- 绑定
Service
,它将跟踪经过的时间并将向AlarmManager
注册警报
- Fragment/Activity可以绑定上面的
Service
,执行resetTimer()
、startTimer()
、getElapsedTime()
等方法。您需要使用Handler
对getElapsedTime()
执行查询,但是 1 秒的超时时间太长(我会使用 0.1 秒或类似时间)。
最后注意:您不能使用在 postDelayed()
上设置的超时来增加计时器。最好使用这样的东西:
public void startTimer(long duration) {
mStartTime = System.currentTimeMillis();
mDuration = duration;
// register alarm with AlarmManager here
}
public long getElapsedTime() {
return System.currentTimeMillis() - mStartTime;
}
对于那些可能需要回答这个问题的人,经过一些研究我决定最好的方法是使用前台服务和处理程序,因为警报管理器对于如此短且恒定的计时器来说效率低下。
总结
服役中Class
- 将计时器广播到 main activity,其中 MainActivity 将使用广播接收器接收它并更新 UI
- 服务 class 使用它自己的广播接收器检查 phone 屏幕是否 on/off 并在它 returns 从睡眠中更新计时器。
主要Activityclass
- 接收定时服务发送的广播并更新UI
- 其他后勤工作,例如何时 register/unregister 广播接收器以及向服务发送操作至 stop/start
服务Class:
//Timer service which uses a handler to monitor tick rate. Also uses a broadcast receiver
//to update the timer if the device was in sleep mode.
public class TimerService extends Service{
Intent intent;
public static final String TAG = TimerService.class.getSimpleName();
private final Handler handler = new Handler();
long currentTime, duration;
long timeSinceLastOn, elapsedTimeSinceOff;
@Override
public void onCreate() {
super.onCreate();
currentTime = duration = elapsedTimeSinceOff = 0L;
timeSinceLastOn = SystemClock.elapsedRealtime();
intent = new Intent(Constants.ACTION.BROADCAST_ACTION);
/**Starting Timer here**/
handler.removeCallbacks(timerThread);
handler.postDelayed(timerThread,0);
/**********************/
/**Broadcast receiver to check if the screen is on **/
IntentFilter screenStateFilter = new IntentFilter();
screenStateFilter.addAction(Intent.ACTION_SCREEN_ON);
screenStateFilter.addAction(Intent.ACTION_SCREEN_OFF);
registerReceiver(broadcastReceiver, screenStateFilter);
/***************************************************/
}
@Override
/**Depending on action issued by MainActivity either puts service in
*foreground with duration or destroys the service**/
public int onStartCommand(Intent intent, int flags, int startId) {
if(intent != null) {
if (intent.getAction().equals(Constants.ACTION.STARTFOREGROUND_ACTION)) {
if (intent.hasExtra(Constants.TIMER.DURATION))
duration = intent.getLongExtra(Constants.TIMER.DURATION, 0);
startForeground(Constants.NOTIFICATION_ID.FOREGROUND_SERVICE, createTimerNotification());
} else if (intent.getAction().equals(Constants.ACTION.STOPFOREGROUND_ACTION)) {
stopForeground(true);
stopSelf();
}
}
return START_STICKY;
}
/**Thread the handler uses to push to message queue. This creates a timer effect.**/
private Runnable timerThread = new Runnable() {
@Override
public void run() {
if(currentTime == duration){
stopSelf();
return;
}
currentTime += 1000;
sendTimerInfo();
handler.postDelayed(this,1000);
}
};
/**Broadcasts the timer in which the MainActivity will receive it and update the UI**/
private void sendTimerInfo(){
Log.d(TAG, "timer running: tick is " + currentTime);
intent.putExtra(Constants.TIMER.CURRENT_TIME, currentTime);
sendBroadcast(intent);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG,"timer service finished");
unregisterReceiver(broadcastReceiver);
handler.removeCallbacks(timerThread);
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
/******************** Broadcast Receiver To Check if Screen is on**************************************/
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
handler.removeCallbacks(timerThread);
/**If the screen is back on then update the timer and start it again**/
if(intent.getAction().equals(Intent.ACTION_SCREEN_ON)){
Log.d(TAG,"Screen is turned on");
elapsedTimeSinceOff = SystemClock.elapsedRealtime() - timeSinceLastOn;
Log.d(TAG," screen was off and updating current time by"+elapsedTimeSinceOff);
currentTime += elapsedTimeSinceOff;
handler.postDelayed(timerThread,0);
}
/**Turns off the timer when the screen is off**/
else if(intent.getAction().equals(Intent.ACTION_SCREEN_OFF)){
Log.d(TAG,"Screen is turned off");
timeSinceLastOn = SystemClock.elapsedRealtime();
}
}
};
/**Since this is foreground service it must have a notification**/
private Notification createTimerNotification() {
Intent notificationIntent = new Intent(this, MainActivity.class);
notificationIntent.setAction(Constants.ACTION.MAIN_ACTION);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
notificationIntent,0);
Bitmap icon = BitmapFactory.decodeResource(getResources(),
R.mipmap.ic_launcher);
Notification notification = new NotificationCompat.Builder(this)
.setContentTitle("Service Timer")
.setTicker("Count up timer")
.setContentText("timer")
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(Bitmap.createScaledBitmap(icon, 128, 128, false))
.setContentIntent(pendingIntent)
.setOngoing(true)
.build();
return notification;
}
}
主要Activity:
public class MainActivity extends Activity {
TextView timerView;
Intent timerService;
//Example duration of 3minutes
long currentTime, duration = 180000;
@Override
protected void onStart() {
super.onStart();
timerService = new Intent(this, TimerService.class);
//Register broadcast if service is already running
if(isMyServiceRunning(TimerService.class)){
registerReceiver(broadcastReceiver, new IntentFilter(Constants.ACTION.BROADCAST_ACTION));
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button startButton, stopButton;
timerView = (TextView) findViewById(R.id.timerValue);
startButton = (Button) findViewById(R.id.startButton);
stopButton = (Button) findViewById(R.id.stopButton);
//Button to Start the service when pushed
startButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
if(!isMyServiceRunning(TimerService.class)) {
timerService.setAction(Constants.ACTION.STARTFOREGROUND_ACTION);
timerService.putExtra(Constants.TIMER.DURATION,duration);
startService(timerService);
registerReceiver(broadcastReceiver, new IntentFilter(Constants.ACTION.BROADCAST_ACTION));
}
}
});
//Button to stop the service when pushed
stopButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
if(isMyServiceRunning(TimerService.class)) {
timerView.setText("0:00");
timerService.setAction(Constants.ACTION.STOPFOREGROUND_ACTION);
startService(timerService);
unregisterReceiver(broadcastReceiver);
}
}
});
}
@Override
protected void onResume() {
super.onResume();
if(!isMyServiceRunning(TimerService.class)) {
//Resets timer if no service is running
timerView.setText("0:00");
}
}
@Override
protected void onStop() {
super.onStop();
if(isMyServiceRunning(TimerService.class)) {
unregisterReceiver(broadcastReceiver);
Log.d(MainActivity.class.getSimpleName(), "unregistered broadcast");
}
}
/******************** Broadcast Receiver **************************************/
//Receives the broadcast sent out by the service and updates the UI accordingly.
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if(!updateUI(intent)){
if(!updateUI(timerService)){
timerService.setAction(Constants.ACTION.STOPFOREGROUND_ACTION);
startService(timerService);
showTimerCompleteNotification();
}
}
}
};
//Receives the timer from the service and updates the UI
public boolean updateUI(Intent intent){
if(!intent.hasExtra(Constants.TIMER.CURRENT_TIME)) return false;
this.currentTime = intent.getLongExtra(Constants.TIMER.CURRENT_TIME, 0L);
if(this.currentTime == duration){
timerView.setText("0:00");
Toast.makeText(this,"Timer done",Toast.LENGTH_SHORT).show();
return false;
}
int secs = (int) (currentTime / 1000);
int minutes = secs / 60;
timerView.setText(Integer.toString(minutes) + ":" + String.format("%02d", secs%60));
return true;
}
/******************************************************************************************/
/************* Helper Methods ****************************/
private void showTimerCompleteNotification() {
Intent resultIntent = new Intent(this, MainActivity.class);
PendingIntent resultPendingIntent =
PendingIntent.getActivity(
this,
0,
resultIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("Timer Done!")
.setContentText("Congrats")
.setContentIntent(resultPendingIntent)
.setColor(Color.BLACK)
.setLights(Color.BLUE, 500, 500)
.setDefaults(NotificationCompat.DEFAULT_VIBRATE)
.setDefaults(NotificationCompat.DEFAULT_SOUND)
.setStyle(new NotificationCompat.InboxStyle());
// Gets an instance of the NotificationManager service
final NotificationManager mNotifyMgr =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
// Builds the notification and issues it.
mNotifyMgr.notify(Constants.NOTIFICATION_ID.FOREGROUND_SERVICE, mBuilder.build());
//Cancel the notification after a little while
Handler h = new Handler();
long delayInMilliseconds = 5000;
h.postDelayed(new Runnable() {
public void run() {
mNotifyMgr.cancel(Constants.NOTIFICATION_ID.FOREGROUND_SERVICE);
}
}, delayInMilliseconds);
}
private boolean isMyServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
}
常数class:
package com.example.admin.servicetimer.service;
public class Constants {
public interface ACTION {
public static String MAIN_ACTION = "com.fahadhd.foregroundservice.action.main";
public static final String STARTFOREGROUND_ACTION = "com.fahadhd.foregroundservice.action.startforeground";
public static final String STOPFOREGROUND_ACTION = "com.fahadhd.foregroundservice.action.stopforeground";
public static final String BROADCAST_ACTION = "com.fahadhd.foregroundservice.action.broadcast";
}
public interface TIMER {
public static final String CURRENT_TIME = "com.fahadhd.foregroundservice.timer.current_time";
public static final String DURATION = "com.fahadhd.foregroundservice.timer.duration";
}
public interface NOTIFICATION_ID {
public static int FOREGROUND_SERVICE = 1;
}
}