【问题标题】:Can I start a foregrouond task in FirebaseMessagingService?我可以在 FirebaseMessagingService 中启动前台任务吗?
【发布时间】:2019-12-16 10:24:17
【问题描述】:

我想通过接收来自 Firebase 的通知来开始一个漫长的过程(比如上传文件)。我不想启动新的前台服务,但我想在同一个类中处理上传,如下所示:

public class MyFirebaseMessagingService extends FirebaseMessagingService {

@Override
public void onMessageReceived(RemoteMessage remoteMessage) {
    if (remoteMessage.getNotification() != null) {
        final String title=remoteMessage.getNotification().getTitle();
        final String tag = remoteMessage.getNotification().getTag();
        String body = remoteMessage.getNotification().getBody();

        if (tag.equals("start")) {
            startUpload(title,body);
        }
    }
}


public void startUplaod(String title,String body){
    ShowNotification(title,body);
    // and start upload
}

public void ShowNotification(String title,String text){
    Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle(title)
            .setContentText(text)
            .setSmallIcon(R.drawable.ic_launcher_foreground)
            .build();
    startForeground(1, notification);
}
}

当我向正在运行的设备发送通知时,有时我会在我的服务器上收到目标文件,有时却没有!通知不粘,我不确定上传任务是否完成?我想完成任务有时间限制(可能是几秒钟),然后上传失败。

FirebaseMessagingService 类中启动长任务是否有任何限制?也就是说startForeground可以强制FirebaseMessagingService长时间启动前台任务吗?

【问题讨论】:

  • 你是怎么解决的?
  • 没有办法。完成任务有时间限制。 @user60108

标签: android firebase-cloud-messaging foreground-service


【解决方案1】:
  • 对于所有提供 onMessageReceived 的消息,您的服务应在收到后 20 秒内处理任何消息(Android Marshmallow 为 10 秒)。时间窗口可能会更短,具体取决于调用 onMessageReceived 之前发生的操作系统延迟。之后,Android O 的后台执行限制等各种操作系统行为可能会干扰您完成工作的能力。
  • 你可以使用 JobIntentService 或 WorkManager 上传任务吗,我收到通知后制作了一个示例下载图片。

    class ImageDownloadPushService : JobIntentService() {
    
    override fun onHandleWork(intent: Intent) {
        val bitmap = downloadImage("url")
        Log.e("ImageDownload", "$bitmap")
    }
    
    private fun downloadImage(address: String?): Bitmap? {
        // Convert string to URL
        val url = getUrlFromString(address)
        // Get input stream
        val inputStream = url?.let { getInputStream(it) } ?: return null
        // Decode bitmap
        // Return bitmap result
        return decodeBitmap(inputStream)
    }
    
    
    private fun getUrlFromString(address: String?): URL? {
        return try {
            URL(address)
        } catch (e1: Throwable) {
            null
        }
    }
    
    private fun getInputStream(url: URL): InputStream? {
        var inputStream: InputStream?
        // Open connection
        val conn: URLConnection
        try {
            conn = url.openConnection()
            conn.connect()
            inputStream = conn.getInputStream()
        } catch (e: IOException) {
            inputStream = null
        }
    
        return inputStream
    }
    
    private fun decodeBitmap(inputStream: InputStream): Bitmap? {
        var bitmap: Bitmap?
        try {
            // Turn response into Bitmap
            bitmap = BitmapFactory.decodeStream(inputStream)
            // Close the input stream
            inputStream.close()
        } catch (e: IOException) {
            bitmap = null
        }
    
        return bitmap
    }
    
    companion object {
        private const val JOB_ID = 101
        fun enqueueWork(context: Context, work: Intent) {
            enqueueWork(context, ImageDownloadPushService::class.java, JOB_ID, work)
        }
    }
    

    }

  • 在 onMessageReceived() 中

    override fun onMessageReceived(context: Context, remoteMessage: ToastRemoteMessage) {
         ImageDownloadPushService.enqueueWork(context, Intent())
    }
    

【讨论】:

  • 不启动前台服务算作处理 FCM 消息吗?
  • 不应该,应该使用后台服务,因为你可以在应用关闭时收到通知。
猜你喜欢
  • 1970-01-01
  • 2018-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-03
  • 1970-01-01
  • 2017-02-13
  • 1970-01-01
相关资源
最近更新 更多