android 中的警报管理器未按时发出通知
Alarm Manager in android does not issue notification on time
我正在尝试在 android 中为大学做一个小项目,用户可以选择 select 时间选择器对话框中的时间,并根据时间 selected将向用户发出喝水通知并每 15 minutes.However 重复一次 警报管理器使用问题通知 vaguely.Sometimes 通知按时发出并每 15 分钟重复一次,尽管午夜后通知 stop.Also 有时会延迟发布 notification.Cant 找出原因!感谢帮助。这是必要的 xml 和 java 文件
activity_water.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/relative"
tools:context="com.example.priyam.databaselogin.Water">
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@android:color/darker_gray"
android:layout_marginTop="70dp"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="15dp">
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/reminderWaterCheckbox"
android:buttonTint="@color/red"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:text="Remind me once at"
android:textStyle="bold"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="170dp"
android:text="09:30 AM"
android:textColor="@color/red"
android:id="@+id/textViewTime"/>
</LinearLayout>
</RelativeLayout>
water.java
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.TimePickerDialog;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.CheckBox;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;
import java.util.Calendar;
public class Water extends AppCompatActivity implements View.OnClickListener {
TextView time;
CheckBox waterReminder;
int h,m;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_water);
setTitle("Water Reminder");
getId();
Toast.makeText(getApplicationContext(),"this",Toast.LENGTH_LONG).show();
}
private void getId(){
time=(TextView)findViewById(R.id.textViewTime);
waterReminder=(CheckBox)findViewById(R.id.reminderWaterCheckbox);
time.setOnClickListener(this);
}
private void showDialog(){
TimePickerDialog timePickerDialog = new TimePickerDialog(this,
new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker view, int hourOfDay,
int minute) {
h=hourOfDay;
m=minute;
Calendar calendar=Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY,h);
calendar.set(Calendar.MINUTE,m);
Intent intent=new Intent(getApplicationContext(),Notification_receiver.class);
PendingIntent pendingIntent=PendingIntent.getBroadcast(getApplicationContext(),100,intent,PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager= (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis(),AlarmManager.INTERVAL_FIFTEEN_MINUTES,pendingIntent);
time.setText(h+":"+m);
}
}, h, m, false);
timePickerDialog.show();
}
@Override
public void onClick(View v) {
showDialog();
}
}
Notification_receiver.java
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.support.v4.app.NotificationCompat;
public class Notification_receiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
NotificationManager notificationManager= (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent1=new Intent(context,DashBoard.class);
intent1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent=PendingIntent.getActivity(context,100,intent1,PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder=new NotificationCompat.Builder(context)
.setContentIntent(pendingIntent)
.setSmallIcon(R.drawable.logo)
.setContentTitle("Hitfit")
.setContentText("Its time you gulped a glass of water!Stay hydrated,stay fit!")
.setAutoCancel(true);
builder.setVibrate(new long[] { 1000, 1000});
Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
builder.setSound(alarmSound);
notificationManager.notify(100,builder.build());
}
}
使用的最小 sdkVersion 是 18
因为 days.Thank 你就一直坚持这个!
在AlarmManager
的文档中,可以看到如下提示:
Note: as of API 19, all repeating alarms are inexact. If your application needs precise delivery times then it must use one-time exact alarms, rescheduling each time as described above. Legacy applications whose targetSdkVersion is earlier than API 19 will continue to have all of their alarms, including repeating alarms, treated as exact.
我认为你实际上就是这种情况,你的警报并不准确,因为从 API 19 开始,系统就是这样保持电池电量的。
我正在尝试在 android 中为大学做一个小项目,用户可以选择 select 时间选择器对话框中的时间,并根据时间 selected将向用户发出喝水通知并每 15 minutes.However 重复一次 警报管理器使用问题通知 vaguely.Sometimes 通知按时发出并每 15 分钟重复一次,尽管午夜后通知 stop.Also 有时会延迟发布 notification.Cant 找出原因!感谢帮助。这是必要的 xml 和 java 文件 activity_water.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/relative"
tools:context="com.example.priyam.databaselogin.Water">
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="@android:color/darker_gray"
android:layout_marginTop="70dp"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="15dp">
<CheckBox
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/reminderWaterCheckbox"
android:buttonTint="@color/red"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="20dp"
android:text="Remind me once at"
android:textStyle="bold"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="170dp"
android:text="09:30 AM"
android:textColor="@color/red"
android:id="@+id/textViewTime"/>
</LinearLayout>
</RelativeLayout>
water.java
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.TimePickerDialog;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.CheckBox;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;
import java.util.Calendar;
public class Water extends AppCompatActivity implements View.OnClickListener {
TextView time;
CheckBox waterReminder;
int h,m;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_water);
setTitle("Water Reminder");
getId();
Toast.makeText(getApplicationContext(),"this",Toast.LENGTH_LONG).show();
}
private void getId(){
time=(TextView)findViewById(R.id.textViewTime);
waterReminder=(CheckBox)findViewById(R.id.reminderWaterCheckbox);
time.setOnClickListener(this);
}
private void showDialog(){
TimePickerDialog timePickerDialog = new TimePickerDialog(this,
new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker view, int hourOfDay,
int minute) {
h=hourOfDay;
m=minute;
Calendar calendar=Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY,h);
calendar.set(Calendar.MINUTE,m);
Intent intent=new Intent(getApplicationContext(),Notification_receiver.class);
PendingIntent pendingIntent=PendingIntent.getBroadcast(getApplicationContext(),100,intent,PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager= (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis(),AlarmManager.INTERVAL_FIFTEEN_MINUTES,pendingIntent);
time.setText(h+":"+m);
}
}, h, m, false);
timePickerDialog.show();
}
@Override
public void onClick(View v) {
showDialog();
}
}
Notification_receiver.java
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.media.RingtoneManager;
import android.net.Uri;
import android.support.v4.app.NotificationCompat;
public class Notification_receiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
NotificationManager notificationManager= (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent1=new Intent(context,DashBoard.class);
intent1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent=PendingIntent.getActivity(context,100,intent1,PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder=new NotificationCompat.Builder(context)
.setContentIntent(pendingIntent)
.setSmallIcon(R.drawable.logo)
.setContentTitle("Hitfit")
.setContentText("Its time you gulped a glass of water!Stay hydrated,stay fit!")
.setAutoCancel(true);
builder.setVibrate(new long[] { 1000, 1000});
Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
builder.setSound(alarmSound);
notificationManager.notify(100,builder.build());
}
}
使用的最小 sdkVersion 是 18
因为 days.Thank 你就一直坚持这个!
在AlarmManager
的文档中,可以看到如下提示:
Note: as of API 19, all repeating alarms are inexact. If your application needs precise delivery times then it must use one-time exact alarms, rescheduling each time as described above. Legacy applications whose targetSdkVersion is earlier than API 19 will continue to have all of their alarms, including repeating alarms, treated as exact.
我认为你实际上就是这种情况,你的警报并不准确,因为从 API 19 开始,系统就是这样保持电池电量的。