我正在尝试启动两个工作请求,一个工作人员向服务器发送请求以生成 excel 文件并获取 URL 以供下载。另一项工作在前一项之后开始,必须下载该文件。第一个工作开始并返回 Result.SUCCESS。问题是另一个 WorkRequest 只是没有执行。LoadInvoiceFileWorker什么都不做。我需要做什么或我做错了什么?
这是我的代码: InvoiceDetailsViewModel:
class InvoiceDetailsViewModel : ViewModel() {
private val mWorkManager: WorkManager = WorkManager.getInstance()
fun generateAndLoadExcel(invoiceId: Int, invoiceName: String, enterpriseId: Int) {
val genInvoiceWorkerBuilder = OneTimeWorkRequest.Builder(GenerateExcelWorker::class.java)
genInvoiceWorkerBuilder.setInputData(createInputDataForGenerateExcel(invoiceId, invoiceName, enterpriseId))
val constraintBuilder = Constraints.Builder()
//constraintBuilder.setRequiredNetworkType(NetworkType.CONNECTED)
genInvoiceWorkerBuilder.setConstraints(constraintBuilder.build())
val continuation = mWorkManager.beginWith(
genInvoiceWorkerBuilder.build()
)
val loadFileWorkerBuilder = OneTimeWorkRequest.Builder(LoadInvoiceFileWorker::class.java)
//loadFileWorkerBuilder.setConstraints(Constraints.NONE)
continuation.then(loadFileWorkerBuilder.build())
continuation.enqueue()
}
private fun createInputDataForGenerateExcel(invoiceId: Int, invoiceName: String, enterpriseId: Int): Data {
val builder = Data.Builder()
builder.putInt(WorkerConstants.INVOICE_ID, invoiceId)
builder.putString(WorkerConstants.INVOICE_NAME, invoiceName)
builder.putInt(WorkerConstants.ENTERPRISE_ID, enterpriseId)
return builder.build()
}
}
生成ExcelWorker:
class GenerateExcelWorker : Worker() {
companion object {
private val TAG = GenerateExcelWorker::class.java.simpleName
}
override fun doWork(): Result {
val appCont = applicationContext
val tokenType = PreferenceUtil.getString(TOKEN_TYPE, appCont, R.string.shared_pref_name)
val accessToken = PreferenceUtil.getString(ACCESS_TOKEN, appCont, R.string.shared_pref_name)
val enterpriseId = inputData.getInt(WorkerConstants.ENTERPRISE_ID, 0)
val invoiceId = inputData.getInt(WorkerConstants.INVOICE_ID, 0)
val invoiceName = inputData.getString(WorkerConstants.INVOICE_NAME)
makeStatusNotification(applicationContext, invoiceId, invoiceName
?: ("Invoice ${invoiceId.str()}"))
try {
val rd = RequestData()
rd.putValue("authorization", "$tokenType $accessToken", RequestData.TYPE_HEADER)
rd.putValue(FTUrls.SendingParameters.ENTERPRISE_ID, enterpriseId, RequestData.TYPE_PATH)
rd.putValue(FTUrls.SendingParameters.INVOICE_ID, invoiceId, RequestData.TYPE_PATH)
val excelUrl = InvoiceManager().generateIncomeInvoiceExcel(rd)
outputData = Data.Builder().putString(WorkerConstants.FILE_URL, excelUrl).build()
return Result.SUCCESS
} catch (t: Throwable) {
Log.e(TAG, "Error generating excel file for invoice $invoiceName ($invoiceId)", t)
if (t is UnauthenticatedException) {
outputData = Data.Builder().putBoolean(WorkerConstants.FILE_URL, true).build()
} else {
ExceptionLogger.logException(t)
Toast.makeText(applicationContext, t.message, Toast.LENGTH_SHORT).show()
}
return Result.FAILURE
}
}
private fun makeStatusNotification(context: Context, invoiceId: Int, invoiceTitle: String) {
// Make a channel if necessary
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
val name = WorkerConstants.NOTIFICATION_CHANNEL_NAME
val description = WorkerConstants.NOTIFICATION_CHANNEL_DESCRIPTION
val importance = NotificationManager.IMPORTANCE_HIGH
val channel = NotificationChannel(WorkerConstants.CHANNEL_ID, name, importance)
channel.description = description
// Add the channel
val notificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.createNotificationChannel(channel)
}
val builder = NotificationCompat.Builder(context, WorkerConstants.CHANNEL_ID)
.setSmallIcon(R.drawable.ic_autorenew_blue)
.setContentTitle(WorkerConstants.NOTIFICATION_TITLE)
.setContentText(String.format(WorkerConstants.NOTIFICATION_TEXT, invoiceTitle))
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setVibrate(LongArray(0))
NotificationManagerCompat.from(context).notify(invoiceId, builder.build())
}
}
加载发票文件工作者:
class LoadInvoiceFileWorker : Worker() {
companion object {
private val TAG = LoadInvoiceFileWorker::class.java.simpleName
}
override fun doWork(): Result {
try {
val fileUrl = inputData.getString(WorkerConstants.FILE_URL)
val invoiceId = inputData.getInt(WorkerConstants.INVOICE_ID, 0)
val invoiceName = inputData.getString(WorkerConstants.INVOICE_NAME)
val r = DownloadManager.Request(Uri.parse(fileUrl))
// This put the download in the same Download dir the browser uses
r.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, invoiceName
?: ("Invoice ${invoiceId.str()}"))
// Notify user when download is completed
r.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
// Start download
val dm = applicationContext.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager?
if (dm != null) {
dm.enqueue(r)
} else {
Log.w(TAG, "Download manager not exists for load invoice excel file")
ToastError(applicationContext, R.string.download_manager_not_found, Toast.LENGTH_SHORT)
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(fileUrl))
try {
applicationContext.startActivity(intent)
} catch (e: ActivityNotFoundException) {
Log.e(TAG, "Error open browser for view invoice excel file", e)
ToastError(applicationContext, R.string.browser_not_found, Toast.LENGTH_SHORT)
}
}
clearGenerateFileNotification(invoiceId)
return Result.SUCCESS
} catch (t: Throwable) {
Log.e(TAG, "Error loading excel generated file", t)
ExceptionLogger.logException(t)
ToastError(applicationContext, R.string.error_during_loading_file, Toast.LENGTH_SHORT)
return Result.FAILURE
}
}
private fun clearGenerateFileNotification(invoiceId: Int) {
val notificationManager = applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.cancel(invoiceId)
}
}
工人常数:
object WorkerConstants {
const val ENTERPRISE_ID = "enterprise_id"
const val INVOICE_ID = "invoice_id"
const val INVOICE_NAME = "invoice_name"
const val FILE_URL = "file_url"
const val UNIQUE_WORK_NAME_FOR_INVOICE = "generate_and_load_excel_for_invoice"
const val NOTIFICATION_CHANNEL_NAME = "GenerateExcelWorker Notifications"
const val NOTIFICATION_CHANNEL_DESCRIPTION = "Shows notifications whenever work starts"
const val NOTIFICATION_TITLE = "Генерація ексель файла"
const val NOTIFICATION_TEXT = "Генерація ексель файла накладної %s"
const val CHANNEL_ID = "GENERATE_INVOICE_NOTIFICATION"
}