服务在关闭应用程序后不会执行,但在后台运行时会执行

问题描述

我一直在尝试提出警报应用程序。我一直在努力进行全屏通知。我最终确实做到了,但是只有在应用程序在后台运行时,它才起作用。

关闭应用程序后,它也需要工作。我不明白该怎么做。我知道这是有可能的,因为我每天使用的闹钟应用程序能够做到这一点。

Mainactivity.java

package com.example.wekkerapp;
import java.util.Calendar;

import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.NotificationCompat;
import androidx.core.app.notificationmanagerCompat;

import android.app.AlarmManager;
import android.app.NotificationChannel;
import android.app.notificationmanager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private static final String CHANNEL_ID = "my_channel";
    static final String FULL_SCREEN_ACTION = "full_screen_action";
    static final int NOTIFICATION_ID = 1;

    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 = "Alarm";
            String description = "Het alarm gaat";
            int importance = notificationmanager.IMPORTANCE_DEFAULT;
            NotificationChannel channel = new NotificationChannel("2",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 = (notificationmanager) getSystemService(this.NOTIFICATION_SERVICE);
            notificationmanager.createNotificationChannel(channel);
        }
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {

        createNotificationChannel(this);
        getwindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
                | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final TimePicker klok = findViewById(R.id.timePicker1);
        klok.setIs24HourView(true);
        final Button getTimeBtn = findViewById(R.id.getTimeBtn);
        final TextView showtext = findViewById(R.id.showtext);

        final AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);


        getTimeBtn.setonClickListener(new View.OnClickListener() {
            @RequiresApi(api = Build.VERSION_CODES.M)
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(FULL_SCREEN_ACTION,null,getApplicationContext(),WekkerService.class);
                PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext(),intent,PendingIntent.FLAG_UPDATE_CURRENT);
                int uur = klok.getHour();
                int minuut = klok.getMinute();
                Calendar cal = Calendar.getInstance();
                cal.set(Calendar.HOUR_OF_DAY,uur);
                cal.set(Calendar.MINUTE,minuut);
                cal.set(Calendar.SECOND,0);
                cal.set(Calendar.MILLISECOND,0);
                Toast.makeText(getApplication().getApplicationContext(),"Alarm gaat om " + uur + ":" + minuut,Toast.LENGTH_LONG).show();
                alarmManager.set(AlarmManager.RTC_WAKEUP,cal.getTimeInMillis(),pendingIntent);


                showtext.setText(Integer.toString(uur) + ':' + Integer.toString(minuut));
                notificationmanagerCompat.from(getApplicationContext()).cancel(NOTIFICATION_ID);

            }
        });


    }

    static void CreateFullScreenNotification(Context context) {
        Intent intent = new Intent(context,MainActivity2.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_NO_USER_ACTION | Intent.FLAG_ACTIVITY_SINGLE_TOP);
        PendingIntent pendingIntent = PendingIntent.getActivity(context,PendingIntent.FLAG_UPDATE_CURRENT);

        NotificationCompat.Builder notificationBuilder =
                new NotificationCompat.Builder(context,CHANNEL_ID)
                        .setSmallIcon(R.drawable.ic_launcher_background)
                        .setContentTitle("Alarm")
                        .setContentText("Het alarm gaat")
                        .setPriority(NotificationCompat.PRIORITY_MAX)
                        .setCategory(NotificationCompat.CATEGORY_ALARM)
                        .setContentIntent(pendingIntent)
                        .setFullScreenIntent(pendingIntent,true);
        notificationmanagerCompat.from(context).notify(NOTIFICATION_ID,notificationBuilder.build());
    }

    private static void createNotificationChannel(Context context) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            notificationmanagerCompat notificationmanager = notificationmanagerCompat.from(context);

            if (notificationmanager.getNotificationChannel(CHANNEL_ID) == null) {
                NotificationChannel channel = new NotificationChannel(CHANNEL_ID,"channel_name",notificationmanager.IMPORTANCE_HIGH);
                channel.setDescription("channel_description");
                notificationmanager.createNotificationChannel(channel);
            }
        }
    }
}

Wekkerservice.java

package com.example.wekkerapp;

import android.app.AlarmManager;
import android.app.IntentService;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.media.MediaPlayer;
import android.util.Log;

import androidx.annotation.Nullable;

public class WekkerService extends IntentService {

    public static MediaPlayer mediaPlayer;
    public WekkerService() {
        super("WekkerService");

    }

    @Override
    public void onCreate() {
        super.onCreate(); // if you override onCreate(),make sure to call super().
    }

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        Log.d("test","onHandleIntent: ");
        mediaPlayer = MediaPlayer.create(getApplicationContext(),R.raw.alarmpie);
        if (MainActivity.FULL_SCREEN_ACTION.equals(intent.getAction()))

            mediaPlayer.setLooping(true);
        mediaPlayer.start(); // no need to call prepare(); create() does that for you
        MainActivity.CreateFullScreenNotification(getApplicationContext());

    }
}

Mainactivity2.java

package com.example.wekkerapp;

import android.app.NotificationChannel;
import android.app.notificationmanager;
import android.media.MediaPlayer;
import android.os.Build;
import android.os.Bundle;

import com.google.android.material.floatingactionbutton.FloatingActionButton;
import com.google.android.material.snackbar.Snackbar;

import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import androidx.core.app.NotificationCompat;

import android.view.View;
import android.view.WindowManager;
import android.widget.Button;

public class MainActivity2 extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main2);
        Button stopbutton = findViewById(R.id.button2);
        stopbutton.setonClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                WekkerService.mediaPlayer.stop();
            }
        });

    }
}

解决方法

我建议您使用BroadcastReceiver,然后从其onReceive方法启动服务。 因此,在MainActivity的onClick侦听器中,您应该更改以下待处理的意图 如下:

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">{{ $player->first_name }} {{ $player->last_name }} <span class="float-right"><a class="" href="{{ route('players.edit',$player->id)}}">
                            {{ __('Spieler bearbeiten') }}
                        </a></span></div>

                <div class="card-body">
                    @if (session('status'))
                    <div class="alert alert-success" role="alert">
                        {{ session('status') }}
                    </div>
                    @endif

                    <ul>
                        <li>Vorname: {{ $player->first_name }}</li>
                        <li>Nachname: {{ $player->last_name }}</li>
                        <li>Land: {{ $player->country }}</li>
                        <li>Bild: {{ $player->image }}</li>
                        <li>Grösse: {{ $player->size }}</li>
                        <li>Gewicht: {{ $player->weight }}</li>
                        <li>Alter: {{ $player->date_of_birth }}</li>


                    </ul>

                    <br>
                    <br>
                    <a href="{{ route('tournaments.show',$player->tournament_id) }}">Zurück</a>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext(),intent,PendingIntent.FLAG_UPDATE_CURRENT);

,您传递的意图将启动BroadcastReceiver。 警报管理器启动BroadcastReceiver后,应立即从其onReceive方法启动服务。

请记住,由于最近的更改,操作系统将不仅仅让您随时随地启动服务或后台服务!

如果应用已关闭并且您要启动该服务,则应以ForgroundService形式启动它并显示一条通知(您有5秒钟的时间进行此调用),否则它将引发RemoteServiceException,这就是服务中代码的原因将无法运行。

我强烈建议您看一下以下答案: https://stackoverflow.com/a/56471104/9023032 这也是另一个有用的答案,可能会派上用场: https://stackoverflow.com/a/54035247/9023032