后台服务在奥利奥中不起作用

Posted

技术标签:

【中文标题】后台服务在奥利奥中不起作用【英文标题】:Background service is not working in Oreo 【发布时间】:2018-07-09 08:35:23 【问题描述】:

如果我也杀死应用程序实例,我想在后台运行我的应用程序。但是在我杀死我的应用程序后,该服务也停止工作。这是我的代码,请任何人帮助我解决我的问题。

我按照此链接在后台运行,但如果我删除实例,它就无法工作。如果实例也被删除,谁能告诉我如何运行后台服务?

这是我的 MainActivity

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    ctx = this;
    setContentView(R.layout.activity_main);
    Intent alarmIntent = new Intent(MainActivity.this, AlarmReceiver.class);
    pendingIntent = PendingIntent.getBroadcast(MainActivity.this, ALARM_REQUEST_CODE, alarmIntent, 0);
    mSensorService = new SensorService(getCtx());
    mServiceIntent = new Intent(getCtx(), mSensorService.getClass());
    if (!isMyServiceRunning(mSensorService.getClass())) 
        startService(mServiceIntent);
    

这是我的服务类

   public class SensorService extends Service

public int counter=0;
public SensorService(Context applicationContext) 
    super();
    Log.i("HERE", "here I am!");


public SensorService() 

@Override
public int onStartCommand(Intent intent, int flags, int startId) 
    super.onStartCommand(intent, flags, startId);
    startTimer();
    return START_STICKY;

@Override
public void onDestroy() 
    super.onDestroy();
    Log.i("EXIT", "ondestroy!");
    Intent broadcastIntent = new Intent("uk.ac.shef.oak.ActivityRecognition.RestartSensor");
    sendBroadcast(broadcastIntent);
  

private Timer timer;
private TimerTask timerTask;
long oldTime=0;
public void startTimer() 
    //set a new Timer
    timer = new Timer();

    //initialize the TimerTask's job
    initializeTimerTask();

    //schedule the timer, to wake up every 1 second
    timer.schedule(timerTask, 1000, 1000); //


/**
 * it sets the timer to print the counter every x seconds
 */
public void initializeTimerTask() 
    timerTask = new TimerTask() 
        public void run() 
            Log.i("in timer", "in timer ++++  "+ (counter++));
        
    ;


/**
 * not needed
 */


@Nullable
@Override
public IBinder onBind(Intent intent) 
    return null;

【问题讨论】:

你检查过我对这个SO的回答了吗? 查看***.com/questions/47110489/… 我试过了,但如果应用程序在前台,它正在运行@hasan_shaikh 在此处添加您的代码 @hasan_shaikh 我添加了我的代码 pease check 一次 【参考方案1】:

说来话长。我已经经历过了。还是实现了。现在我的服务在每个 boot_complete 事件上运行,并且一直运行(带有通知)。

官方文档:

大号。 Google android 开发人员文档很差,也没有适当的示例示例。这是理论上的,只是理论上的。有兴趣请继续阅读

https://developer.android.com/about/versions/oreo/background

概要 1: 您只能接收BOOT_COMPLETE 并且在传统接收器中只能接收很少的广播。休息所有需要在服务中实现运行时的广播接收器,方法是通过始终运行的服务中的代码注册它们。

概要 2: 同样,您不能总是在 8.0 (Oreo) 或更高版本中运行进程... 为了实现始终运行的进程...创建一个 Intentservice 并使用 ongoing 类型的正确通知并创建 OnStartCommand START_STICKY 并使用 OnCreate 中的代码注册接收器

如何实现: 我已经实现了它从这里参考: Oreo: Broadcast receiver Not working

现在你的问题:我想在后台运行我的应用程序,如果它杀死 应用实例。

借助上面我自己的实现链接你就可以实现了

*条款和条件

您的设备必须有适当的 Android 操作系统,并按原样烧录。

是的,我使用的是安卓:

No... You are Using Funtouch OS : VIVO ( By modifying Android)

市面上有很多设备 COLOR OS : OPPO (通过修改安卓) …… ....

    谷歌已经把它复杂化了……逐个版本…… 没有适当的文档和示例代码.... 现在独立的移动设备制造商制造了很多 更改to allow only selective applications run in background 喜欢WhatsApp, Facebook, Google Twitter Instagram

现在你会问一个开发者问题如果这些应用程序在后台运行,那么我也可以让我的应用程序在后台运行....

