使用前台服务
class MyService : Service() {
private var isStarted = false
companion object {
fun newServiceIntent(context: Context, action: String): Intent {
val intent = Intent(context, MyService::class.java)
intent.action = action
return intent
}
}
override fun onCreate() {
isStarted = false
setForeground()
super.onCreate()
}
private fun setForeground() {
val intent = Intent(this, SplashActivity::class.java)
val pi = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_IMMUTABLE)
val notification = NotificationUtil.pupNotification(this, pi, "")
startForeground(1, notification)
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
if (intent != null) {
val action = intent.action
if (TextUtils.equals(action, "start")) {
if (isStarted) {
return super.onStartCommand(intent, flags, startId)
}
isStarted = true
} else if (TextUtils.equals(action, "stop")) {
if (!isStarted) {
return super.onStartCommand(intent, flags, startId)
}
isStarted = false
}
}
return super.onStartCommand(intent, flags, startId)
}
override fun onDestroy() {
isStarted = false
super.onDestroy()
}
override fun onBind(intent: Intent?): IBinder {
return MyBinder()
}
inner class MyBinder : Binder() {
fun getService(): MyService {
return this@MyService
}
}
}
<service
android:name=".android.service.MyService"
android:enabled="true"
android:exported="false" />
object NotificationUtil {
fun pupNotification(mcontext: Context, pi: PendingIntent?, state: String?): Notification? {
var notification: Notification? = null
val mNotificationManager: NotificationManager
val id = "channel_service"
val name: CharSequence = "aispeech recorder"
val importance = NotificationManager.IMPORTANCE_HIGH
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
mNotificationManager =
mcontext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
val channel = NotificationChannel(id, name, importance)
channel.enableVibration(false)
channel.vibrationPattern = longArrayOf(0)
channel.setSound(null, null)
if (mNotificationManager != null) {
mNotificationManager.createNotificationChannel(channel)
notification = Notification.Builder(mcontext, id)
.setContentTitle("服务通知")
.setContentText(state)
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(
BitmapFactory.decodeResource(
mcontext.resources,
R.mipmap.ic_launcher
)
)
.setContentIntent(pi)
.build()
}
} else {
notification = Notification.Builder(mcontext)
.setContentTitle("语音")
.setContentText(state)
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(
BitmapFactory.decodeResource(
mcontext.resources,
R.mipmap.ic_launcher
)
)
.setContentIntent(pi)
.build()
}
return notification
}
}
startService(MyService .newServiceIntent(this, "start"))
使用jobservice
class NotificationService : JobService() {
companion object {
fun scheduleDaemonJob(context: Context, delay: Long = 5000L) {
val jobScheduler =
context.getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler
jobScheduler.cancel(1)
jobScheduler.schedule(
JobInfo.Builder(
context.packageName.hashCode(),
ComponentName(context, NotificationService::class.java)
)
.setMinimumLatency(delay)
.setPersisted(true)
.build()
)
}
}
override fun onLowMemory() {
super.onLowMemory()
scheduleDaemonJob(this)
}
override fun onStartJob(p0: JobParameters?): Boolean {
try {
if (!isAppAlive(packageName)) {
startActivity(packageManager.getLaunchIntentForPackage(packageName))
}
exitLater()
} catch (e: Throwable) {
e.printStackTrace()
}
return false
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
return START_NOT_STICKY
}
override fun onStopJob(p0: JobParameters?): Boolean {
return false
}
private fun isAppAlive(packageName: String): Boolean {
var isAppRunning = false
val am = getSystemService(ACTIVITY_SERVICE) as ActivityManager
val appProcessInfoList = am.runningAppProcesses
for (appProcessInfo in appProcessInfoList) {
if (packageName == appProcessInfo.processName) {
isAppRunning = true
break
}
}
return isAppRunning
}
private fun exitLater() {
Handler(mainLooper).postDelayed({
exitProcess(0)
}, 1000)
}
fun cancelScheduleDaemonJob(context: Context){
val jobScheduler = context.getSystemService(JobService.JOB_SCHEDULER_SERVICE) as JobScheduler
jobScheduler.cancel(context.packageName.hashCode())
}
}
<uses-permission
android:name="android.permission.BIND_JOB_SERVICE"
tools:ignore="ProtectedPermissions" />
<service
android:name=".android.service.NotificationService"
android:enabled="true"
android:exported="false"
android:permission="android.permission.BIND_JOB_SERVICE"
android:process=":guard" />
class MyApplication : Application() {
companion object {
private var mContext: Context? = null
fun getContext(): Context? {
if (mContext == null) {
throw RuntimeException("mContext is null")
}
return mContext
}
}
override fun onCreate() {
super.onCreate()
mContext = this
Fresco.initialize(this)
RobotUtil.init(this)
FaceServer.init(this)
if (isJobRunning(packageName.hashCode())) {
NotificationService.scheduleDaemonJob(this)
}
}
private fun Context.isJobRunning(jobId: Int): Boolean {
val jobScheduler = getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler
for (jobInfo in jobScheduler.allPendingJobs) {
if (jobInfo.id == jobId) {
return true
}
}
return false
}
}