使用服务启动可以执行操作的持续通知
Using a service to start an ongoing notification that can take an action
我已经创建了一个服务,以便我可以有一个持久的通知。我希望此通知有一个选项,可以将意图发送到我的另一个活动。
该选项将固有地停止应用程序产生的每个进程。因此,一旦按下操作,通知也需要关闭。
我正在尝试使用挂起的广播意图来完成此操作,但由于某种原因,广播接收器没有捕捉到意图。我在服务的 onCreate() 方法中动态注册接收器,并在服务的 onDestroy() 方法中注销它。
public class myService extends IntentService {
private boolean shown = false;
private ButtonReceiver buttonReceiver;
//Side note: this is legacy code. Necessary?
public myService() {
super("myService");
}
@Override
public void onCreate() {
super.onCreate();
IntentFilter filter = new IntentFilter("com.myapp.KILL_NOTIFICATION");
this.buttonReceiver = new ButtonReceiver();
this.registerReceiver(this.buttonReceiver, filter);
}
@Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(this.buttonReceiver);
}
@Override
protected void onHandleIntent(Intent intent) {
if(intent.getAction() == "com.myapp.START_SERVICE") {
//generate a unique id for the notification
int id = Integer.parseInt(new SimpleDateFormat("ddHHmmss", Locale.US).format(new Date()));
//create a pending intent to send off when the kill action is pressed
Intent buttonIntent = new Intent("com.myapp.KILL_NOTIFICATION");
buttonIntent.putExtra("notificationId", id);
PendingIntent btPendingIntent = PendingIntent.getBroadcast(this, 0, buttonIntent, 0);
Notification.Builder builder = new Notification.Builder(getApplicationContext());
builder.setAutoCancel(false);
builder.setContentTitle("my app");
//builder.setContentText("Press this notification to kill.");
builder.setOngoing(true);
builder.setSmallIcon(R.drawable.ic_launcher);
//builder.setContentIntent(pendingIntent);
builder.addAction(R.drawable.ic_clear_black_24dp, "Kill my app", btPendingIntent);
builder.setWhen(0);
builder.setPriority(Notification.PRIORITY_MAX);
Notification notification = builder.build();
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
//TODO need to find first unused notif id
notificationManager.notify(id, notification);
}
}
public class ButtonReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
int notificationId = intent.getIntExtra("notificationId", 0);
Intent killIntent = new Intent("com.myapp.KILL_EVERYTHING");
killIntent.addCategory(Intent.CATEGORY_DEFAULT);
startActivity(killIntent);
//cancel notification
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancel(notificationId);
}
}
}
IntentService
在 onHandleIntent()
方法完成后自行停止,因此当它发生时,您动态注册的 Receiver 不再能接收广播。
您不需要 Service
来维持持续的 Notification
。在您的情况下,您可以直接发出 Notification
,而不是启动 Service
来执行此操作。然后在清单中静态注册您的接收器 class,并使用显式 Intent
从 Notification
.
向其广播
将 ButtonReceiver
移动到它自己的 class 文件,并像这样在清单中注册它:
<receiver android:name=".ButtonReceiver" />
您需要对传递给 onReceive()
的 context
参数调用 startActivity()
,就像您是 getSystemService()
一样。您还需要将以下标志添加到 Intent
.
killIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
然后只需将 Notification
的 PendingIntent
的 buttonIntent
更改为:
Intent buttonIntent = new Intent(this, ButtonReceiver.class);
如果那是唯一的广播 ButtonReceiver
将处理,您将不再真正需要 KILL_NOTIFICATION
操作。
我已经创建了一个服务,以便我可以有一个持久的通知。我希望此通知有一个选项,可以将意图发送到我的另一个活动。
该选项将固有地停止应用程序产生的每个进程。因此,一旦按下操作,通知也需要关闭。
我正在尝试使用挂起的广播意图来完成此操作,但由于某种原因,广播接收器没有捕捉到意图。我在服务的 onCreate() 方法中动态注册接收器,并在服务的 onDestroy() 方法中注销它。
public class myService extends IntentService {
private boolean shown = false;
private ButtonReceiver buttonReceiver;
//Side note: this is legacy code. Necessary?
public myService() {
super("myService");
}
@Override
public void onCreate() {
super.onCreate();
IntentFilter filter = new IntentFilter("com.myapp.KILL_NOTIFICATION");
this.buttonReceiver = new ButtonReceiver();
this.registerReceiver(this.buttonReceiver, filter);
}
@Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(this.buttonReceiver);
}
@Override
protected void onHandleIntent(Intent intent) {
if(intent.getAction() == "com.myapp.START_SERVICE") {
//generate a unique id for the notification
int id = Integer.parseInt(new SimpleDateFormat("ddHHmmss", Locale.US).format(new Date()));
//create a pending intent to send off when the kill action is pressed
Intent buttonIntent = new Intent("com.myapp.KILL_NOTIFICATION");
buttonIntent.putExtra("notificationId", id);
PendingIntent btPendingIntent = PendingIntent.getBroadcast(this, 0, buttonIntent, 0);
Notification.Builder builder = new Notification.Builder(getApplicationContext());
builder.setAutoCancel(false);
builder.setContentTitle("my app");
//builder.setContentText("Press this notification to kill.");
builder.setOngoing(true);
builder.setSmallIcon(R.drawable.ic_launcher);
//builder.setContentIntent(pendingIntent);
builder.addAction(R.drawable.ic_clear_black_24dp, "Kill my app", btPendingIntent);
builder.setWhen(0);
builder.setPriority(Notification.PRIORITY_MAX);
Notification notification = builder.build();
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
//TODO need to find first unused notif id
notificationManager.notify(id, notification);
}
}
public class ButtonReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
int notificationId = intent.getIntExtra("notificationId", 0);
Intent killIntent = new Intent("com.myapp.KILL_EVERYTHING");
killIntent.addCategory(Intent.CATEGORY_DEFAULT);
startActivity(killIntent);
//cancel notification
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancel(notificationId);
}
}
}
IntentService
在 onHandleIntent()
方法完成后自行停止,因此当它发生时,您动态注册的 Receiver 不再能接收广播。
您不需要 Service
来维持持续的 Notification
。在您的情况下,您可以直接发出 Notification
,而不是启动 Service
来执行此操作。然后在清单中静态注册您的接收器 class,并使用显式 Intent
从 Notification
.
将 ButtonReceiver
移动到它自己的 class 文件,并像这样在清单中注册它:
<receiver android:name=".ButtonReceiver" />
您需要对传递给 onReceive()
的 context
参数调用 startActivity()
,就像您是 getSystemService()
一样。您还需要将以下标志添加到 Intent
.
killIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
然后只需将 Notification
的 PendingIntent
的 buttonIntent
更改为:
Intent buttonIntent = new Intent(this, ButtonReceiver.class);
如果那是唯一的广播 ButtonReceiver
将处理,您将不再真正需要 KILL_NOTIFICATION
操作。