服务代码:
public class NotificationService extends Service {
// 获取消息线程
private MessageThread messageThread = null;
// 点击查看
private Intent messageIntent = null;
private PendingIntent messagePendingIntent = null;
// 通知栏消息
private int messageNotificationID = 1000;
private Notification messageNotification = null;
private NotificationManager messageNotificatioManager = null;
private NotificationCompat.Builder builder;
public IBinder onBind(Intent intent) {
return null;
}
/**
* START_STICKY:如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,
* 由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传递到service,
* 那么参数Intent将为null。
* <p>
* START_NOT_STICKY:“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务。
* <p>
* START_REDELIVER_INTENT:重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,
* 并将Intent的值传入。
* <p>
* START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保证服务被kill后一定能重启。
*/
private final static int GRAY_SERVICE_ID = 1001;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
/**
* 灰色保活
思路一:API < 18,启动前台Service时直接传入new Notification();
思路二:API >= 18,同时启动两个id相同的前台Service,然后再将后启动的Service做stop处理;
*/
if (Build.VERSION.SDK_INT < 18) {
startForeground(GRAY_SERVICE_ID, new Notification());//API < 18 ,此方法能有效隐藏Notification上的图标
} else {
// >=18
// Intent innerIntent = new Intent(this, GrayInnerService.class);
// startService(innerIntent);
startForeground(GRAY_SERVICE_ID, new Notification());
startForeground(GRAY_SERVICE_ID, new Notification());
stopForeground(true);
}
// 初始化
builder = new NotificationCompat.Builder(this);
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setContentTitle("提醒");
builder.setDefaults(Notification.DEFAULT_SOUND|Notification.DEFAULT_LIGHTS|Notification.DEFAULT_VIBRATE);
//设置点击后清除
builder.setAutoCancel(true);
messageNotificatioManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// messageIntent = new Intent(this, NewJoblogActivity.class);
//组 活动
// messagePendingIntent = PendingIntent.getActivities(this, 0,
// makeIntentStack(this), PendingIntent.FLAG_UPDATE_CURRENT);
//设置点击后 动作浮动窗口
// if(Build.VERSION.SDK_INT < 21){//5.0 21
// builder.setContentIntent(messagePendingIntent);
// }else{
// //浮动通知(Heads-up Notifications)
// builder.setFullScreenIntent(messagePendingIntent, false);
// }
// builder.setContentIntent(messagePendingIntent);
/** //锁屏通知
* VISIBILITY_PRIVATE : 显示基本信息,如通知的图标,但隐藏通知的全部内容
VISIBILITY_PUBLIC : 显示通知的全部内容
VISIBILITY_SECRET : 不显示任何内容,包括图标
*/
builder.setVisibility(VISIBILITY_PRIVATE);
// 开启线程
messageThread = new MessageThread();
messageThread.isRunning = true;
messageThread.start();
return START_STICKY;//kill后,会自动重启
}
Intent[] makeIntentStack(Context context, Class activity) {
Intent[] intents = new Intent[2];
intents[0] = Intent.makeRestartActivityTask(new ComponentName(context, HomeActivity.class));
intents[1] = new Intent(context, activity);
return intents;
}
// public void checkNotify()
// {
// Calendar cal = Calendar.getInstance();
// int hour = cal.get(Calendar.HOUR_OF_DAY);
// //int minute = cal.get(Calendar.MINUTE);
// //int second = cal.get(Calendar.SECOND);
//
// //Log.i(TAG, "hour:" + hour + "m:" + minute + "s:" + second);
//
// }
/**
* 从服务器端获取消息
*/
class MessageThread extends Thread {
// 设置是否循环推送
public boolean isRunning = true;
public void run() {
while (isRunning) {
try {
// 间隔时间 半小时一次(目前测试30s)
Thread.sleep(20 * 1000);
// 获取服务器消息
String serverMessage = getServerMessage();
if (serverMessage != null && !"".equals(serverMessage)) {
Calendar cal = Calendar.getInstance();
int hour = cal.get(Calendar.HOUR_OF_DAY);
int minute = cal.get(Calendar.MINUTE);
Log.w("tag", hour + ": -->" + minute);
//test...
if (hour == 12 && minute == 2) {
builder.setContentText("亲,吃午饭了!");
builder.setTicker("吃午饭了");
messagePendingIntent = PendingIntent.getActivities(getBaseContext(), 0,
makeIntentStack(getBaseContext(),HomeActivity.class), PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(messagePendingIntent);
messageNotification = builder.build();
// 更新通知栏
messageNotificatioManager.notify(messageNotificationID,
messageNotification);
// 每次通知完,通知ID递增一下,避免消息覆盖掉
messageNotificationID++;
}
if (hour == 16 && minute == 30) {
builder.setContentText("亲,今天该提交日志了哦!");
builder.setTicker("今天该提交日志了哦");
messagePendingIntent = PendingIntent.getActivities(getBaseContext(), 0,
makeIntentStack(getBaseContext(),NewJoblogActivity.class), PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(messagePendingIntent);
messageNotification = builder.build();
// 更新通知栏
messageNotificatioManager.notify(messageNotificationID,
messageNotification);
// 每次通知完,通知ID递增一下,避免消息覆盖掉
messageNotificationID++;
}
if (hour == 8 && minute == 30) {
builder.setContentText("打上班卡哦!");
builder.setTicker("一会别忘了打上班卡哦!");
messagePendingIntent = PendingIntent.getActivities(getBaseContext(), 0,
makeIntentStack(getBaseContext(),AttendanceActivity.class), PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(messagePendingIntent);
messageNotification = builder.build();
// 更新通知栏
messageNotificatioManager.notify(messageNotificationID,
messageNotification);
// 每次通知完,通知ID递增一下,避免消息覆盖掉
messageNotificationID++;
}
if (hour == 17 && minute == 30) {
builder.setContentText("打下班卡哦!");
builder.setTicker("一会下班别忘了打下班卡哦!");
messagePendingIntent = PendingIntent.getActivities(getBaseContext(), 0,
makeIntentStack(getBaseContext(),AttendanceActivity.class), PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(messagePendingIntent);
messageNotification = builder.build();
// 更新通知栏
messageNotificatioManager.notify(messageNotificationID,
messageNotification);
// 每次通知完,通知ID递增一下,避免消息覆盖掉
messageNotificationID++;
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
@Override
public void onDestroy() {
// System.exit(0);
messageThread.isRunning = false;
super.onDestroy();
}
/**
* 模拟发送消息
*
* @return 返回服务器要推送的消息,否则如果为空的话,不推送
*/
public String getServerMessage() {
return "NEWS!";
}
/**
* 给 API >= 18 的平台上用的灰色保活手段
*/
public static class GrayInnerService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
startForeground(GRAY_SERVICE_ID, new Notification());
stopForeground(true);
stopSelf();
return super.onStartCommand(intent, flags, startId);
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
}
广播代码:
/**
* 开机接受广播,服务灰色保活(前台服务,但是无notification.)
*/
public class NotifyWriteJoblogReceiver extends BroadcastReceiver {
private final String ACTION_BOOT = "android.intent.action.BOOT_COMPLETED";
private final String ACTION_USER_PRESENT = "android.intent.action.USER_PRESENT";
private final String ACTION_PACKAGE_INSTALL = "android.intent.action.PACKAGE_INSTALL";
private final String ACTION_DATE_CHANGED = "android.intent.action.DATE_CHANGED";
private final String ACTION_TIMEZONE_CHANGED = "android.intent.action.TIMEZONE_CHANGED";
@Override
public void onReceive(Context context, Intent intent) {
/**
*这是一个android解锁的广播事件
<action android:name="android.intent.action.USER_PRESENT"/>
*安装应用
<action android:name="android.intent.action.PACKAGE_INSTALL"/>
*时间变化
<action android:name="android.intent.action.DATE_CHANGED"/>
*时区变化
<action android:name="android.intent.action.TIMEZONE_CHANGED"/>
*/
// an Intent broadcast.
if (intent.getAction().equals(ACTION_BOOT) || intent.getAction().equals(ACTION_USER_PRESENT)
|| intent.getAction().equals(ACTION_PACKAGE_INSTALL) || intent.getAction().equals(ACTION_DATE_CHANGED)
|| intent.getAction().equals(ACTION_TIMEZONE_CHANGED)) {
LogUtils.w("自定义静态广播(开机,亮屏,安装,时区改变)接收执行。。。");
context.startService(new Intent(context, NotificationService.class));
}
}
}
在主页运行服务:
/**
* 运行服务
*/
Intent intent = new Intent(this, NotificationService.class);
startService(intent);
* 注册服务和广播 *
<!-- 通知的服务 本地 -->
<service android:name=".service.NotificationService" >
</service>
<receiver android:name=".broadcast.NotifyWriteJoblogReceiver">
<intent-filter>
<category android:name="android.intent.category.DEFAULT"/>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.USER_PRESENT"/>
<action android:name="android.intent.action.PACKAGE_INSTALL"/>
<action android:name="android.intent.action.DATE_CHANGED"/>
<action android:name="android.intent.action.TIMEZONE_CHANGED"/>
</intent-filter>
</receiver>
* 别忘了添加权限 *
<!--接收开机启动广播-->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />