这是一个闹钟提醒的功能:app一打开就会调用:这两个服务。
AppService
public class AppService extends Service {
private HashMap<String, Integer> clockMap = new HashMap<String, Integer>();
private String notiContent = "";
private String notiTitle = "";
private Clock newestClock;
private WindowUtils w = null;
// 2016.12.29,aidl
private MyBilder mBilder;
private String TAG = "AppService";
private boolean needBind = false;
@Override
public IBinder onBind(Intent arg0) {
if (mBilder == null) {
mBilder = new MyBilder();
}
if (Build.VERSION.SDK_INT >= 26) {
try {
String CHANNEL_ID = "my_channel_02";
NotificationChannel channel = new NotificationChannel(CHANNEL_ID,
"Channel human readable title",
NotificationManager.IMPORTANCE_DEFAULT);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (manager != null) {
manager.createNotificationChannel(channel);
}
Notification notification = new Notification.Builder(this, CHANNEL_ID)
.setContentTitle("")
.setContentText("").build();
startForeground(1, notification);
stopSelf();
} catch (Exception e) {
e.printStackTrace();
}
cancelNotification();
}
return mBilder;
}
class MyBilder extends GuardAidl.Stub {
@Override
public void doSomething() throws RemoteException {
LogUtil.i(TAG, "绑定成功!");
Intent localService = new Intent(AppService.this, RemoteService.class);
try {
if (Build.VERSION.SDK_INT >= 26) {
AppService.this.startForegroundService(localService);
} else {
AppService.this.startService(localService);
AppService.this.bindService(new Intent(AppService.this, RemoteService.class), connection, Context.BIND_ABOVE_CLIENT);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
//服务断开时调用
private ServiceConnection connection = new ServiceConnection() {
/**
* 在终止后调用,我们在杀死服务的时候就会引起意外终止,就会调用onServiceDisconnected
* 则我们就得里面启动被杀死的服务,然后进行绑定
*/
@Override
public void onServiceDisconnected(ComponentName name) {
LogUtil.i(TAG, "RemoteService被杀死了");
Intent localService = new Intent(AppService.this, RemoteService.class);
try {
LogUtil.i(TAG, "RemoteService开启中");
if (Build.VERSION.SDK_INT >= 26) {
AppService.this.startForegroundService(localService);
} else {
AppService.this.startService(localService);
}
LogUtil.i(TAG, "正常开启RemoteService");
} catch (Exception e) {
LogUtil.i(TAG, "异常开启RemoteService");
e.printStackTrace();
}
AppService.this.bindService(new Intent(AppService.this, RemoteService.class), connection, Context.BIND_ABOVE_CLIENT);
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
LogUtil.i(TAG, "RemoteService链接成功!");
try {
if (mBilder != null) {
mBilder.doSomething();
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
};
@SuppressWarnings("deprecation")
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
// 在LocalService运行后,我们对RemoteService进行绑定。 把优先级提升为前台优先级
}
// *********************************2016.12.29,aidl
//闹钟时间到---显示悬浮窗
public BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context arg0, Intent arg1) {
Log.i(TAG, "弹框显示");
if ("dialog".equals(arg1.getAction())) {
NotificationUtil.collapseStatusBar(AppService.this); // 收起下拉通知栏
if (w == null) {
w = new WindowUtils(AppService.this);
if (newestClock == null) {
return; // 如果闹钟信息为空,不做处理
}
w.setClockUpView(newestClock);
}
w.hidePopupWindow();
w.showPopupWindow(); // 显示悬浮框
}
if ("cancel".equals(arg1.getAction())) {
NotificationUtil.collapseStatusBar(AppService.this); // 收起下拉通知栏
}
}
};
@Override
public void onCreate() {
IntentFilter filter = new IntentFilter();
filter.addAction("cancel");
filter.addAction("dialog");
registerReceiver(receiver, filter);
super.onCreate();
}
//创建Notification
private void createNotification(String notiTitle, String notiContent) {
PendingIntent b_intent = PendingIntent.getBroadcast(this, 0, new Intent("cancel"), 0);
PendingIntent l_intent = PendingIntent.getBroadcast(this, 0, new Intent("dialog"), 0);
if (!TextUtils.isEmpty(notiTitle)) {
if (notiTitle.equals(getString(R.string.noti_order_hint))) { // 已认证没设置闹钟,点击通知栏打开订单页面
l_intent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), PendingIntent.FLAG_UPDATE_CURRENT);
} else if (notiTitle.contains("开庭时间") || notiTitle.contains("开庭提醒")) {
Intent intent = new Intent(getBaseContext(), CourtListActivity.class);
l_intent = PendingIntent.getActivity(getBaseContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
} else if (notiTitle.contains("办事时间") || notiTitle.contains("笔记备忘")) {
Intent intent = new Intent(getBaseContext(), NoteListActivity.class);
l_intent = PendingIntent.getActivity(getBaseContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
}
RemoteViews view = new RemoteViews(this.getPackageName(), R.layout.notification); // 自定义通知栏布局
view.setTextViewText(R.id.tvAlarmDate, notiTitle);
view.setTextViewText(R.id.tvContent, notiContent);
view.setOnClickPendingIntent(R.id.btnCancel, b_intent);
view.setOnClickPendingIntent(R.id.llNotification, l_intent);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Notification.Builder builder = null;
Notification notify = null;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel("" + 1234,
"Channel" + 1234, NotificationManager.IMPORTANCE_DEFAULT);
channel.enableLights(true); //是否在桌面icon右上角展示小红点
channel.setLightColor(Color.GREEN); //小红点颜色
channel.setShowBadge(true); //是否在久按桌面图标时显示此渠道的通知
if (manager != null) {
manager.createNotificationChannel(channel);
}
builder = new Notification.Builder(this, "" + 1234);
} else {
builder = new Notification.Builder(this);
}
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
notify = builder.setSmallIcon(R.mipmap.ic_launcher).setCustomContentView(view).build();
} else {
notify = builder.setSmallIcon(R.mipmap.ic_launcher).setContent(view).build();
}
try {
startForeground(1234, notify);
} catch (RuntimeException e) {
e.printStackTrace();
}
}
//取消Notification
private void cancelNotification() {
this.stopForeground(true);
}
@Override
public void onDestroy() {
LogUtil.d("AppService", "app>>>AppService->!!!!!!!onDestroy!!!!!!!");
cancelNotification();
unregisterReceiver(receiver);
super.onDestroy();
}
@Override
public int onStartCommand(Intent intent1, int flags, int startId) {
int num = setClock();//返回设置的闹钟数量
int status = LawyerInfoManager.getLawStatus(getApplicationContext());
String orderFlag = SharedPrefsUtil.getValue(getApplicationContext(), AppConstants.FALVSHUO, UserInfoBean.ORDER_FLAG, "");
if (4 == status && "1".equals(orderFlag) && num == 0) {
createNotification(getString(R.string.noti_order_hint), "tips:屏蔽通知将影响消息接收");
needBind = true;
LogUtil.e("ganjue", "111");
} else {
if (num != 0) {
needBind = true;
LogUtil.e("ganjue", "222");
createNotification(notiTitle, notiContent);
} else {
LogUtil.e("ganjue", "333");
needBind = false;
LogUtil.e(TAG, "nothing");
if (Build.VERSION.SDK_INT >= 26) {
try {
String CHANNEL_ID = "my_channel_02";
NotificationChannel channel = new NotificationChannel(CHANNEL_ID,
"Channel human readable title",
NotificationManager.IMPORTANCE_DEFAULT);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (manager != null) {
manager.createNotificationChannel(channel);
}
Notification notification = new Notification.Builder(this, CHANNEL_ID)
.setContentTitle("")
.setContentText("").build();
startForeground(1, notification);
cancelNotification();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
return super.onStartCommand(intent1, START_FLAG_REDELIVERY, startId);
}
//设置闹钟
@SuppressLint("NewApi")
private int setClock() {
LogUtil.e(TAG, "!!!!!读取db,设置闹钟!!!!!");
SharedPreferences sh = getSharedPreferences("falvshuo", Context.MODE_PRIVATE);
String valueData = sh.getString(LAWYER_ID, "");
if ("".equals(valueData) || "null".equals(valueData) || "NULL".equals(valueData) || valueData == null) {
valueData = "default";
}
D4Service d4 = new D4ServiceImpl(this, valueData);
List<Clock> clockList = d4.D417(0);
if (JsonUtil.listHasData(clockList, 0)) {
LogUtil.e(TAG, "closeSize: " + clockList.size());
}
AlarmManager alarmManager = (AlarmManager) getSystemService(Activity.ALARM_SERVICE);
HashMap<String, Integer> newClockMap = new HashMap<String, Integer>();
for (Clock clock : clockList) {
try {
long triggerTime = DateUtil.convertStrToDate(clock.getAlarm_date(), DateUtil.DATE_NONE_SENCORD_FORMAT).getTime();
if (triggerTime / 1000 <= System.currentTimeMillis() / 1000) {
continue;// 如果是触发时间小于当前时间(精确到分),则不设置闹钟(已过期)
}
int id = 123;
if (clockMap.containsKey(clock.getId())) {
id = clockMap.get(clock.getId());
clockMap.remove(clock.getId());
} else {
id = (int) (Math.random() * 10000);
}
newClockMap.put(clock.getId(), id);
Intent intent = new Intent("com.falvshuo.component.receiver.AlarmReceiver");
intent.setPackage(getPackageName());
intent.putExtra("id", String.valueOf(id));
intent.putExtra("title", clock.getTitle());
intent.putExtra("content", clock.getContent());
intent.putExtra("alarm_date", triggerTime + "");
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, id, intent, PendingIntent.FLAG_UPDATE_CURRENT);
// alarmManager.set(AlarmManager.RTC_WAKEUP, triggerTime,
// pendingIntent);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, triggerTime, pendingIntent);
} else {
alarmManager.set(AlarmManager.RTC_WAKEUP, triggerTime, pendingIntent);
}
LogUtil.w("appService", "设置闹钟" + clock.getId() + " " + clock.getAlarm_date());
// 获取通知栏需要的字段
String[] str = clockList.get(0).getContent().split("\n");
notiTitle = str[0];
if (str.length < 2) {
notiContent = "";
} else {
notiContent = str[1];
}
newestClock = clockList.get(0);
} catch (Exception e) {
LogUtil.e("app", "闹钟加载错误");
e.printStackTrace();
}
}
for (String cid : clockMap.keySet()) {
Intent intent = new Intent("com.falvshuo.component.receiver.AlarmReceiver");
PendingIntent pendingIntent2 = PendingIntent.getBroadcast(this, clockMap.get(cid), intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.cancel(pendingIntent2);// 删除其它
LogUtil.e("appService", "删除闹钟" + cid);
}
clockMap = newClockMap;
return clockMap.size();
}
}
RemoteService:
/**
* 守护服务
*
* @author Richard
*/
public class RemoteService extends Service {
private MyBilder mBilder;
private String TAG = "RemoteService";
private Notification notification;
private Boolean isregister = false;
@Override
public void onCreate() {
super.onCreate();
}
@Override
public IBinder onBind(Intent intent) {
if (mBilder == null) {
mBilder = new MyBilder();
}
if (Build.VERSION.SDK_INT >= 26) {
try {
String CHANNEL_ID = "my_channel_01";
NotificationChannel channel = new NotificationChannel(CHANNEL_ID,
"Channel human readable title",
NotificationManager.IMPORTANCE_DEFAULT);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (manager != null) {
manager.createNotificationChannel(channel);
}
notification = new Notification.Builder(this, CHANNEL_ID)
.setContentTitle("")
.setContentText("").build();
//5秒内必须启动给用户可见
startForeground(1, notification);
showRemoteService();
} catch (Exception e) {
e.printStackTrace();
}
}
return mBilder;
}
@SuppressWarnings("deprecation")
@Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
// 在RemoteService运行后,我们对LocalService进行绑定。 把优先级提升为前台优先级
this.bindService(new Intent(RemoteService.this, AppService.class), connection, Context.BIND_ABOVE_CLIENT);
}
@Override
public void onDestroy() {
super.onDestroy();
// 在RemoteService运行后,我们对LocalService进行绑定。
if (isregister) {
this.unbindService(connection);
}
cancelNotification();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(TAG, "成功开启RemoteService");
if (Build.VERSION.SDK_INT >= 26) {
try {
String CHANNEL_ID = "my_channel_01";
NotificationChannel channel = new NotificationChannel(CHANNEL_ID,
"Channel human readable title",
NotificationManager.IMPORTANCE_DEFAULT);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (manager != null) {
manager.createNotificationChannel(channel);
}
notification = new Notification.Builder(this, CHANNEL_ID)
.setContentTitle("")
.setContentText("").build();
startForeground(1, notification);
showRemoteService();
} catch (Exception e) {
e.printStackTrace();
}
}
return super.onStartCommand(intent, flags, startId);
}
private void showRemoteService() {
try {
SharedPreferences sh = getSharedPreferences("falvshuo", Context.MODE_PRIVATE);
String valueData = sh.getString(LAWYER_ID, "");
if ("".equals(valueData) || "null".equals(valueData) || "NULL".equals(valueData) || valueData == null) {
valueData = "default";
}
D4Service d4 = new D4ServiceImpl(this, valueData);
List<Clock> clockList = d4.D417(0);
if (JsonUtil.listHasData(clockList, 0)) {
boolean needShow = false;
for (Clock clock : clockList) {
try {
long triggerTime = DateUtil.convertStrToDate(clock.getAlarm_date(), DateUtil.DATE_NONE_SENCORD_FORMAT).getTime();
if (triggerTime / 1000 > System.currentTimeMillis() / 1000) {
needShow = true;
break;
// 如果是触发时间大于当前时间(精确到分),则开启守护服务
}
} catch (Exception e) {
LogUtil.e("app", "闹钟加载错误");
e.printStackTrace();
}
}
if (!needShow) {
cancelNotification();
}
} else {
cancelNotification();
}
} catch (Exception e) {
LogUtil.e("app", "闹钟加载错误");
}
}
private void cancelNotification() {
this.stopForeground(true);
}
private class MyBilder extends GuardAidl.Stub {
@Override
public void doSomething() throws RemoteException {
Log.e(TAG, "绑定成功!");
}
}
private ServiceConnection connection = new ServiceConnection() {
/**
* 在终止后调用,我们在杀死服务的时候就会引起意外终止,就会调用onServiceDisconnected
* 则我们就得里面启动被杀死的服务,然后进行绑定
*/
@Override
public void onServiceDisconnected(ComponentName name) {
Log.i(TAG, "AppService被杀死了");
try {
Intent remoteService = new Intent(RemoteService.this, AppService.class);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(remoteService);
isregister = true;
} else {
isregister = true;
startService(remoteService);
}
RemoteService.this.bindService(new Intent(RemoteService.this, AppService.class), connection, Context.BIND_ABOVE_CLIENT);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i(TAG, "AppService链接成功!");
isregister = true;
try {
if (mBilder != null) {
mBilder.doSomething();
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
};
}
然后在使用闹钟服务时,设置了时间,再次调用了一次:
但是有时还是会报错:
全部都是华为手机,系统8.0.0才会有的错误,这是为什么,哪位大佬能解答一下。