Android14新特性 开启前台service服务

1. Android14新特性

1.1. 场景

  在Android14(targetSDK=34)系统手机开启前台service服务崩溃

ATAL EXCEPTION: main
                 Process: com.inspur.lbrd, PID: 15634
                 java.lang.RuntimeException: Unable to create service com.inspur.lbrd.service.KeepAliveService: android.app.MissingForegroundServiceTypeException: Starting FGS without a type  callerApp=ProcessRecord{957facf 15634:com.inspur.lbrd/u0a352} targetSDK=34
                 	at android.app.ActivityThread.handleCreateService(ActivityThread.java:5182)
                 	at android.app.ActivityThread.-$$Nest$mhandleCreateService(Unknown Source:0)
                 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2638)
                 	at android.os.Handler.dispatchMessage(Handler.java:108)
                 	at android.os.Looper.loopOnce(Looper.java:226)
                 	at android.os.Looper.loop(Looper.java:328)
                 	at android.app.ActivityThread.main(ActivityThread.java:9128)
                 	at java.lang.reflect.Method.invoke(Native Method)
                 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:586)
                 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099)
                 Caused by: android.app.MissingForegroundServiceTypeException: Starting FGS without a type  callerApp=ProcessRecord{957facf 15634:com.inspur.lbrd/u0a352} targetSDK=34
                 	at android.app.MissingForegroundServiceTypeException$1.createFromParcel(MissingForegroundServiceTypeException.java:53)
                 	at android.app.MissingForegroundServiceTypeException$1.createFromParcel(MissingForegroundServiceTypeException.java:49)
                 	at android.os.Parcel.readParcelableInternal(Parcel.java:4884)
                 	at android.os.Parcel.readParcelable(Parcel.java:4866)
                 	at android.os.Parcel.createExceptionOrNull(Parcel.java:3066)
                 	at android.os.Parcel.createException(Parcel.java:3055)
                 	at android.os.Parcel.readException(Parcel.java:3038)
                 	at android.os.Parcel.readException(Parcel.java:2980)
                 	at android.app.IActivityManager$Stub$Proxy.setServiceForeground(IActivityManager.java:7415)
                 	at android.app.Service.startForeground(Service.java:775)
                 	at com.inspur.lbrd.service.KeepAliveService.setForeground(SourceFile:118)
                 	at com.inspur.lbrd.service.KeepAliveService.onCreate(SourceFile:32)
                 	at android.app.ActivityThread.handleCreateService(ActivityThread.java:5169)
                 	at android.app.ActivityThread.-$$Nest$mhandleCreateService(Unknown Source:0) 
                 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2638) 
                 	at android.os.Handler.dispatchMessage(Handler.java:108) 
                 	at android.os.Looper.loopOnce(Looper.java:226) 
                 	at android.os.Looper.loop(Looper.java:328) 
                 	at android.app.ActivityThread.main(ActivityThread.java:9128) 
                 	at java.lang.reflect.Method.invoke(Native Method) 
                 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:586) 
                 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1099) 

在这里插入图片描述

1.2. 解决方案

1.2.1. 在清单文件AndroidManifest.xml添加权限和配置

 <!-- android14前台常住服务权限-->
    <uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />
  <service
      android:name=".service.KeepAliveService"
      android:foregroundServiceType="location" />

1.2.2. 授权

      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
            // 定位权限
            requestPermissionLauncher
                    .launch(Manifest.permission.ACCESS_COARSE_LOCATION);
            requestPermissionLauncher
                    .launch(Manifest.permission.ACCESS_FINE_LOCATION);
            requestPermissionLauncher
                    .launch(Manifest.permission.ACCESS_BACKGROUND_LOCATION);
        }
    ActivityResultLauncher<String> requestPermissionLauncher
            = registerForActivityResult(
            new ActivityResultContracts.RequestPermission(),
            result -> {
                if (result.equals(true)) {
                    //权限获取到之后的动作
                } else {
                    //权限没有获取到的动作
                }
            });

1.2.3. service服务