不...它们是基于操作系统的修改,用于检查服务是否来自允许的供应商,然后只有它可以在后台存在。如果他们不允许这些供应商,那么没有人会拿走不运行这些著名社交应用程序的手机。

嘘…………

【讨论】:

【参考方案2】:

您需要创建 ForegroundService 以便在您的应用被杀死时继续处理,如下所示:

 public class SensorService extends Service

    private PowerManager.WakeLock wakeLock;
    @Override
    public void onCreate() 
        super.onCreate();

        //wake lock is need to keep timer alive when device goes to sleep mode          
        final PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "PARTIAL_WAKE_LOCK_TAG");
        createNotificationChannel(this);
        Notification notification = new NotificationCompat.Builder(this, "NOTIFICATION_CHANNEL").setSmallIcon
                (<icon>).setContentTitle("Title")
                .setContentText("Content").build();

        startForeground(1001, notification);
    

    @Override
    public void onDestroy() 
        super.onDestroy();
        if (wakeLock.isHeld()) 
            wakeLock.release();
        

    

     public void createNotificationChannel() 
        // Create the NotificationChannel, but only on API 26+ because
        // the NotificationChannel class is new and not in the support library
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) 

            CharSequence name = "Channel name";
            String description = "Description";
            int importance = NotificationManager.IMPORTANCE_DEFAULT;
            NotificationChannel channel = new NotificationChannel("NOTIFICATION_CHANNEL", name, importance);
            channel.setDescription(description);
            NotificationManager notificationManager = getApplicationContext().getSystemService(NotificationManager.class);
            notificationManager.createNotificationChannel(channel);
        
    

启动服务:

Intent i = new Intent(context, SensorService.class);
ContextCompat.startForegroundService(context, i)

注意:

您不能使用这种方法无休止地运行服务。在打盹模式下,如果操作系统认为它是 CPU 密集型的,那么您的服务将被终止。 您的 Timer 任务执行成功后,您需要调用stopSelf()

【讨论】:

感谢您的回答。我在vivo mobile中运行我的应用程序,在我杀死应用程序后没有进入onDestroy方法。@sagar 在你调用 stopSelf() 之前它不会进入 但它没有继续运行 正如我所说,它不会连续运行。但它会在应用被杀死后运行足够长的时间来完成任务。 跑得够久是什么意思【参考方案3】:

奥利奥推出

新概念画中画(画中画模式) 它通过为它们设置频道和优先级来控制类别服务。您必须为奥利奥更改代码才能创建通知和服务

在这里仔细阅读谷歌开发者文档 https://developer.android.com/guide/topics/ui/notifiers/notifications 此处提供 java 和 kotlin 代码来在 oreo 中创建通知

https://developer.android.com/training/notify-user/build-notification

经过搜索和分享,我努力找到了解决方案。

这里是一些示例代码:

NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, CHANNEL_ID)
    .setSmallIcon(R.drawable.notification_icon)
    .setContentTitle("My notification")
    .setContentText("Much longer text that cannot fit one line...")
    .setStyle(new NotificationCompat.BigTextStyle()
            .bigText("Much longer text that cannot fit one line..."))
    .setPriority(NotificationCompat.PRIORITY_DEFAULT);

要创建频道,请编写以下代码:

private void createNotificationChannel() 
// Create the NotificationChannel, but only on API 26+ because
// the NotificationChannel class is new and not in the support library
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) 
    CharSequence name = getString(R.string.channel_name);
    String description = getString(R.string.channel_description);
    int importance = NotificationManager.IMPORTANCE_DEFAULT;
    NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
    channel.setDescription(description);
    // Register the channel with the system; you can't change the importance
    // or other notification behaviors after this
    NotificationManager notificationManager = getSystemService(NotificationManager.class);
    notificationManager.createNotificationChannel(channel);
    

您可以点击以上链接查看推送通知和发送消息的完整详情。

【讨论】:

以上是关于后台服务在奥利奥中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

Android - 前台在 Oreo 中不起作用。操作系统在一段时间后终止服务

Nodejs 静默推送通知在 iOS 13 中不起作用

Flutter 背景 iOS 通知在 XCode 或 TestFlight 中不起作用

为啥 publishProgress 方法在服务中不起作用?

Firebase 云消息传递前台通知在 Vue 中不起作用

定位服务在 iOS 11 中不起作用