Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Alarmmanager not working when I closed the app from recent apps

When my app is open or in running state alarm manager works fine but when I closed the app It does not working . I have also used Task removed method in service class still not getting alarm.

My code:-

ReminderActivity.java

public class ReminderActivity extends AppCompatActivity {
   static EditText mDatebtn, mTimebtn;
    @SuppressLint("StaticFieldLeak")
    static EditText mTitledit;
    private DBHandler dbHandler;
    TextView textView;
    private static final int REQ_CODE_SPEECH_INPUT = 100;
   private static TextToSpeech textToSpeech;
   static int layoutclick;
    //When user tap on the layout we will increment it , switch to case statement
    static String title,finaltime;
    static String finalalarm;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_reminder2);
        dbHandler = new DBHandler(this);
        mTitledit = (EditText) findViewById(R.id.editTitle);
        textView = findViewById(R.id.addreminder);
        mDatebtn = findViewById(R.id.btnDate);
        mTimebtn = findViewById(R.id.btnTime);
        textToSpeech = new TextToSpeech(this, new TextToSpeech.OnInitListener() {
            @Override
            public void onInit(int status) {
                if (status != TextToSpeech.ERROR) {
                    textToSpeech.setLanguage(Locale.US);
                    textToSpeech.setSpeechRate(1f);
                    textToSpeech.speak("Tell me the exact date", TextToSpeech.QUEUE_FLUSH, null);
                }
            }
        });
        textView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    title = mTitledit.getText().toString();
                    processinsert(title, mDatebtn.getText().toString(), mTimebtn.getText().toString());
                }
                startActivity(new Intent(ReminderActivity.this,Home.class));

            }
        });
    }

     @RequiresApi(api = Build.VERSION_CODES.O)
     private void processinsert(String title, String date, String time) {

        String result = dbHandler.addreminder(title, date, time);//data inserting in sqlite                  //inserts the title,date,time into sql lite database
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

             setAlarm(title, date, time);                                                                //calls the set alarm method to set alarm
         }
        Toast.makeText(getApplicationContext(), result, Toast.LENGTH_SHORT).show();
    }


    private void setAlarm(String text, String date, String time) {
        AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);                   //assigning alarm manager object to set alarm
        Intent intent = new Intent(getApplicationContext(), AlarmBroadcast.class);
        intent.putExtra("event", text);                                                       //sending data to alarm class to create channel and notification
        intent.putExtra("time", date);
        intent.putExtra("date", time);
         @SuppressLint("UnspecifiedImmutableFlag")
        PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, PendingIntent.FLAG_ONE_SHOT);
        finalalarm  = date + " " + mTimebtn.getText();
        Toast.makeText(getApplicationContext(), finalalarm, Toast.LENGTH_LONG).show();
        @SuppressLint("SimpleDateFormat")
        DateFormat formatter = new SimpleDateFormat("d-M-yyyy hh:mm");
        try {

            Date date1 = formatter.parse(finalalarm);
             //Toast.makeText(getApplicationContext(), dateandtime, Toast.LENGTH_LONG).show();
            am.set(AlarmManager.RTC_WAKEUP, date1.getTime(), pendingIntent);

            // Toast.makeText(getApplicationContext(), "Alarm set", Toast.LENGTH_SHORT).show();
        } catch (ParseException e) {
            Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
        }

    }


AlarmBroadcast.java

public class AlarmBroadcast extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Bundle bundle = intent.getExtras();
        String text = bundle.getString("event");
        String date = bundle.getString("date") + " " + bundle.getString("time");
        Intent mIntent = new Intent(context, NotificationMessage.class);
        mIntent.setAction(Intent.ACTION_MAIN);
        mIntent.addCategory(Intent.CATEGORY_LAUNCHER);
        mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(mIntent);

        Intent intentService = new Intent(context, AlarmService.class);
        intentService.putExtra("message",text);
        context.startService(intentService);

    }
}

AlarmService.java

public class AlarmService extends Service {
    private Vibrator vibrator;
    private MediaPlayer mediaPlayer;
    int count = 0;
    static String message;
    static TextToSpeech mTts;