public class KeepAliveService extends Service {
    private final String TAG = "szyj_GridTraceS-";

    public KeepAliveService() {
    }
    @Override
    public void onCreate() {
        super.onCreate();
        // 添加常驻通知栏
        setForeground();
       // startXcService();
    }
    private void startXcService() {
        try {
            String patrolStatus = SpUtil.getInstance(this).getString(
                    GridTraceConstant.SP_PATROL_STATUS,
                    GridTraceConstant.SP_PATROL_STATUS_FALSE);
            //巡查服务已开启
            if (TextUtils.equals(patrolStatus, GridTraceConstant.SP_PATROL_STATUS_TRUE)) {
                if (!ServiceUtil.isServiceRunning(this, GridTraceService.class.getName())) {
                    startService(new Intent(this, GridTraceService.class));
                }
            } else {//未开启巡查服务
                if (ServiceUtil.isServiceRunning(this, GridTraceService.class.getName())) {
                    stopService(new Intent(this, GridTraceService.class));
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        //可将onStartCommand() 方法的返回值设为 START_STICKY或START_REDELIVER_INTENT ,
        //该值表示服务在内存资源紧张时被杀死后,在内存资源足够时再恢复。
        //也可将Service设置为前台服务,这样就有比较高的优先级,在内存资源紧张时也不会被杀掉。
        return START_STICKY;
        //return super.onStartCommand(intent, flags, startId);
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        // 删除图标
        stopForeground(true);
    }

    @Override
    public IBinder onBind(Intent intent) {
        throw new UnsupportedOperationException("Not yet implemented");
    }
    /**
     * 添加常驻通知栏
     */
    private void setForeground() {
        NotificationManager notificationManager = (NotificationManager) getSystemService
                (Context.NOTIFICATION_SERVICE);
        String notificationId = "serviceid";
        String notificationName = "servicename";
        int noticeId = 2;
        Notification.Builder builder = new Notification.Builder(this);
        //创建NotificationChannel
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel(notificationId,
                    notificationName, NotificationManager.IMPORTANCE_HIGH);
            channel.enableLights(true);//设置高亮(选填)
            channel.setShowBadge(true);//设置角标(选填)
            //设置锁屏可见(选填)
            channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
            notificationManager.createNotificationChannel(channel);
            builder.setChannelId(notificationId);
        }
        Intent intent = new Intent(KeepAliveService.this, MainActivity.class);
        PendingIntent pendingIntent;
        //Android12
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) {
            pendingIntent = PendingIntent.getActivity(this,
                    123, intent, PendingIntent.FLAG_IMMUTABLE);
        } else {
            pendingIntent = PendingIntent.getActivity(this,
                    123, intent, PendingIntent.FLAG_ONE_SHOT
                            | PendingIntent.FLAG_MUTABLE);
        }
        builder.setSmallIcon(R.mipmap.icon_app)
                .setLargeIcon(BitmapFactory.decodeResource(getResources(),
                        R.mipmap.icon_app))
                .setContentTitle(getString(R.string.app_name))//选填
                .setContentText(getString(R.string.app_name))//选填
                .setWhen(System.currentTimeMillis())
                .setContentIntent(pendingIntent);
        Notification notification = builder.build();
        startForeground(noticeId, notification);
    }
}

1.2.4. 启动service服务

  if (!ServiceUtil.isServiceRunning(this, KeepAliveService.class.getName())) {
            startService(new Intent(this, KeepAliveService.class));
        }

&emsp;&emsp;判断服务是否开启

public class ServiceUtil {
    /**
     * @param context
     * @param className service后台服务名称
     * @return
     * @desc 查询service是否在运行
     */
    public static boolean isServiceRunning(Context context, String className) {
        ActivityManager activityManager = (ActivityManager) context
                .getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningServiceInfo> serviceList = activityManager
                .getRunningServices(Integer.MAX_VALUE);

        if (!(serviceList.size() > 0)) {
            return false;
        }

        for (int i = 0; i < serviceList.size(); i++) {
            ActivityManager.RunningServiceInfo serviceInfo = serviceList.get(i);
            ComponentName serviceName = serviceInfo.service;

            if (serviceName.getClassName().equals(className)) {
                return true;
            }
        }
        return false;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/282354.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

计算机毕业设计 基于html5的图书管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

数据结构期末复习(1)数据结构和算法 线性表

数据结构期末总复习&#xff08;gaois课堂版&#xff09; 数据结构的概念 数据结构是计算机科学中的一个重要概念&#xff0c;它指的是组织和存储数据的方式。数据结构可以帮助我们高效地操作和管理数据&#xff0c;使得计算机程序能够更加有效地执行各种任务。 数据结构有很…

关于链表的一些问题

求链表的中间节点 可以定义两个指针&#xff0c;一个一次走两步一个一次走一步&#xff0c;当走的快的走到NULL时&#xff0c;走的慢的就是链表的中间节点。&#xff08;此法求出的偶数个节点的链表的中间节点是它中间的第二个&#xff09; 求倒数第K个节点 也可以定义两个指…

【HarmonyOS】ArkTS语言介绍与组件方式运用

从今天开始&#xff0c;博主将开设一门新的专栏用来讲解市面上比较热门的技术 “鸿蒙开发”&#xff0c;对于刚接触这项技术的小伙伴在学习鸿蒙开发之前&#xff0c;有必要先了解一下鸿蒙&#xff0c;从你的角度来讲&#xff0c;你认为什么是鸿蒙呢&#xff1f;它出现的意义又是…

【网络安全 | MD5截断比较】PHP、Python脚本利用

前言 在解题中&#xff0c;当遇到类似 substr(md5(a),-6,6) 7788这样的MD5截断比较的题目时&#xff0c;只有求出a的值才能进行接下来的操作。 一个一个去猜是不可能的&#xff0c;通常使用脚本解决&#xff0c;文末给出实战案例。 PHP循环脚本 <?phpfor($i1;$i<9…

小信跳房子的题解

原题描述&#xff1a; 时间&#xff1a;1s 空间&#xff1a;256M 题目描述&#xff1a; 小信在玩跳房子游戏&#xff0c;已知跳房子游戏的图表现为一颗完美的具有个节点的二叉树。从根节点依次编号为。节点的左子节点编号为&#xff0c;右子节点编号为。 小信从从节点出发&…

python观察图像的直流分量——冈萨雷斯数字图像处理

原理 在数字图像处理中&#xff0c;图像的直流分量&#xff08;DC分量&#xff09;是指图像中的平均亮度水平。这个概念源自于傅里叶变换&#xff0c;其中信号可以分解为多个频率成分。在这个上下文中&#xff0c;直流分量对应于频率为零的成分&#xff0c;即信号的平均值。 在…

【实用工具】vim常用命令

快速移动(上下左右箭头可替代) 左移 h 右移 l 下移 j 上移 K在本行操作 0 移动到本行行首 ^ 移动到本行的第一个不是 blank 字符 $ 移动到本行行尾 w 光标移动到下一个单词的开头 e 光标移动到下一个单词的结尾跨行移动光标 nG 光标定位到第n行的行首 gg 光标定位到第一行的…

基于JAVA的食品生产管理系统 开源项目

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 加工厂管理模块2.2 客户管理模块2.3 食品管理模块2.4 生产销售订单管理模块2.5 系统管理模块2.6 其他管理模块 三、系统展示四、核心代码4.1 查询食品4.2 查询加工厂4.3 新增生产订单4.4 新增销售订单4.5 查询客户 五、…

看懂基本的电路原理图(入门)

文章目录 前言一、二极管二、电容三、接地一般符号四、晶体振荡器五、各种符号的含义六、查看原理图的顺序总结 前言 电子入门&#xff0c;怎么看原理图&#xff0c;各个图标都代表什么含义&#xff0c;今天好好来汇总一下。 就比如这个电路原理图来说&#xff0c;各个符号都…

我的2023年度总结(一)

在本文开始之前&#xff0c;先对我2023年的所为进行一些道歉&#xff1a; 部分工作中的客户/合作伙伴&#xff0c;在2023年我可能时长怠慢了您的消息。但我真不是故意的(有时可能在忙其他事情)。2024年&#xff0c;如有任何问题请尽可能抛过来吧。部分粉丝朋友&#xff0c;甚至…

2023-12-22 LeetCode每日一题(得到山形数组的最少删除次数)

2023-12-22每日一题 一、题目编号 1671. 得到山形数组的最少删除次数二、题目链接 点击跳转到题目位置 三、题目描述 我们定义 arr 是 山形数组 当且仅当它满足&#xff1a; arr.length > 3存在某个下标 i &#xff08;从 0 开始&#xff09; 满足 0 < i < arr.…

精品Nodejs实现的在线菜谱食谱美食学习系统的设计与实现

《[含文档PPT源码等]精品Nodejs实现的在线菜谱学习系统的设计与实现[包运行成功]》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程、包运行成功&#xff01; 软件开发环境及开发工具&#xff1a; 操作系统&#xff1a;Windows 10、Windows 7、Windows…

【数据结构——图】图的遍历(头歌习题)【合集】

目录 第1关&#xff1a;邻接矩阵存储图的深度优先遍历任务描述相关知识邻接矩阵存储图图的遍历DFS伪代码——邻接矩阵存储实现 完整代码 第2关&#xff1a;邻接表存储图的广度优先遍历任务描述相关知识邻接表存储图图的遍历广度优先遍历过程&#xff1a;BFS伪代码——邻接表实现…

安装Hadoop:Hadoop的单机模式、伪分布式模式——备赛笔记——2024全国职业院校技能大赛“大数据应用开发”赛项

前言 Hadoop包括三种安装模式&#xff1a; 单机模式&#xff1a;只在一台机器上运行&#xff0c;存储是采用本地文件系统&#xff0c;没有采用分布式文件系统HDFS&#xff1b;伪分布式模式&#xff1a;存储采用分布式文件系统HDFS&#xff0c;但是&#xff0c;HDFS的名称节点…

2024 GMF|The Sandbox 为创作者赋能的新时代

以新的 GMF 模型和专门的参与池奖励来开启 2024 年吧。 11 月 3 日&#xff0c;我们在香港全球创作者日上宣布&#xff0c;The Sandbox 已为所有创作者分配了100,000,000 SAND&#xff0c;将通过 GMF 进行分发。作为首次启动的建设者挑战&#xff0c;我们准备了专门的 SAND 参与…

day9--java高级编程:多线程

1 Day16–多线程01 1.1 程序概念 程序(program)&#xff1a;是为完成特定任务、用某种语言编写的一组指令的集合。即指一段静态的代码&#xff0c;静态对象。 1.2 进程 1.2.1 概念 进程(process)&#xff1a;是程序的一次执行过程&#xff0c;或是正在运行的一个程序。是一…

2024年【安全员-A证】考试内容及安全员-A证最新解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 安全员-A证考试内容参考答案及安全员-A证考试试题解析是安全生产模拟考试一点通题库老师及安全员-A证操作证已考过的学员汇总&#xff0c;相对有效帮助安全员-A证最新解析学员顺利通过考试。 1、【多选题】下列关于门…

龙年红包封面来了,可以领取了。

今天是周六&#xff0c;后天就是元旦了&#xff0c;过完元旦就快要过年了&#xff0c;大家又要开始发红包和收红包了。下面分享一个腾讯的龙年红包封面给大家&#xff0c;可以免费领取&#xff0c;大家可以看下我领取的发红包的效果图&#xff0c;如下所示。 下面这个是红包打开…

Unity之组件的生命周期

PS&#xff1a;第二天&#xff0c;依旧在摸鱼学unity 一、组件的概念 我本身是由Web后端转到了游戏后端&#xff0c;最近因为工作原因在学ET框架。学到了 ECS 编程模式开发&#xff08;E —— Entity&#xff0c;C —— Component &#xff0c; S —— System&#xff09;实体、…