Android高版本后台开机检测自启动service(解决did not then call Service.startForeground())

非android工程师,单纯个人临时有需要,赶时间借鉴很多文章做出来的,单纯记录备忘下。原帖之一如下:

【错误记录】前台进程报错 ( Bad notification for startForeground invalid channel for service notification )_韩曙亮的博客-CSDN博客

1、新建一个Receiver,继承BroadcastRecevier类,用于开机广播,启动service服务。

java 复制代码
/**
 * 接收开机广播来启动service
 */
public class BootReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
            Intent serviceIntent = new Intent(context, WebSocketService.class);
            // 判断版本
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (Settings.canDrawOverlays(context)) {
                    // 有悬浮框权限
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                        context.startForegroundService(serviceIntent);
                    } else {
                        context.startService(serviceIntent);
                    }
                } else {
                    //没有悬浮框权限 要去索要悬浮框权限
                    System.out.println("没有悬浮框权限 要去索要悬浮框权限");
                }
            } else {
                //低版本不需要悬浮框权限 直接显示
                context.startService(serviceIntent);
                System.out.println("低版本不需要悬浮框权限 直接显示");
            }
        }
    }
}

2、在AndroidManifest.xml中配置如下:

java 复制代码
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /><!-- 接收广播 -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /><!-- 悬浮窗权限 -->
<uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW" />
java 复制代码
        <!-- 广播 -->
        <receiver
            android:name=".Receiver.BootReceiver"
            android:exported="true">
            <intent-filter android:priority="1000">
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <category android:name="android.intent.category.HOME" />
            </intent-filter>
        </receiver>

3、在service中的oncreated和onDestroy中添加如下:

java 复制代码
    @Override
    public void onCreate() {
        super.onCreate();
        startForeground();
    }

    //关闭长连接
    @Override
    public void onDestroy() {
        super.onDestroy();
        stopForeground(true);
    }

    /**
     * 启动前台服务
     */
    private void startForeground() {
        String channelId = null;
        // 8.0 以上需要特殊处理
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            channelId = createNotificationChannel("kim.hsl", "ForegroundService");
        } else {
            channelId = "";
        }
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, channelId);
        Notification notification = builder.setOngoing(true)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setPriority(PRIORITY_MIN)
                .setCategory(Notification.CATEGORY_SERVICE)
                .build();
        startForeground(1, 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;
    }
相关推荐
进阶的小叮当1 小时前
Vue代码打包成apk?Cordova帮你解决!
android·前端·javascript
-指短琴长-2 小时前
MySQL快速入门——基本查询(上)
android·数据库·mysql
下位子3 小时前
『OpenGL学习滤镜相机』- Day6: EGL 与 GLSurfaceView 深入理解
android·opengl
java干货3 小时前
MySQL “灵异事件”:我 INSERT id=11,为什么被 UPDATE id=10 锁住了?
android·数据库·mysql
正经教主4 小时前
【App开发】ADB 详细使用教程- Android 开发新人指南
android·adb
gx23484 小时前
MySQL-5-触发器和储存过程
android·mysql·adb
六件套是我12 小时前
redission实现延时队列
android·java·servlet
00后程序员张16 小时前
iOS 上架费用全解析 开发者账号、App 审核、工具使用与开心上架(Appuploader)免 Mac 成本优化指南
android·macos·ios·小程序·uni-app·cocoa·iphone
来来走走17 小时前
Android开发(Kotlin) 扩展函数和运算符重载
android·开发语言·kotlin
wuwu_q17 小时前
用通俗易懂 + Android 开发实战的方式,详细讲解 Kotlin Flow 中的 retryWhen 操作符
android·开发语言·kotlin