I am working on scheduling app in which i have to run the app until it completes it process
but the problem is , Process is getting killed after few minute even it is running on foreground service ...
class MyService : Service(){
#RequiresApi(Build.VERSION_CODES.O)
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
showNotification()
println("intent ${startId}")
isServiceStarted =true
val action = intent?.action
when(action){
ADD_SERVICE ->{
val sms = intent.getParcelableExtra<Sms>(Add_kEY)
if(sms!=null) {
schedule(sms) } }
DELETE_SERVICE ->{ }
}
return START_REDELIVER_INTENT
}
}
// Manifest file
<service android:name=".service.MyService "
android:foregroundServiceType="dataSync"
/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
you should call startForeground() in your service to attach your service to your application lifecycle to prevent OS from killing your service.
foreground-services
Related
I have a service app with no activity. I want to connect it with my main app, because I will send data from main app to service, then get response from it. Service should be launched programmatically.
If they was in same project, i could tag it in manifest like <service android:name.../> . I tried to intent but packageManager.getLaunchIntentForPackage also didn't work. Other apps with activity works with this way but service app is different.
Main App - Try to intent
val i = packageManager.getLaunchIntentForPackage("com.myexample.serviceapp")
if (i!=null) {
Log.d("MyService","Success")
startService(i)
} else {
Toast.makeText(this,"Fail",Toast.LENGTH_SHORT).show()
}
Main App - Manifest
<queries>
<package android:name="com.myexample.serviceapp"/>
</queries>
Service App
class RegistryService : Service() {
override fun onBind(p0: Intent?): IBinder? = null
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
Log.d("MyService","working")
Thread {
while (true) {
Log.d("MyService","working 2")
}
}.start()
return START_STICKY
}
}
Service Manifest
<service android:name=".RegistryService" />
It solve the problem.
val i = Intent().apply {
this.setClassName("com.myexample.serviceapp", "com.myexample.serviceapp.RegistryService")
}
startForegroundService(i)
Since AsyncTask, IntentSerrvice and JobIntentService are all deprecated, which tool or class should I go for in 2022?
I want to re-schedule alarms in a BroadcastReceiver after a device rebooted (since alarms get lost in the process). The task will most probably take < 1 min to finish. I just need the safety of it completing and not being killed off by the system.
The documentation on Broadcasts shows an (outdated) example with goAsync() and the deprecated AsyncTask.
But it also mentions JobService. Is that the replacement? What about WorkManager?
goAsync() return a PendingIntent - it mean you ask for android system extend time life of Broadcast receiver => goAsync() is used for short background task.
Life time of BroadcastReceiver is very short, so... for long time background task, you must to change to other context has longer life time, such as: Service, JobService..etc.
Example:
BroadcastReceiver received intent
BroadcastReceiver start a service, run worker thread to process long time task
after worker thread finish, call finish service too
=========================================
class MyIntentService : Service() {
private val handleThread = HandlerThread("MyThread")
private lateinit var workerHandler: Handler
override fun onCreate() {
super.onCreate()
handleThread.start()
workerHandler = Handler(handleThread.looper)
}
override fun onDestroy() {
workerHandler.removeCallbacksAndMessages(null)
handleThread.quitSafely()
super.onDestroy()
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
val data = intent?.data
workerTask(data)
return START_NOT_STICKY
}
private fun workerTask(data: Uri?) {
workerHandler.post {
heavyTask(data)
finishMyIntentService()
}
}
private fun finishMyIntentService() {
stopSelf()
}
private fun heavyTask(data: Uri?) {
// to do heavyTask example
for (i in 1..20)
{
Log.d("test","#heavyTask() $i")
Thread.sleep(1000)
}
}
override fun onBind(intent: Intent?): IBinder? {
TODO("Not yet implemented")
}
}
then startService from BroadCastReceiver
I'm making a todolist app where the user needs to add a task along with date and time that i use later to trigger the notification , when app is in foreground , it works fine but since services are submitted to limitations after android oreo , now i'm lost on how to trigger the notification when app is in background or killed , if you guys could enlighten me , i woudl appreciate it
This is my service class
class NotificationService(var context: FragmentActivity) : Service(){
private lateinit var remindersViewModel: remindersViewModel
private lateinit var compat : NotificationManagerCompat
override fun onCreate() {
super.onCreate()
compat = NotificationManagerCompat.from(this)
remindersViewModel = ViewModelProvider(context)[remindersViewModel::class.java]
}
override fun onBind(intent: Intent?): IBinder? {
return null
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
isNotificationEnabled()
return START_NOT_STICKY
}
override fun onDestroy() {
super.onDestroy()
}
private fun isNotificationEnabled(){
//TODO : NOTIFICATION
val notificationPrefs = getSharedPreferences("notificationPrefs", Context.MODE_PRIVATE)
val isNotificationEnabled = notificationPrefs.getBoolean("notification", false)
remindersViewModel.getAllTasks().observe(context, Observer {
if(isNotificationEnabled){
CoroutineScope(Dispatchers.Main).launch {
delay(3000)
HandleOperations.taskNotification(it, context, compat)
}
}
})
}
}
As of Android Oreo, all background services will be killed if not visible by a foreground service. The best case scenario for your problem is to use a Job Scheduler (here).
For timely event based tasks Job Sceduler is the only options though it's no longer available in the support library.
You will also need a Notification Channel for devices with Oreo and above.
I have an Intent service & a BroadcastReceiver.
As per background limitation on Android Oreo & above, the background applications(when an application is not foreground ) cannot use the started service. When you call startService() method from the background applications simply through the IllegalStateException.
But In my case, My intent service is running properly even when the app is in the background.
I am using ADB cmd to trigger broadcast.
Please correct where I am missing.
adb shell am broadcast -a android.intent.action.TEST --es maxCountValue 10 -n com.example.servicedemo/.MyReceiver
enter code here
BroadcastReceiver class
class MyReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
Toast.makeText(context, "CompleteReceiver", Toast.LENGTH_LONG).show()
if (intent!!.action.equals("android.intent.action.TEST")) {
val mIntent = Intent(context, MyIntentService::class.java).apply {
Log.v("MyIntentService", intent.data.toString())
this.putExtra("maxCountValue", 100)
}
context?.startService(mIntent)
}
}
}
Intent Service
private const val SERVICE_NAME = "MyIntentService"
class MyIntentService : IntentService(SERVICE_NAME) {
private val handler = Handler()
override fun onCreate() {
super.onCreate()
showToast("Job Execution Started")
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
showToast("Job Execution onStartCommand")
return super.onStartCommand(intent, flags, startId)
}
override fun onDestroy() {
super.onDestroy()
showToast("Job Execution onDestroy")
}
override fun onHandleIntent(intent: Intent?) {
val maxCount = intent!!.getIntExtra("maxCountValue", -1)
for (i in 0 until maxCount) {
Log.d(SERVICE_NAME, "onHandleWork: The number is: $i")
try {
Thread.sleep(100)
} catch (e: InterruptedException) {
Log.d(SERVICE_NAME, "Exception: ")
e.printStackTrace()
}
}
}
private fun showToast(msg: String) {
handler.post {
Toast.makeText(this#MyIntentService, msg, Toast.LENGTH_LONG).show()
}
}
}
Manifest :
<service android:name=".MyIntentService"/>
<receiver android:name=".MyReceiver">
<intent-filter>
<action android:name="android.intent.action.TEST" />
</intent-filter>
</receiver>
"The definition of background for purposes of service limitations is distinct from the definition used by memory management; an app might be in the background as pertains to memory management, but in the foreground as pertains to its ability to launch services."
-
https://developer.android.com/about/versions/oreo/background
PS that's the whole purpose of services
I did a Foreground Service using Kotlin. It's works , but after seven hours running my service stop and my app returned to its first page (login page). But the only method to stop my service is executed when I click in a "stop service" button, so why my service is stopping after 7 hours if i didn't press any button? i'm using a moto g7, android 9.0
class RastreioService : Service() {
companion object {
var serviceAtivado = false //service activated
}
override fun onBind(intent: Intent?): IBinder? {
TODO("Not yet implemented")
}
override fun onCreate() {
super.onCreate()
serviceAtivado = true
val notificationIntent = Intent(this, RastreioService::class.java)
val pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
val notification = Notification.Builder(this, "1")
.setSmallIcon(R.drawable.ic_gps_ativo)
.setContentTitle("Localização Sendo Acessada")
.setContentText("A sua localização está sendo acessada")
.setContentIntent(pendingIntent)
.build()
startForeground(1, notification)
/*request location methods*/
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
return START_NOT_STICKY
}
override fun onDestroy() {
serviceAtivado = false
super.onDestroy()
this.gerenciadorDeLocalizacao.DesativarBuscaPorLocalizaca()
}
}
OS still can shut down services if it feels like it needs to, but it can be resumed afterward.
on onStartCommand you are returning START_NOT_STICKY
you can use which does not re start the service.
You can use START_REDELIVER_INTENT to save progress of your service and re start it from where it left of.
Link to the docs
A foreground service can still be killed by the OS, you have no guarantees that the service will last forever. A foreground service just makes it less likely to be killed