Things i want to achieve:
- The task will be continuously running in background no matter if the app gets killed or the device reboots. Let say I'm syncing my contacts to a server and i need to check every minute if there's a new contact which is a very important requirement for my task.
- If we go to developers settings and then "Running Services" those services never gets killed. And keeps restarting after the device reboots. For e.g
facebookServices
orWhatsApp
.
Information of The physical device I'm using:
Android 10.
API Level 29
Things i have tried:
JobScheduler
WorkManager
Service (startService())
JobIntentService
AlarmManager
Problems I'm facing:
I have read many articles, blogs and watched a lot of videos but still not able to achieve what i exactly wanted. I also know if i use foregroundService with a notification channel my service will not get killed and persist but i Don't want that because there must be way facebookServices are running without any notification channel they are just running background Services even on API level 29 with all background restrictions after Android O.
- Used a combination of AlarmManager with a BroadcastReceiver which tries to start a service on a specific time. But there's continuous exception throwing
java.lang.IllegalStateException: Not allowed to start service Intent
. - Tried workManager, it does the job only when the app is open and not when i close the app. It also not restarting the work if i reboot the device.
- JobScheduler is also not able to fetch exactly what i want.
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.basicplayer">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<application
android:allowBackup="true"
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">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".MyAlarmService"
android:enabled="true"
android:exported="true"
/>
<receiver android:name=".MyAlarmReceiver"
android:enabled="true"
android:exported="true"
>
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
MyAlarmReceiver.java
package com.example.basicplayer;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Build;
import android.provider.Settings;
import androidx.annotation.RequiresApi;
public class MyAlarmReceiver extends BroadcastReceiver {
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public void onReceive(Context context, Intent intent) {
context.startService(new Intent(context, MyAlarmService.class));
}
}
MyAlarmService.java
package com.example.basicplayer;
import android.app.Notification;
import android.app.Service;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.IBinder;
import android.provider.Settings;
import androidx.annotation.Nullable;
public class MyAlarmService extends Service {
private MediaPlayer mediaPlayer;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
mediaPlayer = MediaPlayer.create(this,
Settings.System.DEFAULT_ALARM_ALERT_URI);
mediaPlayer.setLooping(true);
mediaPlayer.start();
return START_STICKY;
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public void onDestroy() {
super.onDestroy();
try{
startService(new Intent(this, MyAlarmService.class));
}catch (Exception e){
e.printStackTrace();
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
MainActivity.java
package com.example.basicplayer;
import androidx.appcompat.app.AppCompatActivity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.provider.Settings;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setAlarm();
}
private void setAlarm() {
//getting the alarm manager
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
//creating a new intent specifying the broadcast receiver
Intent i = new Intent(this, MyAlarmReceiver.class);
//creating a pending intent using the intent
PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0);
//setting the repeating alarm that will be fired every day
am.setRepeating(AlarmManager.RTC, 10000, AlarmManager.INTERVAL_FIFTEEN_MINUTES, pi);
Toast.makeText(this, "Alarm is set", Toast.LENGTH_SHORT).show();
}
}
Can you guys help?