AlarmReceiver works only for short time (WakeLock? / Process killed?) - android

I have an AlarmReceiver with an AlarmService and my problem is, if I set the AlertDate about 30min away from the current time, it just does it's job and calls the Alert-function. But if I set it about 5hours away, it won't call the function, no matter if I do it at night (not using my phone) or at day (while my phone is in use).
So my question is, why can't I set the AlertDate in the "far" future? Is the process killed or is there anything strange happening? And in particular: How can I fix this problem??
Basically I have the arrangement from here: Android Alarm Clock Tutorial
So I just point out my main lines in the code:
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="apm.smoothalert" >
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
...
<application
...
<activity
android:name=".main"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".AlarmService"
android:enabled="true" />
<receiver android:name=".AlarmReceiver" />
</application>
main:
public class main extends ActionBarActivity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
PowerManager powman = (PowerManager) getSystemService(POWER_SERVICE);
PowerManager.WakeLock wakeLock = powman.newWakeLock(PowerManager.FULL_WAKE_LOCK,"MyWakelockTag");
wakeLock.acquire();
...
}
AlarmManager alarmManager;
private PendingIntent pendingIntent;
private void smoothAlertOn ()
{
Date AlertDate = ... ; //Here I select the Alert date with a Timepicker
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent myIntent = new Intent(main.this, AlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(main.this, 0, myIntent, 0);
alarmManager.set(AlarmManager.RTC, AlertDate.getTime(), pendingIntent);
}
public static void SmoothAlert(final Context context)
{
//Here i do the Alert with Notifications etc.
}
}
AlarmReceiver:
public class AlarmReceiver extends WakefulBroadcastReceiver
{
static Context Alarmcontext;
#Override
public void onReceive(final Context context, Intent intent)
{
Alarmcontext = context;
ComponentName comp = new ComponentName(context.getPackageName(),AlarmService.class.getName());
startWakefulService(context, (intent.setComponent(comp)));
setResultCode(Activity.RESULT_OK);
}
}
AlarmService:
public class AlarmService extends IntentService
{
public AlarmService()
{
super("AlarmService");
}
#Override
public void onCreate()
{
super.onCreate();
}
#Override
public void onHandleIntent(Intent intent)
{
main.SmoothAlert(AlarmReceiver.Alarmcontext);
}
}

Related

Repeating alarm is not working in marshmallow

