Android: AlarmManager sometimes doesn't call BroadcastReceiver - java

In my app, I've got a BroadcastReceiver, which is called by an AlarmManager. That BroadcastReceiver calls CommonsWare's WakefulIntentservice.
I tested this on my phone, and it appeared that sometimes, my BroadcastReceiver isn't called at all. I'm really confused about what it could be. My BroadcastReceiver and WakefulIntentservice are registerd in the manifest.
This is my code:
In AlarmActivity:
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, 2);
Intent intent = new Intent(this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), savedIntervalAutomaticMilisInt, pendingIntent);
Toast.makeText(this, "Saved", Toast.LENGTH_LONG).show();
finish();
AlarmReceiver:
package com.something.app;
import com.commonsware.cwac.wakeful.WakefulIntentService;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context, AlarmService.class);
WakefulIntentService.sendWakefulWork(context, i);
}
}
And AlarmService:
package com.something.app;
import android.app.PendingIntent;
import android.content.Intent;
import com.commonsware.cwac.wakeful.WakefulIntentService;
public class AlarmService extends WakefulIntentService {
public AlarmService() {
super("AlarmService");
}
#Override
protected void doWakefulWork(Intent arg0) {
//A looooooooot of stuff
}
Does anyone know why the BroadcastReceiver sometimes isn't called?
EDIT: I heard about setting a BroadcastReceiver which receives onBootCompleted. Is that required?

So, that's the problem: If the device reboots, it sometimes clears the alarm, so you have to reset them in a BroadcastReceiver which receives onBootCompleted

Related

How to create Notification with timer inside

I'm trying to make notification with a countdown timer.
Am I doing wrong?
I try to update information inside notification using a countdown timer.
If the screen doesn't lock it works correctly. But in case of locked, my screen turns on each notification (so each second). So timer working correctly but it's very annoying that each second makes my screen turning on.
package com.example.yanec.schedulekpi;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.CountDownTimer;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationManagerCompat;
import android.util.Log;
import com.example.yanec.schedulekpi.Activities.MainActivity;
import com.example.yanec.schedulekpi.Fragments.DetailScheduleInfoFragment;
public class ServiceShowNotification extends BroadcastReceiver {
CountDownTimer countDownTimer;
long timeLeft;
NotificationCompat.Builder mBuilder;
NotificationManagerCompat notificationManager;
#Override
public void onReceive(final Context context, final Intent intent) {
Log.d("myLogs", "OnReceive");
timeLeft = intent.getLongExtra(Constants.INTENT_PASS_DATE, 0);
showNotification(intent, context, Parser.toStringFrom(timeLeft));
countDownTimer = new CountDownTimer(timeLeft, Constants.COUNT_DOWN_INTERVAL) {
#Override
public void onTick(long millisUntilFinished) {
timeLeft -= Constants.COUNT_DOWN_INTERVAL;
mBuilder.setContentText(Parser.toStringFrom(timeLeft));
mBuilder.setVisibility(Notification.VISIBILITY_PUBLIC);
notificationManager.notify(Constants.NOTIFICATION_ID, mBuilder.build());
}
#Override
public void onFinish() {
DetailScheduleInfoFragment.isServiceWorking = false;
}
};
countDownTimer.start();
}
private void showNotification(Intent intent, Context context, String time){
Intent intent1 = new Intent(context, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent1, 0);
mBuilder = new NotificationCompat.Builder(context, Constants.CHANNEL_ID)
.setSmallIcon(R.drawable.ic_bar)
.setContentTitle(intent.getStringExtra(Constants.INTENT_PASS_NAME))
.setContentText(time)
.setPriority(NotificationCompat.PRIORITY_MAX)
.setContentIntent(pendingIntent)
.setAutoCancel(true);
mBuilder.setVisibility(Notification.VISIBILITY_PUBLIC);
notificationManager = NotificationManagerCompat.from(context);
notificationManager.notify(Constants.NOTIFICATION_ID, mBuilder.build());
}
}
If my screen is locked and I'm updating notification, my screen doesn't wake up. But if I wake up the screen by myself (don't unlock just wake up using wakeUp button), it shows me updated info. Thanks.

How can I make this Alarm Clock app. to be able to set alarm at any time of the day and exactly at that time?

I am new to android development and have very little knowledge in java and I have seen this Alarm Clock app tutorial in the internet. The application has problems. It can't set time before the current time of phone and it doesn't start at the exact time. How to make this application so it can set alarm within 24 hours and at the exact time?
AlarmActivity.java
package com.javapapers.androidalarmclock;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.ToggleButton;
import java.util.Calendar;
public class AlarmActivity extends Activity {
AlarmManager alarmManager;
private PendingIntent pendingIntent;
private TimePicker alarmTimePicker;
private static AlarmActivity inst;
private TextView alarmTextView;
public static AlarmActivity instance() {
return inst;
}
#Override
public void onStart() {
super.onStart();
inst = this;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
alarmTimePicker = (TimePicker) findViewById(R.id.alarmTimePicker);
alarmTextView = (TextView) findViewById(R.id.alarmText);
ToggleButton alarmToggle = (ToggleButton) findViewById(R.id.alarmToggle);
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
}
public void onToggleClicked(View view) {
if (((ToggleButton) view).isChecked()) {
Log.d("MyActivity", "Alarm On");
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, alarmTimePicker.getCurrentHour());
calendar.set(Calendar.MINUTE, alarmTimePicker.getCurrentMinute());
Intent myIntent = new Intent(AlarmActivity.this, AlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(AlarmActivity.this, 0, myIntent, 0);
alarmManager.set(AlarmManager.RTC, calendar.getTimeInMillis(), pendingIntent);
} else {
alarmManager.cancel(pendingIntent);
setAlarmText("");
Log.d("MyActivity", "Alarm Off");
}
}
public void setAlarmText(String alarmText) {
alarmTextView.setText(alarmText);
}
}
AlarmReceiver.java
package com.javapapers.androidalarmclock;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.support.v4.content.WakefulBroadcastReceiver;
public class AlarmReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(final Context context, Intent intent) {
//this will update the UI with message
AlarmActivity inst = AlarmActivity.instance();
inst.setAlarmText("Alarm! Wake up! Wake up!");
//this will sound the alarm tone
//this will sound the alarm once, if you wish to
//raise alarm in loop continuously then use MediaPlayer and setLooping(true)
Uri alarmUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
if (alarmUri == null) {
alarmUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
}
Ringtone ringtone = RingtoneManager.getRingtone(context, alarmUri);
ringtone.play();
//this will send a notification message
ComponentName comp = new ComponentName(context.getPackageName(),
AlarmService.class.getName());
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
}
AlarmService.java
package com.javapapers.androidalarmclock;
import android.app.IntentService;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
public class AlarmService extends IntentService {
private NotificationManager alarmNotificationManager;
public AlarmService() {
super("AlarmService");
}
#Override
public void onHandleIntent(Intent intent) {
sendNotification("Wake Up! Wake Up!");
}
private void sendNotification(String msg) {
Log.d("AlarmService", "Preparing to send notification...: " + msg);
alarmNotificationManager = (NotificationManager) this
.getSystemService(Context.NOTIFICATION_SERVICE);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, AlarmActivity.class), 0);
NotificationCompat.Builder alamNotificationBuilder = new NotificationCompat.Builder(
this).setContentTitle("Alarm").setSmallIcon(R.drawable.ic_launcher)
.setStyle(new NotificationCompat.BigTextStyle().bigText(msg))
.setContentText(msg);
alamNotificationBuilder.setContentIntent(contentIntent);
alarmNotificationManager.notify(1, alamNotificationBuilder.build());
Log.d("AlarmService", "Notification sent.");
}
}
Please Help! I am desperate.
If you want to have a 24hour span, you also need to set the day, that's why you can't set the time before the current time of the phone.
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, alarmTimePicker.getCurrentHour());
calendar.set(Calendar.MINUTE, alarmTimePicker.getCurrentMinute());
if(calendar.getTimeInMillis() < System.currentTimeMillis())
calendar.add(Calendar.DAY, 1);
https://stackoverflow.com/a/20438452/6873402
I would just like to share this answer that I found about the Delay Problem in the Alarm Clock

