Android 后台启动startService()相关问题的解决

这篇具有很好参考价值的文章主要介绍了Android 后台启动startService()相关问题的解决。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

需求

有一个用户需要这样一个功能,要求是APP能在充电的时候自动进入APP的一个界面
我寻思着,这玩意用普通权限做不了呀,不过APP有root权限倒也无妨,于是便决定采用Service去做后台服务

问题

某天,在Bugly看到如下的错误报告

java.lang.IllegalStateException:
   Not allowed to start service Intent  
   app is in background uid UidRecord

Android 后台启动startService()相关问题的解决
提示我无法在后台启动这个服务
于是便开始着手解决这个问题

解决问题

使用startForegroundService()

根据不同的SDK版本采用不同的启动方案

  /**
   * 开启用户服务 需要在目标Service的 onCreate方法中加入startForeground(1, new Notication())
   *
   * @param cls class
   * @param context 上下文
   */
  public static void startUseService(Context context, Class cls) {
    Intent intent = new Intent(context, cls);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
      context.startForegroundService(intent);
    } else {
      context.startService(intent);
    }
  }

解决方法:使用startForegroundService()

必须在5秒内调用该服务的 startForeground(int id, Notification notification) 方法,否则将停止服务并抛出 *android.app.RemoteServiceException:Context.startForegroundService() did not then call Service.startForeground()*异常。

Bad notification for startForeground

结果发现调用了**startForeground(int id, Notification notification)**依旧不起作用,提示

FATAL EXCEPTION: main
    android.app.RemoteServiceException: Bad notification for startForeground: java.lang.RuntimeException: invalid channel for service notification: Notification(channel=null pri=0 contentView=null vibrate=null sound=null defaults=0x0 flags=0x40 color=0x00000000 vis=PRIVATE)

解决方法 :自定义notification

Android 8.0 以上不能用空的通知了 , 必须自己创建通知通道

/** 启动前台服务 */
  private void startForeground() {
    Log.d(TAG, "startForeground: ");
    String channelId = null;
    // 8.0 以上需要特殊处理
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
      channelId = createNotificationChannel("fuck.foreground", "ForegroundService");
    } else {
      channelId = "";
    }
    NotificationCompat.Builder builder = new NotificationCompat.Builder(this, channelId);
    Notification notification =
        builder
            .setContentText("充电控制服务已启动!")
            .setSmallIcon(R.mipmap.fuck)
            .setPriority(PRIORITY_MIN)
            .setCategory(Notification.CATEGORY_SERVICE)
            .build();
     // 设置 ID 为 0 , 就不显示已通知了 , 但是 oom_adj 值会变成后台进程 11
    // 设置 ID 为 大于0 , 会在通知栏显示该前台服务
    startForeground(0, notification);
  }
/**
   * 创建通知通道
   *
   * @param channelId
   * @param channelName
   * @return
   */
  @RequiresApi(Build.VERSION_CODES.O)
  private String createNotificationChannel(String channelId, String channelName) {
    NotificationChannel chan =
        new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_NONE);
    chan.setLightColor(Color.BLUE);
    chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
    NotificationManager service =
        (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    service.createNotificationChannel(chan);
    return channelId;
  }

以为这样就可以在不弹出通知的情况下去启动前台服务

解决通知问题

由于上述的startForeground(0, notification)
会不显示通知,结果出现了新的问题

android.app.ForegroundServiceDidNotStartInTimeException: 
		Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord

原来是转为了后台服务,前台服务启动了个寂寞
这个时候就必须使用startForeground(大于零, notification)
通知会影响到用户的体验,如何去避免呢

这个时候在网上看到有人在说可以删除管道的方式
本人实际测试并不能解决问题

失败方案1:

 NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        manager.cancel(1);

失败方案2

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        NotificationChannel channel = new NotificationChannel(channelId,
                    "Channel for  notification",
                    NotificationManager.IMPORTANCE_NONE);
        mNotificationManager.createNotificationChannel(channel);
}

会出现以下之类的问题,无法去操作前台服务的channel
Not allowed to delete channel fuck.foreground with a foreground service

解决方案 :stopForeground(true)

用定时线程池之类的去定一个延迟任务删除前台通知
由于通知发出是有延迟的,基本上在发出去之前删除掉,
可以实现调用了startForeground(???, notification)而又不会弹出通知消息烦恼用户的情况

 //    延迟2s删除前台通知
      executorService.schedule(() -> 
      stopForeground(true), 
      2, 
      TimeUnit.SECONDS);