I am using the following code to start a service periodically whether the app is foreground or not .
Intent getAlertIntent = new Intent(getApplicationContext(), GetAlertAlarmReceiver.class);
PendingIntent getAlertpendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, getAlertIntent, 0);
AlarmManager getAlertmanager = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
getAlertmanager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 10000, getAlertpendingIntent);
The code for my receiver is following
public class GetAlertAlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context, GetAlertServiceIntent.class);
context.startService(i);
}
}
And and service
public class GetAlertServiceIntent extends IntentService {
public GetAlertServiceIntent() {
super("GetAlertServiceIntent");
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
protected void onHandleIntent(Intent intent) {
doSomething();
}
}
In my manifest file I declared everything as following
<receiver
android:name=".broadcastreceiver.GetAlertAlarmReceiver"
android:enabled="true">
<intent-filter android:priority="999">
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service
android:name="com.surroundapps.shotorkoporibar.services.GetAlertServiceIntent" />
This code work as expected in API level below Marshmallow but in marshmallow it doesn't work .

Why is my alarm not being executed?

I have an Activity that is supposed to launch a Service via a BroadcastReceiver.
Overview of the three:
Activity = Tracking
Service = PhoneManagementService
BroadcastReceiver = TrackingRestart
The Activity launches the AlarmManager in the onCreate() method:
public class Tracking extends Activity {
private static final int ALARM_FREQUENCY_SECONDS = 60;
#Override
protected void onCreate(Bundle savedInstanceState) {
startService(new Intent(Tracking.this, PhoneManagementService.class));
Intent alarm = new Intent(this, TrackingRestart.class);
boolean alarmRunning = (PendingIntent.getBroadcast(this, 0, alarm, PendingIntent.FLAG_NO_CREATE) != null);
if(!alarmRunning) {
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, alarm, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime(), (ALARM_FREQUENCY_SECONDS * 1000), pendingIntent);
}
}
I included startService(new Intent(Tracking.this, PhoneManagementService.class)); in there because this is the only time that the Service is called.
The BroadcastReceiver looks like this:
public class TrackingRestart extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
context.startService(new Intent(context, PhoneManagementService.class));
context.stopService(new Intent(context, PhoneManagementService.class));
}
}
The Service class looks like this:
public class PhoneManagementService extends Service {
private String user = "Service";
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
#Override
public void onCreate() {
startForeground(NotificationCreator.getNotificationId(), NotificationCreator.getNotification(this));
DBAdapter newEntry = new DBAdapter(this);
newEntry.open();
newEntry.addEntry("charging", user, getChargerType());
newEntry.addEntry("battery", user, getBatteryStats());
newEntry.addEntry("network", user, getNetworkType());
newEntry.close();
}
}
The Manifest containts those three entries:
<activity android:name=".Tracking">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".GPSService"
android:process=":trackingService_gps"
android:launchMode="singleTop"
android:enabled="true" />
<service
android:name=".PhoneManagementService"
android:process=":trackingService_phoneManagement"
android:launchMode="singleTop"
android:enabled="true" />
<receiver
android:name=".TrackingRestart"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="ch.jpabig.jonastrackingapp.ActivityRecognition.RestartTracking"/>
<action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/>
<action android:name="android.intent.action.BATTERY_LOW"/>
<action android:name="android.intent.action.BATTERY_OKAY"/>
</intent-filter>
</receiver>
Somehow the entries into the database are not made and I'm at a lost why this is the case. It must be the alarm but I could be very wrong.

AlarmManager sometimes not firing

Strange issue, my app has tens of thousands of users, for most of them this works perfectly. Some, let's say 5%, experience issue that causes reminders to not be fired.
I've put logging on the scheduling mechanism, including the scheduled timestamp, so I know that the reminder was scheduled, but it AlarmReceiver wasn't called.
Why would AlarmManager sometimes not fire?
ReminderLogic.java -
public class ReminderLogic {
public static void schedule() {
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
PendingIntent alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
int timeMillis = ... // some calculation
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
alarmManager.setExact(AlarmManager.RTC_WAKEUP, timeMillis, alarmIntent);
else
alarmManager.set(AlarmManager.RTC_WAKEUP, timeMillis, alarmIntent);
}
}
AlarmReceiver.java -
public class AlarmReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent service = new Intent(context, AlarmService.class);
startWakefulService(context, service);
}
}
AlarmService.java -
public class AlarmService extends IntentService {
private final static String TAG = "AlarmService";
public AlarmService() {
super(TAG);
}
#Override
protected void onHandleIntent(Intent intent) {
ReminderLogic.schedule();
AlarmReceiver.completeWakefulIntent(intent);
}
}
BootReceiver.java -
public class BootReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
ReminderLogic.schedule();
}
}
PackageReplaceReceiver.java -
public class PackageReplaceReceiver extends BroadcastReceiver {
private static final String TAG = "BootReceiver";
#Override
public void onReceive(Context context, Intent intent) {
ReminderLogic.schedule();
}
}
AndroidManifest.xml -
<service android:name=".reminders.AlarmService" />
<receiver android:name=".reminders.AlarmReceiver" />
<receiver
android:name=".reminders.BootReceiver"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<receiver
android:name=".reminders.PackageReplaceReceiver"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
</intent-filter>
</receiver>

