I want to set an alarm at 9am that will execute only once in a day and with
this alarm i want to execute one BroadcastReciver and through that BroadcastReciver
i want to execute Service.
I am Using the following code but in this code following are problems
1)Alarm is not execute at exact 9am.
2)When it execute it execute more than one times
Please help me to resolve this problems.Any help will be appreciable.
===========================================================
The value of breakfastflag is boolean which i am taking from this activity when user press on the click to customize b
if(breakfastflag){
Intent myIntent = new Intent(SplashScreenActivity.this, MyBreakfastReciver.class);
System.out.println("getting Breakfast Reminder");
pendingIntent = PendingIntent.getBroadcast(SplashScreenActivity.this, 0, myIntent,0);
// Set the alarm to start at approximately 9:00 a.m.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 9);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
// With setInexactRepeating(), you have to use one of the AlarmManager interval
// constants--in this case, AlarmManager.INTERVAL_DAY.
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent);
}
BreakfastReciever.java
==============================
public class MyBreakfastReciver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
Intent service1 = new Intent(context, MyBreakfastAlarmService.class);
context.startService(service1);
}
}
MyBreakfastAlarmService.java
===================================
public class MyBreakfastAlarmService extends Service
{
private NotificationManager mManager;
#Override
public IBinder onBind(Intent arg0)
{
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate()
{
// TODO Auto-generated method stub
super.onCreate();
}
#SuppressWarnings("static-access")
#Override
public void onStart(Intent intent, int startId)
{
DatabaseHandler db=new DatabaseHandler(getApplicationContext());
HashMap<String,String> user = new HashMap<String,String>();
String abc="Breakfast";
user= db.getUserCalDetails();
String userid=user.get("userid");
final Calendar c = Calendar.getInstance();
int mYear = c.get(Calendar.YEAR);
int mMonth = c.get(Calendar.MONTH);
int mDay = c.get(Calendar.DAY_OF_MONTH);
String day="";
String month="";
mMonth=mMonth+1;
if(mMonth<=9){
month="0"+mMonth;
}
else{
month=""+month;
}
if(mDay<=9){
day="0"+mDay;
}
else{
day=""+mDay;
}
String year=mYear+"";
String finalDate=year+"-"+month+"-"+day;
int ab=db.getMealDettailsForRemider(userid,abc ,finalDate);
if(ab==0)
{
showNotification(this);
}
}
#SuppressLint("NewApi") private void showNotification(Context context) {
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.capture)
.setAutoCancel(true)
.setContentTitle("DietGuru")
.setContentText("You haven't logged your Breakfast for today.")
.setSubText("Would you like to do it now?")
;
// Creates an explicit intent for an Activity in your app
Intent resultIntent = new Intent(context, SplashScreenActivity.class);
// The stack builder object will contain an artificial back stack for the
// started Activity.
// This ensures that navigating backward from the Activity leads out of
// your application to the Home screen.
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
// Adds the back stack for the Intent (but not the Intent itself)
stackBuilder.addParentStack(SplashScreenActivity.class);
// Adds the Intent that starts the Activity to the top of the stack
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(
0,
PendingIntent.FLAG_UPDATE_CURRENT
);
mBuilder.setContentIntent(resultPendingIntent);
mBuilder.setContentIntent(resultPendingIntent);
mBuilder.setDefaults(Notification.DEFAULT_ALL);
NotificationManager mNotificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
// mId allows you to update the notification later on.
mNotificationManager.notify(1, mBuilder.build());
}
#Override
public void onDestroy()
{
super.onDestroy();
}
}
You should use setRepeating() instead of setInexactRepeating().
EDIT:
I have noticed two more mistakes in your code:
1. You have called mBuilder.setContentIntent(resultPendingIntent) twice. You should call it only once. I think this is why the alarm may be coming more than once.
2. You have written month=""+month;. It should be month=""+mMonth;
Try this. This should work.
EDIT 2:
According to the docs:
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.
To get the exact time, the only way is to use setExact() which needs to be set each time the alarm rings, because it doesn't repeat.
Related
My application targets KITKAT and up android version and i am trying to create repetitive notification daily via Alarm Manager below is my code :
public class AlarmReceiver extends BroadcastReceiver {
public static final String MY_ACTION = "mymasterpeice.foreverservice.myaction";
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(MY_ACTION)) {
// Do something here
// For our recurring task, we'll just display a message
Toast.makeText(context, "I'm running", Toast.LENGTH_SHORT).show();
// displayNotification(context, "Checkout New Articles");
sendNotification(context, "Checkout New Articles - Team");
}
}
/**
* Issues a notification to inform the user that server has sent a message.
*/
private static void sendNotification(Context context, String message) {
if (message != null && !TextUtils.isEmpty(message)) {
int icon = R.mipmap.ic_launcher;
long when = System.currentTimeMillis();
NotificationManager notificationManager = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
String title = context.getString(R.string.app_name);
Intent notificationIntent = new Intent(context, MainActivity.class);
// set intent so it does not start a new activity
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent =
PendingIntent.getActivity(context, 0, notificationIntent, 0);
Notification.Builder builder = new Notification.Builder(context);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP |
Intent.FLAG_ACTIVITY_SINGLE_TOP);
builder.setSmallIcon(icon)
.setContentTitle(title)
.setContentText(message)
.setContentIntent(intent);
Notification notification = builder.getNotification();
notificationManager.notify(icon, notification);
}
}
}
Main Activity :
public class MainActivity extends AppCompatActivity {
private String TAG=MainActivity.class.getSimpleName();
public static final String MY_ACTION = "mymasterpeice.foreverservice.myaction";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setRecusrringTimer();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
private void setRecusrringTimer() {
Intent myIntent = new Intent(MY_ACTION);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
this, 0, myIntent, 0);
AlarmManager alarmManager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
Calendar firingCal = Calendar.getInstance();
Calendar currentCal = Calendar.getInstance();
firingCal.set(Calendar.HOUR, 7); // At the hour you wanna fire
firingCal.set(Calendar.MINUTE, 0); // Particular minute
firingCal.set(Calendar.SECOND, 0); // particular second
long intendedTime = firingCal.getTimeInMillis();
long currentTime = currentCal.getTimeInMillis();
if (intendedTime >= currentTime) // you can add buffer time too here to ignore some small differences in milliseconds
{
alarmManager.setRepeating(AlarmManager.RTC,
intendedTime, AlarmManager.INTERVAL_DAY,
pendingIntent);
Log.d(TAG, "setRecusrringTimer ");
} else {
intendedTime = firingCal.getTimeInMillis();
Log.d(TAG, "setRecusrringTimer ");
alarmManager.setRepeating(AlarmManager.RTC,
intendedTime, AlarmManager.INTERVAL_DAY,
pendingIntent);
}
}
}
Manifest :
<receiver android:name=".AlarmReceiver">
<intent-filter>
<action android:name="mymasterpeice.foreverservice.myaction"/>
</intent-filter>
</receiver>
Issue is This code runs properly on Kitkat device until app is in memory , there are some delays like as in doc specified :
Note: Beginning with API 19 (KITKAT) alarm delivery is inexact: the OS
will shift alarms in order to minimize wakeups and battery use. There
are new APIs to support applications which need strict delivery
guarantees; see setWindow(int, long, long, PendingIntent) and
setExact(int, long, PendingIntent). Applications whose
targetSdkVersion is earlier than API 19 will continue to see the
previous behavior in which all alarms are delivered exactly when
requested.
But When app is not in memory the alarm manager does not show notification . I am specifically targeting Kitkat and above version of android.
I lost 1 month of my time for the same issue. Finally I found the solution. For the recent Android versions(exact version I am not sure ), an option called 'Auto Launch' have been introduced, which means the user can actually configure whether any app can be automatically started or not. So please check whether your app has permission for auto launch. This setting location may vay based on phone manufacturer. So you need to search for this 'Auto Lanuch' option in your phone settings. Even if it doesn't work, try removing your app from the 'Optimizations List' as well, which you can find in the settings.
Hello I have my Alarm Manager to show a Notification. The problem is that once the alarm is triggered and the notification is shown, when the code of MainActivity(super.onCreate) is executed, it always triggers the notification.
Here is my MainActivity which executes the Alarm.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initAlarm();
}
private void initAlarm(){
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.MONTH, 8);
calendar.set(Calendar.YEAR, 2015);
calendar.set(Calendar.DAY_OF_MONTH, 21);
calendar.set(Calendar.HOUR_OF_DAY, 15);
calendar.set(Calendar.MINUTE, 45);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.AM_PM,Calendar.PM);
//Creo un intent que ejecutara el BroadcastReceiver
Intent myIntent = new Intent(MainActivity.this, AlarmBroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC, calendar.getTimeInMillis(), pendingIntent);
}
Here is the AlarmBroadcastReceiver which is supposed to be called only when the time of the AlarmManager expires.
public class AlarmBroadcastReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Intent startIntent = new Intent(context, AlarmService.class);
context.startService(startIntent);
}
}
The service launched by the BroadcastReceiver:
public class AlarmService extends Service{
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
generarNotificacion();
return Service.START_NOT_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
public void generarNotificacion(){
Intent resultIntent = new Intent(this.getApplicationContext(), MainActivity.class);
android.support.v4.app.NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.logo)
.setContentTitle(getResources().getString(R.string.app_name))
.setContentText(getResources().getString(R.string.texto_notificacion));
PendingIntent resultPendingIntent =
PendingIntent.getActivity(
this,
0,
resultIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);
mBuilder.setContentIntent(resultPendingIntent);
// Sets an ID for the notification
int mNotificationId = 001;
// Gets an instance of the NotificationManager service
NotificationManager mNotifyMgr =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
// Builds the notification and issues it.
mNotifyMgr.notify(mNotificationId, mBuilder.build());
}
}
And finally I have added this code to the manifest.xml
<application
android:allowBackup="true"
android:icon="#mipmap/logo"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<service android:name=".AlarmService"
android:enabled="true" />
<receiver android:name=".AlarmBroadcastReceiver"/>
...
</application>
It is obvious. You are calling initAalarm() in onCreate. To understand execute following test case with your code:
Lets say current date and time is 20 Sep 2015 1:00pm and
Alarm is set to future date say 15 min after current time i.e. 20 Sep 2015 1:15pm
Now to test it you can either wait for time to arrive or change system date-time. After doing this you will see notification is fired on same time.Now don't change anything in initAlarm() , close activity and again start it , you will see notification again. The reason behind this is if alarm is set to some past date with respect system time then it is immediately fired.
See documentation of Alarm Manager's set method
You Posted this in month of September which is 9th Month
where as
You are trying this in past date which is
calendar.set(Calendar.MONTH, 8);
change it with future date.
I want to display notification every morning at 9 AM from my app.
So I am using Notification Manager, Alarm Manager, BroadcastReciever and Service to make that possible.
But I have a problem, because the notification shows randomly. When I first start the app and set the time, it works OK, but later the app fires and shows notification at random time.
How I can solve that?
Here is my code:
MainActivity
#Override
protected void onStart() {
super.onStart();
setAlarm();
}
public void setAlarm(){
Calendar calendar = Calendar.getInstance();
Calendar now = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 15);
calendar.set(Calendar.MINUTE, 43);
calendar.set(Calendar.SECOND, 0);
if(calendar.getTime().after(now.getTime())) {
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmIntent = new Intent(MainActivity.this, HoroscopeNotification.class);
pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent); }
}
HoroscopNotification (BroadcastReciever)
public class HoroscopeNotification extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent arg1) {
showNotification(context);
}
private void showNotification(Context context) {
Intent service1 = new Intent(context, AlarmService.class);
context.startService(service1);
}
}
AlarmService
public class AlarmService extends Service {
private static final int NOTIFICATION_ID = 1;
private NotificationManager notificationManager;
private PendingIntent pendingIntent;
#Override
public IBinder onBind(Intent arg0)
{
return null;
}
#SuppressWarnings("static-access")
#Override
public void onStart(Intent intent, int startId)
{
super.onStart(intent, startId);
Context context = this.getApplicationContext();
notificationManager = (NotificationManager)context.getSystemService(context.NOTIFICATION_SERVICE);
Intent mIntent = new Intent(this, MainActivity.class);
pendingIntent = PendingIntent.getActivity(context, 0, mIntent, PendingIntent.FLAG_CANCEL_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setContentTitle("Horoskop");
builder.setContentText("Pročitajte današnji horoskop");
builder.setSmallIcon(R.drawable.ic_bik);
builder.setAutoCancel(true);
builder.setContentIntent(pendingIntent);
notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(NOTIFICATION_ID, builder.build());
}
}
You'll notice in the Android SDK Reference material for the AlarmManager.setRepeating() states:
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.
You need to use AlarmManager.set() on pre-APIv19 and AlarmManager.setExact() on APIv19+. When your PendingIntent is fired and you receive your Broadcast in your BroadcastReceiver.onReceive() you can set another exact alarm for the next day.
Alarm Manager Example
I think you should follow above link. From my point of view, your design pattern (setting alarm in Activity class is not a good approach). Instead (like showed in the answer above) you should set your alarm from a service. Also the code for notification goes in BroadcastReceiver class, method OnReceive (In the example it is commented "Put here YOUR code").
Good luck
I have done some research and tried to implement a one time alarm that sends a notification to the user, but for some reason I cannot understand, when the time comes, the alarm is not being activated. I think the onReceive method is not being called, but I don't know why, since it's the first time I try to implement an alarm.
=== Edit: it seems that the alarm's onReceive is working after all, I got the toast message "Alarm!!" at the right time (don't know why it didn't the first time I tested), but no notification was received, though... Any clues?
This is the code for the Alarm class:
public class Alarm extends BroadcastReceiver {
public static final String PREFS_FILE_NAME = MainActivity.PREFS_FILE_NAME;
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
// send notification
Toast.makeText(context, "Alarm!!", Toast.LENGTH_SHORT).show();
// API < 16 so have to use compat
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setContentTitle(context.getResources().getString(R.string.memo_test_ready))
.setContentText(context.getResources().getString(R.string.click_to_start));
Intent resultIntent = new Intent(context, UpcomingTest.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addParentStack(UpcomingTest.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(
0,
PendingIntent.FLAG_UPDATE_CURRENT
);
mBuilder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(123, mBuilder.build());
}
public void Set(Context context)
{
DatabaseHandler db = new DatabaseHandler(context);
MemoryTestLevel memoTestLevel = new MemoryTestLevel();
long timeInterval;
long memoryTest_dateTime;
String alarmMemoLevel;
List<Phrase> studyPhrasesList = db.getPhrasesWithState(Phrase.START_STUDYING);
if (studyPhrasesList.size() > 0 ){ // if there are any phrases here, update them; dateTime == level 1
alarmMemoLevel = "Level 1 ";
memoTestLevel = db.getMemoryTestLevelWithLevel(MemoryTestLevel.LEVEL_1);
timeInterval = memoTestLevel.getTimeInterval();
TestDateTimeCalculator datetimeCalc = new TestDateTimeCalculator();
memoryTest_dateTime = datetimeCalc.calculate(timeInterval);
for(Phrase phrase : studyPhrasesList){
phrase.setMemoryTestPending(memoTestLevel.getMemoryTest_id(), memoryTest_dateTime);
db.updatePhrase(phrase);
}
} else {
// if there are no phrases to be set at level 1, then get the lowest memoTest_datime of
// the ones that are pending
alarmMemoLevel = "next after L1 ";
memoryTest_dateTime = db.getLowestMemoTestDateTime();
}
/* 2. Set new Alarm
* 2.1. Determine which phrases will go into this new alarm */
List<Phrase> nextMemoryTestPhrases = db.getNextMemoryTestPhrases(memoryTest_dateTime);
for(Phrase phrase : nextMemoryTestPhrases) {
phrase.setState(Phrase.MEMORY_TEST_SCHEDULED);
db.updatePhrase(phrase);
}
// 2.3 set alarm for required dateTime
AlarmManager alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, Alarm.class);
PendingIntent pendingInt = PendingIntent.getBroadcast(context, 0, intent, 0);
alarmMgr.set(AlarmManager.RTC_WAKEUP, memoryTest_dateTime, pendingInt);
// 2.4 save the alarm.dateTime in the preferences so it can be used in the "upcoming test" activity
SharedPreferences preferences = context.getSharedPreferences(PREFS_FILE_NAME, Context.MODE_PRIVATE);
Editor editor = preferences.edit();
editor.putLong("NEXT_TEST_DATETIME", memoryTest_dateTime);
SimpleDateFormat sdf = new SimpleDateFormat("EEE, MMM d, yyyy hh:mm");
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(memoryTest_dateTime);
String nextTestDateStr = sdf.format(calendar.getTime());
Toast.makeText(context, "Alarm set to " + alarmMemoLevel + nextTestDateStr, Toast.LENGTH_LONG).show();
editor.commit();
}
public void Cancel(Context context)
{
Intent intent = new Intent(context, MyBroadcastReceiver.class);
PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(sender);
}
}
And I have a broadcast receiver in case the phone is rebooted:
public class MyBroadcastReceiver extends BroadcastReceiver {
public static final String PREFS_FILE_NAME = MainActivity.PREFS_FILE_NAME;
#Override
public void onReceive(Context context, Intent intent) {
// TODO setup alarm again (get datetime from system)
Alarm alarm = new Alarm();
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED"))
{
SharedPreferences preferences = context.getSharedPreferences(PREFS_FILE_NAME, Context.MODE_PRIVATE);
long nextTestDateInMillis = preferences.getLong("NEXT_TEST_DATETIME", 0);
if(nextTestDateInMillis > 0){
alarm.Set(context);
}
}
}
}
From the research I found, it seems that something is missing/wrong in my manifest. This is what I have there:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"></uses-permission>
The below is inside application:
<receiver android:name="liliana.phrasememo.util.MyBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<receiver android:process=":remote" android:name="liliana.phrasememo.util.Alarm"/>
Also, if you see anything else that's wrong in my implementation of Alarm + Notification it would be brilliant to give me the heads up. Thank you very much :-)
to set alarm may be this code helps you
Intent myIntent = new Intent(yourcontext, Alarm.class);
PendingIntent pendingIntent = PendingIntent.getService(act, 0, myIntent, 0);
AlarmManager alarmManager = (AlarmManager)act.getSystemService(act.ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 8);
calendar.set(Calendar.MINUTE,22);
calendar.set(Calendar.SECOND, 0);
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
also you must implement service instead of broadcastreciever to run at alarm time
Thanks very much to answer posted here, what is missing in my code is the notification icon, which I have added like this:
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.ic_launcher) // this was missing
.setContentTitle(context.getResources().getString(R.string.memo_test_ready))
.setContentText(context.getResources().getString(R.string.click_to_start));
And in fact, if we look at the documentation, it does specify that the small icon must be in the notification:
Required notification contents
A Notification object must contain the following:
A small icon, set by setSmallIcon()
A title, set by setContentTitle()
Detail text, set by setContentText()
The LogCat does have a file not found error:
05-05 12:39:39.191: A/NetworkStats(89): Caused by: java.io.FileNotFoundException: /proc/net/xt_qtaguid/stats: open failed: ENOENT (No such file or directory)
But it doesn't cause any crashes so you might not realise it. I'm not sure anything could be added to the notification constructor itself that would allow the user to see right away that something is missing. I don't have very advanced Java knowledge.
this is my code for menage a single notification:
myActivity.java
public class myActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mylayout);
cal = Calendar.getInstance();
// it is set to 10.30
cal.set(Calendar.HOUR, 10);
cal.set(Calendar.MINUTE, 30);
cal.set(Calendar.SECOND, 0);
long start = cal.getTimeInMillis();
if(cal.before(Calendar.getInstance())) {
start += AlarmManager.INTERVAL_FIFTEEN_MINUTES;
}
Intent mainIntent = new Intent(this, myReceiver.class);
pIntent = PendingIntent.getBroadcast(this, 0, mainIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager myAlarm = (AlarmManager)getSystemService(ALARM_SERVICE);
myAlarm.setRepeating(AlarmManager.RTC_WAKEUP, start, AlarmManager.INTERVAL_FIFTEEN_MINUTES, pIntent);
}
}
myReceiver.java
public class myReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context c, Intent i) {
Intent myService1 = new Intent(c, myAlarmService.class);
c.startService(myService1);
}
}
myAlarmService.java
public class myAlarmService extends Service {
#Override
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
}
#SuppressWarnings("deprecation")
#Override
public void onStart(Intent intent, int startId) {
super.onStart(intent, startId);
displayNotification();
}
#Override
public void onDestroy() {
super.onDestroy();
}
public void displayNotification() {
Intent mainIntent = new Intent(this, myActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, mainIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationManager nm = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
Notification.Builder builder = new Notification.Builder(this);
builder.setContentIntent(pIntent)
.setAutoCancel(true)
.setSmallIcon(R.drawable.ic_noti)
.setTicker(getString(R.string.notifmsg))
.setContentTitle(getString(R.string.app_name))
.setContentText(getString(R.string.notifmsg));
nm.notify(0, builder.build());
}
}
AndroidManifest.xml
<uses-permission android:name="android.permission.WAKE_LOCK" />
...
...
...
<service android:name=".myAlarmService" android:enabled="true" />
<receiver android:name=".myReceiver"/>
IF the time has NOT past yet everything works perfectly. The notification appears when it must appear.
BUT if the time HAS past (let's assume it is 10.31 AM) the notification fires every time... when I close and re-open the app, when I click on the notification... it has a really strange behavior.
I can't figure out what's wrong in it. Can you help me please (and explain why, if you find a solution), thanks in advance :)
Place display notification inside an if statement , such that compare the current time with the notification set time and if the current time is before the set time then display notification, else do nothing.
int temp = calTemp.getTime().compareTo(calendar.getTime());
if(temp > 0){
}else{
alarmManager.set(AlarmManager.RTC, calendar.getTimeInMillis(),
pendingIntent1);
}
here calTemp gives current time and calender gives the time i want to fire the alarm. So according to above code if the time has already past then the notification will not fire for sure .
Hi I've had the same problem and found a solution in this SO post, basically the idea is to rely on AlarmManager, Receiver but avoid usage of Service.
Since you are using the Service just to build and display the notification you may find useful my approach.
Let me know.