add WorkManager extension
This commit is contained in:
parent
f35dbeb567
commit
0ea023047d
@ -38,6 +38,7 @@ include modulePrefix + 'extension-vp9'
|
||||
include modulePrefix + 'extension-rtmp'
|
||||
include modulePrefix + 'extension-leanback'
|
||||
include modulePrefix + 'extension-jobdispatcher'
|
||||
include modulePrefix + 'extension-workmanager'
|
||||
|
||||
project(modulePrefix + 'library').projectDir = new File(rootDir, 'library/all')
|
||||
project(modulePrefix + 'library-core').projectDir = new File(rootDir, 'library/core')
|
||||
@ -60,3 +61,4 @@ project(modulePrefix + 'extension-vp9').projectDir = new File(rootDir, 'extensio
|
||||
project(modulePrefix + 'extension-rtmp').projectDir = new File(rootDir, 'extensions/rtmp')
|
||||
project(modulePrefix + 'extension-leanback').projectDir = new File(rootDir, 'extensions/leanback')
|
||||
project(modulePrefix + 'extension-jobdispatcher').projectDir = new File(rootDir, 'extensions/jobdispatcher')
|
||||
project(modulePrefix + 'extension-workmanager').projectDir = new File(rootDir, 'extensions/workmanager')
|
||||
|
23
extensions/workmanager/README.md
Normal file
23
extensions/workmanager/README.md
Normal file
@ -0,0 +1,23 @@
|
||||
# ExoPlayer WorkManager extension #
|
||||
|
||||
This extension provides a Scheduler implementation which uses [Android Arch WorkManager][].
|
||||
|
||||
[Android Arch WorkManager]: https://developer.android.com/topic/libraries/architecture/workmanager.html
|
||||
|
||||
## Getting the extension ##
|
||||
|
||||
The easiest way to use the extension is to add it as a gradle dependency:
|
||||
|
||||
```gradle
|
||||
implementation 'com.google.android.exoplayer:extension-workmanager:2.X.X'
|
||||
```
|
||||
|
||||
where `2.X.X` is the version, which must match the version of the ExoPlayer
|
||||
library being used.
|
||||
|
||||
Alternatively, you can clone the ExoPlayer repository and depend on the module
|
||||
locally. Instructions for doing this can be found in ExoPlayer's
|
||||
[top level README][].
|
||||
|
||||
[top level README]: https://github.com/google/ExoPlayer/blob/release-v2/README.md
|
||||
|
49
extensions/workmanager/build.gradle
Normal file
49
extensions/workmanager/build.gradle
Normal file
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
apply from: '../../constants.gradle'
|
||||
apply plugin: 'com.android.library'
|
||||
|
||||
android {
|
||||
compileSdkVersion project.ext.compileSdkVersion
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion project.ext.minSdkVersion
|
||||
targetSdkVersion project.ext.targetSdkVersion
|
||||
}
|
||||
|
||||
testOptions.unitTests.includeAndroidResources = true
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation project(modulePrefix + 'library-core')
|
||||
implementation 'android.arch.work:work-runtime:1.0.0'
|
||||
}
|
||||
|
||||
ext {
|
||||
javadocTitle = 'Android Arch WorkManager extension'
|
||||
}
|
||||
apply from: '../../javadoc_library.gradle'
|
||||
|
||||
ext {
|
||||
releaseArtifact = 'extension-workmanager'
|
||||
releaseDescription = 'Android Arch WorkManager extension for ExoPlayer.'
|
||||
}
|
||||
apply from: '../../publish.gradle'
|
18
extensions/workmanager/src/main/AndroidManifest.xml
Normal file
18
extensions/workmanager/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (C) 2018 The Android Open Source Project
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<manifest package="com.google.android.exoplayer2.ext.workmanager"/>
|
@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright (C) 2018 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.google.android.exoplayer2.ext.workmanager;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
|
||||
import com.google.android.exoplayer2.scheduler.Requirements;
|
||||
import com.google.android.exoplayer2.scheduler.Scheduler;
|
||||
import com.google.android.exoplayer2.util.Assertions;
|
||||
import com.google.android.exoplayer2.util.Log;
|
||||
import com.google.android.exoplayer2.util.Util;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.work.Constraints;
|
||||
import androidx.work.Data;
|
||||
import androidx.work.ExistingWorkPolicy;
|
||||
import androidx.work.NetworkType;
|
||||
import androidx.work.OneTimeWorkRequest;
|
||||
import androidx.work.WorkManager;
|
||||
import androidx.work.Worker;
|
||||
import androidx.work.WorkerParameters;
|
||||
|
||||
/***
|
||||
* A {@link Scheduler} that uses {@link WorkManager}.
|
||||
*/
|
||||
public final class WorkManagerScheduler implements Scheduler {
|
||||
|
||||
private static final String TAG = "WorkManagerScheduler";
|
||||
private static final String KEY_SERVICE_ACTION = "service_action";
|
||||
private static final String KEY_SERVICE_PACKAGE = "service_package";
|
||||
private static final String KEY_REQUIREMENTS = "requirements";
|
||||
|
||||
private final String workName;
|
||||
|
||||
/**
|
||||
* @param workName A name for work scheduled by this instance. If the same name was used by a previous
|
||||
* instance, anything scheduled by the previous instance will be canceled by this instance if
|
||||
* {@link #schedule(Requirements, String, String)} or {@link #cancel()} are called.
|
||||
*/
|
||||
public WorkManagerScheduler(String workName) {
|
||||
this.workName = workName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean schedule(Requirements requirements, String servicePackage, String serviceAction) {
|
||||
Constraints constraints = buildConstraints(requirements);
|
||||
Data inputData = buildInputData(requirements, servicePackage, serviceAction);
|
||||
OneTimeWorkRequest workRequest = buildWorkRequest(constraints, inputData);
|
||||
logd("Scheduling work: " + workName);
|
||||
WorkManager.getInstance().enqueueUniqueWork(workName, ExistingWorkPolicy.KEEP, workRequest);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cancel() {
|
||||
logd("Canceling work: " + workName);
|
||||
WorkManager.getInstance().cancelUniqueWork(workName);
|
||||
return true;
|
||||
}
|
||||
|
||||
private static Constraints buildConstraints(Requirements requirements) {
|
||||
Constraints.Builder builder = new Constraints.Builder();
|
||||
|
||||
switch (requirements.getRequiredNetworkType()) {
|
||||
case Requirements.NETWORK_TYPE_NONE:
|
||||
builder.setRequiredNetworkType(NetworkType.NOT_REQUIRED);
|
||||
break;
|
||||
case Requirements.NETWORK_TYPE_ANY:
|
||||
builder.setRequiredNetworkType(NetworkType.CONNECTED);
|
||||
break;
|
||||
case Requirements.NETWORK_TYPE_UNMETERED:
|
||||
builder.setRequiredNetworkType(NetworkType.UNMETERED);
|
||||
break;
|
||||
default:
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
if (requirements.isChargingRequired()) {
|
||||
builder.setRequiresCharging(true);
|
||||
}
|
||||
|
||||
if (requirements.isIdleRequired() && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
builder.setRequiresDeviceIdle(true);
|
||||
}
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private static Data buildInputData(Requirements requirements, String servicePackage, String serviceAction) {
|
||||
Data.Builder builder = new Data.Builder();
|
||||
|
||||
builder.putInt(KEY_REQUIREMENTS, requirements.getRequirements());
|
||||
builder.putString(KEY_SERVICE_PACKAGE, servicePackage);
|
||||
builder.putString(KEY_SERVICE_ACTION, serviceAction);
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private static OneTimeWorkRequest buildWorkRequest(Constraints constraints, Data inputData) {
|
||||
OneTimeWorkRequest.Builder builder = new OneTimeWorkRequest.Builder(SchedulerWorker.class);
|
||||
|
||||
builder.setConstraints(constraints);
|
||||
builder.setInputData(inputData);
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private static void logd(String message) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, message);
|
||||
}
|
||||
}
|
||||
|
||||
/** A {@link Worker} that starts the target service if the requirements are met. */
|
||||
public static final class SchedulerWorker extends Worker {
|
||||
|
||||
private final WorkerParameters workerParams;
|
||||
private final Context context;
|
||||
|
||||
public SchedulerWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
|
||||
super(context, workerParams);
|
||||
this.workerParams = workerParams;
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Result doWork() {
|
||||
logd("SchedulerWorker is started");
|
||||
Data inputData = workerParams.getInputData();
|
||||
Assertions.checkNotNull(inputData, "Work started without input data.");
|
||||
Requirements requirements = new Requirements(inputData.getInt(KEY_REQUIREMENTS, 0));
|
||||
if (requirements.checkRequirements(context)) {
|
||||
logd("Requirements are met");
|
||||
String serviceAction = inputData.getString(KEY_SERVICE_ACTION);
|
||||
String servicePackage = inputData.getString(KEY_SERVICE_PACKAGE);
|
||||
Assertions.checkNotNull(serviceAction, "Service action missing.");
|
||||
Assertions.checkNotNull(servicePackage, "Service package missing.");
|
||||
Intent intent = new Intent(serviceAction).setPackage(servicePackage);
|
||||
logd("Starting service action: " + serviceAction + " package: " + servicePackage);
|
||||
Util.startForegroundService(context, intent);
|
||||
return Result.success();
|
||||
} else {
|
||||
logd("Requirements are not met");
|
||||
return Result.retry();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user