-1

Things i want to achieve:

  1. 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.
  2. 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 or WhatsApp.

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.

  1. 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.
  2. 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.
  3. 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?

0xdeadbeef
  • 21
  • 4

1 Answers1

1

In new versions of android, restrictions have been introduced on background running processes. the reason they do this is to provide battery optimization. I think you should use workmanager library. It is awesome library for background process. Also when device is rebooted, you can start a job with workmanager. I found for you an answer : PeriodicWorkRequest not working after device reboot in android oreo

  • one of my work is not deferrable and is need of executing every 60 seconds, what could be done in that situation? – 0xdeadbeef Jun 29 '20 at 16:09