I'm trying to make an Alarm using the Alarm Manager. The app runs without any error messages, but nothing happens.
I tried solutions from developer.android.com and suggestions from stackoverflow.
I also tried copying a complete tutorial i found, but nothing worked.
The app runs on API22 and was tested on an emulator(API23) and a real device(API22).
This is my Code:
MainActivity.java startAlarm():
AlarmManager manager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent myIntent = new Intent(MainActivity.this,AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this,0,myIntent,0);
manager.set(AlarmManager.RTC_WAKEUP, SystemClock.elapsedRealtime()+3000,pendingIntent);
AlarmReceiver.java:
public class AlarmReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"THIS IS MY ALARM",Toast.LENGTH_LONG).show();
}
}
AndroidManifest.xml, between <manifest...> and </manifest>:
<receiver android:process=":remote" android:name=".AlarmReceiver"></receiver>
your reciever name is AlarmToastReceiver not AlarmReceiver
try:
<receiver android:process=":remote" android:name=".AlarmToastReceiver "></receiver>
Related
Google rejecting my app and i'm having trouble with this security error that appear when i submit app as production release:
Implicit Internal Intent
Your app contains an Implicit Internal Intent vulnerability. Please
see this Google Help Center article for details.
com.mypackage.name.sync.SyncService.onHandleIntent
I applied all recommendations listed here:
Remediation for Implicit PendingIntent Vulnerability
But the error still persists.
My service:
public class SyncService extends IntentService {
protected void onHandleIntent(Intent intent) {
...
Intent i = new Intent("com.mypackage.name.REFRESH");
app.sendBroadcast(i);
...
}
}
Manifest:
<service
android:name=".sync.SyncService"
android:exported="false" >
</service>
The service started in many places in 3 methods like this:
(As recommended by google i did add PendingIntent.FLAG_IMMUTABLE)
Method 1:
Intent intent = new Intent(this, SyncService.class);
PendingIntent pIntent = PendingIntent.getService(this, 0, intent,
PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmMgr = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
alarmMgr.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtMillis,
SYNC_FREQUENCY, pIntent);
Method 2:
Intent intent = new Intent("com.mypackage.name.REFRESH");
intent = new Intent(getApplicationContext(), SyncService.class);
intent.putExtra("notification_unassigned_sync", true);
startService(intent);
Method 3:
Intent intent = new Intent(getApplicationContext(), SyncService.class);
startService(intent);
Is there anything wrong in my code ? Any recommendations ?
Setting the package name for the intents should fix the issue
intent.setPackage("com.mypackage.name"); // replace with your package name
// from AndroidManifest.xml
How to implement broadcast receiver?
Create a java class named MyBroadcastReceiver.java.
Paste this code in the class
public class MyBroadcastReceiverextends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"I have received.",Toast.LENGHT_SHORT).show();
}
}
Once you have implemented this code, you need to add this to you manifest inside the application tag.
<receiver android:name="com.chatverse.free.TimeBroadcastReceiver"
android:exported="true">
<intent-filter>
<action android:name="com.mypackage.name.REFRESH"/>
</intent-filter>
</receiver>
Add this code to your activity which opens the first.
IntentFilter mFilter = new IntentFilter("com.mypackage.name.REFRESH");
registerReceiver(new MyBroadcastReceiver(), mFilter);
This question already has answers here:
How to show daily offline notifications in Android 10?
(3 answers)
Closed 2 years ago.
I literally read all threads about this subject but none of them worked. (None of them also has a accepted valid answer that everyone says yay! reading it)
What I am trying to do is to send notification to the user at specific time that user specifies. these are what I tried so far:
Alarm manager + Broadcast receiver: this work on the emulator, but not on my device (Xiaomi Redmi note 8). It actually works for short periods like 1 or 2 minutes, but doesnt work for longer periods like 10 or 15 minutes. there is a funny bug about alarms that I will explain later.
wrokmanager: again works on the emulator, but not on my device.
Alarm manager + Broadcast receiver + JobServiceIntent: this doesn't change anything. again it works fine on emulator as expected. But on my phone, it works for short periods but not when the alarm is set for 15 minutes later.
P.S: I also tried many variation, like different types of alarm (RTC, RTC_WAKEUP). or different methods to set it like setExact, setReapiting etc. did the same with workmanger.
Final Result(Important):
after days of research I reached to this thread and I was convinced that these are all forced by manufacturers and there is no way to solve it rather than asking the user to do some manual changes (like auto start, battery saver etc). However, I found an app that is not one of those whitelisted apps(like facebook, whatsapp etc), it's a local app and is sending notifications on time. First I though it is using FCM, then I turned off my internet connection and I still received notification exactly on time.
Now I can not really think of any other solutions, and couldn't find any on other threads that actually work. Any helps would be appreciated from the bottom of my heart.
this is my BROADCASTRECEIVER:
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("NOTIF","YESSSS, IT's WORKING");
NotifJobIntentService.enqueueWork(context,intent);
}}
this is my JobIntentSerice class:
public class NotifJobIntentService extends JobIntentService {
private static final String TAG = "NotifJobIntentService";
private Context context;
static void enqueueWork(Context context, Intent intent) {
enqueueWork(context, NotifJobIntentService.class, 123 , intent);
}
#Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate");
}
#Override
protected void onHandleWork(#NonNull Intent intent) {
context = getApplicationContext();
Log.d(TAG, "OnHandleWork");
String input = intent.getStringExtra("inputExtra");
intent.setFlags(intent.FLAG_INCLUDE_STOPPED_PACKAGES);
Intent intent1 = new Intent(context , MainFragment.class);
PendingIntent pIntent = PendingIntent.getActivity(context, 0, intent, 0);
// TODO: Make this accessible to exterior projects, such as web interface.
Notification.Builder builder = new Notification.Builder(context)
.setTicker("Notification")
.setContentTitle("Important Message")
.setContentText("This is an example of a push notification using a Navigation Manager")
.setSmallIcon(R.drawable.ic_add)
.setContentIntent(pIntent);
NotificationManager notificationManager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
{
String channelId = "Your_channel_id";
NotificationChannel channel = new NotificationChannel(
channelId,
"Reminder to remind to review your notes",
NotificationManager.IMPORTANCE_HIGH);
channel.setDescription("Hello Dear friends"); //this is to test what this is
notificationManager.createNotificationChannel(channel);
builder.setChannelId(channelId);
}
Notification notification = builder.build();
notification.flags = Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(0, notification);
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy");
}
#Override
public boolean onStopCurrentWork() {
Log.d(TAG, "onStopCurrentWork");
return false;
}
}
this is my Main activity that sets the alarm manager:
private void setNotificationAlarm(){
//Alarm Manager
Calendar time = Calendar.getInstance();
time.set(Calendar.HOUR_OF_DAY,11);//set the alarm time
time.set(Calendar.MINUTE, 30);
time.set(Calendar.SECOND,0);
AlarmManager am =( AlarmManager)getContext().getSystemService(Context.ALARM_SERVICE);
Intent i = new Intent(getActivity(), AlarmReceiver.class);
i.setAction("android.intent.action.NOTIFY");
PendingIntent pi = PendingIntent.getBroadcast(getContext(), 0, i, PendingIntent.FLAG_ONE_SHOT);
if (Build.VERSION.SDK_INT >= 23){
am.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,time.getTimeInMillis(),pi);
}
else{
am.set(AlarmManager.RTC_WAKEUP,time.getTimeInMillis(),pi);
}
}
and here is my manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="ir.zima.schema">
<application
android:name=".CustomApplication"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.AppCompat.Light.NoActionBar">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".ListActivity"></activity>
<activity android:name=".MenuItemActivity"></activity>
<service
android:name=".NotifJobIntentService"
android:permission="android.permission.BIND_JOB_SERVICE"
android:exported="true"
android:enabled="true"/>
<receiver android:name=".AlarmReceiver" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.NOTIFY">
</action>
</intent-filter>
</receiver>
</application>
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
and finally the funny bug:
There are many threads that say alarm set by alarm manager is cleared when you swipe away your app and that actually happens (i figured that with adb shell dumpsys...). However after days of research I finally found it in this thread accidently that there is something like a bug. If you run your app via android studio (clicking "run app" button) and then swipe the app away, all alarms will be cleared(adb shell dumpsys returns nothing). But if you run the same app using the launcher Icon and then swipe it away, the alarms are set and adb shell dumpsys also shows it. (which those alarms still work fine on emulator but not on my device).
Once I had made an app that gets data from server (one hour interval) then show notifications based on the data. I basically created an AlarmManager which will trigger each hour and start an IntentService which will initiate the network call and show notifications. You can see here how to start the AlarmManager. Then you can see this nice articale from Journaldev. That should work. But one thing I want to mention that, it is possible that the alarmmanger may be cleared as you mentioned. In my case I created 3 alarmanager instances, one is the main, and the other 2 was for checking that 1 was triggered or not. Worked just fine for me though it is not a good solution.
I am sharing the code. But I should tell you that it is not the most efficient and recommended way. This will only serve your needs.
For setting and canceling alarm:
private void setAlarmTask(AlarmManager alarmManager, long time, Intent intent, int request_code){
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, request_code, intent, 0);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, time, AlarmManager.INTERVAL_HOUR, pendingIntent);
}
private void cancelAlarmTask(Intent intent, int request_code){
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, request_code, intent, 0);
pendingIntent.cancel();
}
For starting scheduler:
private void setScheduler(long time_in_miliseconds){
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(time_in_miliseconds);
AlarmManager mainAlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
AlarmManager failSafeAlarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
AlarmManager failSafeAlarmManager_2 = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent scheduleServiceExecuterIntent = new Intent(this, ScheduledServiceExecuter.class);
scheduleServiceExecuterIntent.putExtra("state", "Main");
setAlarmTask(mainAlarmManager, time_in_miliseconds, scheduleServiceExecuterIntent, 0);
calendar.add(calendar.MINUTE, 5);
scheduleServiceExecuterIntent.putExtra("state", "Fail Safe");
setAlarmTask(failSafeAlarmManager, calendar.getTimeInMillis(), scheduleServiceExecuterIntent, 1);
calendar.add(calendar.MINUTE, 5);
scheduleServiceExecuterIntent.putExtra("state", "Fail Safe 2");
setAlarmTask(failSafeAlarmManager_2, calendar.getTimeInMillis(), scheduleServiceExecuterIntent, 2);
}
For Stopping scheduler:
private void stopScheduler(){
Intent scheduleServiceExecuterIntent = new Intent(this, ScheduledServiceExecuter.class);
cancelAlarmTask(scheduleServiceExecuterIntent,0);
cancelAlarmTask(scheduleServiceExecuterIntent,1);
cancelAlarmTask(scheduleServiceExecuterIntent,2);
}
I am trying to get "DeleteIntent" callback from my notification.
BroadcastReceiver.onReceive not called from PendengIntent, while it works OK when broadcast is launched manually with sendBroadcast(deleteIntent).
It works well when intent target is Activity (hits Activity.onNewIntent) but it is weird to use it since activity goes foreground when message dismissed.
Please, help to get onReceive call to BroadcastReceiver.
It is visible, exported and enabled, located in the same package.
MyCancelReceiver class
public class MyCancelReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
}
}
Android manifest
<activity android:name=".MainActivity" android:launchMode="singleTask">
<MyCancelReceiver" android:enabled="true" android:exported="true">
<intent-filter>
<action android:name="notification_cancelled"/>
</intent-filter>
</receiver>
MainActivity
private MyCancelReceiver mReceiver;
#Override
public void onStart() {
super.onStart();
IntentFilter filter = new IntentFilter();
filter.addAction("notification_cancelled");
mReceiver = new MyCancelReceiver();
registerReceiver(mReceiver, filter);
}
#Override
public void onStop() {
super.onStop();
unregisterReceiver(mReceiver);
}
Notification creation:
Intent cancelIntent = new Intent(getApplicationContext(), MyCancelReceiver.class);
cancelIntent.setAction("notification_cancelled");
cancelIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent deleteIntent = PendingIntent.getActivity(getApplicationContext(), 0, cancelIntent, PendingIntent.FLAG_CANCEL_CURRENT);
Notification not = new Notification.Builder(getApplicationContext(), Util.ANDROID_CHANNEL_ID)
.setContentTitle(messageTitle)
.setContentText(messageBody)
.setSmallIcon(R.drawable.default)
.setAutoCancel(true)
.setDeleteIntent(deleteIntent)
.setContentIntent(contentIntent)
.build();
NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, not);
Thank you in advance.
It's because when you start your activity, onStart() gets called and you will get a callback in onReceive() as soon as the activity is launched. But when you click your notification onStart won't be called as the activity is already created, In this case, onStart wont be called. Try registering in onResume(), I am pretty sure it will work.
Problem solved using an answer from this thread Click on android notification icon does not trigger broadcast receiver
Explicit intent replaced with implicit one.
Intent cancelIntent = new Intent("notification_canceled");
I'm programming an application that will fire a specific method once it hits a certain date / time. However, my broadcast reciever is not firing...i can see that the alarm is set.
my method within an activity:
private void setAlarm(Date date){
Intent activate = new Intent(this, Alarm.class);
AlarmManager alarms ;
Calendar cal = new GregorianCalendar();
cal.setTimeInMillis(date.getTime());
PendingIntent alarmIntent = PendingIntent.getBroadcast(this, 0, activate, 0);
alarms = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
Log.d("ALARM","Setting alarm");
alarms.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), alarmIntent);
Log.d("ALARM","Setting time "+cal.getTimeInMillis());
}
My BroadcastReciever:
public class Alarm extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("ALARM", "RING RING");
}
}
My manifest within the <application> tag:
<receiver android:name=".Alarm" android:process=":remote" >
<intent-filter>
<action android:name="com.package.feature.subpackage.arrangealarm.ALARM_ACTION"/>
</intent-filter>
</receiver>
Does anyone have any idea why this is not firing?
There seems to be nothing wrong with your code (I copied the snippet and had Android Studio generate a BroadcastReceiver for which I set android:process=":remote" just like you do).
When I run the app, the BroadcastReceiver fires but I can only see the respective Logcat entry when I select "No Filters" in the Logcat settings (on the right side), not when I choose "Show only selected application".
This happens because you use android:process=":remote". The BroadcastReceiver will run in another process than the "main" application process, so the "RING RING" will appear under another process id.
I've been trying to setup my first alarm using AlarmManager and BroadCastReceiver as explained here: http://smartandroidians.blogspot.com.es/2010/04/alarmmanager-and-notification-in.html
My setup:
AndroidManifest.xml:
<receiver android:name="es.radiopodcastellano.player.SleepAlarm" />
My main Activity onCreate (this code actually resides on a subclass, but to simplify I put it there):
#Override
public void onCreate(Bundle savedInstanceState) {
// <Stripped code>
AlarmManager alarm = (AlarmManager) currentContext.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this.getApplicationContext(), SleepAlarm.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this.getApplicationContext(), 0, intent, PendingIntent.FLAG_ONE_SHOT);
alarm.set(AlarmManager.RTC_WAKEUP,(System.currentTimeMillis() + (5 * 1000)),pendingIntent);
}
SleepAlarm.java:
public class SleepAlarm extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("RPod_SleepAlarm","Alarm!!");
}
}
Output from "adb shell dumpsys alarm" show this, so it seems the intent is being called:
es.radiopodcastellano.player
221ms running, 32 wakeups
44 alarms: flg=0x4 cmp=es.radiopodcastellano.player/.SleepAlarm
However, Logcat shows nothing for "RPod_SleepAlarm" tag. What could I be doing wrong?
I found the problem.
The receiver on the manifest was inside another receiver for a widget, and it must be a children of the application. So, if you're having the same behaviour as me, please check that you've set up the AndroidManifest.xml correctly: