小工具知识网

当前位置: 首页 > 行业知识 > Android14新特性 开启前台service服务

行业知识

Android14新特性 开启前台service服务

2026-10-20 06:02:14 来源:互联网转载

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.createFromParcel(MissingForegroundServiceTypeException.java:53)                 at android.app.MissingForegroundServiceTypeException.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添加权限和配置

     
  

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 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));        }

  判断服务是否开启

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 serviceList = activityManager                .getRunningServices(Integer.MAX_VALUE);        if (!(serviceList.size() > 0)) {            return false;        }        for (int i = 0; i                                                 

上一篇:cs进服务器怎么开始?

下一篇:lce服务器怎么玩?