LoginSignup
9
12

More than 5 years have passed since last update.

Android Oreo対応 - バックグラウンドジョブ編

Last updated at Posted at 2018-09-19

背景

Android Oreoのリリースにより、従来バックグラウンド上常に動くServiceは動かなくなるため、対応しました。以下はその対応の記載です。

Android Oreo Background Limit

対応策

Serviceはそのまま使えないので、Androidドキュメントに勧められたJobSchedulerを使って、実装しようと思います。

選択肢として以下のライブラリがあります。

accaa1e9-daee-fb4a-d74f-f1dff959bb1f.png

ちなみに、android-jobというevernoteが作ったライブラリもありますが、WorkManagerは同じ実装をしたようです。

その中でできればAPIレベル低い、かつ柔軟に対応してくれるのは基準としてWorkManagerを選びました。

メリット

  • API 14+
  • No require Google Play Service
  • Googleが出している
  • 端末のOSバージョンとアプリのtargetSdkVersionにより、柔軟に対応してくれる

デメリット

実装

  • Workerを実装
public class MyWorker extends Worker {
    public static final String TAG = MyWorker.class.getSimpleName();

    @NonNull
    @Override
    public Result doWork() {
        LogUtil.debug(TAG, "Start My Worker");

        try {
            MYTracking myTracking = MyTracking.getInstance(getApplicationContext());
            myTracking.start();
        }
        catch (Exception e) {
            e.printStackTrace();
            // TODO: deal with exception
            return Result.RETRY;
        }
        return Result.SUCCESS;
    }
}
  • Trackingクラスを実装
public class MyTracking {

    private MyTracking() {

    }

    public static MyTracking getInstance(Context _context) {
        context = _context;

        return instance;
    }

    public void start() {
        if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            LogUtil.e(TAG, "Need ACCESS_FINE_LOCATION permission to start MyWorker!");
            return;
        }

        // 制約を設定する
        Criteria criteria = new Criteria();
        criteria.setSpeedRequired(false);
        criteria.setAltitudeRequired(false);
        criteria.setBearingRequired(false);
        criteria.setCostAllowed(true);

        locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
        String bestProvider = locationManager.getBestProvider(criteria, true);
        LogUtil.debug(TAG, "The best provider is: " + bestProvider);

        Looper looper = Looper.getMainLooper();
        MyListener myListener = new MyListener(context);

        locationManager.requestSingleUpdate(bestProvider, myListener, looper);
    }
}
  • Mainのcreateメソッドの中からWorkerを呼び出す
private void startTracking() {
        Constraints constraints = new Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build();
        PeriodicWorkRequest request = new PeriodicWorkRequest.Builder(MyWorker.class, REPEAT_INTERVAL, TimeUnit.MINUTES).setConstraints(constraints).addTag(MyWorker.TAG).build();
        // すでにMyWorkerが存在している場合は、入れ替えます。
        WorkManager.getInstance().enqueueUniquePeriodicWork("MyWorker", ExistingPeriodicWorkPolicy.REPLACE, request);
    }

感想

WorkManagerを使ってバックグラウンドジョブの実装は大分楽になりました。

参照

9
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
12