我正在为前台服务苦苦挣扎。在我的设备(Redmi 5 Plus,Android 8.1.0)上,当以下情况时,服务通知不再可见 该应用已从最近的应用中删除。在其他设备(Android 5.0.1,Android 7.0)和模拟器(Android 8.1-API 27)上,从最近使用的应用中删除该应用后,该通知仍然可见。
在主要活动中,我正在使用ContextCompat.startForegroundService(this, intent)
来启动服务。
在前台服务的代码下面:
package com.ngallazzi.bluetoothtests.services
import android.annotation.SuppressLint
import android.annotation.TargetApi
import android.app.*
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.IBinder
import android.support.v4.app.NotificationCompat
import android.support.v4.app.NotificationCompat.PRIORITY_LOW
import android.util.Log
import com.ngallazzi.blemanager.managers.DeviceScanningListener
import com.ngallazzi.blemanager.managers.InRangeDetectionManager
import com.ngallazzi.bluetoothtests.MainActivity
import com.polidea.rxandroidble2.RxBleDevice
/**
* BluetoothTests
* Created by Nicola on 12/17/2018.
* Copyright © 2018 Zehus. All rights reserved.
*/
class DeviceDetectionService : Service() {
private lateinit var detectionManager: InRangeDetectionManager
override fun onBind(intent: Intent): IBinder? {
// We don't provide binding, so return null
return null
}
override fun onCreate() {
super.onCreate()
detectionManager = InRangeDetectionManager(this)
}
@SuppressLint("MissingPermission")
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
if (intent != null) {
val action = intent.action
when (action) {
ACTION_START_FOREGROUND_SERVICE -> {
startForegroundService()
detectionManager.startDeviceScanning(object : DeviceScanningListener {
@SuppressLint("CheckResult")
override fun onDeviceFound(device: RxBleDevice) {
device.establishConnection(false).subscribe({
Log.v(TAG, "Connected")
displayNotification(getNotification("Connected with: {${device.name}}"))
}, {
displayNotification(getNotification("An error occurred: {$it.message!!}"))
})
}
override fun onError(message: String?) {
displayNotification(getNotification("An error occurred: {$message}"))
}
})
}
ACTION_STOP_FOREGROUND_SERVICE -> {
stopForegroundService()
}
}
}
return START_NOT_STICKY
}
@SuppressLint("MissingPermission")
private fun startForegroundService() {
startForeground(NOTIFICATION_ID, getNotification(SEARCHING_DEVICES_MESSAGE))
Log.v(TAG, "Device detection service started")
}
private fun getNotification(message: String): Notification {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
createChannel()
val mBuilder = NotificationCompat.Builder(this, CHANNEL_NAME).apply {
setSmallIcon(android.R.drawable.ic_menu_mylocation)
setContentTitle(message)
setContentIntent(getMainActivityPendingIntent())
}
return mBuilder
.setPriority(PRIORITY_LOW)
.setCategory(Notification.CATEGORY_SERVICE)
.build()
}
private fun displayNotification(notification: Notification) {
val mNotificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
mNotificationManager.notify(NOTIFICATION_ID, notification)
}
private fun getMainActivityPendingIntent(): PendingIntent {
// Create an Intent for the activity you want to start
val intent = Intent(this, MainActivity::class.java)
// Create the TaskStackBuilder
val pendingIntent = PendingIntent.getActivity(
this, 0,
intent, PendingIntent.FLAG_UPDATE_CURRENT
);
return pendingIntent!!
}
@TargetApi(26)
@Synchronized
private fun createChannel() {
val mNotificationManager = this.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val importance = NotificationManager.IMPORTANCE_DEFAULT
val mChannel = NotificationChannel(CHANNEL_NAME, SEARCHING_DEVICES_MESSAGE, importance)
mNotificationManager.createNotificationChannel(mChannel)
}
private fun stopForegroundService() {
Log.d(TAG, "Stop foreground service.")
// Stop foreground service and remove the notification.
stopForeground(true)
// Stop the foreground service.
stopSelf()
}
override fun onDestroy() {
super.onDestroy()
}
companion object {
private val TAG = DeviceDetectionService::class.java.simpleName
const val NOTIFICATION_ID = 1
const val ACTION_START_FOREGROUND_SERVICE = "start_service"
const val ACTION_STOP_FOREGROUND_SERVICE = "stop_service"
const val CHANNEL_NAME = "DEVICE_DETECTION_SERVICE"
const val SEARCHING_DEVICES_MESSAGE = "Searching in range device"
}
}
这是我的清单文件:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ngallazzi.bluetoothtests">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:name=".App"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity" android:launchMode="singleInstance">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<service android:name=".services.DeviceDetectionService" android:enabled="true"/>
<receiver android:name=".BootCompletedReceiver" android:enabled="true" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.REBOOT"/>
<action android:name="android.intent.action.QUICKBOOT_POWERON"/>
</intent-filter>
</receiver>
</application>
</manifest>
我想念什么?它与后台执行限制有关吗?
答案 0 :(得分:1)
尝试
步骤1 )将此标签
android:process
添加到您的服务类标签中 android:process =“ classname” 清单文件
然后在服务类别中执行此操作
第2步)在服务类中覆盖
onTaskRemoved()
使用警报管理器重新启动服务
第3步)要求用户启用已自定义操作系统的自动运行 权限
如果用户启用它,则您的服务将在该应用被终止后运行。
Link for autoenable permission code
注意:-复制此代码并将其粘贴,Kotlin转换器将自动对其进行转换