Off RingtoneManager song android

I have tried many solutions such as-
RingtoneManager.stopPreviousRingtone();
But it comes with an error of -
Cannot make a static reference to the non-static method stopPreviousRingtone() from the type RingtoneManager
MyAlarmService.java
package com.example.getbettersoon;
import android.app.Service;
import android.content.Intent;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.IBinder;
import android.widget.Toast;
public class MyAlarmService extends Service {
static Ringtone ringtone;
#Override
public void onDestroy() {
super.onDestroy();
//Toast.makeText(this, "MyAlarmService.onDestroy()", Toast.LENGTH_LONG).show();
//RingtoneManager.stopPreviousRingtone();
ringtone.stop(); // THIS DOES NOT STOP THE RINGTONE
}
#SuppressWarnings("deprecation")
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
Toast.makeText(this, "MyAlarmService.onStart()", Toast.LENGTH_LONG).show();
Uri alarm = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
ringtone = RingtoneManager.getRingtone(getApplicationContext(), alarm);
ringtone.play();
}
}
Alarm.java
package com.example.getbettersoon;
import java.util.Calendar;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.media.Ringtone;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class Alarm extends Activity {
String gethours;
int myNum;
private PendingIntent pendingIntent;
public void SetAlarm(View arg0) {
Intent myIntent = new Intent(Alarm.this, MyAlarmService.class);
pendingIntent = PendingIntent.getService(Alarm.this, 0, myIntent, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 10); // test
//TextView tv = (TextView) findViewById(R.id.bthrs);
//tv.setText(myNum);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
Toast.makeText(Alarm.this, "Start Alarm", Toast.LENGTH_LONG).show();
};
public void OffAlarm(View arg0) {
Intent myIntent = new Intent(Alarm.this, MyAlarmService.class);
pendingIntent = PendingIntent.getService(Alarm.this, 0, myIntent, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
// Tell the user about what we did.
Toast.makeText(Alarm.this, "Cancel!", Toast.LENGTH_LONG).show();
};
}
When my button is pressed, the ring tone starts after 10 seconds but when I press the stop button the music doesn't stop. Can anyone help me with it?
I assume you are relying on your service being stopped to stop the ringtone playback. The line:
alarmManager.cancel(pendingIntent);
merely removes the service from being deployed in the future by the AlarmManager and does not stop an active service.
To stop a running service you need to use Context.stopService()
For example:
public void OffAlarm(View arg0){
Intent myIntent = new Intent(Alarm.this, MyAlarmService.class);
pendingIntent = PendingIntent.getService(Alarm.this, 0, myIntent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
// Stops an existing running service
stopService(myIntent);
// Tell the user about what we did.
Toast.makeText(Alarm.this, "Cancel!", Toast.LENGTH_LONG).show();
}
only then will the onDestroy() method be called by the android system and your ringtone stopped.

Android Alarm Not Firing

I am trying to register an alarm with the android alarm manager and cannot seem to figure out why the the alarms aren't firing. I've looked at many examples online and my code seems to be doing the same thing that they suggest but still no success. I am running it on android 4.4 (KitKat)
Here is how I set the alarm:
public void registerAlarm(Context context, int hour, int minute) {
AlarmManager alarmMgr = (AlarmManager) context.getSystemService(
Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReciever.class);
PendingIntent alarmIntent = PendingIntent.getBroadcast(context,
0, intent, 0);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, minute);
calendar.set(Calendar.SECOND, 0);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 10000,
alarmIntent);
}
and here is how my receiver for it:
package com.alarm.alarm;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class AlarmReciever extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "recieved", Toast.LENGTH_LONG).show();
}
}
Here is how I declare my receiver in the manifest
<receiver android:name="com.alarm.alarm.AlarmReceiver">
</receiver>
and here is the SET ALARM permission
<uses-permission android:name="com.alarm.permission.SET_ALARM"/>
I have been stuck on this issue for hours. any clarification as to what i might be doing wrong would be greatly appreciated!
You have a typo in Broadcast class name, it should be AlarmReceiver instead of AlarmReciever per your Manifest

