我想创建一个服务并使它在前台运行。
大多数示例代码都带有通知,但我不想显示任何通知。这可能吗?
你能给我一些例子吗?还有其他替代方案吗?
我的应用服务正在执行播放器功能。如何让系统不杀死我的服务,除非应用程序自己终止它(例如通过按钮暂停或停止音乐)?
我想创建一个服务并使它在前台运行。
大多数示例代码都带有通知,但我不想显示任何通知。这可能吗?
你能给我一些例子吗?还有其他替代方案吗?
我的应用服务正在执行播放器功能。如何让系统不杀死我的服务,除非应用程序自己终止它(例如通过按钮暂停或停止音乐)?
public class BootCompletedIntentReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Intent notificationIntent = new Intent(context, BluetoothService.class);
context.startForegroundService(notificationIntent);
} else {
//...
}
}
}
}
还有在 BluetoothService.class 中:
@Override
public void onCreate(){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
Intent notificationIntent = new Intent(this, BluetoothService.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
Notification notification = new Notification.Builder(this)
.setContentTitle("Title")
.setContentText("App is running")
.setSmallIcon(R.drawable.notif)
.setContentIntent(pendingIntent)
.setTicker("Title")
.setPriority(Notification.PRIORITY_DEFAULT)
.build();
startForeground(15, notification);
}
}
虽然不会出现持续性通知,但你会看到Android系统的“x个应用程序正在后台运行”通知。
有时客户不想让前台服务一直显示通知,这对开发人员来说是很麻烦的。我创建了一个假通知来启动服务,然后通过notificationManager.cancel(1);
取消它。
final String NOTIFICATION_CHANNEL_ID = "com.exmaple.project";
final String channelName = "Notification";
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public void onCreate() {
super.onCreate();
stopForeground(true);
Intent stopSelf = new Intent(this, Notification_Service.class);
stopSelf.setAction("ACTION_STOP_SERVICE");
PendingIntent pStopSelf = PendingIntent
.getService(this, 0, stopSelf
, PendingIntent.FLAG_CANCEL_CURRENT);
Notification notification;
NotificationCompat.Action action =
new NotificationCompat.Action.Builder(
0, "Close", pStopSelf
).build();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel serviceChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "Notification One", NotificationManager.IMPORTANCE_DEFAULT);
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(serviceChannel);
notification = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
.setSmallIcon(R.drawable.ic_launcher_background)
.setContentText("Welcome to App.")
.setPriority(Notification.PRIORITY_MIN)
.addAction(action)
.build();
} else {
notification = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
.setSmallIcon(R.drawable.ic_launcher_background)
.setContentTitle("App")
.setContentText("Welcome to App.")
.setPriority(Notification.PRIORITY_MIN)
.addAction(action)
.build();
}
NotificationManager notificationManager =
(NotificationManager) getSystemService(Service.NOTIFICATION_SERVICE);
notificationManager.notify(1, notification);
startForeground(1, notification);
notificationManager.cancel(1);
}
notificationManager.cancel(1);
无法移除永久通知。为此,我添加了一个虚假的关闭操作按钮。
操作按钮结果:
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
if ("ACTION_STOP_SERVICE".equals(intent.getAction())) {
stopSelf();
}
return START_STICKY;
}
if (!isMyServiceRunning()) {
Intent serviceIntent = new Intent(this, Notification_Service.class);
ContextCompat.startForegroundService(this, serviceIntent);
}
检查服务是否已经在运行。
private boolean isMyServiceRunning() {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (Notification_Service.class.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
notificationManager.createNotificationChannel(channel)
。val notificationManager =
getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val channel = NotificationChannel(
notificationChannelId,
"Endless Service notifications channel",
NotificationManager.IMPORTANCE_HIGH
).let {
it.description = "Endless Service channel"
it.enableLights(true)
it.lightColor = Color.RED
it.enableVibration(true)
it.vibrationPattern = longArrayOf(100, 200, 300, 400, 500, 400, 300, 200, 400)
it
}
notificationManager.createNotificationChannel(channel)
OR
通过简单地使用notificationManager.deleteNotificationChannel("channel_id")
即可实现。
但是,不建议删除正在被前台服务使用的通知。
更新:在 Android 7.1 及以上版本中,此链接不再可用。
这里有一种方法可以将您的应用程序的 oom_adj 设置为 1(在 ANDROID 6.0 SDK 模拟器中测试过)。添加一个临时服务,在您的主服务中调用 startForgroundService(NOTIFICATION_ID, notificion)
。然后再次使用相同的通知 ID 调用临时服务中的 startForgroundService(NOTIFICATION_ID, notificion)
,一段时间后在临时服务中调用 stopForgroundService(true) 来关闭正在进行的通知。
你也可以将你的应用程序声明为持久化。
<application
android:icon="@drawable/icon"
android:label="@string/app_name"
android:theme="@style/Theme"
*android:persistent="true"* >
</application>
这实际上将您的应用程序设置为更高的内存优先级,降低了其被终止的可能性。