AlarmManager doesn`t start BroadcastReceiver

I am trying to use BroadcastReceiver and AlarmManager to set a one-shot alarm. I have no idea why isn`t it working. What am I doing wrong? I have no exceptions, no logs about, no suggestions from IDE, everything seems fine, but onReceive method in my BroadcastReceiver is never called.
public void setAlarm(Context mContext) {
AlarmManager alarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(mContext, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, 505151550 ,intent, PendingIntent.FLAG_UPDATE_CURRENT);
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, 20);
alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pendingIntent);
Log.d("alarm",cal.getTime().toString());
}
I am calling it from the activity:
new MyManager().setAlarm(this);
but I have also tried: new MyManager().setAlarm(MyActivity.this);
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("alarm","got into alarm receiver");
}}
in AndroidManifest.xml :
<receiver android:name="com.example.AlarmReceiver"></receiver>
but I have also tried
<receiver android:name=".AlarmReceiver"></receiver>
try like this: it will fire alarm after 30 second.
public class TestAlarmManager extends Activity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setAlarm(getApplicationContext());
}
public void setAlarm(Context mContext) {
Intent intent = new Intent(this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
this.getApplicationContext(), 234324243, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()
+ (30 * 1000), pendingIntent);
Toast.makeText(this, "Alarm set in " + 30 + " seconds",Toast.LENGTH_LONG).show();
}
}
AlarmReceiver.java
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent arg1) {
Log.e("alarm","got into alarm receiver");
Toast.makeText(context, "Alarm Started..", Toast.LENGTH_LONG).show();
}
}
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.think.androidteststackoverflow"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher_3"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.think.androidteststackoverflow.TestAlarmManager"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".AlarmReceiver"></receiver>
</application>
</manifest>

Android Status bar notification every day at time

In my app, users have to fill in 9 different times with timepickers. These times are stored in a SQLite database. I want that users get a status bar notification when one of the times has been reached.
Example:
Users fill the first time in at 09:00.
If it is 09:00 in real time, users need to get a statusbar notification. I want that they don't need to start the app, it has to be automatic.
After spending more then 4 hours today at stackoverflow and other websites, I didn't succeed. I have tried the following code, but I didn't succeed. The notification is now set to 12:00. When the time reached 12:00, I didn't get a message.
MainActivity:
public class MainActivity extends Activity {
AlarmManager am;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Intent alarmIntent = new Intent(this, TimeAlarm.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 12);
calendar.set(Calendar.MINUTE, 00);
calendar.set(Calendar.SECOND, 00);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 5000, pendingIntent); } }
TimeAlarm.class:
public class TimeAlarm extends BroadcastReceiver {
NotificationManager nm;
#Override
public void onReceive(Context context, Intent intent) {
Intent startServiceIntent = new Intent(context, NotificationService.class);
context.startService(startServiceIntent);
}
}
NotificationService.class:
public class NotificationService extends Service {
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
handleIntent(intent);
return START_NOT_STICKY;
}
private NotificationManager nm;
private WakeLock mWakeLock;
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onDestroy() {
super.onDestroy();
mWakeLock.release();
}
private void showNotification() {
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("Test")
.setContentText("Test message");
Intent resultIntent = new Intent(this, MainActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(1, mBuilder.build());
}
private class PollTask extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
showNotification();
return null;
}
#Override
protected void onPostExecute(Void result) {
stopSelf();
}
}
private void handleIntent(Intent intent) {
PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"NotificationsService");
mWakeLock.acquire();
ConnectivityManager cm = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
if (!cm.getBackgroundDataSetting()) {
stopSelf();
return;
}
new PollTask().execute();
}
AndroidManifest:
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test.app"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission
android:name="com.test.app.permission.C2D_MESSAGE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<!-- This app has permission to register and receive data message. -->
<uses-permission
android:name="com.google.android.c2dm.permission.RECEIVE" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#android:style/Theme.Black.NoTitleBar.Fullscreen" >
<activity
android:name="com.test.app.MainActivity"
android:label="#string/app_name"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name="com.test.app.TimeAlarm">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
Try changing START_NOT_STICKY to START_STICKY;. If your service isn't sticky android does not try to restart it if it has to be killed to make room for other apps in memory.

Categories

Resources