I'm working on a Project that takes a date and time and automatically sends a pre-written message on that day to the specified Mobile number.
I'm using alarm Manager for this, but it's not working. I've been trying to debug my program for so long that I'm unable to see what's exactly wrong.
final Calendar c = Calendar.getInstance();
String date=releaseDateEditText.getText().toString();
String data[]= date.split("-");
c.set(Calendar.DAY_OF_MONTH, Integer.parseInt(data[0]));
c.set(Calendar.MONTH,Integer.parseInt(data[1]));
c.set(Calendar.YEAR,Integer.parseInt(data[2]));
c.set(Calendar.AM_PM, Calendar.PM);
c.set(Calendar.HOUR_OF_DAY, 11);
c.set(Calendar.MINUTE, 18);
c.set(Calendar.SECOND, 0);
Intent _myIntent = new Intent(getApplicationContext(), message.class);
_myIntent.putExtra("name", name.getText());
_myIntent.putExtra("agency", agency.getText());
_myIntent.putExtra("book", bookingDateEditText.getText());
_myIntent.putExtra("release", releaseDateEditText.getText());
pintent = PendingIntent.getBroadcast(getApplicationContext(), 1, _myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pintent);
Toast.makeText(getApplicationContext(), "Alarm set for " + releaseDateEditText.getText(), Toast.LENGTH_LONG).show();
public class message extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String SPhone = "Phonenumber";
String SSms = intent.getStringExtra("name");
SSms = SSms + "\n" + intent.getStringExtra("agency") + "\n" + intent.getStringExtra("book") + "\n" + intent.getStringExtra("release");
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage(SPhone, null, SSms, null, null);
}
}
If you go through Use of SMS or Call Log permission groups, you will find that from DEC 2018 onwards, apps using permissions to SEND_SMS are not allowed on playstore, unless they are default SMS/Dialer app. Either you will have to file your app as exception or remove the SMS permissions.
For apps requesting access to the SMS or Call Log permissions, the intended and permitted uses include default SMS handling, default phone handling, or Assistant handling capability.
Apps must be actively registered as the default SMS, Phone, or Assistant handler before prompting users to accept any of the above permissions and must immediately stop the use of the permission when they no longer are the default handler.
ANSWER TO QUESTION:
Well, coming back to your question, many android device manufacturers are using aggressive policies to save battery. When a user clears his/her app from recent tabs, the app is force closed, thus cancelling all alarms,broadcastReceivers,services etc. This happens in most of the device manufacturers like OnePlus,Huwaei, Xiaomi, Vivo, Oppo etc.
They have AutoStartManagers/AutoLaunchManagers that prevent the background running of the apps. You will have to white list your app using steps mentioned in THIS SO ANSWER.
Related
Scenario
i am developing an app that works kind of like subscription, i start an alarm manager for days, suppose the alarm manager has started yesterday and it should go off tomorrow, how do i know exact time remaining till alarm manager goes off?
// ALARM_MANAGER setting to expired
SharedPreferences alarmpreferences = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor alarmEditor = alarmpreferences.edit();
alarmEditor.putString("ALARM_MANAGER", "active");
alarmEditor.apply();
AlarmManager service = (AlarmManager) getApplicationContext()
.getSystemService(getApplicationContext().ALARM_SERVICE);
Intent i = new Intent(getApplicationContext(), MyReceiver.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pending = PendingIntent.getBroadcast(getApplicationContext(), mainAlarmRequestCode, i,
PendingIntent.FLAG_CANCEL_CURRENT);
Calendar cal = Calendar.getInstance();
// Start 20 seconds after boot completed
int secondTime = Integer.parseInt(expireTime)*60;
cal.add(Calendar.SECOND, secondTime);
//
// Fetch every 20 seconds
// InexactRepeating allows Android to optimize the energy consumption
service.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pending);
I check to see if the alarm manager is running in the 0 background with this method.
Intent i = new Intent(getApplicationContext(), MyReceiver.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
boolean alarmUp = (PendingIntent.getBroadcast(getApplicationContext(), mainAlarmRequestCode, i, PendingIntent.FLAG_NO_CREATE) != null);
if (alarmUp) {
Log.d("myTag", "Alarm is already active");
Toast.makeText(this, "alarm manager is active!", Toast.LENGTH_SHORT).show();
//alarm is active check alarm manager counter time
} else {
Toast.makeText(this, "alarm manager is not active!", Toast.LENGTH_SHORT).show(); }
The alarm manager is active, but how do I know the number of seconds remaining until the alarm goes off?
Any help would be appreciated!
You can try to store the expiration date of your AlarmManager and run a test at regular interval, to check if the current date is greater than the expiration one.
I wanna set multiple alarm using request code.
I give different values of the request codes to each alarm, but the alarmManager still executes only the last set alarm.
Here's my existing code:
public void Alarm(){
Intent intent = new Intent(MainActivity.this, BroadCast.class);
alarmID = (int)(System.currentTimeMillis() % 1000000000); //for request code
PendingIntent sender = PendingIntent.getBroadcast(
MainActivity.this, alarmID, intent, 0);
Calendar calendar = Calendar.getInstance();
calendar.set(calendar.get(Calendar.YEAR), calendar.get(Calendar.MONTH),
calendar.get(Calendar.DATE),hours,mins,0);
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
am.setInexactRepeating(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(),am.INTERVAL_DAY, sender);
}
try setRepeating instead of setInexactRepeating you will get repeating alarm.
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()
+ (5 * 1000),5 * 1000, pendingIntent);
As of Android 5.1 (API version 22) there is a minimum period of 1 minute for repeating alarms. If you need to do work within one minute, just set the alarm directly, then set the next one from that alarm's handler, etc. If you need to do work within 5 seconds (for example), post it to a Handler instead of using the AlarmManager.
Good documetion here :
https://en.proft.me/2017/05/7/scheduling-operations-alarmmanager-android/
Say Application X has push notification service. On push receive, the intent is to receive the JSON in PushListenerService and add a date and time to Google Calendar (the code to do this is below for reference). However, if Application X is closed, yet still receiving push notification, how does one open Google Calendar?
Opening the push notification only starts the app, not Google Calendar. I cannot start Google Calendar from a service, and a broadcast receiver in the main thread with below code does not open Google Calendar.
Calendar beginTime = Calendar.getInstance();
beginTime.set(NPdateStartYearInt, NPdateStartMonthInt - 1, NPdateStartDayInt,
NPdateStartHourInt, NPdateStartMinuteInt);
Calendar endTime = Calendar.getInstance();
endTime.set(NPdateFinishYearInt, NPdateFinishMonthInt - 1, NPdateFinishDayInt,
NPdateFinishHourInt, NPdateFinishMinuteInt);
Intent intent1 = new Intent(Intent.ACTION_INSERT)
.setData(Events.CONTENT_URI)
.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.getTimeInMillis())
.putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.getTimeInMillis())
.putExtra(Events.TITLE, title)
.putExtra(Events.DESCRIPTION, text)
.putExtra(Events.EVENT_LOCATION, location)
.putExtra(Events.AVAILABILITY, Events.AVAILABILITY_BUSY)
.putExtra(Events.CALENDAR_COLOR, Color.GREEN)
.putExtra(Intent.EXTRA_EMAIL, R.string.emailAddress);
I'm developing an android app in which there is this option to Follow/Unfollow a user. Whenever someone follows him, the counter in FirebaseDatabase gets increased by 1 and when someone unfollows him, the counter gets decreased by 1.
I'm trying to notify user every time someone follows him by starting a service as soon as he leave the app and writing the code in the Service.
Here's the code in onCreate() of the Service:
firebaseDatabaseFollowers.child("***").child("***").child("followers").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
b = sharedPref2.getBoolean(SettingsActivity.KEY_PREF_NOTIF_FOLLOW, true);
Toast.makeText(getBaseContext(), "b: " + String.valueOf(b), Toast.LENGTH_SHORT).show();
if (dataSnapshot.getValue() != null) {
if (String.valueOf(b).equals("true")) {
final int m = (int) ((new Date().getTime() / 1000L) % Integer.MAX_VALUE);
Intent notificationIntent = new Intent(getBaseContext(), NotificationARBroadcastReceiver.class);
notificationIntent.putExtra(NotificationARBroadcastReceiver.NOTIFICATION, getNotificationService());
PendingIntent pendingIntent = PendingIntent.getBroadcast(getBaseContext(), m, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 0, pendingIntent);
}
} else {
Toast.makeText(getBaseContext(), "database is null", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
The notification part is working fine. The only problem is that the notification is delivered even when someone unfollows the user and I don't want this to happen.
So, is there any way to know that if the counter in FirebaseDatabase increased or decreased so that I can notify accordingly?
Please let me know.
I would store a global variable in your app that holds the number of followers that the user currently has. When the database sends down new info, you can compare it to the number you have saved by using if new number > or < than saved number. This could be problematic, however, in case the user goes offline and comes back online after, say 1 user unfollowed and 2 others followed. In this case, the user would just get a +1 follower notification. What I might recommend is sending down the username of the user that followed, just like Instagram does. For example, "John Smith followed you!" or "James Smith unfollowed you!".
My program is designed to create a repeating alarm that triggers a broadcastreceiver in turn making a notification. The alarm is repeated using a user-entered interval.
For example, if i want to set the alarm to run every 10 seconds, how would I do that?
am.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 10000, calpendingintent);
Is this right? and my broadcast receiver isn't being called either for some reason.
public static void createAlarms(Context mcontext) {
cal = Calendar.getInstance();
cal.add(Calendar.HOUR, alarmintervalint);
calintent = new Intent(mcontext, AlarmBroadcastReceiver.class);
calpendingintent = PendingIntent.getBroadcast(mcontext.getApplicationContext(), 12345, calintent, 0);
am = (AlarmManager)mcontext.getSystemService(Activity.ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 10000, calpendingintent);
}
My broadcastreceiver class is not being called and Im not sure the "setRepeating()" method Im using is set correctly..
Please help!
use this code
AlarmManager alarmMgr;
PendingIntent pendingIntent;
public void startAlarmManager()
{
Intent dialogIntent = new Intent(getBaseContext(), AlarmBroadcastReceiver.class);
alarmMgr = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
pendingIntent = PendingIntent.getBroadcast(this, 0, dialogIntent,PendingIntent.FLAG_CANCEL_CURRENT);
alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP,System.currentTimeMillis(), 10000, pendingIntent);
}
}
wheather you want to stop alarm
public void stopAlarmManager()
{
if(alarmMgr != null)
alarmMgr.cancel(pendingIntent);
}
Be Remembered dont forget to register Receiver in manifest file
<receiver android:name=".AlarmBroadcastReceiver" >
</receiver>
Use setInexactRepeating() instead of setRepeating(). When you use setInexactRepeating(), Android synchronizes repeating alarms from multiple apps and fires them at the same time.
This reduces the total number of times the system must wake the device, thus reducing drain on the battery. As of Android 4.4 (API Level 19), all repeating alarms are inexact.
Note that while setInexactRepeating() is an improvement over setRepeating(), it can still overwhelm a server if every instance of an app hits the server around the same time. Therefore, for network requests, add some randomness to your alarms
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, 30);
long time = cal.getTimeInMillis();
Intent i = new Intent(G.context, BootCompleteReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(G.context, 0, i, 0);
G.alarmManager.set(AlarmManager.RTC_WAKEUP, time, pi);
you can use this. Hope it solves your problem
am.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_DAY,
AlarmManager.INTERVAL_DAY, pi);