Android Broadcast receiver gives Error

Got another problem. Trying to use a broadcastreceiver to catch off an Alarm (alarm manager).
The following code is used:
package com.suncco.shangxinbao.service;
import java.util.Calendar;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;
import com.suncco.shangxinbao.model.ScheduledSms;
public class SmsTimerService extends BroadcastReceiver {
public SmsTimerService(Context context, int timeoutInSeconds,
ScheduledSms sms) {
Intent myIntent = new Intent(context, SmsTimerService.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
sms.getRequestCodeForListener(), myIntent, 0);
AlarmManager alarmManager = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 5); // should be timeoutInSeconds instead of 5
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
pendingIntent);
}
#Override
public void onReceive(Context context, Intent intent) {
Log.w("Karl", "yay");
}
In the manifest I put this as receiver:
<receiver
android:name="com.suncco.shangxinbao.service.SmsTimerService"
android:process=":remote" />
And I make an object of my SmsTimerService like this:
SmsTimerService smsTimerService = new SmsTimerService(this,5,sms);
And this is the well known error...
java.lang.RuntimeException: Unable to instantiate receiver
com.suncco.shangxinbao.service.SmsTimerService: java.lang.InstantiationException:
com.suncco.shangxinbao.service.SmsTimerService
You're getting the unable to instantiate receiver error because you don't have an empty constructor such as SmsTimerService(). The point is you need an empty constructor for this receiver to be created when receiving the intent. And it's ok if you don't implement any constructor. However, if you implement a constructor with parameters, you also need to implement an empty one!
So you can do something like this. Note that I didn't study what you actually want to do when creating intents.
public class SmsTimerService extends BroadcastReceiver {
private void doAction(Context context, int timeoutInSeconds, ScheduledSms sms) {
Intent myIntent = new Intent(context, SmsTimerService.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
sms.getRequestCodeForListener(), myIntent, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 5); // should be timeoutInSeconds instead of
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
}
#Override
public void onReceive(Context context, Intent intent) {
// you get to replace sms with something!
doAction(context, 5, sms); // original u do - > new SmsTimerService(this,5,sms);
}
}

Categories

Resources