Android startForegroundService与startForeground

启动service

service启动有四种形式。

1.显示启动(如直接按service的全路径启动)

2.隐示启动(如通过intent-filter的action标签启动)

3.通过bindservice显示启动。

4.通过bindservice隐示启动。

Demo

创建一个service的子类,如

import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Build;
import android.os.IBinder;
import android.util.Log;

import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;


public class ForceGroundServer extends Service {
    private static final String TAG = "ForceGroundServer";

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.d(TAG, "onBind: ");
        return null;
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.d(TAG, "onUnbind: ");
        return super.onUnbind(intent);
    }

    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "onCreate: ");
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            sendNotification();
        }
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "onStartCommand: ");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy: ");
    }

    private final String CHANNEL_ID = "TestID";
    @RequiresApi(api = Build.VERSION_CODES.O)
    private void sendNotification() {
        NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        NotificationChannel channel = new NotificationChannel(CHANNEL_ID, "TEstName", NotificationManager.IMPORTANCE_HIGH);
        channel.enableLights(true);//设置提示灯
        channel.setLightColor(Color.BLUE);//设置提示灯颜色
        channel.setShowBadge(true);//显示logo
        channel.setDescription("test");//设置描述
        channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);//锁屏可见
        manager.createNotificationChannel(channel);
        Notification testNotification = new Notification.Builder(this)
                .setChannelId(CHANNEL_ID)
                .setContentText("服务已经至于前台了")
                .setWhen(System.currentTimeMillis())
                .setSmallIcon(R.mipmap.ic_launcher)
                .setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher))
                .build();
        //id 不能是0
        startForeground(1, testNotification);
    }
}

显示启动

    private final static String TARGET_APP_PACKAGE = "com.example.mycolorpicker";
    private final static String TARGET_SERVICE_NAME = TARGET_APP_PACKAGE + ".ForceGroundServer";
    private final static String TARGET_SERVICE_ACTION = TARGET_SERVICE_NAME + ".action";

    private void startServerVisible() {
        Intent intent = new Intent();
        intent.setComponent(new ComponentName(
                TARGET_APP_PACKAGE,  
                TARGET_SERVICE_NAME));
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            startForegroundService(intent);
            Log.d(TAG, "startForegroundService");
        } else {
            startService(intent);
            Log.d(TAG, "startService");
        }
    }

隐示启动

    private void startServerHide() {
        Intent intent = new Intent();
        intent.setPackage(TARGET_APP_PACKAGE);
        intent.setAction(TARGET_SERVICE_ACTION);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            startForegroundService(intent);
        } else {
            startService(intent);
        }
    }

设置前台服务

首先需要在Manifest中声明权限需求。

    <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>

若无此权限声明,系统会抛SecurityException异常

                                                                                                    java.lang.RuntimeException: Unable to create service com.example.mycolorpicker.ForceGroundServer: java.lang.SecurityException: Permission Denial: startForeground from pid=12931, uid=10247 requires android.permission.FOREGROUND_SERVICE

上面通过startForegroundService启动了servervice,会执行Service的Oncreate和OnStartCommand,service需要在5秒内调用startForeground,否则系统就会报TimeExceptio异常,app闪退。

ndroid.app.ForegroundServiceDidNotStartInTimeException: Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord{263b8f7 u0 com.example.mycolorpicker/.ForceGroundServer}
                                                                                                    	at android.app.ActivityThread.throwRemoteServiceException(ActivityThread.java:2046)
                                                                                                    	at android.app.ActivityThread.access$2900(ActivityThread.java:275)
                                                                                                    	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2271)
                                                                                                    	at android.os.Handler.dispatchMessage(Handler.java:106)
                                                                                                    	at android.os.Looper.loopOnce(Looper.java:211)
                                                                                                    	at android.os.Looper.loop(Looper.java:300)
                                                                                                    	at android.app.ActivityThread.main(ActivityThread.java:8291)
                                                                                                    	at java.lang.reflect.Method.invoke(Native Method)

上一篇:excel 无法正确处理 1900-03-01 前的日期


下一篇:aws挂载s3-配置path