就这样,问题愉快的解决了!文章来源地址https://www.toymoban.com/news/detail-432038.html

总结

  1. 使用startForegroundService(intent)并且在目标service中自己去创建notification
  2. 在自己创建的channel中去使用startForeground(大于零, notification)
  3. 如果需要没有通知,使用stopForeground(true)去停止前台服务

到了这里,关于Android 后台启动startService()相关问题的解决的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Android 后台启动Activity适配

    在Android 9及以下版本,后台启动Activity相对自由,但是如果在Activity上下文之外启动Activity会有限制。 所以此时需要给intent添加flag:FLAG_ACTIVITY_NEW_TASK。 在Android版本10及以后版本, 引入了后台执行限制,限制了应用在后台执行操作的能力。非核心任务的后台启动 Activity 可能会

    2024年02月10日
    浏览(29)
  • android 如何从后台启动activity

            从事开发android的工程师都知道 从android 10之后的系统是不允许从后台启动activity,这就导致很多功能实现不了,比如android 10的手机,app在后台,收到一条推送,是可以把自己拉起到前台,从而提高用户时长。         那么,有没有办法解决呢?所谓,上有政策,下游

    2024年02月10日
    浏览(31)
  • Android13关于获取外部存储文件的相关问题及解决方案记录

      Android的学习路上... 测试设备:vivo X90s 安卓版本: Android13 开发环境:AndroidStudio Flamingo SDK:33 最近我在Android13的环境下尝试写一个 文件选择器 ,以便日后的开发使用。但是我们知道,从Android13 (API33) 开始,外部存储权限发生了变化,要想读取外部存储文件,使用原来的权

    2024年01月15日
    浏览(40)
  • Android实现监听APP启动、前台和后台

    前言 在我们开发的过程中,经常会遇到需要我们判断app进入后台,或者切换到前台的情况。比如我们想判断app切换到前台时,显示一个解锁界面,要求用户输入解锁密码才能继续进行操作;我们想判断app切换到后台,记录一下log;或者当用户切换回前台时,我们想刷新一下页

    2024年02月11日
    浏览(29)
  • Android Q以上后台启动Activity初步尝试

    在Android Q以后 google不允许在后台service 广播等等启动Activity 具体请看google文档从后台启动 Activity 的限制  |  Android 开发者  |  Android Developers 文档里有详细的说明,在哪种情况下可以后台启动Activity。 大体分为以下几种情况: 1、应用具有可见窗口,例如前台 Activity。 2、应用

    2024年02月14日
    浏览(39)
  • 解决Mac系统android monitor启动时卡住,显示白屏的问题

    清安装1.8版本的jdk,java1.8版本以上不支持android monitor;如果你电脑上安装有java 11等高级别的版本,请自行搜索,如果在mac上安装多jdk,以及如何切换到1.8版本上 请更新SWT插件,下载地址; 1.打开网页,点击4.9 跳转到另外的网页  2.跳转到的网页如下所示意   3. 点击下载此版

    2024年02月12日
    浏览(26)
  • 【Node.js相关问题】npm install报错后重装node版本及npm环境变量配置及npm run dev启动报错原因分析解决办法

    昨天在准备打开b站up主三更草堂的博客项目08-02.基础版本前端联调_哔哩哔哩_bilibili中的前端工程时,使用以下两个命令分别都出现了报错。 命令1 : # install dependencies npm install 命令2 : # serve with hot reload at localhost:8080 npm run dev 2.1 首先是淘宝镜像过期的问题,这个解决办法比

    2024年04月10日
    浏览(66)
  • Android 10.0 开机启动时PMS扫描apk耗时相关功能优化

      在android10.0的系统rom定制化开发中,在系统中开发产品时,会根据客户要求内置第三方app,这时如果内置app过多,或者安装的app过多,在系统开机的过程中 在pms扫描安装app的时候,就会比较耗时,这时候就需要优化下pms扫描安装app这块的功能代码,用多线程来实现pms扫描安装

    2024年02月04日
    浏览(48)
  • 关于hive启动的相关问题记录

    问题:初始化hive元数据报错 首先想到的是删除hive在MySQL中创建的元数据库Metastore 和HDFS中创建的目录 结果还是报错 仔细一看是hive.metastore连接问题 查看MySQL中的用户权限 参考:https://blog.csdn.net/peterchan88/article/details/78341852 使用初始化命令还是报错,继续往下查 检查 MySQL 服务

    2024年04月10日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包