问题描述
我一直在尝试提出警报应用程序。我一直在努力进行全屏通知。我最终确实做到了,但是只有在应用程序在后台运行时,它才起作用。
关闭应用程序后,它也需要工作。我不明白该怎么做。我知道这是有可能的,因为我每天使用的闹钟应用程序能够做到这一点。
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