    @RequiresApi(api = Build.VERSION_CODES.M)
    @Override
    public void onCreate() {
        super.onCreate();

        mediaPlayer = MediaPlayer.create(this, R.raw.reminder);

        vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        Intent intent1 = new Intent(this, NotificationMessage.class);
        message = intent.getStringExtra("message");

        PendingIntent pendingIntent = PendingIntent.getActivity(this, 1, intent1, PendingIntent.FLAG_ONE_SHOT);
        NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
         NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this, "notify_001");
        //here we set all the properties for the notification
        RemoteViews contentView = new RemoteViews(this.getPackageName(), R.layout.notification_layout);
        contentView.setImageViewResource(R.id.image, R.mipmap.ic_launcher);
        PendingIntent pendingSwitchIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
        contentView.setOnClickPendingIntent(R.id.flashButton, pendingSwitchIntent);
        contentView.setTextViewText(R.id.message, intent.getStringExtra("message"));
        contentView.setTextViewText(R.id.date, "date");
        mBuilder.setSmallIcon(R.drawable.alarm);
        mBuilder.setOngoing(true);
        mBuilder.setAutoCancel(true);
        mBuilder.setPriority(Notification.PRIORITY_HIGH);
        mBuilder.setOnlyAlertOnce(true);
        mBuilder.build().flags = Notification.FLAG_NO_CLEAR | Notification.PRIORITY_HIGH;
        intent1.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP
                | Intent.FLAG_ACTIVITY_SINGLE_TOP);
        mBuilder.setContent(contentView);
        mBuilder.setContentIntent(pendingIntent);

        //we have to create notification channel after api level 26
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            String channelId = "channel_id";
            NotificationChannel channel = new NotificationChannel(channelId, "channel name", NotificationManager.IMPORTANCE_HIGH);
            channel.enableVibration(true);
            notificationManager.createNotificationChannel(channel);
            mBuilder.setChannelId(channelId);
            mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp) {
                    if (count < 2) {
                        mp.start();
                        count++;
                    }
                }
            });
            mediaPlayer.start();

            Notification notification = mBuilder.build();
            notificationManager.cancelAll();
            long[] pattern = {0, 100, 1000, 200, 2000};
            vibrator.vibrate(pattern, -1);
            startForeground(1, notification);
        }
        return START_STICKY;
    }


    @Override
    public void onDestroy() {
        super.onDestroy();
        mediaPlayer.stop();
        vibrator.cancel();

    }


    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
 
        return null;
    }


    @Override
    public void onTaskRemoved(Intent rootIntent) {
        super.onTaskRemoved(rootIntent);

        @SuppressLint("UnspecifiedImmutableFlag") PendingIntent service = PendingIntent.getService(
                getApplicationContext(),
                1001,
                new Intent(getApplicationContext(), AlarmService.class),
                PendingIntent.FLAG_ONE_SHOT);

        AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 1000, service);
    }
    }
}

NotificationMessage.java

public class AlarmBroadcast extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Bundle bundle = intent.getExtras();
        String text = bundle.getString("event");
        String date = bundle.getString("date") + " " + bundle.getString("time");
        Intent mIntent = new Intent(context, NotificationMessage.class);
        mIntent.setAction(Intent.ACTION_MAIN);
        mIntent.addCategory(Intent.CATEGORY_LAUNCHER);
        mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(mIntent);

        Intent intentService = new Intent(context, AlarmService.class);
        intentService.putExtra("message",text);
        context.startService(intentService);

    }
}

Manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="org.tensorflow.lite.examples.detection">

    <uses-sdk />
     <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
    <uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
    <uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />
    <uses-permission android:name="android.permission.VIBRATE" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/blind"
        android:label="@string/app_name"
        android:roundIcon="@drawable/blind"
        android:supportsRtl="true"
        android:theme="@style/AppTheme.ObjectDetection">

        <activity
            android:name=".Reminder.NotificationMessage"
            android:exported="true"
            >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
        </activity>
        <activity
            android:name=".Reminder.ReminderActivity"
            android:exported="true" />
        <activity
            android:name=".Reminder.Reminder"
            android:exported="true" />     
        <activity
            android:name=".Home"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
         <receiver android:name=".Reminder.AlarmBroadcast"
             android:enabled="true"
            android:exported="true">
         </receiver>
        <service android:name=".Reminder.AlarmService" />
    </application>

</manifest>

The alarm seems to work flawlessly when the app is open, or running in the background, but as soon as I exit the app, it seems to completely stop. Can I also add multiple alarms?


1 Answers

This behavior is by design -- if a user force-closes the app (which is the same thing as removing it from recent apps), the app will not be allowed to do anything at all -- no alarms, no responding to intent broadcasts, no background services, etc.

I think that the only thing it'll be allowed to do is receive FCM notifications, but even with that one, I'm not 100% sure.

The bottom line is that if the user purposefully shuts down your app, Google wants it to stay shut down, until the user opens it again

like image 148
user496854 Avatar answered Dec 23 '25 11:12

user496854



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!