6

Currently i am working with an application and my app has a feature that the user will be able to click on a Navigate button and my app will start the Google Map. Till now it's fine and i have done it. But the fact where i am stuck is that i want my app to perform some tasks. To achieve that i have used JobService and scheduled it to run after every 5 seconds even when the app is in background.

When the user presses the back button then inside onDestroy method i have cancelled the scheduler. But when the app is removed from the background by sliding or pressing the cross icon the JobService keeps running as the onDestroy method can be called or not by the os when it is removed from the background. How can i stop the scheduled job when the app is removed from the background?

enter image description here

enter image description here

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="javarank.com.serviceinbackground">

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

    <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=".MyJobService" android:exported="true" android:permission="android.permission.BIND_JOB_SERVICE" />

    </application>

</manifest>

MyJobService class

public class MyJobService extends JobService {

    @Override
    public boolean onStartJob(final JobParameters jobParameters) {
        Toast.makeText(getApplicationContext(), "Doing job", Toast.LENGTH_SHORT).show();
        jobFinished(jobParameters, true);
        return false;
    }

    @Override
    public boolean onStopJob(JobParameters jobParameters) {
        return false;
    }
}

Here is my MainActivity

public class MainActivity extends AppCompatActivity {

    private static final  int JOB_ID = 1;

    private JobInfo jobInfo;
    private JobScheduler scheduler;

    private Button navigateButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ComponentName componentName = new ComponentName(this, MyJobService.class);
        JobInfo.Builder builder = new JobInfo.Builder(JOB_ID, componentName);
        builder.setPeriodic(5000);
        builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
        // if true this job exists even after a system reboot...
        builder.setPersisted(false);


        jobInfo = builder.build();

        scheduler = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE);
        scheduler.schedule(jobInfo);

        navigateButton = (Button) findViewById(R.id.navigate_button);

        navigateButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                StringBuffer url = new StringBuffer("https://www.google.com/maps/dir/?api=1");
                url.append("&origin=23.755736,90.374627");
                url.append("&destination=23.754047,90.371682");
                url.append("&travelmode=driving");
                Uri gmmIntentUri = Uri.parse(url.toString());
                Intent mapIntent = new Intent(Intent.ACTION_VIEW, gmmIntentUri);
                mapIntent.setPackage("com.google.android.apps.maps");
                startActivity(mapIntent);
            }
        });

    }

    @Override
    protected void onDestroy() {
        Toast.makeText(getApplicationContext(), "Destroy called.", Toast.LENGTH_SHORT).show();
        scheduler.cancel(JOB_ID);
        super.onDestroy();
    }

}
Zoe
  • 27,060
  • 21
  • 118
  • 148
Anik Dey
  • 616
  • 8
  • 17

4 Answers4

0

You can create a new service like

MyService.java

public class MyService extends Service {
public MyService() {
}

@Override
public IBinder onBind(Intent intent) {
    return null;
}    
@Override
public void onTaskRemoved(Intent rootIntent) {
    super.onTaskRemoved(rootIntent);
    //stop you jobservice from here
    stopSelf();
}
 }

and start it from MainActivity.java

startService(new Intent(MainActivity.this,MyService.class));
Mayank Panchal
  • 355
  • 1
  • 10
0

I think you need to override following onStop() method and put stopService() command to stop the JobService.

@Override
protected void onStop() {
    // A service can be "started" and/or "bound". In this case, it's "started" by this Activity
    // and "bound" to the JobScheduler (also called "Scheduled" by the JobScheduler). This call
    // to stopService() won't prevent scheduled jobs to be processed. However, failing
    // to call stopService() would keep it alive indefinitely.
    stopService(new Intent(this, MyJobService.class));
    super.onStop();
}
Pang
  • 9,564
  • 146
  • 81
  • 122
0

Android> 7 automatically saves battery power. You must turn on the application's battery saving stop feature.

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            Intent intent = new Intent();
            String packageName = getPackageName();
            PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
            if (!pm.isIgnoringBatteryOptimizations(packageName)) {
                intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
                intent.setData(Uri.parse("package:" + packageName));
                startActivity(intent);
            }
        }

add this to AndroidManifest.xml

<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
khoane
  • 31
  • 1
  • 4
0

I faced this issue, but I found that after schedule job service, it can't be canceled (From view). So I turned to stop it inside the job service by calling onStopJob(params) and it worked.

Eng.OsamaYousef
  • 458
  • 2
  • 5
  • 10