Context.startForegroundService()然后没有调用Service.startForeground()?

2024-01-07

我的用户报告了数百起崩溃,但我仍然找不到解决方案。这些崩溃来自 Android 8(三星、华为、谷歌)。

我遇到这两次崩溃:

Fatal Exception: android.app.RemoteServiceException: Context.startForegroundService() did not then call Service.startForeground()
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1881)
       at android.os.Handler.dispatchMessage(Handler.java:105)
       at android.os.Looper.loop(Looper.java:164)
       at android.app.ActivityThread.main(ActivityThread.java:6938)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)

另一个:

Fatal Exception: android.app.RemoteServiceException: Context.startForegroundService() did not then call Service.startForeground()
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2104)
       at android.os.Handler.dispatchMessage(Handler.java:108)
       at android.os.Looper.loop(Looper.java:166)
       at android.app.ActivityThread.main(ActivityThread.java:7428)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:245)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:921)

我假设这些崩溃是相同的,但正如您所看到的,堆栈跟踪显示了不同的代码行。

问题是我无法重现它,在我的设备和模拟器上一切正常。但是,我(以某种方式)通过创建服务而不调用startForeground()Service class.

我无法“捕获”异常,因为它是在创建服务 5 秒后立即来自系统级别的。

我所做的是创建了一个方法,该方法创建粘性通知并调用startForeground方法(我的服务类):

private void startWithNotification() {
     Resources res = getResources();
     String title = res.getString(R.string.application_name);

     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
         createChannels();
     }

     NotificationCompat.Builder builder =  new NotificationCompat.Builder(context, ANDROID_CHANNEL_ID)
             .setContentTitle(title)
             .setChannelId(ANDROID_CHANNEL_ID)
             .setCategory(NotificationCompat.CATEGORY_SERVICE)
             .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
             .setPriority(NotificationCompat.PRIORITY_DEFAULT)
             .setOngoing(true)
             .setAutoCancel(false)
             .setSmallIcon(R.drawable.ic_siluette)
             .setColor(ContextCompat.getColor(this, R.color.colorPrimary))
             .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.drawable.application_icon));

     startForeground(NOTIFICATION_APP, builder.build());
 }

 private void createChannels() {
     // create android channel
     NotificationChannel androidChannel = new NotificationChannel(ANDROID_CHANNEL_ID, ANDROID_CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT);
     // Sets whether notifications posted to this channel should display notification lights
     androidChannel.enableLights(true);
     // Sets whether notification posted to this channel should vibrate.
     androidChannel.enableVibration(true);
     // Sets the notification light color for notifications posted to this channel
     androidChannel.setLightColor(Color.GREEN);
     // Sets whether notifications posted to this channel appear on the lockscreen or not
        androidChannel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);

     NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

     nm.createNotificationChannel(androidChannel);
 }

从不同的服务生命周期事件调用此方法:

onCreate()
onStartCommand()
stopService()
onDestroy()

我在这些事件中调用该方法,因为人们说服务可能不会被创建并且它会自动销毁。

当通过以下方式拨打或拨出电话时,该服务就会启动BroadcastReceiver:

public class IncomingOutgoingCallReceiver extends BroadcastReceiver {
   private void callAppService(Context context, int callType) {
        Intent intent = new Intent(context, MyService.class);
        Bundle bundle = new Bundle();
        bundle.putInt(CALL_TYPE, callType);
        intent.putExtras(bundle);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            context.startForegroundService(intent);
        }
        else {
            context.startService(intent);
        }
    }

    private void onCallEnd(Context context) {
       context.stopService(new Intent(context, MyService.class));
    }
}

服务类别:

public class MyService extends Service {

    private void handleIntent(Intent intent) {
        // Use intent data and do work

        if (canStartService(intent)) {
            return;
        }
    }

    private boolean canStartService(Intent intent) {
        // multiple checks
        // if (intent bundle contains ... ) return false;
        // if (phone number contains .... ) return false;

        return true;
    }

    @Override
    public void onCreate() {
        super.onCreate();

        startWithNotification();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        handleIntent(intent);
        startWithNotification();

        return START_NOT_STICKY;
    }

    private void startWithNotification() {
        // Contains the code from above (didn't put here because of space)
    }

    @Override
    public boolean stopService(Intent name) {
        startWithNotification();

        return super.stopService(name);
    }

    // Can be called from different Views which are attached to the WindowManager (user interacting with the UI)
    public void stopService() {
        startWithNotification();

        stopForeground(true);
        stopSelf();
    }

