我试图在应用程序启动 10 分钟后生成警报。根据我的要求,无论用户关闭应用程序、关闭并再次打开,还是重启后,这个警报都应该起作用。下面是我的代码。
MainActivity.java
import android.app.ActivityManager;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private Context context;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.context=this;
startService(new Intent(getBaseContext(), MyService.class));
}
public void startService(View view) {
// startService(new Intent(getBaseContext(), MyService.class));
}
// Method to stop the service
public void stopService(View view) {
// stopService(new Intent(getBaseContext(), MyService.class));
}
}
MyService.java - 这是服务类。
import android.app.AlarmManager;
import android.app.IntentService;
import android.app.PendingIntent;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.IBinder;
import android.os.SystemClock;
import android.widget.Toast;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Calendar;
import java.util.GregorianCalendar;
/**
* Created by Nirodha Mihiran on 6/8/2016.
*/
public class MyService extends Service {
public static boolean doneCreted = false;
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// Let it continue running until it is stopped.
Toast.makeText(this, "Service Started Second", Toast.LENGTH_LONG).show();
Calendar calendar = new GregorianCalendar();
calendar.setTimeInMillis(System.currentTimeMillis() + 10 * 60 * 1000);
intent = new Intent(MyService.this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(MyService.this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager) MyService.this.getSystemService(MyService.this.ALARM_SERVICE);
// am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 1000 * 60 * 5, pendingIntent);
// am.setWindow(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis(), 1000 * 60 * 5 , pendingIntent);
am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
}
}
AlarmReciever.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;
import android.widget.Toast;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Calendar;
import java.util.GregorianCalendar;
/**
* Created by thisararanawaka on 6/2/16.
*/
public class AlarmReceiver extends BroadcastReceiver {
private int MID = 0;
public static boolean isCreated;
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
long when = System.currentTimeMillis();
Calendar calendar = new GregorianCalendar();
calendar.setTimeInMillis(System.currentTimeMillis()+5*60*1000);
NotificationManager notificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
Intent notificationIntent = new Intent(context, MainActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder mNotifyBuilder = new NotificationCompat.Builder(
context).setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("Alaram Fired")
.setContentText("Events To be Performed").setSound(alarmSound)
.setAutoCancel(true)
.setContentIntent(pendingIntent)
.setVibrate(new long[]{1000, 1000, 1000, 1000, 1000});
notificationManager.notify(MID, mNotifyBuilder.build());
MID++;
Toast.makeText(context, "Notification Created .", Toast.LENGTH_LONG).show();
}
}
如果我没有关闭并关闭手机或重新启动手机,我可以按时收到警报。我按时接到闹钟。
但是,如果我关闭并打开手机,或者如果我重新启动手机,我会在手机打开/重启后立即收到警报和通知 - 可能在一分钟后。在这种情况下,即使闹钟安排在明天也没关系,我会在手机开机/重启后立即收到。
我做错了什么?
最佳答案
通过查看您的代码,这可能是一个原因
在您的 onStartCommand() 中,您将时间设置为
calendar.setTimeInMillis(System.currentTimeMillis() + 10 * 60 * 1000);
设置日历时间 + 10 分钟,然后您在下面的行中设置相同的时间
am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
这样试试,
long myAlarmTime = System.currentTimeMillis() + 10 * 60 * 1000;
am.set(AlarmManager.RTC_WAKEUP, myAlarmTime, pendingIntent);
重启后出现这个问题的原因
服务可以被系统运行的原因有两个。如果有人调用 Context.startService() 那么系统将检索服务(创建它并在需要时调用它的 onCreate() 方法)然后使用客户端提供的参数调用它的 onStartCommand(Intent, int, int) 方法。此时服务将继续运行,直到调用 Context.stopService() 或 stopSelf()。 https://developer.android.com/reference/android/app/Service.html
关于Android:警报在预定时间之前被触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38114366/