Android AlarmManager lifecycle not working

212 views Asked by At

I'm trying to make an app that fires a user set timed notification, that once pressed will send the user to their requested website. Thing is, since these notifications can fire after hours, android restarts the application, erasing all the alarms and notifications. I've tried putting the persistent attribute in the manifest to extend the life but it still erases everything. Then I tried finding a way to save the timers in a bundle but I could not find a way to make it so it would fire the notification on time.

NOTE: This happens when the app is set in the background for too long.

This is My MainActivity

 protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    // Makes it so the app continues last session if already created
    if(!isTaskRoot()) {
        finish();
    }


}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == 15){
        name = data.getStringExtra("Name");
        String x = data.getStringExtra("url");
        hours = data.getIntExtra("Hour", 0);
        minutes = data.getIntExtra("Minute",0);


        AlarmManager alarmManager =
                (AlarmManager) getSystemService(ALARM_SERVICE);

        if((!x.contains("http://") && (!x.contains("https://")))){
            x = "http://" + x ;
        }
        final Uri u = Uri.parse(x);
        Calendar executeTime = Calendar.getInstance();
        executeTime.add(Calendar.MINUTE, minutes);
        executeTime.add(Calendar.HOUR, hours);
        /*BroadcastReceiver br = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                notification(name, u);
                startActivity(new Intent(Intent.ACTION_VIEW, u));

            }
        };
        registerReceiver(br, new IntentFilter(this.getClass().getSimpleName()) );

        PendingIntent pi =
                PendingIntent.getBroadcast(getApplicationContext(), 0, new Intent(this.getClass().getSimpleName()), 0);
        */
        //Intent i = new Intent(this,AlarmReceiver.class);
        AlarmReceiver AR = new AlarmReceiver(name,u);
        Intent i = new Intent(this,AR.getClass());

        PendingIntent pi =
                PendingIntent.getBroadcast(this,0,i,0);
        alarmManager.set(AlarmManager.RTC_WAKEUP, executeTime.getTimeInMillis(), pi);

        //notification(name,u,executeTime);

        ListView listView = (
                ListView) findViewById(R.id.bountyview);

        ArrayAdapter<String> mAdapter =
                new ArrayAdapter<>(getApplicationContext(),android.R.layout.simple_list_item_1,list);
        listView.setAdapter(mAdapter);

        DecimalFormat time = new DecimalFormat("00");
        //Adds said data to list(In this case the time it gets executed)
        mAdapter.add(name + " | " + executeTime.get(Calendar.HOUR) + ":" + time.format(executeTime.get(Calendar.MINUTE))); //+" " +Calendar.getInstance().get(Calendar.AM_PM));
        mAdapter.notifyDataSetChanged();
    }
    //if (resultCode == RESULT_CANCELED) {
        //Write your code if there's no result
    //}
}

public void notification (String name,Uri u){
    // prepare intent which is triggered if the
    // notification is selected

    //Intent intent = new Intent(this, NotificationReceiver.class);
    PendingIntent pIntent = PendingIntent.getActivity(this, 0, (new Intent(Intent.ACTION_VIEW, u)), 0);

    // build notification
    // the addAction re-use the same intent to keep the example short
    Notification n  = new Notification.Builder(this)
            .setContentTitle("Time to Attack " + name)
            .setContentText("Timer has finished, its time to attack!")
            .setSmallIcon(R.drawable.ic_launcher)
            .setContentIntent(pIntent)
            .setAutoCancel(true)
            .build();


    NotificationManager notificationManager =
            (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    n.flags = Notification.FLAG_AUTO_CANCEL;
    n.defaults |= Notification.DEFAULT_SOUND;

    notificationManager.notify(0, n);
}

This is my Broadcast Receiver class public class AlarmReceiver extends BroadcastReceiver {

String Name;
Uri url;


@Override
public void onReceive(Context context, Intent intent) {
    notification(Name, url ,context);
    context.startActivity(new Intent(Intent.ACTION_VIEW,url));

}
public AlarmReceiver(){}
public AlarmReceiver(String name, Uri u){
    Name = name;
    url = u;
}
public void setName(String name){
    Name = name;
}
public void setURL(Uri u){
    url = u;
}
public void notification (String name,Uri u, Context context ){
    // prepare intent which is triggered if the
    // notification is selected

    //Intent intent = new Intent(this, NotificationReceiver.class);
    PendingIntent pIntent = PendingIntent.getActivity(context, 0, (new Intent(Intent.ACTION_VIEW, u)), 0);

    // build notification
    // the addAction re-use the same intent to keep the example short
    Notification n  = new Notification.Builder(context)
            .setContentTitle("Time to Attack " + name)
            .setContentText("Timer has finished, its time to attack!")
            .setSmallIcon(R.drawable.ic_launcher)
            .setContentIntent(pIntent)
            .setAutoCancel(true)
            .build();


    NotificationManager notificationManager =
            (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    n.flags = Notification.FLAG_AUTO_CANCEL;
    n.defaults |= Notification.DEFAULT_SOUND;

    notificationManager.notify(0, n);
}

}

My Manifest

    <?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.omnination.ossusum.bountyurltimer"
    android:versionCode="7"
    android:versionName="7.0"

    >
    <uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
    <application
        android:persistent="true"
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".NewTimer"
            android:label="@string/title_activity_new_timer" >
        </activity>
        <receiver
            android:name=".AlarmReceiver"
            android:enabled="true"
            />
    </application>

</manifest>

Some code might be redundant because of me playing around with it, trying to figure this out.

1

There are 1 answers

9
siva On

You should not use timer classes for such use cases as timer class will not work when the device goes to idle. Instead please use Alarm Manager