In my main activity, I am executing this:
Calendar calendar = Calendar.getInstance();
// 9:45 PM
calendar.set(Calendar.HOUR_OF_DAY, 21);
calendar.set(Calendar.MINUTE, 45);
calendar.set(Calendar.SECOND, 0);
AlarmManager am = (AlarmManager) this.getApplicationContext().getSystemService(Context.ALARM_SERVICE);
PendingIntent pi = PendingIntent.getService(this.getApplicationContext(), 0, new Intent(this.getApplicationContext(), MorningReceiver.class), PendingIntent.FLAG_UPDATE_CURRENT);
am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pi);
Toast msg = Toast.makeText(NotificationScanner.this,
"Scheduled: " + calendar.getTime(), Toast.LENGTH_LONG);
msg.show();
And this is my receiver
public class MorningReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
MediaPlayer mMediaPlayer = new MediaPlayer();
Uri alert = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
try {
mMediaPlayer.setDataSource(context, alert);
final AudioManager audioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
if (audioManager.getStreamVolume(AudioManager.STREAM_ALARM) != 0) {
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);
mMediaPlayer.start();
PackageManager packageManager = context.getPackageManager();
Intent skype = packageManager.getLaunchIntentForPackage("com.skype.raider");
context.startActivity(skype);
}
}catch(Exception e){
Toast msg = Toast.makeText(context,
"Exception thrown", Toast.LENGTH_LONG);
msg.show();
}
}
}
The Toast from the main activity displays, so I know the alarm is getting set, but the receiver is never getting called (the ring is never playing, nor the Toast exception message). Does anyone know what I'm doing wrong here with my AlarmManager? Am I supposed to do something in my Manifest to get the Receiver working?
Thanks
Related
I am trying to develop an application in which the user can create more than 1 alarms for the same time ,say, 09:48. And for this time, each alarm has to create its own notification which leads the user to an activity when the notification is clicked. The other alarms which were scheduled at the same time must keep ringing until their notifications are clicked. Now, I am able to create alarms for different times and get their corresponding notifications which lead to an activity in which the user can dismiss or snooze the alarm. However, when I schedule more than one alarm for the same time, only 1 alarm is ringing and the other one gets lost. I share my code pieces at the below.
public void schedule(Context context) {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmBroadcastReceiver.class);
PendingIntent alarmPendingIntent = PendingIntent.getBroadcast(context, alarmId, intent, 0);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, minute);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
alarmManager.setExact(
AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(),
alarmPendingIntent
);
In my broadcastReceiver class:
private void startAlarmService(Context context, Intent intent) {
Intent intentService = new Intent(context, AlarmService.class);
Log.println(Log.DEBUG, "DEBUG", "************Alarm Broadcast Receiver**********");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
context.startForegroundService(intentService);
} else {
context.startService(intentService);
}
}
In my AlarmService :
#Override
public void onCreate() {
super.onCreate();
mediaPlayer = MediaPlayer.create(this, R.raw.alarm);
mediaPlayer.setLooping(true);
vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Intent notificationIntent = new Intent(this, RingActivity.class);
int requestCode = new Random().nextInt(Integer.MAX_VALUE);
PendingIntent pendingIntent = PendingIntent.getActivity(this, requestCode, notificationIntent, 0);
//String alarmTitle = String.format("%s Alarm", intent.getStringExtra(TITLE));
int notificationId = new Random().nextInt(Integer.MAX_VALUE);
Notification notification = new NotificationCompat.Builder(this, String.valueOf(notificationId))
.setContentTitle("PASS1")
.setContentText("PASS2")
.setSmallIcon(R.drawable.pill)
.setContentIntent(pendingIntent)
.build();
mediaPlayer.start();
long[] pattern = { 0, 100, 1000 };
vibrator.vibrate(pattern, 0);
startForeground(1, notification);
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
mediaPlayer.stop();
vibrator.cancel();
}
in this code
startForeground(1, notification);
you are using 1 as the id.
If a notification with the same id has already been posted by your application and has not yet been canceled, it will be replaced by the updated information.
So the second alarm notification with the same id (because you are using a fixed value of 1) is replacing the old one
I'm using wakeful broadcast receiver with alarm manager in my app to performing some tasks at a specific time.
its working well. But I'm facing a minor problem
for example I set my alarm manager at 9:00 PM after that if I remove my app from recent app it's definitely working in background, But after that specific time (9:00 PM) whenever I'm using my app my alarm trigger immediately.
I hope everyone (relating this problem) understand my point.
If anyone knows about this problem tell me.
Thanks.
Here I'm registering my receiver
<receiver
android:name="com.example.chartdemo.MyBroadcastReceiver"
android:enabled="true"
android:exported="true">
</receiver>
Here's my MainActivity.java code
public class MainActivity extends AppCompatActivity {
public static TextView textView,textView1;
Button button, button1,button2,button3;
public static int counter=0, time;
MyBroadcastReceiver myBroadcastReceiver;
myDbAdapter helper;
//private final MyDateChangeReceiver mDateReceiver = new MyDateChangeReceiver();
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView=findViewById(R.id.text);
textView1=findViewById(R.id.text1);
button=findViewById(R.id.counterbtn);
button1=findViewById(R.id.showbtn);
button2=findViewById(R.id.savebtn);
button3=findViewById(R.id.delbtn);
helper = new myDbAdapter(this);
loadData(); //for data retrieving from shared preferences
startAlarm(this);
}
private void startAlarm(Context context) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, 9);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
cal.set(AM_PM, PM);
time= (int) cal.getTimeInMillis();
AlarmManager alarmManager = (AlarmManager)context.getSystemService(ALARM_SERVICE);
Intent intent = new Intent(context, MyBroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 234, intent, 0);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
alarmManager.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
Toast.makeText(context, "alarm set after "+cal.getTimeInMillis(), Toast.LENGTH_SHORT).show();
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
Toast.makeText(context, "alarm set after "+cal.getTimeInMillis(), Toast.LENGTH_SHORT).show();
} else {
alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
Toast.makeText(context, "alarm set after "+cal.getTimeInMillis(), Toast.LENGTH_SHORT).show();
}
}
And Here's my WakefulBroadcastReceiver.java code
public class MyBroadcastReceiver extends WakefulBroadcastReceiver {
MediaPlayer mp;
myDbAdapter helper;
MainActivity mainActivity=new MainActivity();
#Override
public void onReceive(Context context, Intent intent) {
SharedPreferences sh = context.getSharedPreferences("MySharedPref", MODE_PRIVATE);
int a = sh.getInt("counter", 0);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String date = sdf.format(new Date());
helper = new myDbAdapter(context);
long id = helper.insertData(date, String.valueOf(a));
if (id <= 0) {
Toast.makeText(context, "Insertion UnSuccessful", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "Insertion Successful", Toast.LENGTH_SHORT).show();
}
mp = MediaPlayer.create(context, R.raw.alarm);
mp.start();
Toast.makeText(context, "Alarm...!!!!!! ", Toast.LENGTH_LONG).show();
SharedPreferences sharedPreferences = context.getSharedPreferences("MySharedPref", MODE_PRIVATE);
SharedPreferences.Editor myEdit = sharedPreferences.edit();
myEdit.putInt("counter", 0);
myEdit.commit();
}
Before, the alarm manager was working. I don't think I changed anything, but now it isn't starting at all.
Here is the code where I set the alarm manager:
SettingsActivity.java
Intent intent;
static PendingIntent recurringDownload;
intent = new Intent(context, UpdateScoresService.class);
recurringDownload = PendingIntent.getService(context, 0, intent, 0);
Preference.OnPreferenceChangeListener refreshListener = new Preference.OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if(newValue.toString().equals("1")){ /* daily */
background_refresh.setSummary("Scores will be refreshed daily.");
AlarmManager manager = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE);
manager.cancel(recurringDownload);
recurringDownload.cancel();
Log.e("DAILY REFRESH", " ");
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY,10);
calendar.set(Calendar.MINUTE,00);
if(calendar.before(Calendar.getInstance())){
Log.e("AFTER", "10 AM DAILY");
calendar.add(Calendar.DATE, 1);
}
manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, recurringDownload);
}else if(newValue.toString().equals("2")){ /* weekly */
Log.e("WEEKLY REFRESH", " ");
background_refresh.setSummary("Scores will be refreshed weekly.");
AlarmManager manager = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE);
manager.cancel(recurringDownload);
recurringDownload.cancel();
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY,10);
calendar.set(Calendar.MINUTE,00);
if(calendar.before(Calendar.getInstance())){
Log.e("AFTER", "10 AM WEEKLY");
calendar.add(Calendar.DATE, 1);
}
manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY * 7, recurringDownload);
}else{ /* manually */
background_refresh.setSummary("Scores will be refreshed manually.");
Log.e("MANUAL REFRESH", " ");
AlarmManager manager = (AlarmManager) getActivity().getSystemService(Context.ALARM_SERVICE);
manager.cancel(recurringDownload);
recurringDownload.cancel();
}
return true;
}
};
The UpdateScoresService is here:
public class UpdateScoresService extends IntentService {
public int countChanged;
Context context = this;
public UpdateScoresService() {
super("UpdateScoresService");
}
#Override
protected void onHandleIntent(Intent intent) {
Log.e("onHandleIntent", "grabbing scores");
countChanged = new GetAnimeScores(getApplicationContext()).refreshScores();
if(countChanged>0){ //Display notification if any scores changed
Log.d("Creating notification", " ");
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setSmallIcon(R.drawable.ic_timeline_white_24dp);
builder.setContentTitle("MAL Score Tracker");
builder.setAutoCancel(true);
if(countChanged==1){
builder.setContentText("1 score changed since you were gone!");
}else{
builder.setContentText(countChanged+" scores changed since you were gone!");
}
Intent intent1 = new Intent(context, MainActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(intent1);
PendingIntent pendingIntent = stackBuilder.getPendingIntent(0,PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0,builder.build());
}
}
}
}
The Log in the SettingsActivity print but the Log in the onHandleIntent from the Service do not print. I'm not sure what is wrong.
It is better to have a BroadcastReceiver which will be responsible for starting the service. The code for it should look something like this:
Create a BroadcastReceiver class:
public class ReceiverToStartService extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context, UpdateScoresService.class);
ComponentName service = context.startService(i);
}
}
Register receiver in your Manifest:
<receiver android:name=".ReceiverToStartService"/>
Now change the Intent in your Activity that you are passing to PendingIntent:
intent = new Intent(context, ReceiverToStartService.class);
recurringDownload = PendingIntent.getService(context, 0, intent, 0);
I would like to create a custom notification service in my app.
I wouldn't use the google service (google cloud messaging).
Is there a way to create a daemon that check every X seconds a particular condition on my app db and show a notification?
Thank you,
edit
I call this method in MainActivity's oncreate(). I get the times from my db
private void restartNotify() {
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,
intent, PendingIntent.FLAG_CANCEL_CURRENT);
am.cancel(pendingIntent);
ArrayList<String> item = new ArrayList<String>();
item = GetLists.GetTimesListForNotification(this);
for (int i = 0; i < item.size(); ++i) {
String time = item.get(i);
int Position = time.indexOf(":");
int hour = Integer.parseInt(time.substring(0, Position));
int min = Integer.parseInt(time.substring(Position + 1));
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY, hour);
cal.set(Calendar.MINUTE, min);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
am.set(AlarmManager.RTC, cal.getTimeInMillis(),
pendingIntent);
}
And this is my broadcast receiver
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
NotificationManager mManager;
mManager = (NotificationManager) context.getApplicationContext()
.getSystemService(
context.getApplicationContext().NOTIFICATION_SERVICE);
Intent intent1 = new Intent(context.getApplicationContext(),
MainActivity.class);
Notification notification = new Notification(R.drawable.ic_launcher,
"New message to read", System.currentTimeMillis());
intent1.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingNotificationIntent = PendingIntent.getActivity(
context.getApplicationContext(), 0, intent1,
PendingIntent.FLAG_UPDATE_CURRENT);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.setLatestEventInfo(context.getApplicationContext(),
"notification are work", "it's work",
pendingNotificationIntent);
mManager.notify(0, notification);
}
}
You can use AlarmManager + BroadcastReceiver like so:
private void setRecurringAlarm(Context context) {
Intent downloader = new Intent(this, MyStartServiceReceiver.class);
downloader.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, downloader, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 6000, 10000, pendingIntent);
}
BroadcastReceiver class:
public class MyStartServiceReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//do the stuff...
}
}
And don't forget to register receiver in your manifest:
<receiver android:name=".MyStartServiceReceiver"
android:enabled="true"/>
You have to use Alarm Manager to schedule code for execution every specific period. take a look here:
http://developer.android.com/training/scheduling/alarms.html
Date dat = new Date();
Calendar cal_alarm = Calendar.getInstance();
Calendar cal_now = Calendar.getInstance();
cal_alarm.setTime(dat);
cal_alarm.set(Calendar.HOUR_OF_DAY, hrs);// set the alarm time
cal_alarm.set(Calendar.MINUTE, min);
cal_alarm.set(Calendar.SECOND, 0);
cal_alarm.set(Calendar.MILLISECOND, 0);
if (cal_alarm.before(cal_now)) {// if its in the past increment
cal_alarm.add(Calendar.DATE, 1);
}
Intent intent = new Intent(ctx, AlarmReceiver.class);
// intent.putExtra("Reminder to Take Photo", "Pixitch!");
PendingIntent sender = PendingIntent.getBroadcast(ctx, 0010000,
intent, 0);
// Get the AlarmManager service
long tmemills = cal_alarm.getTimeInMillis()
- cal_now.getTimeInMillis();
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP, tmemills,
AlarmManager.INTERVAL_DAY, sender);
Alarm Receiver Class
public class AlarmReceiver extends BroadcastReceiver {
private static final int MY_NOTIFICATION_ID = 1;
private NotificationManager notificationManager;
private Notification myNotification;
// Context ctx = this;
#SuppressWarnings("deprecation")
#Override
public void onReceive(Context context, Intent intent) {
try {
NotificationManager mNM;
mNM = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(
R.drawable.ic_launcher, "Pixitch Notification !",
System.currentTimeMillis());
PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
new Intent(context, AlarmManage.class), 0);
// Set the info for the views that show in the notification panel.
notification.setLatestEventInfo(context, "Pixitch Notification!",
"Reminder For TakePhoto", contentIntent);
mNM.notify(0, notification);
} catch (Exception e) {
Toast.makeText(
context,
"There was an error somewhere, but we still received an alarm",
Toast.LENGTH_SHORT).show();
e.printStackTrace();
}
}
}
the value of tmemills is 278,088
the tmemills is around 4.5 minutes but
the alarm Manager is Running immediately
I am not able to find where the problem is because I am beginner for Android. please help me
Try this:
am.setRepeating(AlarmManager.RTC_WAKEUP, tmemills + System.currentTimeMillis(),
AlarmManager.INTERVAL_DAY, sender);
Get rid of tmemills. Use cal_alarm.getTimeInMillis() as the second parameter to your set() call on AlarmManager, as that is the number of milliseconds since the Unix epoch at which you want the event to occur.