    @Override
    public void onDestroy() {
        startWithNotification();

        super.onDestroy();
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

None

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Context.startForegroundService()然后没有调用Service.startForeground()? 的相关文章

随机推荐

  • RecyclerView:notify* 和scrollToPostion 之间的竞争条件?

    之间可能存在竞争条件notify 的方法RecyclerView Adapter and scrollToPosition and smoothScrollToPosition 的RecyclerView本身 如果是这样 我该如何强制scr
  • jQuery UI Datepicker 仅启用数组中的特定日期

    我试图禁用日期选择器中的所有日期 并仅启用数组中的日期 这是我到目前为止的代码http jsfiddle net peter yXMKC http jsfiddle net peter yXMKC 问题是只有 5 月 14 日才显示为已启用
  • Spring 3 AJAX POST请求与@RequestBody和@ModelAttribute和@SessionAttribute一起使用?

    有一个 Java spring MVC Web 应用程序 并且正在发出 jquery ajax post 请求 我的控制器设置为接收和发送 json 数据 一切正常 JSON 字符串格式良好 控制器可以创建并填充 Command 对象 并使
  • Chrome 控制台中展开视图与折叠视图中的按键顺序

    在工作的同时另一个问题 https stackoverflow com questions 70847891 promises keep track of matching input output identifiers 我被 Chrom
  • 如何使用指定的字符集在 Java 8 中将文本附加到文件

    我正在寻找一种简单且保存的解决方案 使用指定的方法将文本附加到 Java 8 中的现有文件中Charset cs 我找到的解决方案here https stackoverflow com questions 1625234 how to a
  • 测试 Spring @MVC 注释

    前几天我遇到了一个问题 Valid 注释被意外地从控制器类中删除 不幸的是 它没有破坏我们的任何测试 我们的单元测试都没有真正运用 SpringAnnotationMethodHandlerAdapter途径 我们只是直接测试我们的控制器类
  • 这就是你构建 CSS 样式表的方式吗?

    抛开是否应该提供单个或多个样式表的问题 假设您只发送一个样式表 您认为这是一个基本结构吗 结构 任何模板布局内容都应该放入此处 例如页眉 页脚 正文等 结构体结束 常用组件 重复的元素 例如注册表单 列表等 公共组件结束 具体第1页 有些页
  • 如何将鼠标事件委托给 JavaFX 中所有底层重叠窗格?

    我有一些顶部装饰窗格 我想处理 预处理鼠标事件 但不应该消耗它们 即所有重叠的窗格都应该像它们没有被装饰窗格重叠一样工作 这个怎么做 我尝试了几次都失败了 下面是包含 3 个窗格的代码 绿色的是 装饰 任务是使其对鼠标事件透明 黄色和蓝色窗
  • Haskell 中的非整体数组

    我已经接受了下面问题的答案 但我似乎误解了 haskell 中的数组是如何工作的 我以为他们只是加强了清单 阅读下面的问题时请记住这一点 我发现当将 Haskell 中的整体数组用于较大的数组时 它们的效率非常低 我还没能在 haskell
  • R - ggplot 中奇怪的饼图行为

    我正在尝试从一个小数据框中生成一个饼图 起初一切顺利 library ggplot2 library data table c1 lt c 2 3 c2 lt c second third c2 lt factor c2 levels c
  • 获取Python字典中最大嵌套键的键

    我有一本像这样的字典 my dictionary key1 a 1 b 1 c 10 key2 a 1 b 1 c 11 key3 a 1 b 1 c 12 如何比较该字典的 c 子键 找到最大的子键 并返回该字典的相应父键 在本例中我想输
  • 骨干.marionette + i18n + 车把

    有人可以发布一个将这些库组合在一起的示例吗 包括 i18n 和 marionette 的处理程序 Thanks 指向backbone marionette 模板来编译hendlebars 这可以在你的 main js 上完成 Backbon
  • 如何使回收器视图开始从中心添加项目?

    我有一个以 水平线性布局 作为布局管理器的 recyclerView Recycler View 采用框架布局 layout gravity center layout width wrap content 我希望回收器视图开始从中心添加项
  • 如何判断 MouseDown 事件中是否按下了 Shift?

    我正在抓一个MouseDown控件上的事件 这给了我一个MouseEventArgs签名中的对象 现在我希望能够判断用户在单击时是否按住了 Shift 或 Control 键 但是MouseEventArgs对象不包含任何键盘信息 What
  • 页面内锚链接的 jQuery this.hash 行为

    我有一个关于 this hash 如何在 jQuery 中的页面锚链接工作的问题 每次用户单击该链接时 我都需要处理哈希属性 a href foo class inpageLink Click Me lt a gt a a h3 Targe
  • System.Net.MailMessage 允许某些无效的电子邮件地址格式

    许多人可能已经意识到 正确验证电子邮件地址可能有点像一场噩梦 您可以整天搜索与当前 RFC 标准匹配的 C 正则表达式 您会发现不同的正则表达式会给出不同的结果 如果你看http en wikipedia org wiki Email ad
  • 使用无符号字符计数器从 0 到 255 进行无限循环

    我想打印 0 255 中的所有数字 但这个循环不会停止 为什么 for unsigned char i 0 i lt 255 i cout lt lt int i lt lt endl i is an unsigned char其范围通常为
  • MVC4 Razor 视图中出现奇怪的空白

    我正在 ASP Net MVC4 中开发一个应用程序 并且遇到了一个奇怪的空白问题 我用 Razor 开发了很多 MVC3 网站 没有出现这个问题 这是我的模板 cshtml 文件 content bootstrap bootstrap m
  • querySelector() 和 querySelectorAll() 之间的区别[0]

    我遇到了一些 JS 代码 使用以下代码来选择多个节点中的第一个 querySelectorAll 0 下面的代码不是在做同样的事情吗 querySelector 使用有什么好处吗querySelectorAll 0 两个表达式将返回完全相同
  • Context.startForegroundService()然后没有调用Service.startForeground()?

    我的用户报告了数百起崩溃 但我仍然找不到解决方案 这些崩溃来自 Android 8 三星 华为 谷歌 我遇到这两次崩溃 Fatal Exception android app RemoteServiceException Context s