يوفّر WorkManager دعمًا مضمَّنًا للعاملين على المدى البعيد. في مثل هذه الحالات، يمكن أن يقدم WorkManager إشارة لنظام التشغيل بضرورة استمرار العملية إن أمكن أثناء تنفيذ هذا العمل. يمكن لهؤلاء العاملين العمل لفترة أطول من 10 دقيقة. من أمثلة حالات الاستخدام لهذه الميزة الجديدة التحميلات المجمّعة أو عمليات التنزيل (التي لا يمكن تجزئتها) أو معالجة نموذج تعلُّم الآلة محليًا أو مهمة المهم لمستخدم التطبيق.
الخيارات المتقدمة، يدير WorkManager خدمة تعمل في المقدّمة ويديرها نيابةً عنك
لتنفيذ WorkRequest
، مع عرض رمز قابل للضبط أيضًا
.
أصبحت ListenableWorker
متوافقة الآن مع setForegroundAsync()
API
يتوافق CoroutineWorker
مع واجهة برمجة تطبيقات setForeground()
للتعليق. هذه
تتيح واجهات برمجة التطبيقات للمطوّرين تحديد أنّ WorkRequest
مهمة هذه (بدءًا من
منظور المستخدم) أو على المدى الطويل.
بدءًا من 2.3.0-alpha03
، يسمح لك WorkManager أيضًا بإنشاء
PendingIntent
، التي يمكن استخدامها لإلغاء الموظفين بدون الحاجة إلى
تسجيل مكوّن Android جديد باستخدام createCancelPendingIntent()
واجهة برمجة التطبيقات. ويكون هذا المنهج مفيدًا بشكل خاص عند استخدامه مع
واجهات برمجة التطبيقات setForegroundAsync()
أو setForeground()
، والتي يمكن استخدامها لإضافة
إشعار لإلغاء Worker
.
خلق عمالة طويلة الأمد وإدارتها
ستستخدم أسلوبًا مختلفًا قليلاً اعتمادًا على ما إذا كنت تقوم بالترميز في Kotlin أو Java.
Kotlin
على مطوّري Kotlin استخدام CoroutineWorker
. بدلاً من استخدام
setForegroundAsync()
، يمكنك استخدام الإصدار المعلَّق من هذه الطريقة،
setForeground()
class DownloadWorker(context: Context, parameters: WorkerParameters) :
CoroutineWorker(context, parameters) {
private val notificationManager =
context.getSystemService(Context.NOTIFICATION_SERVICE) as
NotificationManager
override suspend fun doWork(): Result {
val inputUrl = inputData.getString(KEY_INPUT_URL)
?: return Result.failure()
val outputFile = inputData.getString(KEY_OUTPUT_FILE_NAME)
?: return Result.failure()
// Mark the Worker as important
val progress = "Starting Download"
setForeground(createForegroundInfo(progress))
download(inputUrl, outputFile)
return Result.success()
}
private fun download(inputUrl: String, outputFile: String) {
// Downloads a file and updates bytes read
// Calls setForeground() periodically when it needs to update
// the ongoing Notification
}
// Creates an instance of ForegroundInfo which can be used to update the
// ongoing notification.
private fun createForegroundInfo(progress: String): ForegroundInfo {
val id = applicationContext.getString(R.string.notification_channel_id)
val title = applicationContext.getString(R.string.notification_title)
val cancel = applicationContext.getString(R.string.cancel_download)
// This PendingIntent can be used to cancel the worker
val intent = WorkManager.getInstance(applicationContext)
.createCancelPendingIntent(getId())
// Create a Notification channel if necessary
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
createChannel()
}
val notification = NotificationCompat.Builder(applicationContext, id)
.setContentTitle(title)
.setTicker(title)
.setContentText(progress)
.setSmallIcon(R.drawable.ic_work_notification)
.setOngoing(true)
// Add the cancel action to the notification which can
// be used to cancel the worker
.addAction(android.R.drawable.ic_delete, cancel, intent)
.build()
return ForegroundInfo(notificationId, notification)
}
@RequiresApi(Build.VERSION_CODES.O)
private fun createChannel() {
// Create a Notification channel
}
companion object {
const val KEY_INPUT_URL = "KEY_INPUT_URL"
const val KEY_OUTPUT_FILE_NAME = "KEY_OUTPUT_FILE_NAME"
}
}
Java
بإمكان المطوّرين الذين يستخدمون ListenableWorker
أو Worker
الاتصال بـ
setForegroundAsync()
API التي تعرض ListenableFuture<Void>
. إِنْتَ
سيكون بإمكان الطفل أيضًا الاتصال بـ setForegroundAsync()
لتعديل Notification
الحالية.
في ما يلي مثال بسيط على عامل يعمل لوقت طويل وينزّل أحد الملفات. هذا النمط
يتتبّع العامل مستوى التقدّم لتعديل "Notification
" الحالي الذي يعرض.
تقدم التنزيل.
public class DownloadWorker extends Worker {
private static final String KEY_INPUT_URL = "KEY_INPUT_URL";
private static final String KEY_OUTPUT_FILE_NAME = "KEY_OUTPUT_FILE_NAME";
private NotificationManager notificationManager;
public DownloadWorker(
@NonNull Context context,
@NonNull WorkerParameters parameters) {
super(context, parameters);
notificationManager = (NotificationManager)
context.getSystemService(NOTIFICATION_SERVICE);
}
@NonNull
@Override
public Result doWork() {
Data inputData = getInputData();
String inputUrl = inputData.getString(KEY_INPUT_URL);
String outputFile = inputData.getString(KEY_OUTPUT_FILE_NAME);
// Mark the Worker as important
String progress = "Starting Download";
setForegroundAsync(createForegroundInfo(progress));
download(inputUrl, outputFile);
return Result.success();
}
private void download(String inputUrl, String outputFile) {
// Downloads a file and updates bytes read
// Calls setForegroundAsync(createForegroundInfo(myProgress))
// periodically when it needs to update the ongoing Notification.
}
@NonNull
private ForegroundInfo createForegroundInfo(@NonNull String progress) {
// Build a notification using bytesRead and contentLength
Context context = getApplicationContext();
String id = context.getString(R.string.notification_channel_id);
String title = context.getString(R.string.notification_title);
String cancel = context.getString(R.string.cancel_download);
// This PendingIntent can be used to cancel the worker
PendingIntent intent = WorkManager.getInstance(context)
.createCancelPendingIntent(getId());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
createChannel();
}
Notification notification = new NotificationCompat.Builder(context, id)
.setContentTitle(title)
.setTicker(title)
.setSmallIcon(R.drawable.ic_work_notification)
.setOngoing(true)
// Add the cancel action to the notification which can
// be used to cancel the worker
.addAction(android.R.drawable.ic_delete, cancel, intent)
.build();
return new ForegroundInfo(notificationId, notification);
}
@RequiresApi(Build.VERSION_CODES.O)
private void createChannel() {
// Create a Notification channel
}
}
إضافة نوع خدمة تعمل في المقدّمة إلى عامل منذ فترة طويلة
إذا كان تطبيقك يستهدف Android 14 (المستوى 34 لواجهة برمجة التطبيقات) أو إصدارًا أحدث، عليك تحديد
لنوع الخدمة التي تعمل في المقدّمة لجميع العاملين منذ فترة طويلة.
إذا كان تطبيقك يستهدف الإصدار 10 من نظام التشغيل Android (المستوى 29 من واجهة برمجة التطبيقات) أو إصدارًا أحدث ويحتوي على
عاملًا منذ فترة طويلة يتطلب الوصول إلى موقع جغرافي، إلى أن يشير إلى أنّ العامل
تستخدم نوع الخدمة التي تعمل في المقدّمة من location
.
إذا كان تطبيقك يستهدف الإصدار 11 من نظام التشغيل Android (المستوى 30 من واجهة برمجة التطبيقات) أو الإصدارات الأحدث
ويحتوي على عامل عريقة يتطلب الوصول إلى الكاميرا أو الميكروفون،
توضيح camera
أو microphone
في المقدّمة
أنواع الخدمات على التوالي.
لإضافة هذه الأنواع من الخدمات التي تعمل في المقدّمة، عليك إكمال الخطوات الموضّحة في الأقسام التالية.
تعريف أنواع الخدمات التي تعمل في المقدّمة في بيان التطبيق
يُرجى تعريف نوع الخدمة التي تعمل في المقدّمة في بيان التطبيق في بيان التطبيق. في جلسة المعمل، على سبيل المثال، يطلب العامل الوصول إلى الموقع والميكروفون:
<service android:name="androidx.work.impl.foreground.SystemForegroundService" android:foregroundServiceType="location|microphone" tools:node="merge" />
تحديد أنواع الخدمات التي تعمل في المقدّمة في وقت التشغيل
عند استدعاء setForeground()
أو setForegroundAsync()
، تأكد من تحديد
نوع الخدمة التي تعمل في المقدّمة:
Kotlin
private fun createForegroundInfo(progress: String): ForegroundInfo { // ... return ForegroundInfo(NOTIFICATION_ID, notification, FOREGROUND_SERVICE_TYPE_LOCATION or FOREGROUND_SERVICE_TYPE_MICROPHONE) }
Java
@NonNull private ForegroundInfo createForegroundInfo(@NonNull String progress) { // Build a notification... Notification notification = ...; return new ForegroundInfo(NOTIFICATION_ID, notification, FOREGROUND_SERVICE_TYPE_LOCATION | FOREGROUND_SERVICE_TYPE_MICROPHONE); }